diff options
67 files changed, 4979 insertions, 449 deletions
diff --git a/.gitignore b/.gitignore index 04c277989a..2969b015f6 100644 --- a/.gitignore +++ b/.gitignore @@ -125,6 +125,9 @@ config.log /xbmc/guilib/Profile /xbmc/guilib/Profile_FastCap +# /xbmc/peripherals/ +/xbmc/peripherals/bus/Makefile + # /lib/ /lib/Makefile diff --git a/Makefile.in b/Makefile.in index 1aecd71889..aa956c6e1f 100644 --- a/Makefile.in +++ b/Makefile.in @@ -73,7 +73,11 @@ BIN_DIRS= \ xbmc/input/linux \ xbmc/osx \ xbmc/threads \ - xbmc/windowing + xbmc/windowing \ + xbmc/peripherals \ + xbmc/peripherals/bus \ + xbmc/peripherals/devices \ + xbmc/peripherals/dialogs ifeq (@USE_OPENGL@,1) BIN_DIRS += xbmc/rendering/gl @@ -348,6 +352,14 @@ xbmc/utils/utils.a: force $(MAKE) -C xbmc/utils xbmc/osx/osx.a: force $(MAKE) -C xbmc/osx +xbmc/peripherals/peripherals.a: force + $(MAKE) -C xbmc/peripherals +xbmc/peripherals/bus/peripheral-bus.a: force + $(MAKE) -C xbmc/peripherals/bus +xbmc/peripherals/devices/peripheral-devices.a: force + $(MAKE) -C xbmc/peripherals/devices +xbmc/peripherals/dialogs/peripheral-dialogs.a: force + $(MAKE) -C xbmc/peripherals/dialogs lib/libapetag/.libs/libapetag.a: force $(MAKE) -C lib/libapetag lib/cpluff/libcpluff/.libs/libcpluff.a: force @@ -482,7 +494,11 @@ OBJSXBMC= \ lib/libhts/libhts.a \ lib/xbmc-dll-symbols/dll-symbols.a \ xbmc/rendering/rendering.a \ - xbmc/windowing/windowing.a + xbmc/windowing/windowing.a \ + xbmc/peripherals/peripherals.a \ + xbmc/peripherals/bus/peripheral-bus.a \ + xbmc/peripherals/devices/peripheral-devices.a \ + xbmc/peripherals/dialogs/peripheral-dialogs.a ifeq (@USE_OPENGL@,1) OBJSXBMC += xbmc/rendering/gl/rendering_gl.a diff --git a/README.linux b/README.linux index 8d4c6ca1d1..b361da6d85 100644 --- a/README.linux +++ b/README.linux @@ -55,7 +55,7 @@ Build-Depends: debhelper (>= 7.0.50~), python-support, cmake, libbluetooth-dev, zlib1g-dev, libsmbclient-dev, libboost-thread-dev libiso9660-dev, libssl-dev, lsb-release, libvdpau-dev, libmicrohttpd-dev, libmodplug-dev, librtmp-dev, libcrystalhd-dev, curl, python-dev, libyajl-dev, - libplist-dev + libplist-dev, libusb-dev, libudev-dev *** For developers and anyone else who compiles frequently it is recommended to use ccache diff --git a/README.ubuntu b/README.ubuntu index 92af2e7dcb..3d239a8056 100644 --- a/README.ubuntu +++ b/README.ubuntu @@ -44,7 +44,7 @@ Two methods exist to install the required Ubuntu packages: For Ubuntu (all versions >= 7.04): - # sudo apt-get install git-core make g++ gcc gawk pmount libtool nasm yasm automake cmake gperf zip unzip bison libsdl-dev libsdl-image1.2-dev libsdl-gfx1.2-dev libsdl-mixer1.2-dev libfribidi-dev liblzo2-dev libfreetype6-dev libsqlite3-dev libogg-dev libasound-dev python-sqlite libglew-dev libcurl3 libcurl4-gnutls-dev libxrandr-dev libxrender-dev libmad0-dev libogg-dev libvorbisenc2 libsmbclient-dev libmysqlclient-dev libpcre3-dev libdbus-1-dev libhal-dev libhal-storage-dev libjasper-dev libfontconfig-dev libbz2-dev libboost-dev libenca-dev libxt-dev libxmu-dev libpng-dev libjpeg-dev libpulse-dev mesa-utils libcdio-dev libsamplerate-dev libmpeg3-dev libflac-dev libiso9660-dev libass-dev libssl-dev fp-compiler gdc libmpeg2-4-dev libmicrohttpd-dev libmodplug-dev libssh-dev gettext cvs python-dev libyajl-dev libboost-thread-dev libplist-dev + # sudo apt-get install git-core make g++ gcc gawk pmount libtool nasm yasm automake cmake gperf zip unzip bison libsdl-dev libsdl-image1.2-dev libsdl-gfx1.2-dev libsdl-mixer1.2-dev libfribidi-dev liblzo2-dev libfreetype6-dev libsqlite3-dev libogg-dev libasound-dev python-sqlite libglew-dev libcurl3 libcurl4-gnutls-dev libxrandr-dev libxrender-dev libmad0-dev libogg-dev libvorbisenc2 libsmbclient-dev libmysqlclient-dev libpcre3-dev libdbus-1-dev libhal-dev libhal-storage-dev libjasper-dev libfontconfig-dev libbz2-dev libboost-dev libenca-dev libxt-dev libxmu-dev libpng-dev libjpeg-dev libpulse-dev mesa-utils libcdio-dev libsamplerate-dev libmpeg3-dev libflac-dev libiso9660-dev libass-dev libssl-dev fp-compiler gdc libmpeg2-4-dev libmicrohttpd-dev libmodplug-dev libssh-dev gettext cvs python-dev libyajl-dev libboost-thread-dev libplist-dev libusb-dev libudev-dev For Ubuntu Maverick (10.10): # sudo apt-get install autopoint diff --git a/XBMC.xcodeproj/project.pbxproj b/XBMC.xcodeproj/project.pbxproj index a7d63bd320..1b70b4e1bf 100644 --- a/XBMC.xcodeproj/project.pbxproj +++ b/XBMC.xcodeproj/project.pbxproj @@ -68,8 +68,6 @@ 18B4A00B1152BFA5001AF8A6 /* Scraper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B49FFC1152BFA5001AF8A6 /* Scraper.cpp */; }; 18B4A00C1152BFA5001AF8A6 /* ScreenSaver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B49FFE1152BFA5001AF8A6 /* ScreenSaver.cpp */; }; 18B4A00D1152BFA5001AF8A6 /* Visualisation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B4A0001152BFA5001AF8A6 /* Visualisation.cpp */; }; - 18B7006113A697270009C1AF /* KeymapLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7005F13A697270009C1AF /* KeymapLoader.cpp */; }; - 18B7006213A697270009C1AF /* KeymapLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7005F13A697270009C1AF /* KeymapLoader.cpp */; }; 18B700E113A6A5750009C1AF /* AddonVersion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B700DF13A6A5750009C1AF /* AddonVersion.cpp */; }; 18B700E213A6A5750009C1AF /* AddonVersion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B700DF13A6A5750009C1AF /* AddonVersion.cpp */; }; 18B7C3841294203F009E7A26 /* AddonDatabase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C3821294203F009E7A26 /* AddonDatabase.cpp */; }; @@ -1851,6 +1849,32 @@ F5DC888B110A654000EE1B15 /* libapetag.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F5DC888A110A654000EE1B15 /* libapetag.a */; }; F5DC888C110A654000EE1B15 /* libapetag.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F5DC888A110A654000EE1B15 /* libapetag.a */; }; F5E10D381428426B00175026 /* JpegIO.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32C631261423A90F00F18420 /* JpegIO.cpp */; }; + F5E10537140AA38100175026 /* PeripheralBusUSB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5E10513140AA38000175026 /* PeripheralBusUSB.cpp */; }; + F5E10538140AA38100175026 /* PeripheralBus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5E10515140AA38000175026 /* PeripheralBus.cpp */; }; + F5E1053B140AA38100175026 /* Peripheral.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5E1051C140AA38000175026 /* Peripheral.cpp */; }; + F5E1053C140AA38100175026 /* PeripheralBluetooth.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5E1051E140AA38000175026 /* PeripheralBluetooth.cpp */; }; + F5E1053D140AA38100175026 /* PeripheralCecAdapter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5E10520140AA38000175026 /* PeripheralCecAdapter.cpp */; }; + F5E1053E140AA38100175026 /* PeripheralDisk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5E10522140AA38000175026 /* PeripheralDisk.cpp */; }; + F5E1053F140AA38100175026 /* PeripheralHID.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5E10524140AA38000175026 /* PeripheralHID.cpp */; }; + F5E10540140AA38100175026 /* PeripheralNIC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5E10526140AA38000175026 /* PeripheralNIC.cpp */; }; + F5E10541140AA38100175026 /* PeripheralNyxboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5E10528140AA38000175026 /* PeripheralNyxboard.cpp */; }; + F5E10542140AA38100175026 /* PeripheralTuner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5E1052A140AA38000175026 /* PeripheralTuner.cpp */; }; + F5E10543140AA38100175026 /* GUIDialogPeripheralManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5E1052D140AA38000175026 /* GUIDialogPeripheralManager.cpp */; }; + F5E10544140AA38100175026 /* GUIDialogPeripheralSettings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5E1052F140AA38000175026 /* GUIDialogPeripheralSettings.cpp */; }; + F5E10547140AA38100175026 /* Peripherals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5E10533140AA38000175026 /* Peripherals.cpp */; }; + F5E10549140AA38100175026 /* PeripheralBusUSB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5E10513140AA38000175026 /* PeripheralBusUSB.cpp */; }; + F5E1054A140AA38100175026 /* PeripheralBus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5E10515140AA38000175026 /* PeripheralBus.cpp */; }; + F5E1054D140AA38100175026 /* Peripheral.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5E1051C140AA38000175026 /* Peripheral.cpp */; }; + F5E1054E140AA38100175026 /* PeripheralBluetooth.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5E1051E140AA38000175026 /* PeripheralBluetooth.cpp */; }; + F5E1054F140AA38100175026 /* PeripheralCecAdapter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5E10520140AA38000175026 /* PeripheralCecAdapter.cpp */; }; + F5E10550140AA38100175026 /* PeripheralDisk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5E10522140AA38000175026 /* PeripheralDisk.cpp */; }; + F5E10551140AA38100175026 /* PeripheralHID.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5E10524140AA38000175026 /* PeripheralHID.cpp */; }; + F5E10552140AA38100175026 /* PeripheralNIC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5E10526140AA38000175026 /* PeripheralNIC.cpp */; }; + F5E10553140AA38100175026 /* PeripheralNyxboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5E10528140AA38000175026 /* PeripheralNyxboard.cpp */; }; + F5E10554140AA38100175026 /* PeripheralTuner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5E1052A140AA38000175026 /* PeripheralTuner.cpp */; }; + F5E10555140AA38100175026 /* GUIDialogPeripheralManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5E1052D140AA38000175026 /* GUIDialogPeripheralManager.cpp */; }; + F5E10556140AA38100175026 /* GUIDialogPeripheralSettings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5E1052F140AA38000175026 /* GUIDialogPeripheralSettings.cpp */; }; + F5E10559140AA38100175026 /* Peripherals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5E10533140AA38000175026 /* Peripherals.cpp */; }; F5E55B5D10741272006E788A /* DVDPlayerTeletext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5E55B5B10741272006E788A /* DVDPlayerTeletext.cpp */; }; F5E55B5E10741272006E788A /* DVDPlayerTeletext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5E55B5B10741272006E788A /* DVDPlayerTeletext.cpp */; }; F5E55B66107412DE006E788A /* GUIDialogTeletext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5E55B65107412DE006E788A /* GUIDialogTeletext.cpp */; }; @@ -1943,8 +1967,6 @@ 18B49FFF1152BFA5001AF8A6 /* ScreenSaver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScreenSaver.h; sourceTree = "<group>"; }; 18B4A0001152BFA5001AF8A6 /* Visualisation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Visualisation.cpp; sourceTree = "<group>"; }; 18B4A0011152BFA5001AF8A6 /* Visualisation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Visualisation.h; sourceTree = "<group>"; }; - 18B7005F13A697270009C1AF /* KeymapLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KeymapLoader.cpp; sourceTree = "<group>"; }; - 18B7006013A697270009C1AF /* KeymapLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KeymapLoader.h; sourceTree = "<group>"; }; 18B700DF13A6A5750009C1AF /* AddonVersion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AddonVersion.cpp; sourceTree = "<group>"; }; 18B700E013A6A5750009C1AF /* AddonVersion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AddonVersion.h; sourceTree = "<group>"; }; 18B7C3821294203F009E7A26 /* AddonDatabase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AddonDatabase.cpp; sourceTree = "<group>"; }; @@ -3840,6 +3862,33 @@ F5DC87FF110A46C700EE1B15 /* ModplugCodec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ModplugCodec.h; sourceTree = "<group>"; }; F5DC8800110A46C700EE1B15 /* ModplugCodec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ModplugCodec.cpp; sourceTree = "<group>"; }; F5DC888A110A654000EE1B15 /* libapetag.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libapetag.a; path = lib/libapetag/.libs/libapetag.a; sourceTree = "<group>"; }; + F5E10513140AA38000175026 /* PeripheralBusUSB.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PeripheralBusUSB.cpp; sourceTree = "<group>"; }; + F5E10514140AA38000175026 /* PeripheralBusUSB.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PeripheralBusUSB.h; sourceTree = "<group>"; }; + F5E10515140AA38000175026 /* PeripheralBus.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PeripheralBus.cpp; sourceTree = "<group>"; }; + F5E10516140AA38000175026 /* PeripheralBus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PeripheralBus.h; sourceTree = "<group>"; }; + F5E1051C140AA38000175026 /* Peripheral.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Peripheral.cpp; sourceTree = "<group>"; }; + F5E1051D140AA38000175026 /* Peripheral.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Peripheral.h; sourceTree = "<group>"; }; + F5E1051E140AA38000175026 /* PeripheralBluetooth.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PeripheralBluetooth.cpp; sourceTree = "<group>"; }; + F5E1051F140AA38000175026 /* PeripheralBluetooth.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PeripheralBluetooth.h; sourceTree = "<group>"; }; + F5E10520140AA38000175026 /* PeripheralCecAdapter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PeripheralCecAdapter.cpp; sourceTree = "<group>"; }; + F5E10521140AA38000175026 /* PeripheralCecAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PeripheralCecAdapter.h; sourceTree = "<group>"; }; + F5E10522140AA38000175026 /* PeripheralDisk.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PeripheralDisk.cpp; sourceTree = "<group>"; }; + F5E10523140AA38000175026 /* PeripheralDisk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PeripheralDisk.h; sourceTree = "<group>"; }; + F5E10524140AA38000175026 /* PeripheralHID.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PeripheralHID.cpp; sourceTree = "<group>"; }; + F5E10525140AA38000175026 /* PeripheralHID.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PeripheralHID.h; sourceTree = "<group>"; }; + F5E10526140AA38000175026 /* PeripheralNIC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PeripheralNIC.cpp; sourceTree = "<group>"; }; + F5E10527140AA38000175026 /* PeripheralNIC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PeripheralNIC.h; sourceTree = "<group>"; }; + F5E10528140AA38000175026 /* PeripheralNyxboard.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PeripheralNyxboard.cpp; sourceTree = "<group>"; }; + F5E10529140AA38000175026 /* PeripheralNyxboard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PeripheralNyxboard.h; sourceTree = "<group>"; }; + F5E1052A140AA38000175026 /* PeripheralTuner.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PeripheralTuner.cpp; sourceTree = "<group>"; }; + F5E1052B140AA38000175026 /* PeripheralTuner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PeripheralTuner.h; sourceTree = "<group>"; }; + F5E1052D140AA38000175026 /* GUIDialogPeripheralManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUIDialogPeripheralManager.cpp; sourceTree = "<group>"; }; + F5E1052E140AA38000175026 /* GUIDialogPeripheralManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUIDialogPeripheralManager.h; sourceTree = "<group>"; }; + F5E1052F140AA38000175026 /* GUIDialogPeripheralSettings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUIDialogPeripheralSettings.cpp; sourceTree = "<group>"; }; + F5E10530140AA38000175026 /* GUIDialogPeripheralSettings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUIDialogPeripheralSettings.h; sourceTree = "<group>"; }; + F5E10533140AA38000175026 /* Peripherals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Peripherals.cpp; sourceTree = "<group>"; }; + F5E10534140AA38000175026 /* Peripherals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Peripherals.h; sourceTree = "<group>"; }; + F5E10535140AA38000175026 /* PeripheralTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PeripheralTypes.h; sourceTree = "<group>"; }; F5E55B5B10741272006E788A /* DVDPlayerTeletext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DVDPlayerTeletext.cpp; sourceTree = "<group>"; }; F5E55B5C10741272006E788A /* DVDPlayerTeletext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DVDPlayerTeletext.h; sourceTree = "<group>"; }; F5E55B64107412DE006E788A /* GUIDialogTeletext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUIDialogTeletext.h; sourceTree = "<group>"; }; @@ -4347,8 +4396,6 @@ 18B7C8CE12942546009E7A26 /* KeyboardLayoutConfiguration.h */, 18B7C8CF12942546009E7A26 /* KeyboardStat.cpp */, 18B7C8D012942546009E7A26 /* KeyboardStat.h */, - 18B7005F13A697270009C1AF /* KeymapLoader.cpp */, - 18B7006013A697270009C1AF /* KeymapLoader.h */, 18B7C8D112942546009E7A26 /* MouseStat.cpp */, 18B7C8D212942546009E7A26 /* MouseStat.h */, 18B7C8D312942546009E7A26 /* SDLJoystick.cpp */, @@ -5028,6 +5075,7 @@ 18B7C853129423A7009E7A26 /* music */, 431376F212D6449100680C15 /* network */, E37D5CB40D3023BB0081D327 /* osx */, + F5E1050C140AA38000175026 /* peripherals */, 4313767E12D63EC200680C15 /* pictures */, 18B7C91B129428CA009E7A26 /* playlists */, 430C880812D649B10098821A /* powermanagement */, @@ -6959,6 +7007,72 @@ path = "json-rpc"; sourceTree = "<group>"; }; + F5E1050C140AA38000175026 /* peripherals */ = { + isa = PBXGroup; + children = ( + F5E1050D140AA38000175026 /* bus */, + F5E1051A140AA38000175026 /* devices */, + F5E1052C140AA38000175026 /* dialogs */, + F5E10533140AA38000175026 /* Peripherals.cpp */, + F5E10534140AA38000175026 /* Peripherals.h */, + F5E10535140AA38000175026 /* PeripheralTypes.h */, + ); + path = peripherals; + sourceTree = "<group>"; + }; + F5E1050D140AA38000175026 /* bus */ = { + isa = PBXGroup; + children = ( + F5E10512140AA38000175026 /* osx */, + F5E10515140AA38000175026 /* PeripheralBus.cpp */, + F5E10516140AA38000175026 /* PeripheralBus.h */, + ); + path = bus; + sourceTree = "<group>"; + }; + F5E10512140AA38000175026 /* osx */ = { + isa = PBXGroup; + children = ( + F5E10513140AA38000175026 /* PeripheralBusUSB.cpp */, + F5E10514140AA38000175026 /* PeripheralBusUSB.h */, + ); + path = osx; + sourceTree = "<group>"; + }; + F5E1051A140AA38000175026 /* devices */ = { + isa = PBXGroup; + children = ( + F5E1051C140AA38000175026 /* Peripheral.cpp */, + F5E1051D140AA38000175026 /* Peripheral.h */, + F5E1051E140AA38000175026 /* PeripheralBluetooth.cpp */, + F5E1051F140AA38000175026 /* PeripheralBluetooth.h */, + F5E10520140AA38000175026 /* PeripheralCecAdapter.cpp */, + F5E10521140AA38000175026 /* PeripheralCecAdapter.h */, + F5E10522140AA38000175026 /* PeripheralDisk.cpp */, + F5E10523140AA38000175026 /* PeripheralDisk.h */, + F5E10524140AA38000175026 /* PeripheralHID.cpp */, + F5E10525140AA38000175026 /* PeripheralHID.h */, + F5E10526140AA38000175026 /* PeripheralNIC.cpp */, + F5E10527140AA38000175026 /* PeripheralNIC.h */, + F5E10528140AA38000175026 /* PeripheralNyxboard.cpp */, + F5E10529140AA38000175026 /* PeripheralNyxboard.h */, + F5E1052A140AA38000175026 /* PeripheralTuner.cpp */, + F5E1052B140AA38000175026 /* PeripheralTuner.h */, + ); + path = devices; + sourceTree = "<group>"; + }; + F5E1052C140AA38000175026 /* dialogs */ = { + isa = PBXGroup; + children = ( + F5E1052D140AA38000175026 /* GUIDialogPeripheralManager.cpp */, + F5E1052E140AA38000175026 /* GUIDialogPeripheralManager.h */, + F5E1052F140AA38000175026 /* GUIDialogPeripheralSettings.cpp */, + F5E10530140AA38000175026 /* GUIDialogPeripheralSettings.h */, + ); + path = dialogs; + sourceTree = "<group>"; + }; F5E55E601076B34F006E788A /* libsquish */ = { isa = PBXGroup; children = ( @@ -8114,7 +8228,6 @@ 1840B74D13993D8A007C848B /* JSONVariantParser.cpp in Sources */, 1840B75313993DA0007C848B /* JSONVariantWriter.cpp in Sources */, 7C0A7EC013A5DBCE00AFC2BD /* AppParamParser.cpp in Sources */, - 18B7006113A697270009C1AF /* KeymapLoader.cpp in Sources */, 18B700E113A6A5750009C1AF /* AddonVersion.cpp in Sources */, F558F25613ABCF7800631E12 /* WinEventsOSX.mm in Sources */, F558F27B13ABD56600631E12 /* DirtyRegionSolvers.cpp in Sources */, @@ -8143,6 +8256,19 @@ DF44845E140048C80069344B /* PipesManager.cpp in Sources */, DF4484EE140054530069344B /* BXAcodec.cpp in Sources */, DF98D98C1434F47D00A6EBE1 /* SkinVariable.cpp in Sources */, + F5E10537140AA38100175026 /* PeripheralBusUSB.cpp in Sources */, + F5E10538140AA38100175026 /* PeripheralBus.cpp in Sources */, + F5E1053B140AA38100175026 /* Peripheral.cpp in Sources */, + F5E1053C140AA38100175026 /* PeripheralBluetooth.cpp in Sources */, + F5E1053D140AA38100175026 /* PeripheralCecAdapter.cpp in Sources */, + F5E1053E140AA38100175026 /* PeripheralDisk.cpp in Sources */, + F5E1053F140AA38100175026 /* PeripheralHID.cpp in Sources */, + F5E10540140AA38100175026 /* PeripheralNIC.cpp in Sources */, + F5E10541140AA38100175026 /* PeripheralNyxboard.cpp in Sources */, + F5E10542140AA38100175026 /* PeripheralTuner.cpp in Sources */, + F5E10543140AA38100175026 /* GUIDialogPeripheralManager.cpp in Sources */, + F5E10544140AA38100175026 /* GUIDialogPeripheralSettings.cpp in Sources */, + F5E10547140AA38100175026 /* Peripherals.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -9018,7 +9144,6 @@ 1840B74E13993D8A007C848B /* JSONVariantParser.cpp in Sources */, 1840B75413993DA0007C848B /* JSONVariantWriter.cpp in Sources */, 7C0A7EC113A5DBCE00AFC2BD /* AppParamParser.cpp in Sources */, - 18B7006213A697270009C1AF /* KeymapLoader.cpp in Sources */, 18B700E213A6A5750009C1AF /* AddonVersion.cpp in Sources */, F558F25713ABCF7800631E12 /* WinEventsOSX.mm in Sources */, F558F27C13ABD56600631E12 /* DirtyRegionSolvers.cpp in Sources */, @@ -9047,6 +9172,19 @@ DF448460140048C80069344B /* PipesManager.cpp in Sources */, DF4484EF140054530069344B /* BXAcodec.cpp in Sources */, DF98D98D1434F47D00A6EBE1 /* SkinVariable.cpp in Sources */, + F5E10549140AA38100175026 /* PeripheralBusUSB.cpp in Sources */, + F5E1054A140AA38100175026 /* PeripheralBus.cpp in Sources */, + F5E1054D140AA38100175026 /* Peripheral.cpp in Sources */, + F5E1054E140AA38100175026 /* PeripheralBluetooth.cpp in Sources */, + F5E1054F140AA38100175026 /* PeripheralCecAdapter.cpp in Sources */, + F5E10550140AA38100175026 /* PeripheralDisk.cpp in Sources */, + F5E10551140AA38100175026 /* PeripheralHID.cpp in Sources */, + F5E10552140AA38100175026 /* PeripheralNIC.cpp in Sources */, + F5E10553140AA38100175026 /* PeripheralNyxboard.cpp in Sources */, + F5E10554140AA38100175026 /* PeripheralTuner.cpp in Sources */, + F5E10555140AA38100175026 /* GUIDialogPeripheralManager.cpp in Sources */, + F5E10556140AA38100175026 /* GUIDialogPeripheralSettings.cpp in Sources */, + F5E10559140AA38100175026 /* Peripherals.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/addons/skin.confluence/720p/DialogPeripheralManager.xml b/addons/skin.confluence/720p/DialogPeripheralManager.xml new file mode 100644 index 0000000000..16195d97ca --- /dev/null +++ b/addons/skin.confluence/720p/DialogPeripheralManager.xml @@ -0,0 +1,381 @@ +<window id="10140"> + <defaultcontrol always="true">20</defaultcontrol> + <allowoverlay>no</allowoverlay> + <coordinates> + <system>1</system> + <posx>190</posx> + <posy>30</posy> + </coordinates> + <include>dialogeffect</include> + + <controls> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>900</width> + <height>660</height> + <texture border="40">DialogBack.png</texture> + </control> + <control type="image"> + <description>Dialog Header image</description> + <posx>40</posx> + <posy>16</posy> + <width>820</width> + <height>40</height> + <texture>dialogheader.png</texture> + </control> + <control type="label"> + <description>header label</description> + <posx>40</posx> + <posy>20</posy> + <width>820</width> + <height>30</height> + <font>font13_title</font> + <label>$LOCALIZE[35000]</label> + <align>center</align> + <aligny>center</aligny> + <textcolor>selected</textcolor> + <shadowcolor>black</shadowcolor> + </control> + <control type="label"> + <description>header label</description> + <posx>40</posx> + <posy>20</posy> + <width>820</width> + <height>30</height> + <font>font13_title</font> + <label>$LOCALIZE[35000]</label> + <align>center</align> + <aligny>center</aligny> + <textcolor>selected</textcolor> + <shadowcolor>black</shadowcolor> + </control> + <control type="button"> + <description>Close Window button</description> + <posx>810</posx> + <posy>15</posy> + <width>64</width> + <height>32</height> + <label>-</label> + <font>-</font> + <onclick>PreviousMenu</onclick> + <texturefocus>DialogCloseButton-focus.png</texturefocus> + <texturenofocus>DialogCloseButton.png</texturenofocus> + <onleft>10</onleft> + <onright>10</onright> + <onup>10</onup> + <ondown>10</ondown> + <visible>system.getbool(input.enablemouse)</visible> + </control> + + <control type="group"> + <description>Peripheral list</description> + <posx>20</posx> + <posy>70</posy> + <control type="label"> + <description>peripheral option header</description> + <posx>130</posx> + <posy>0</posy> + <width>380</width> + <height>20</height> + <font>font12_title</font> + <label>$LOCALIZE[35000]</label> + <align>left</align> + <aligny>center</aligny> + <textcolor>blue</textcolor> + <shadowcolor>black</shadowcolor> + </control> + <control type="scrollbar" id="60"> + <posx>0</posx> + <posy>40</posy> + <width>25</width> + <height>445</height> + <texturesliderbackground border="0,14,0,14">ScrollBarV.png</texturesliderbackground> + <texturesliderbar border="0,14,0,14">ScrollBarV_bar.png</texturesliderbar> + <texturesliderbarfocus border="0,14,0,14">ScrollBarV_bar_focus.png</texturesliderbarfocus> + <textureslidernib>ScrollBarNib.png</textureslidernib> + <textureslidernibfocus>ScrollBarNib.png</textureslidernibfocus> + <onleft>9000</onleft> + <onright>20</onright> + <showonepage>false</showonepage> + <orientation>vertical</orientation> + </control> + <control type="image"> + <posx>25</posx> + <posy>35</posy> + <width>330</width> + <height>440</height> + <texture border="5">button-nofocus.png</texture> + </control> + + <control type="list" id="20"> + <posx>30</posx> + <posy>40</posy> + <width>320</width> + <height>445</height> + <onup>20</onup> + <ondown>20</ondown> + <onleft>60</onleft> + <onright>9000</onright> + <pagecontrol>60</pagecontrol> + <scrolltime>200</scrolltime> + <itemlayout height="45" width="320"> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>320</width> + <height>40</height> + <texture border="5">button-nofocus.png</texture> + </control> + <control type="label"> + <posx>10</posx> + <posy>0</posy> + <width>320</width> + <height>40</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>grey2</textcolor> + <selectedcolor>selected</selectedcolor> + <info>ListItem.Label</info> + </control> + </itemlayout> + <focusedlayout height="45" width="320"> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>320</width> + <height>40</height> + <texture border="5">button-nofocus.png</texture> + <visible>!Control.HasFocus(20)</visible> + </control> + <control type="image"> + <posx>0</posx> + <posy>0</posy> + <width>320</width> + <height>40</height> + <texture border="5">button-focus2.png</texture> + <visible>Control.HasFocus(20)</visible> + </control> + <control type="label"> + <posx>10</posx> + <posy>0</posy> + <width>320</width> + <height>40</height> + <font>font12</font> + <align>left</align> + <aligny>center</aligny> + <textcolor>white</textcolor> + <selectedcolor>selected</selectedcolor> + <info>ListItem.Label</info> + </control> + </focusedlayout> + </control> + + <control type="label"> + <description>Page Count Label</description> + <posx>80</posx> + <posy>480</posy> + <width>420</width> + <height>20</height> + <font>font12</font> + <textcolor>grey</textcolor> + <scroll>false</scroll> + <align>center</align> + <aligny>center</aligny> + <label>([COLOR=blue]$INFO[Container(20).NumItems][/COLOR]) $LOCALIZE[19019] - $LOCALIZE[31024] ([COLOR=blue]$INFO[Container(20).CurrentPage]/$INFO[Container(20).NumPages][/COLOR])</label> + </control> + </control> + + <control type="group" id="9002"> + <control type="group"> + <posx>400</posx> + <posy>70</posy> + <control type="label"> + <description>peripheral option header</description> + <posx>150</posx> + <posy>0</posy> + <width>380</width> + <height>20</height> + <font>font12_title</font> + <label>$LOCALIZE[33029]</label> + <align>left</align> + <aligny>center</aligny> + <textcolor>blue</textcolor> + <shadowcolor>black</shadowcolor> + </control> + + <control type="label"> + <description>name</description> + <posx>0</posx> + <posy>35</posy> + <width>380</width> + <height>20</height> + <label>$LOCALIZE[35502]</label> + <align>left</align> + <aligny>center</aligny> + <font>font12</font> + <textcolor>blue</textcolor> + <shadowcolor>black</shadowcolor> + </control> + <control type="label"> + <description>name value</description> + <posx>150</posx> + <posy>35</posy> + <width>330</width> + <height>20</height> + <label fallback="13205">$INFO[Container(20).ListItem.Label]</label> + <align>left</align> + <aligny>center</aligny> + <font>font12</font> + <scroll>true</scroll> + <shadowcolor>black</shadowcolor> + </control> + + <control type="label"> + <description>location</description> + <posx>0</posx> + <posy>60</posy> + <width>380</width> + <height>20</height> + <label>$LOCALIZE[35500]</label> + <align>left</align> + <aligny>center</aligny> + <font>font12</font> + <textcolor>blue</textcolor> + <shadowcolor>black</shadowcolor> + </control> + <control type="label"> + <description>location value</description> + <posx>150</posx> + <posy>60</posy> + <width>330</width> + <height>20</height> + <label fallback="13205">$INFO[Container(20).ListItem.Property(Bus)] - $INFO[Container(20).ListItem.Property(Location)]</label> + <align>left</align> + <aligny>center</aligny> + <font>font12</font> + <scroll>true</scroll> + <shadowcolor>black</shadowcolor> + </control> + + <control type="label"> + <description>class</description> + <posx>0</posx> + <posy>85</posy> + <width>380</width> + <height>20</height> + <label>$LOCALIZE[35501]</label> + <align>left</align> + <aligny>center</aligny> + <font>font12</font> + <textcolor>blue</textcolor> + <shadowcolor>black</shadowcolor> + </control> + <control type="label"> + <description>class value</description> + <posx>150</posx> + <posy>85</posy> + <width>330</width> + <height>20</height> + <label fallback="13205">$INFO[Container(20).ListItem.Property(Class)]</label> + <align>left</align> + <aligny>center</aligny> + <font>font12</font> + <scroll>true</scroll> + <shadowcolor>black</shadowcolor> + </control> + + <control type="label"> + <description>vendor</description> + <posx>0</posx> + <posy>110</posy> + <width>380</width> + <height>20</height> + <label>$LOCALIZE[35503]</label> + <align>left</align> + <aligny>center</aligny> + <font>font12</font> + <textcolor>blue</textcolor> + <shadowcolor>black</shadowcolor> + </control> + <control type="label"> + <description>vendor value</description> + <posx>150</posx> + <posy>110</posy> + <width>330</width> + <height>20</height> + <label fallback="13205">$INFO[Container(20).ListItem.Property(Vendor)]</label> + <align>left</align> + <aligny>center</aligny> + <font>font12</font> + <scroll>true</scroll> + <shadowcolor>black</shadowcolor> + </control> + + <control type="label"> + <description>product</description> + <posx>0</posx> + <posy>135</posy> + <width>380</width> + <height>20</height> + <label>$LOCALIZE[35504]</label> + <align>left</align> + <aligny>center</aligny> + <font>font12</font> + <textcolor>blue</textcolor> + <shadowcolor>black</shadowcolor> + </control> + <control type="label"> + <description>product value</description> + <posx>150</posx> + <posy>135</posy> + <width>330</width> + <height>20</height> + <label fallback="13205">$INFO[Container(20).ListItem.Property(Product)]</label> + <align>left</align> + <aligny>center</aligny> + <font>font12</font> + <scroll>true</scroll> + <shadowcolor>black</shadowcolor> + </control> + + </control> + </control> + + <control type="group" id="9000"> + <posx>70</posx> + <posy>590</posy> + <control type="button" id="10"> + <description>Close Button</description> + <posy>0</posy> + <posx>100</posx> + <width>200</width> + <height>40</height> + <align>center</align> + <aligny>center</aligny> + <font>font12_title</font> + <label>186</label> + <onleft>11</onleft> + <onright>11</onright> + <onup>20</onup> + <ondown>20</ondown> + </control> + <control type="button" id="11"> + <description>Settings Button</description> + <posy>0</posy> + <posx>400</posx> + <width>200</width> + <height>40</height> + <align>center</align> + <aligny>center</aligny> + <font>font12_title</font> + <label>5</label> + <onleft>10</onleft> + <onright>10</onright> + <onup>20</onup> + <ondown>20</ondown> + </control> + </control> + </controls> +</window> diff --git a/addons/skin.confluence/720p/DialogPeripheralSettings.xml b/addons/skin.confluence/720p/DialogPeripheralSettings.xml new file mode 100644 index 0000000000..df089c1764 --- /dev/null +++ b/addons/skin.confluence/720p/DialogPeripheralSettings.xml @@ -0,0 +1,183 @@ +<window id="123"> + <defaultcontrol>5</defaultcontrol> + <coordinates> + <system>1</system> + <posx>240</posx> + <posy>60</posy> + </coordinates> + <include>dialogeffect</include> + <controls> + <control type="group"> + <animation effect="fade" start="100" end="0" time="400" condition="Window.IsVisible(SliderDialog) | Window.IsVisible(FileBrowser)">Conditional</animation> + <control type="image"> + <description>background image</description> + <posx>0</posx> + <posy>0</posy> + <width>800</width> + <height>600</height> + <texture border="40">DialogBack2.png</texture> + </control> + <control type="image"> + <description>Dialog Header image</description> + <posx>40</posx> + <posy>16</posy> + <width>720</width> + <height>40</height> + <texture>dialogheader.png</texture> + </control> + <control type="button"> + <description>Close Window button</description> + <posx>710</posx> + <posy>15</posy> + <width>64</width> + <height>32</height> + <label>-</label> + <font>-</font> + <onclick>PreviousMenu</onclick> + <texturefocus>DialogCloseButton-focus.png</texturefocus> + <texturenofocus>DialogCloseButton.png</texturenofocus> + <onleft>2</onleft> + <onright>2</onright> + <onup>2</onup> + <ondown>2</ondown> + <visible>system.getbool(input.enablemouse)</visible> + </control> + <control type="label" id="3"> + <description>No Settings Label</description> + <posx>20</posx> + <posy>180</posy> + <width>760</width> + <align>center</align> + <label>35004</label> + <font>font13caps</font> + </control> + <control type="grouplist" id="5"> + <description>control area</description> + <posx>40</posx> + <posy>65</posy> + <width>720</width> + <height>490</height> + <itemgap>5</itemgap> + <pagecontrol>60</pagecontrol> + <onleft>9000</onleft> + <onright>60</onright> + <onup>5</onup> + <ondown>5</ondown> + </control> + <control type="scrollbar" id="60"> + <posx>760</posx> + <posy>65</posy> + <width>25</width> + <height>450</height> + <texturesliderbackground border="0,14,0,14">ScrollBarV.png</texturesliderbackground> + <texturesliderbar border="0,14,0,14">ScrollBarV_bar.png</texturesliderbar> + <texturesliderbarfocus border="0,14,0,14">ScrollBarV_bar_focus.png</texturesliderbarfocus> + <textureslidernib>ScrollBarNib.png</textureslidernib> + <textureslidernibfocus>ScrollBarNib.png</textureslidernibfocus> + <onleft>5</onleft> + <onright>9000</onright> + <ondown>61</ondown> + <onup>61</onup> + <showonepage>true</showonepage> + <orientation>vertical</orientation> + </control> + </control> + <control type="sliderex" id="10"> + <description>Default Slider</description> + <height>40</height> + <texturenofocus border="5">button-nofocus.png</texturenofocus> + <texturefocus border="5">button-focus2.png</texturefocus> + <font>font13</font> + <textcolor>grey2</textcolor> + <focusedcolor>white</focusedcolor> + </control> + <control type="button" id="7"> + <description>Default Button</description> + <posx>0</posx> + <posy>0</posy> + <height>40</height> + <font>font13</font> + <textcolor>grey2</textcolor> + <focusedcolor>white</focusedcolor> + <texturefocus border="5">button-focus2.png</texturefocus> + </control> + <control type="radiobutton" id="8"> + <description>Default RadioButton</description> + <posx>0</posx> + <posy>0</posy> + <height>40</height> + <font>font13</font> + <textcolor>grey2</textcolor> + <focusedcolor>white</focusedcolor> + <texturefocus border="5">button-focus2.png</texturefocus> + </control> + <control type="spincontrolex" id="9"> + <description>Default SpinControlex</description> + <posx>0</posx> + <posy>0</posy> + <height>40</height> + <font>font13</font> + <textcolor>grey2</textcolor> + <focusedcolor>white</focusedcolor> + <texturenofocus border="5">button-nofocus.png</texturenofocus> + <texturefocus border="5">button-focus2.png</texturefocus> + <aligny>center</aligny> + <reverse>yes</reverse> + </control> + <control type="image" id="11"> + <description>separator image</description> + <height>2</height> + <texture>separator2.png</texture> + </control> + + <control type="group" id="9000"> + <posx>50</posx> + <posy>530</posy> + <control type="button" id="29"> + <description>Cancel Button</description> + <posy>0</posy> + <posx>0</posx> + <width>200</width> + <height>40</height> + <align>center</align> + <aligny>center</aligny> + <font>font12_title</font> + <label>222</label> + <onleft>50</onleft> + <onright>28</onright> + <onup>5</onup> + <ondown>5</ondown> + </control> + <control type="button" id="28"> + <description>OK Button</description> + <posy>0</posy> + <posx>250</posx> + <width>200</width> + <height>40</height> + <align>center</align> + <aligny>center</aligny> + <font>font12_title</font> + <label>186</label> + <onleft>29</onleft> + <onright>50</onright> + <onup>5</onup> + <ondown>5</ondown> + </control> + <control type="button" id="50"> + <description>Defaults Button</description> + <posy>0</posy> + <posx>500</posx> + <width>200</width> + <height>40</height> + <align>center</align> + <aligny>center</aligny> + <font>font12_title</font> + <label>409</label> + <onleft>28</onleft> + <onright>29</onright> + <onup>5</onup> + <ondown>5</ondown> + </control> + </control> + </controls> +</window> diff --git a/configure.in b/configure.in index 08ef959902..5f6fc78f3f 100755 --- a/configure.in +++ b/configure.in @@ -119,6 +119,10 @@ libplist_disabled="== AirPlay support disabled. ==" alsa_not_found="== Could not find ALSA. ALSA support disabled. ==" dbus_not_found="== Could not find DBUS. DBUS support disabled. ==" +udev_not_found="== Could not find libudev. Will use polling to check for device changes. ==" +udev_disabled="== udev support disabled. Will use polling to check for device changes. ==" +libusb_not_found="== Could not find libusb. Plug and play USB device support will not be available. ==" +libusb_disabled="== libusb disabled. Plug and play USB device support will not be available. ==" # External library message strings external_libraries_enabled="== Use of all supported external libraries enabled. ==" @@ -378,6 +382,18 @@ AC_ARG_WITH([lirc-device], [lirc_device=/dev/lircd]) AC_DEFINE_UNQUOTED([LIRC_DEVICE], ["$lirc_device"], [Default LIRC device]) +AC_ARG_ENABLE([udev], + [AS_HELP_STRING([--enable-udev], + [enable udev support (default is yes)])], + [use_udev=$enableval], + [use_udev=yes]) + +AC_ARG_ENABLE([libusb], + [AS_HELP_STRING([--enable-libusb], + [enable libusb support (default is yes)])], + [use_libusb=$enableval], + [use_libusb=yes]) + ### External libraries options AC_ARG_ENABLE([external-libraries], [AS_HELP_STRING([--enable-external-libraries], @@ -1050,6 +1066,39 @@ if test "x$use_airtunes" != "xno"; then fi fi +# udev +if test "$host_vendor" = "apple" ; then + use_udev="no" + AC_MSG_NOTICE($udev_disabled) +else + if test "$use_udev" = "yes" ; then + PKG_CHECK_MODULES([UDEV], [libudev], + [INCLUDES="$INCLUDES $UDEV_CFLAGS"; LIBS="$LIBS $UDEV_LIBS"]; \ + AC_DEFINE([HAVE_LIBUDEV],[1],["Define to 1 if libudev is installed"]), + use_udev="no";AC_MSG_ERROR($udev_not_found)) + else + AC_MSG_NOTICE($udev_disabled) + fi +fi + +# libusb +if test "$host_vendor" = "apple" ; then + use_libusb="no" + HAVE_LIBUSB=0 + AC_MSG_NOTICE($libusb_disabled) +else + if test "$use_libusb" = "yes" ; then + PKG_CHECK_MODULES([USB], [libusb], + [INCLUDES="$INCLUDES $USB_CFLAGS"; LIBS="$LIBS $USB_LIBS"; HAVE_LIBUSB=1]; \ + AC_DEFINE([HAVE_LIBUSB],[1],["Define to 1 if libusb is installed"]), + use_libusb="no"; HAVE_LIBUSB=0; AC_MSG_ERROR($libusb_not_found)) + else + use_libusb="no" + HAVE_LIBUSB=0 + AC_MSG_NOTICE($libusb_disabled) + fi +fi + ### External libraries checks # External FFmpeg if test "$use_external_ffmpeg" = "yes"; then @@ -1729,7 +1778,8 @@ OUTPUT_FILES="Makefile \ tools/Linux/xbmc.sh \ tools/Linux/xbmc-standalone.sh \ tools/TexturePacker/Makefile \ - tools/EventClients/Clients/OSXRemote/Makefile" + tools/EventClients/Clients/OSXRemote/Makefile \ + xbmc/peripherals/bus/Makefile" # Line below is used so we can use AM_INIT_AUTOMAKE. The corresponding # .dummy.am does nothing. @@ -1781,6 +1831,7 @@ AC_SUBST(USE_TEXTUREPACKER) AC_SUBST(USE_TEXTUREPACKER_NATIVE) AC_SUBST(USE_TEXTUREPACKER_NATIVE_ROOT) AC_SUBST(USE_AIRTUNES) +AC_SUBST(HAVE_LIBUSB) # pushd and popd are not available in other shells besides bash, so implement # our own pushd/popd functions diff --git a/language/English/strings.xml b/language/English/strings.xml index f3095f803d..6bcb702ba0 100644 --- a/language/English/strings.xml +++ b/language/English/strings.xml @@ -2351,4 +2351,28 @@ <string id="34201">Can't find a next item to play</string> <string id="34202">Can't find a previous item to play</string> + + <string id="35000">Peripherals</string> + + <string id="35001">Generic HID device</string> + <string id="35002">Generic network adapter</string> + <string id="35003">Generic disk</string> + <string id="35004">There are no settings available for this peripheral.</string> + <string id="35005">New device configured</string> + <string id="35006">Device removed</string> + <string id="35007">Keymap to use for this device</string> + <string id="35008">Keymap enabled</string> + + <string id="35500">Location</string> + <string id="35501">Class</string> + <string id="35502">Name</string> + <string id="35503">Vendor</string> + <string id="35504">Product ID</string> + + <string id="36000">Pulse-Eight CEC adapter</string> + <string id="36001">Pulse-Eight Nyxboard</string> + <string id="36002">Switch to keyboard side command</string> + <string id="36003">Switch to remote side command</string> + <string id="36004">Press "user" button command</string> + <string id="36005">Enable switch side commands</string> </strings> diff --git a/project/VS2010Express/XBMC.vcxproj b/project/VS2010Express/XBMC.vcxproj index 51afad2f84..19b6aa2dcd 100644 --- a/project/VS2010Express/XBMC.vcxproj +++ b/project/VS2010Express/XBMC.vcxproj @@ -451,7 +451,6 @@ <ClCompile Include="..\..\xbmc\input\InertialScrollingHandler.cpp" /> <ClCompile Include="..\..\xbmc\input\KeyboardLayoutConfiguration.cpp" /> <ClCompile Include="..\..\xbmc\input\KeyboardStat.cpp" /> - <ClCompile Include="..\..\xbmc\input\KeymapLoader.cpp" /> <ClCompile Include="..\..\xbmc\input\MouseStat.cpp" /> <ClCompile Include="..\..\xbmc\input\SDLJoystick.cpp" /> <ClCompile Include="..\..\xbmc\input\windows\IRServerSuite.cpp" /> @@ -676,6 +675,19 @@ <ClCompile Include="..\..\xbmc\NfoFile.cpp" /> <ClCompile Include="..\..\xbmc\PartyModeManager.cpp" /> <ClCompile Include="..\..\xbmc\PasswordManager.cpp" /> + <ClCompile Include="..\..\xbmc\peripherals\bus\PeripheralBus.cpp" /> + <ClCompile Include="..\..\xbmc\peripherals\bus\win32\PeripheralBusUSB.cpp" /> + <ClCompile Include="..\..\xbmc\peripherals\devices\Peripheral.cpp" /> + <ClCompile Include="..\..\xbmc\peripherals\devices\PeripheralBluetooth.cpp" /> + <ClCompile Include="..\..\xbmc\peripherals\devices\PeripheralCecAdapter.cpp" /> + <ClCompile Include="..\..\xbmc\peripherals\devices\PeripheralDisk.cpp" /> + <ClCompile Include="..\..\xbmc\peripherals\devices\PeripheralHID.cpp" /> + <ClCompile Include="..\..\xbmc\peripherals\devices\PeripheralNIC.cpp" /> + <ClCompile Include="..\..\xbmc\peripherals\devices\PeripheralNyxboard.cpp" /> + <ClCompile Include="..\..\xbmc\peripherals\devices\PeripheralTuner.cpp" /> + <ClCompile Include="..\..\xbmc\peripherals\dialogs\GUIDialogPeripheralManager.cpp" /> + <ClCompile Include="..\..\xbmc\peripherals\dialogs\GUIDialogPeripheralSettings.cpp" /> + <ClCompile Include="..\..\xbmc\peripherals\Peripherals.cpp" /> <ClCompile Include="..\..\xbmc\pictures\GUIDialogPictureInfo.cpp" /> <ClCompile Include="..\..\xbmc\pictures\GUIViewStatePictures.cpp" /> <ClCompile Include="..\..\xbmc\pictures\GUIWindowPictures.cpp" /> @@ -837,7 +849,6 @@ <ClCompile Include="..\..\xbmc\win32\strverscmp.cpp" /> <ClCompile Include="..\..\xbmc\win32\Win32DelayedDllLoad.cpp" /> <ClCompile Include="..\..\xbmc\win32\win32env.cpp" /> - <ClCompile Include="..\..\xbmc\win32\WIN32USBScan.cpp" /> <ClCompile Include="..\..\xbmc\win32\WIN32Util.cpp" /> <ClCompile Include="..\..\xbmc\win32\WINDirectSound.cpp" /> <ClCompile Include="..\..\xbmc\win32\WindowHelper.cpp" /> @@ -1371,7 +1382,6 @@ <ClInclude Include="..\..\xbmc\input\InertialScrollingHandler.h" /> <ClInclude Include="..\..\xbmc\input\KeyboardLayoutConfiguration.h" /> <ClInclude Include="..\..\xbmc\input\KeyboardStat.h" /> - <ClInclude Include="..\..\xbmc\input\KeymapLoader.h" /> <ClInclude Include="..\..\xbmc\input\MouseStat.h" /> <ClInclude Include="..\..\xbmc\input\SDLJoystick.h" /> <ClInclude Include="..\..\xbmc\input\windows\IRServerSuite.h" /> @@ -1518,6 +1528,20 @@ <ClInclude Include="..\..\xbmc\NfoFile.h" /> <ClInclude Include="..\..\xbmc\PartyModeManager.h" /> <ClInclude Include="..\..\xbmc\PasswordManager.h" /> + <ClInclude Include="..\..\xbmc\peripherals\bus\PeripheralBus.h" /> + <ClInclude Include="..\..\xbmc\peripherals\bus\win32\PeripheralBusUSB.h" /> + <ClInclude Include="..\..\xbmc\peripherals\devices\Peripheral.h" /> + <ClInclude Include="..\..\xbmc\peripherals\devices\PeripheralBluetooth.h" /> + <ClInclude Include="..\..\xbmc\peripherals\devices\PeripheralCecAdapter.h" /> + <ClInclude Include="..\..\xbmc\peripherals\devices\PeripheralDisk.h" /> + <ClInclude Include="..\..\xbmc\peripherals\devices\PeripheralHID.h" /> + <ClInclude Include="..\..\xbmc\peripherals\devices\PeripheralNIC.h" /> + <ClInclude Include="..\..\xbmc\peripherals\devices\PeripheralNyxboard.h" /> + <ClInclude Include="..\..\xbmc\peripherals\devices\PeripheralTuner.h" /> + <ClInclude Include="..\..\xbmc\peripherals\dialogs\GUIDialogPeripheralManager.h" /> + <ClInclude Include="..\..\xbmc\peripherals\dialogs\GUIDialogPeripheralSettings.h" /> + <ClInclude Include="..\..\xbmc\peripherals\Peripherals.h" /> + <ClInclude Include="..\..\xbmc\peripherals\PeripheralTypes.h" /> <ClInclude Include="..\..\xbmc\pictures\DllImageLib.h" /> <ClInclude Include="..\..\xbmc\pictures\DllLibExif.h" /> <ClInclude Include="..\..\xbmc\pictures\GUIDialogPictureInfo.h" /> @@ -1687,7 +1711,6 @@ <ClInclude Include="..\..\xbmc\ViewState.h" /> <ClInclude Include="..\..\xbmc\win32\pch.h" /> <ClInclude Include="..\..\xbmc\win32\PlatformDefs.h" /> - <ClInclude Include="..\..\xbmc\win32\WIN32USBScan.h" /> <ClInclude Include="..\..\xbmc\XBDateTime.h" /> <CustomBuild Include="..\..\xbmc\win32\PlatformInclude.h"> <Command Condition="'$(Configuration)|$(Platform)'=='Release (DirectX)|Win32'">update_git_rev.bat</Command> diff --git a/project/VS2010Express/XBMC.vcxproj.filters b/project/VS2010Express/XBMC.vcxproj.filters index 69354d64f4..8b6e188acf 100644 --- a/project/VS2010Express/XBMC.vcxproj.filters +++ b/project/VS2010Express/XBMC.vcxproj.filters @@ -238,6 +238,18 @@ <Filter Include="interfaces\info"> <UniqueIdentifier>{cea579fc-bdd7-499e-a6a6-07d681d1ab24}</UniqueIdentifier> </Filter> + <Filter Include="peripherals"> + <UniqueIdentifier>{43fa1d09-88f3-4c03-92f4-27ce109a0b1f}</UniqueIdentifier> + </Filter> + <Filter Include="peripherals\bus"> + <UniqueIdentifier>{387fb53b-4497-4e2b-a37d-2efa9db0fce8}</UniqueIdentifier> + </Filter> + <Filter Include="peripherals\devices"> + <UniqueIdentifier>{a3fe63d5-92eb-47e6-90f6-40b6e25d11d2}</UniqueIdentifier> + </Filter> + <Filter Include="peripherals\dialogs"> + <UniqueIdentifier>{9571e2bc-891d-4496-bcba-2ec3eed45704}</UniqueIdentifier> + </Filter> </ItemGroup> <ItemGroup> <ClCompile Include="..\..\xbmc\win32\pch.cpp"> @@ -1811,12 +1823,6 @@ <ClCompile Include="..\..\xbmc\settings\VideoSettings.cpp"> <Filter>settings</Filter> </ClCompile> - <ClCompile Include="..\..\xbmc\win32\WIN32USBScan.cpp"> - <Filter>win32</Filter> - </ClCompile> - <ClCompile Include="..\..\xbmc\input\KeymapLoader.cpp"> - <Filter>input</Filter> - </ClCompile> <ClCompile Include="..\..\xbmc\storage\AutorunMediaJob.cpp"> <Filter>storage</Filter> </ClCompile> @@ -2505,6 +2511,45 @@ <ClCompile Include="..\..\xbmc\interfaces\info\SkinVariable.cpp"> <Filter>interfaces\info</Filter> </ClCompile> + <ClCompile Include="..\..\xbmc\peripherals\Peripherals.cpp"> + <Filter>peripherals</Filter> + </ClCompile> + <ClCompile Include="..\..\xbmc\peripherals\bus\PeripheralBus.cpp"> + <Filter>peripherals\bus</Filter> + </ClCompile> + <ClCompile Include="..\..\xbmc\peripherals\devices\Peripheral.cpp"> + <Filter>peripherals\devices</Filter> + </ClCompile> + <ClCompile Include="..\..\xbmc\peripherals\devices\PeripheralCecAdapter.cpp"> + <Filter>peripherals\devices</Filter> + </ClCompile> + <ClCompile Include="..\..\xbmc\peripherals\devices\PeripheralDisk.cpp"> + <Filter>peripherals\devices</Filter> + </ClCompile> + <ClCompile Include="..\..\xbmc\peripherals\devices\PeripheralHID.cpp"> + <Filter>peripherals\devices</Filter> + </ClCompile> + <ClCompile Include="..\..\xbmc\peripherals\devices\PeripheralNIC.cpp"> + <Filter>peripherals\devices</Filter> + </ClCompile> + <ClCompile Include="..\..\xbmc\peripherals\devices\PeripheralNyxboard.cpp"> + <Filter>peripherals\devices</Filter> + </ClCompile> + <ClCompile Include="..\..\xbmc\peripherals\bus\win32\PeripheralBusUSB.cpp"> + <Filter>peripherals\bus</Filter> + </ClCompile> + <ClCompile Include="..\..\xbmc\peripherals\devices\PeripheralBluetooth.cpp"> + <Filter>peripherals\devices</Filter> + </ClCompile> + <ClCompile Include="..\..\xbmc\peripherals\devices\PeripheralTuner.cpp"> + <Filter>peripherals\devices</Filter> + </ClCompile> + <ClCompile Include="..\..\xbmc\peripherals\dialogs\GUIDialogPeripheralManager.cpp"> + <Filter>peripherals\dialogs</Filter> + </ClCompile> + <ClCompile Include="..\..\xbmc\peripherals\dialogs\GUIDialogPeripheralSettings.cpp"> + <Filter>peripherals\dialogs</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="..\..\xbmc\win32\pch.h"> @@ -4315,12 +4360,6 @@ <ClInclude Include="..\..\xbmc\settings\VideoSettings.h"> <Filter>settings</Filter> </ClInclude> - <ClInclude Include="..\..\xbmc\win32\WIN32USBScan.h"> - <Filter>win32</Filter> - </ClInclude> - <ClInclude Include="..\..\xbmc\input\KeymapLoader.h"> - <Filter>input</Filter> - </ClInclude> <ClInclude Include="..\..\xbmc\storage\AutorunMediaJob.h"> <Filter>storage</Filter> </ClInclude> @@ -5033,6 +5072,48 @@ <ClInclude Include="..\..\xbmc\interfaces\info\SkinVariable.h"> <Filter>interfaces\info</Filter> </ClInclude> + <ClInclude Include="..\..\xbmc\peripherals\Peripherals.h"> + <Filter>peripherals</Filter> + </ClInclude> + <ClInclude Include="..\..\xbmc\peripherals\bus\PeripheralBus.h"> + <Filter>peripherals\bus</Filter> + </ClInclude> + <ClInclude Include="..\..\xbmc\peripherals\devices\Peripheral.h"> + <Filter>peripherals\devices</Filter> + </ClInclude> + <ClInclude Include="..\..\xbmc\peripherals\devices\PeripheralCecAdapter.h"> + <Filter>peripherals\devices</Filter> + </ClInclude> + <ClInclude Include="..\..\xbmc\peripherals\devices\PeripheralDisk.h"> + <Filter>peripherals\devices</Filter> + </ClInclude> + <ClInclude Include="..\..\xbmc\peripherals\devices\PeripheralHID.h"> + <Filter>peripherals\devices</Filter> + </ClInclude> + <ClInclude Include="..\..\xbmc\peripherals\devices\PeripheralNIC.h"> + <Filter>peripherals\devices</Filter> + </ClInclude> + <ClInclude Include="..\..\xbmc\peripherals\devices\PeripheralNyxboard.h"> + <Filter>peripherals\devices</Filter> + </ClInclude> + <ClInclude Include="..\..\xbmc\peripherals\bus\win32\PeripheralBusUSB.h"> + <Filter>peripherals\bus</Filter> + </ClInclude> + <ClInclude Include="..\..\xbmc\peripherals\PeripheralTypes.h"> + <Filter>peripherals</Filter> + </ClInclude> + <ClInclude Include="..\..\xbmc\peripherals\devices\PeripheralBluetooth.h"> + <Filter>peripherals\devices</Filter> + </ClInclude> + <ClInclude Include="..\..\xbmc\peripherals\devices\PeripheralTuner.h"> + <Filter>peripherals\devices</Filter> + </ClInclude> + <ClInclude Include="..\..\xbmc\peripherals\dialogs\GUIDialogPeripheralManager.h"> + <Filter>peripherals\dialogs</Filter> + </ClInclude> + <ClInclude Include="..\..\xbmc\peripherals\dialogs\GUIDialogPeripheralSettings.h"> + <Filter>peripherals\dialogs</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <ResourceCompile Include="..\..\xbmc\win32\XBMC_PC.rc"> @@ -5044,4 +5125,4 @@ <Filter>win32</Filter> </CustomBuild> </ItemGroup> -</Project>
\ No newline at end of file +</Project> diff --git a/system/deviceidmappings.xml b/system/deviceidmappings.xml deleted file mode 100644 index 7114170a6d..0000000000 --- a/system/deviceidmappings.xml +++ /dev/null @@ -1,3 +0,0 @@ -<devicemappings> - <device id="HID#VID_1915&PID_003B&MI_00#7&314e95d&0&0000#" keymap="Motorola Nyxboard Hybrid" /> -</devicemappings>
\ No newline at end of file diff --git a/system/peripherals.xml b/system/peripherals.xml new file mode 100644 index 0000000000..d410f433c7 --- /dev/null +++ b/system/peripherals.xml @@ -0,0 +1,30 @@ +<peripherals> + <peripheral vendor="1915" product="003B" bus="usb" name="Motorola Nyxboard Hybrid" mapTo="nyxboard"> + <setting key="keymap_enabled" type="bool" value="1" label="35008" configurable="0" /> + <setting key="keymap" value="Motorola Nyxboard Hybrid" label="35007" configurable="0" /> + <setting key="enable_flip_commands" type="bool" value="1" label="36005" /> + <setting key="flip_keyboard" value="XBMC.VideoLibrary.Search" label="36002" /> + <setting key="flip_remote" value="Dialog.Close(virtualkeyboard)" label="36003" /> + <setting key="key_user" value="" label="36004" /> + </peripheral> + <peripheral vendor="22B8" product="003B" bus="usb" name="Motorola Nyxboard Hybrid" mapTo="nyxboard"> + <setting key="keymap_enabled" type="bool" value="1" label="35008" configurable="0" /> + <setting key="keymap" value="Motorola Nyxboard Hybrid" label="35007" configurable="0" /> + <setting key="enable_flip_commands" type="bool" value="1" label="36005" /> + <setting key="flip_keyboard" value="XBMC.VideoLibrary.Search" label="36002" /> + <setting key="flip_remote" value="Dialog.Close(virtualkeyboard)" label="36003" /> + <setting key="key_user" value="" label="36004" /> + </peripheral> + + <peripheral class="hid" name="Generic HID device" mapTo="hid"> + <setting key="keymap_enabled" type="bool" value="0" label="35008" /> + <setting key="keymap" value="" label="35007" /> + </peripheral> + + <peripheral vendor="1234" product="5678" bus="usb" name="Demo Device" mapTo="hid"> + <setting key="demo1" type="int" label="1" value="50" min="0" max="100" step="5" /> + <setting key="demo2" type="float" label="2" value="13.37" min="0" max="100" step="0.50" /> + <setting key="demo3" type="string" label="3" value="demoOrigValue" /> + <setting key="demo4" type="bool" label="4" value="1" /> + </peripheral> +</peripherals> diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp index d67875d68d..af7e605731 100644 --- a/xbmc/Application.cpp +++ b/xbmc/Application.cpp @@ -148,6 +148,9 @@ #include "cores/dvdplayer/DVDCodecs/Video/CrystalHD.h" #endif #include "interfaces/AnnouncementManager.h" +#include "peripherals/Peripherals.h" +#include "peripherals/dialogs/GUIDialogPeripheralManager.h" +#include "peripherals/dialogs/GUIDialogPeripheralSettings.h" // Windows includes #include "guilib/GUIWindowManager.h" @@ -252,7 +255,6 @@ #ifdef _WIN32 #include <shlobj.h> #include "win32util.h" -#include "win32/WIN32USBScan.h" #endif #ifdef HAS_XRANDR #include "windowing/X11/XRandR.h" @@ -309,6 +311,7 @@ using namespace DBUSSERVER; using namespace JSONRPC; #endif using namespace ANNOUNCEMENT; +using namespace PERIPHERALS; using namespace XbmcThreads; @@ -612,10 +615,6 @@ bool CApplication::Create() g_powerManager.Initialize(); -#ifdef _WIN32 - CWIN32USBScan(); -#endif - CLog::Log(LOGNOTICE, "load settings..."); g_guiSettings.Initialize(); // Initialize default Settings - don't move @@ -661,6 +660,8 @@ bool CApplication::Create() FatalErrorHandler(true, true, true); } + g_peripherals.Initialise(); + // Create the Mouse, Keyboard, Remote, and Joystick devices // Initialize after loading settings to get joystick deadzone setting g_Mouse.Initialize(); @@ -1121,6 +1122,9 @@ bool CApplication::Initialize() g_windowManager.Add(new CGUIDialogPlayEject); + g_windowManager.Add(new CGUIDialogPeripheralManager); + g_windowManager.Add(new CGUIDialogPeripheralSettings); + g_windowManager.Add(new CGUIWindowMusicPlayList); // window id = 500 g_windowManager.Add(new CGUIWindowMusicSongs); // window id = 501 g_windowManager.Add(new CGUIWindowMusicNav); // window id = 502 @@ -1579,6 +1583,8 @@ void CApplication::StopServices() CLog::Log(LOGNOTICE, "stop dvd detect media"); m_DetectDVDType.StopThread(); #endif + + g_peripherals.Clear(); } void CApplication::ReloadSkin() diff --git a/xbmc/GUIUserMessages.h b/xbmc/GUIUserMessages.h index e73ab0adbb..c5f100c9ad 100644 --- a/xbmc/GUIUserMessages.h +++ b/xbmc/GUIUserMessages.h @@ -124,3 +124,6 @@ // Sent from filesystem if a path is known to have changed #define GUI_MSG_UPDATE_PATH GUI_MSG_USER + 33 + +// Sent to tell window to initiate a search dialog +#define GUI_MSG_SEARCH GUI_MSG_USER + 34 diff --git a/xbmc/guilib/Key.h b/xbmc/guilib/Key.h index b900577fed..aa0e7ae51b 100644 --- a/xbmc/guilib/Key.h +++ b/xbmc/guilib/Key.h @@ -381,6 +381,8 @@ #define WINDOW_DIALOG_ADDON_INFO 10146 #define WINDOW_DIALOG_TEXT_VIEWER 10147 #define WINDOW_DIALOG_PLAY_EJECT 10148 +#define WINDOW_DIALOG_PERIPHERAL_MANAGER 10149 +#define WINDOW_DIALOG_PERIPHERAL_SETTINGS 10150 #define WINDOW_MUSIC_PLAYLIST 10500 #define WINDOW_MUSIC_FILES 10501 diff --git a/xbmc/input/KeyboardStat.cpp b/xbmc/input/KeyboardStat.cpp index 7afed1d6b3..158dbb1d5d 100644 --- a/xbmc/input/KeyboardStat.cpp +++ b/xbmc/input/KeyboardStat.cpp @@ -29,6 +29,16 @@ #include "windowing/XBMC_events.h" #include "utils/TimeUtils.h" #include "input/XBMC_keytable.h" +#include "peripherals/Peripherals.h" +#include "peripherals/devices/PeripheralHID.h" + +#if defined(_LINUX) && !defined(__APPLE__) +#include <X11/Xlib.h> +#include <X11/XKBlib.h> +#endif + +using namespace std; +using namespace PERIPHERALS; CKeyboardStat g_Keyboard; @@ -46,6 +56,20 @@ void CKeyboardStat::Initialize() { } +bool CKeyboardStat::LookupSymAndUnicodePeripherals(XBMC_keysym &keysym, uint8_t *key, char *unicode) +{ + vector<CPeripheral *> hidDevices; + g_peripherals.GetPeripheralsWithFeature(hidDevices, FEATURE_HID); + for (unsigned int iDevicePtr = 0; iDevicePtr < hidDevices.size(); iDevicePtr++) + { + CPeripheralHID *hidDevice = (CPeripheralHID *) hidDevices.at(iDevicePtr); + if (hidDevice && hidDevice->LookupSymAndUnicode(keysym, key, unicode)) + return true; + } + + return false; +} + const CKey CKeyboardStat::ProcessKeyDown(XBMC_keysym& keysym) { uint8_t vkey; wchar_t unicode; @@ -74,9 +98,15 @@ const CKey CKeyboardStat::ProcessKeyDown(XBMC_keysym& keysym) vkey = 0; held = 0; - // Start by trying to match both the sym and unicode. This will identify + // Start by check whether any of the HID peripherals wants to translate this keypress + if (LookupSymAndUnicodePeripherals(keysym, &vkey, &ascii)) + { + CLog::Log(LOGDEBUG, "%s - keypress translated by a HID peripheral", __FUNCTION__); + } + + // Continue by trying to match both the sym and unicode. This will identify // the majority of keypresses - if (KeyTableLookupSymAndUnicode(keysym.sym, keysym.unicode, &keytable)) + else if (KeyTableLookupSymAndUnicode(keysym.sym, keysym.unicode, &keytable)) { vkey = keytable.vkey; ascii = keytable.ascii; diff --git a/xbmc/input/KeyboardStat.h b/xbmc/input/KeyboardStat.h index 9d00809e83..d663fe8e86 100644 --- a/xbmc/input/KeyboardStat.h +++ b/xbmc/input/KeyboardStat.h @@ -55,6 +55,8 @@ public: CStdString GetKeyName(int KeyID); private: + bool LookupSymAndUnicodePeripherals(XBMC_keysym &keysym, uint8_t *key, char *unicode); + XBMC_keysym m_lastKeysym; unsigned int m_lastKeyTime; }; diff --git a/xbmc/input/KeymapLoader.cpp b/xbmc/input/KeymapLoader.cpp deleted file mode 100644 index 031c9b3ea7..0000000000 --- a/xbmc/input/KeymapLoader.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (C) 2005-2011 Team XBMC - * http://xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * http://www.gnu.org/copyleft/gpl.html - * - */ - -#include "KeymapLoader.h" -#include "filesystem/File.h" -#include "settings/Settings.h" -#include "utils/log.h" -#include "utils/XMLUtils.h" - -using namespace std; -using namespace XFILE; - -static std::map<CStdString, CStdString> deviceMappings; -bool CKeymapLoader::parsedMappings = false; - -void CKeymapLoader::DeviceAdded(const CStdString& deviceId) -{ - ParseDeviceMappings(); - CStdString keymapName; - if (CKeymapLoader::FindMappedDevice(deviceId, keymapName)) - { - CLog::Log(LOGDEBUG, "Switching Active Keymapping to: %s", keymapName.c_str()); - g_settings.m_activeKeyboardMapping = keymapName; - } -} - -void CKeymapLoader::DeviceRemoved(const CStdString& deviceId) -{ - ParseDeviceMappings(); - CStdString keymapName; - if (FindMappedDevice(deviceId, keymapName)) - { - CLog::Log(LOGDEBUG, "Switching Active Keymapping to: default"); - g_settings.m_activeKeyboardMapping = "default"; - } -} - -void CKeymapLoader::ParseDeviceMappings() -{ - if (!parsedMappings) - { - parsedMappings = true; - CStdString file("special://xbmc/system/deviceidmappings.xml"); - TiXmlDocument deviceXML; - if (!CFile::Exists(file) || !deviceXML.LoadFile(file)) - return; - - TiXmlElement *pRootElement = deviceXML.RootElement(); - if (!pRootElement || strcmpi(pRootElement->Value(), "devicemappings") != 0) - return; - - TiXmlElement *pDevice = pRootElement->FirstChildElement("device"); - while (pDevice) - { - CStdString deviceId(pDevice->Attribute("id")); - CStdString keymap(pDevice->Attribute("keymap")); - if (!deviceId.empty() && !keymap.empty()) - deviceMappings.insert(pair<CStdString, CStdString>(deviceId.ToUpper(), keymap)); - pDevice = pDevice->NextSiblingElement("device"); - } - } -} - -bool CKeymapLoader::FindMappedDevice(const CStdString& deviceId, CStdString& keymapName) -{ - CStdString deviceIdTemp = deviceId; - std::map<CStdString, CStdString>::iterator deviceIdIt = deviceMappings.find(deviceIdTemp.ToUpper()); - if (deviceIdIt == deviceMappings.end()) - return false; - - keymapName = deviceIdIt->second; - return true; -} - -CStdString CKeymapLoader::ParseWin32HIDName(const CStdString& deviceLongName) -{ - return deviceLongName.Mid(deviceLongName.find_last_of('\\')+1, deviceLongName.find_last_of('#') - deviceLongName.find_last_of('\\')); -}
\ No newline at end of file diff --git a/xbmc/input/Makefile b/xbmc/input/Makefile index 6221f4a133..f74c2b3c65 100644 --- a/xbmc/input/Makefile +++ b/xbmc/input/Makefile @@ -2,7 +2,6 @@ SRCS=ButtonTranslator.cpp \ InertialScrollingHandler.cpp \ KeyboardLayoutConfiguration.cpp \ KeyboardStat.cpp \ - KeymapLoader.cpp \ MouseStat.cpp \ SDLJoystick.cpp \ XBMC_keytable.cpp \ diff --git a/xbmc/interfaces/Builtins.cpp b/xbmc/interfaces/Builtins.cpp index f191d21f71..23641d55a5 100644 --- a/xbmc/interfaces/Builtins.cpp +++ b/xbmc/interfaces/Builtins.cpp @@ -205,6 +205,7 @@ const BUILT_IN commands[] = { { "LCD.Suspend", false, "Suspends LCDproc" }, { "LCD.Resume", false, "Resumes LCDproc" }, #endif + { "VideoLibrary.Search", false, "Brings up a search dialog which will search the library" }, }; bool CBuiltins::HasCommand(const CStdString& execString) @@ -1539,6 +1540,11 @@ int CBuiltins::Execute(const CStdString& execString) CGUIMessage msg(GUI_MSG_MOVE_OFFSET, 0, 0, 0); g_windowManager.SendMessage(msg, WINDOW_WEATHER); } + else if (execute.Equals("videolibrary.search")) + { + CGUIMessage msg(GUI_MSG_SEARCH, 0, 0, 0); + g_windowManager.SendMessage(msg, WINDOW_VIDEO_NAV); + } else return -1; return 0; diff --git a/xbmc/peripherals/Makefile b/xbmc/peripherals/Makefile new file mode 100644 index 0000000000..754a2c5de3 --- /dev/null +++ b/xbmc/peripherals/Makefile @@ -0,0 +1,6 @@ +SRCS=Peripherals.cpp + +LIB=peripherals.a + +include ../../Makefile.include +-include $(patsubst %.cpp,%.P,$(patsubst %.c,%.P,$(SRCS))) diff --git a/xbmc/peripherals/PeripheralTypes.h b/xbmc/peripherals/PeripheralTypes.h new file mode 100644 index 0000000000..9323325cf2 --- /dev/null +++ b/xbmc/peripherals/PeripheralTypes.h @@ -0,0 +1,170 @@ +#pragma once +/* + * Copyright (C) 2005-2011 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include <map> +#include <stdio.h> +#ifdef _WIN32 +#include "PlatformDefs.h" +#endif +#include "utils/StdString.h" + +class CSetting; + +namespace PERIPHERALS +{ + enum PeripheralBusType + { + PERIPHERAL_BUS_UNKNOWN = 0, + PERIPHERAL_BUS_USB, + PERIPHERAL_BUS_PCI + }; + + enum PeripheralFeature + { + FEATURE_UNKNOWN = 0, + FEATURE_HID, + FEATURE_NIC, + FEATURE_DISK, + FEATURE_NYXBOARD, + FEATURE_CEC, + FEATURE_BLUETOOTH, + FEATURE_TUNER + }; + + enum PeripheralType + { + PERIPHERAL_UNKNOWN = 0, + PERIPHERAL_HID, + PERIPHERAL_NIC, + PERIPHERAL_DISK, + PERIPHERAL_NYXBOARD, + PERIPHERAL_CEC, + PERIPHERAL_BLUETOOTH, + PERIPHERAL_TUNER + }; + + struct PeripheralDeviceMapping + { + int m_iVendorId; + int m_iProductId; + PeripheralBusType m_busType; + PeripheralType m_class; + CStdString m_strDeviceName; + PeripheralType m_mappedTo; + std::map<CStdString, CSetting *> m_settings; + }; + + class PeripheralTypeTranslator + { + public: + static const char *TypeToString(const PeripheralType type) + { + switch (type) + { + case PERIPHERAL_BLUETOOTH: + return "bluetooth"; + case PERIPHERAL_CEC: + return "cec"; + case PERIPHERAL_DISK: + return "disk"; + case PERIPHERAL_HID: + return "hid"; + case PERIPHERAL_NIC: + return "nic"; + case PERIPHERAL_NYXBOARD: + return "nyxboard"; + case PERIPHERAL_TUNER: + return "tuner"; + default: + return "unknown"; + } + }; + + static PeripheralType GetTypeFromString(const CStdString &strType) + { + CStdString strTypeLowerCase(strType); + strTypeLowerCase.ToLower(); + + if (strTypeLowerCase.Equals("bluetooth")) + return PERIPHERAL_BLUETOOTH; + else if (strTypeLowerCase.Equals("cec")) + return PERIPHERAL_CEC; + else if (strTypeLowerCase.Equals("disk")) + return PERIPHERAL_DISK; + else if (strTypeLowerCase.Equals("hid")) + return PERIPHERAL_HID; + else if (strTypeLowerCase.Equals("nic")) + return PERIPHERAL_NIC; + else if (strTypeLowerCase.Equals("nyxboard")) + return PERIPHERAL_NYXBOARD; + else if (strTypeLowerCase.Equals("tuner")) + return PERIPHERAL_TUNER; + + return PERIPHERAL_UNKNOWN; + }; + + static const char *BusTypeToString(const PeripheralBusType type) + { + switch(type) + { + case PERIPHERAL_BUS_USB: + return "usb"; + case PERIPHERAL_BUS_PCI: + return "pci"; + default: + return "unknown"; + } + }; + + static PeripheralBusType GetBusTypeFromString(const CStdString &strType) + { + CStdString strTypeLowerCase(strType); + strTypeLowerCase.ToLower(); + + if (strTypeLowerCase.Equals("usb")) + return PERIPHERAL_BUS_USB; + else if (strTypeLowerCase.Equals("pci")) + return PERIPHERAL_BUS_PCI; + + return PERIPHERAL_BUS_UNKNOWN; + }; + + static int HexStringToInt(const char *strHex) + { + int iVal; + sscanf(strHex, "%x", &iVal); + return iVal; + }; + + static char *IntToHexString(int iVal) + { + if (iVal < 0) + iVal = 0; + if (iVal > 65536) + iVal = 65536; + + char *buf = new char[4]; + sprintf(buf, "%04X", iVal); + return buf; + }; + }; +} diff --git a/xbmc/peripherals/Peripherals.cpp b/xbmc/peripherals/Peripherals.cpp new file mode 100644 index 0000000000..eab975b69f --- /dev/null +++ b/xbmc/peripherals/Peripherals.cpp @@ -0,0 +1,476 @@ +/* + * Copyright (C) 2005-2011 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "Peripherals.h" +#include "bus/PeripheralBus.h" +#include "devices/PeripheralBluetooth.h" +#include "devices/PeripheralCecAdapter.h" +#include "devices/PeripheralDisk.h" +#include "devices/PeripheralHID.h" +#include "devices/PeripheralNIC.h" +#include "devices/PeripheralNyxboard.h" +#include "devices/PeripheralTuner.h" +#include "dialogs/GUIDialogPeripheralManager.h" + +#include "threads/SingleLock.h" +#include "utils/log.h" +#include "utils/XMLUtils.h" +#include "settings/GUISettings.h" +#include "tinyXML/tinyxml.h" +#include "filesystem/Directory.h" +#include "guilib/GUIWindowManager.h" +#include "guilib/LocalizeStrings.h" +#include "dialogs/GUIDialogKaiToast.h" +#include "utils/StringUtils.h" + +#if defined(TARGET_WINDOWS) +#include "bus/win32/PeripheralBusUSB.h" +#elif defined(TARGET_LINUX) && defined(HAVE_LIBUSB) +#include "bus/linux/PeripheralBusUSB.h" +#elif defined(TARGET_DARWIN) +#include "bus/osx/PeripheralBusUSB.h" +#endif + +using namespace PERIPHERALS; +using namespace XFILE; +using namespace std; + +CPeripherals::CPeripherals(void) +{ + CDirectory::Create("special://profile/peripheral_data"); + + Clear(); +} + +CPeripherals::~CPeripherals(void) +{ + Clear(); +} + +CPeripherals &CPeripherals::Get(void) +{ + static CPeripherals peripheralsInstance; + return peripheralsInstance; +} + +void CPeripherals::Initialise(void) +{ + CSingleLock lock(m_critSection); + if (!m_bIsStarted) + { + m_bIsStarted = true; + + /* load mappings from peripherals.xml */ + LoadMappings(); + +#if defined(TARGET_WINDOWS) + /* add all busses for win32 */ + m_busses.push_back(new CPeripheralBusUSB(this)); +#elif defined(TARGET_LINUX) && defined(HAVE_LIBUSB) + /* add all busses for linux */ + m_busses.push_back(new CPeripheralBusUSB(this)); +#elif defined(TARGET_DARWIN) + /* add all busses for darwin */ + m_busses.push_back(new CPeripheralBusUSB(this)); +#endif + + /* initialise all known busses */ + for (int iBusPtr = (int)m_busses.size() - 1; iBusPtr >= 0; iBusPtr--) + { + if (!m_busses.at(iBusPtr)->Initialise()) + { + CLog::Log(LOGERROR, "%s - failed to initialise bus %s", __FUNCTION__, PeripheralTypeTranslator::BusTypeToString(m_busses.at(iBusPtr)->Type())); + delete m_busses.at(iBusPtr); + m_busses.erase(m_busses.begin() + iBusPtr); + } + } + + m_bInitialised = true; + } +} + +void CPeripherals::Clear(void) +{ + CSingleLock lock(m_critSection); + /* delete busses and devices */ + for (unsigned int iBusPtr = 0; iBusPtr < m_busses.size(); iBusPtr++) + delete m_busses.at(iBusPtr); + m_busses.clear(); + + /* delete mappings */ + for (unsigned int iMappingPtr = 0; iMappingPtr < m_mappings.size(); iMappingPtr++) + m_mappings.at(iMappingPtr).m_settings.clear(); + m_mappings.clear(); + + /* reset class state */ + m_bIsStarted = false; + m_bInitialised = false; +} + +void CPeripherals::TriggerDeviceScan(const PeripheralBusType type /* = PERIPHERAL_BUS_UNKNOWN */) +{ + CSingleLock lock(m_critSection); + for (unsigned int iBusPtr = 0; iBusPtr < m_busses.size(); iBusPtr++) + { + if (type == PERIPHERAL_BUS_UNKNOWN || m_busses.at(iBusPtr)->Type() == type) + { + m_busses.at(iBusPtr)->TriggerDeviceScan(); + if (type != PERIPHERAL_BUS_UNKNOWN) + break; + } + } +} + +CPeripheralBus *CPeripherals::GetBusByType(const PeripheralBusType type) const +{ + CPeripheralBus *bus(NULL); + + CSingleLock lock(m_critSection); + for (unsigned int iBusPtr = 0; iBusPtr < m_busses.size(); iBusPtr++) + { + if (m_busses.at(iBusPtr)->Type() == type) + { + bus = m_busses.at(iBusPtr); + break; + } + } + + return bus; +} + +CPeripheral *CPeripherals::GetPeripheralAtLocation(const CStdString &strLocation, PeripheralBusType busType /* = PERIPHERAL_BUS_UNKNOWN */) const +{ + CPeripheral *peripheral(NULL); + CSingleLock lock(m_critSection); + for (unsigned int iBusPtr = 0; iBusPtr < m_busses.size(); iBusPtr++) + { + /* check whether the bus matches if a bus type other than unknown was passed */ + if (busType != PERIPHERAL_BUS_UNKNOWN && m_busses.at(iBusPtr)->Type() != busType) + continue; + + /* return the first device that matches */ + if ((peripheral = m_busses.at(iBusPtr)->GetPeripheral(strLocation)) != NULL) + break; + } + + return peripheral; +} + +bool CPeripherals::HasPeripheralAtLocation(const CStdString &strLocation, PeripheralBusType busType /* = PERIPHERAL_BUS_UNKNOWN */) const +{ + return (GetPeripheralAtLocation(strLocation, busType) != NULL); +} + +CPeripheralBus *CPeripherals::GetBusWithDevice(const CStdString &strLocation) const +{ + CSingleLock lock(m_critSection); + for (unsigned int iBusPtr = 0; iBusPtr < m_busses.size(); iBusPtr++) + { + /* return the first bus that matches */ + if (m_busses.at(iBusPtr)->HasPeripheral(strLocation)) + return m_busses.at(iBusPtr); + } + + return NULL; +} + +int CPeripherals::GetPeripheralsWithFeature(vector<CPeripheral *> &results, const PeripheralFeature feature, PeripheralBusType busType /* = PERIPHERAL_BUS_UNKNOWN */) const +{ + int iReturn(0); + CSingleLock lock(m_critSection); + for (unsigned int iBusPtr = 0; iBusPtr < m_busses.size(); iBusPtr++) + { + /* check whether the bus matches if a bus type other than unknown was passed */ + if (busType != PERIPHERAL_BUS_UNKNOWN && m_busses.at(iBusPtr)->Type() != busType) + continue; + + iReturn += m_busses.at(iBusPtr)->GetPeripheralsWithFeature(results, feature); + } + + return iReturn; +} + +bool CPeripherals::HasPeripheralWithFeature(const PeripheralFeature feature, PeripheralBusType busType /* = PERIPHERAL_BUS_UNKNOWN */) const +{ + vector<CPeripheral *> dummy; + return (GetPeripheralsWithFeature(dummy, feature, busType) > 0); +} + +CPeripheral *CPeripherals::CreatePeripheral(CPeripheralBus &bus, const PeripheralType type, const CStdString &strLocation, int iVendorId /* = 0 */, int iProductId /* = 0 */) +{ + CPeripheral *peripheral = GetPeripheralAtLocation(strLocation, bus.Type()); + + /* only create a new device instances if there's no device at the given location */ + if (!peripheral) + { + /* check whether there's something mapped in peripherals.xml */ + PeripheralType mappedType = type; + CStdString strDeviceName; + int iMappingPtr = GetMappingForDevice(bus, type, iVendorId, iProductId); + bool bHasMapping(iMappingPtr >= 0); + if (bHasMapping) + { + mappedType = m_mappings[iMappingPtr].m_mappedTo; + strDeviceName = m_mappings[iMappingPtr].m_strDeviceName; + } + + switch(mappedType) + { + case PERIPHERAL_HID: + peripheral = new CPeripheralHID(type, bus.Type(), strLocation, strDeviceName, iVendorId, iProductId); + break; + + case PERIPHERAL_NIC: + peripheral = new CPeripheralNIC(type, bus.Type(), strLocation, strDeviceName, iVendorId, iProductId); + break; + + case PERIPHERAL_DISK: + peripheral = new CPeripheralDisk(type, bus.Type(), strLocation, strDeviceName, iVendorId, iProductId); + break; + + case PERIPHERAL_NYXBOARD: + peripheral = new CPeripheralNyxboard(type, bus.Type(), strLocation, strDeviceName, iVendorId, iProductId); + break; + + case PERIPHERAL_CEC: + peripheral = new CPeripheralCecAdapter(type, bus.Type(), strLocation, strDeviceName, iVendorId, iProductId); + break; + + case PERIPHERAL_TUNER: + peripheral = new CPeripheralTuner(type, bus.Type(), strLocation, strDeviceName, iVendorId, iProductId); + break; + + case PERIPHERAL_BLUETOOTH: + peripheral = new CPeripheralBluetooth(type, bus.Type(), strLocation, strDeviceName, iVendorId, iProductId); + break; + + default: + peripheral = new CPeripheral(type, bus.Type(), strLocation, strDeviceName, iVendorId, iProductId); + break; + } + + if (peripheral) + { + /* try to initialise the new peripheral + * Initialise() will make sure that each device is only initialised once */ + if (peripheral->Initialise()) + { + if (!bHasMapping) + peripheral->SetHidden(true); + bus.Register(peripheral); + } + else + { + CLog::Log(LOGDEBUG, "%s - failed to initialise peripheral on '%s'", __FUNCTION__, strLocation.c_str()); + delete peripheral; + peripheral = NULL; + } + } + } + + return peripheral; +} + +void CPeripherals::OnDeviceAdded(const CPeripheralBus &bus, const CStdString &strLocation) +{ + CGUIDialogPeripheralManager *dialog = (CGUIDialogPeripheralManager *)g_windowManager.GetWindow(WINDOW_DIALOG_PERIPHERAL_MANAGER); + if (dialog && dialog->IsActive()) + dialog->Update(); + + CPeripheral *peripheral = GetByPath(strLocation); + if (peripheral) + CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, g_localizeStrings.Get(35005), peripheral->DeviceName()); +} + +void CPeripherals::OnDeviceDeleted(const CPeripheralBus &bus, const CStdString &strLocation) +{ + CGUIDialogPeripheralManager *dialog = (CGUIDialogPeripheralManager *)g_windowManager.GetWindow(WINDOW_DIALOG_PERIPHERAL_MANAGER); + if (dialog && dialog->IsActive()) + dialog->Update(); + + CPeripheral *peripheral = GetByPath(strLocation); + if (peripheral) + CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, g_localizeStrings.Get(35006), peripheral->DeviceName()); +} + +int CPeripherals::GetMappingForDevice(const CPeripheralBus &bus, const PeripheralType classType, int iVendorId, int iProductId) const +{ + /* check all mappings in the order in which they are defined in peripherals.xml */ + for (unsigned int iMappingPtr = 0; iMappingPtr < m_mappings.size(); iMappingPtr++) + { + PeripheralDeviceMapping mapping = m_mappings.at(iMappingPtr); + bool bBusMatch = (mapping.m_busType == PERIPHERAL_BUS_UNKNOWN || mapping.m_busType == bus.Type()); + bool bVendorMatch = (mapping.m_iVendorId == 0 || mapping.m_iVendorId == iVendorId); + bool bProductMatch = (mapping.m_iProductId == 0 || mapping.m_iProductId == iProductId); + bool bClassMatch = (mapping.m_class == PERIPHERAL_UNKNOWN || mapping.m_class == classType); + + if (bBusMatch && bVendorMatch && bProductMatch && bClassMatch) + { + CLog::Log(LOGDEBUG, "%s - device (%s:%s) mapped to %s (type = %s)", __FUNCTION__, PeripheralTypeTranslator::IntToHexString(iVendorId), PeripheralTypeTranslator::IntToHexString(iProductId), mapping.m_strDeviceName.c_str(), PeripheralTypeTranslator::TypeToString(mapping.m_mappedTo)); + return iMappingPtr; + } + } + + return -1; +} + +void CPeripherals::GetSettingsFromMapping(CPeripheral &peripheral) const +{ + /* check all mappings in the order in which they are defined in peripherals.xml */ + for (unsigned int iMappingPtr = 0; iMappingPtr < m_mappings.size(); iMappingPtr++) + { + const PeripheralDeviceMapping *mapping = &m_mappings.at(iMappingPtr); + bool bBusMatch = (mapping->m_busType == PERIPHERAL_BUS_UNKNOWN || mapping->m_busType == peripheral.GetBusType()); + bool bVendorMatch = (mapping->m_iVendorId == 0 || mapping->m_iVendorId == peripheral.VendorId()); + bool bProductMatch = (mapping->m_iProductId == 0 || mapping->m_iProductId == peripheral.ProductId()); + bool bClassMatch = (mapping->m_class == PERIPHERAL_UNKNOWN || mapping->m_class == peripheral.Type()); + + if (bBusMatch && bVendorMatch && bProductMatch && bClassMatch) + { + for (map<CStdString, CSetting *>::const_iterator itr = mapping->m_settings.begin(); itr != mapping->m_settings.end(); itr++) + peripheral.AddSetting((*itr).first, (*itr).second); + } + } +} + +bool CPeripherals::LoadMappings(void) +{ + TiXmlDocument xmlDoc; + if (!xmlDoc.LoadFile("special://xbmc/system/peripherals.xml")) + { + CLog::Log(LOGWARNING, "%s - peripherals.xml does not exist", __FUNCTION__); + return true; + } + + TiXmlElement *pRootElement = xmlDoc.RootElement(); + if (strcmpi(pRootElement->Value(), "peripherals") != 0) + { + CLog::Log(LOGERROR, "%s - peripherals.xml does not contain <peripherals>", __FUNCTION__); + return false; + } + + TiXmlElement *currentNode = pRootElement->FirstChildElement("peripheral"); + while (currentNode) + { + PeripheralDeviceMapping mapping; + + mapping.m_iVendorId = currentNode->Attribute("vendor") ? PeripheralTypeTranslator::HexStringToInt(currentNode->Attribute("vendor")) : 0; + mapping.m_iProductId = currentNode->Attribute("product") ? PeripheralTypeTranslator::HexStringToInt(currentNode->Attribute("product")) : 0; + mapping.m_busType = PeripheralTypeTranslator::GetBusTypeFromString(currentNode->Attribute("bus")); + mapping.m_class = PeripheralTypeTranslator::GetTypeFromString(currentNode->Attribute("class")); + mapping.m_strDeviceName = currentNode->Attribute("name") ? CStdString(currentNode->Attribute("name")) : StringUtils::EmptyString; + mapping.m_mappedTo = PeripheralTypeTranslator::GetTypeFromString(currentNode->Attribute("mapTo")); + GetSettingsFromMappingsFile(currentNode, mapping.m_settings); + + m_mappings.push_back(mapping); + currentNode = currentNode->NextSiblingElement("peripheral"); + } + + return true; +} + +void CPeripherals::GetSettingsFromMappingsFile(TiXmlElement *xmlNode, map<CStdString, CSetting *> &m_settings) +{ + TiXmlElement *currentNode = xmlNode->FirstChildElement("setting"); + while (currentNode) + { + CSetting *setting = NULL; + CStdString strKey(currentNode->Attribute("key")); + if (strKey.IsEmpty()) + continue; + + CStdString strSettingsType(currentNode->Attribute("type")); + int iLabelId = currentNode->Attribute("label") ? atoi(currentNode->Attribute("label")) : -1; + bool bConfigurable = (!currentNode->Attribute("configurable") || + strcmp(currentNode->Attribute("configurable"), "") == 0 || + (strcmp(currentNode->Attribute("configurable"), "no") != 0 && + strcmp(currentNode->Attribute("configurable"), "false") != 0 && + strcmp(currentNode->Attribute("configurable"), "0") != 0)); + if (strSettingsType.Equals("bool")) + { + bool bValue = (strcmp(currentNode->Attribute("value"), "no") != 0 && + strcmp(currentNode->Attribute("value"), "false") != 0 && + strcmp(currentNode->Attribute("value"), "0") != 0); + setting = new CSettingBool(0, strKey, iLabelId, bValue, CHECKMARK_CONTROL); + } + else if (strSettingsType.Equals("int")) + { + int iValue = currentNode->Attribute("value") ? atoi(currentNode->Attribute("value")) : 0; + int iMin = currentNode->Attribute("min") ? atoi(currentNode->Attribute("min")) : 0; + int iStep = currentNode->Attribute("step") ? atoi(currentNode->Attribute("step")) : 0; + int iMax = currentNode->Attribute("max") ? atoi(currentNode->Attribute("max")) : 0; + CStdString strFormat(currentNode->Attribute("format")); + setting = new CSettingInt(0, strKey, iLabelId, iValue, iMin, iStep, iMax, SPIN_CONTROL_INT, strFormat); + } + else if (strSettingsType.Equals("float")) + { + float fValue = currentNode->Attribute("value") ? atof(currentNode->Attribute("value")) : 0; + float fMin = currentNode->Attribute("min") ? atof(currentNode->Attribute("min")) : 0; + float fStep = currentNode->Attribute("step") ? atof(currentNode->Attribute("step")) : 0; + float fMax = currentNode->Attribute("max") ? atof(currentNode->Attribute("max")) : 0; + setting = new CSettingFloat(0, strKey, iLabelId, fValue, fMin, fStep, fMax, SPIN_CONTROL_FLOAT); + } + else + { + CStdString strValue(currentNode->Attribute("value")); + setting = new CSettingString(0, strKey, iLabelId, strValue, EDIT_CONTROL_INPUT, !bConfigurable, -1); + } + + //TODO add more types if needed + setting->SetVisible(bConfigurable); + m_settings[strKey] = setting; + currentNode = currentNode->NextSiblingElement("setting"); + } +} + +void CPeripherals::GetDirectory(const CStdString &strPath, CFileItemList &items) const +{ + if (!strPath.Left(14).Equals("peripherals://")) + return; + + CStdString strPathCut = strPath.Right(strPath.length() - 14); + CStdString strBus = strPathCut.Left(strPathCut.Find('/')); + + CSingleLock lock(m_critSection); + for (unsigned int iBusPtr = 0; iBusPtr < m_busses.size(); iBusPtr++) + { + if (strBus.Equals("all") || strBus.Equals(PeripheralTypeTranslator::BusTypeToString(m_busses.at(iBusPtr)->Type()))) + m_busses.at(iBusPtr)->GetDirectory(strPath, items); + } +} + +CPeripheral *CPeripherals::GetByPath(const CStdString &strPath) const +{ + if (!strPath.Left(14).Equals("peripherals://")) + return NULL; + + CStdString strPathCut = strPath.Right(strPath.length() - 14); + CStdString strBus = strPathCut.Left(strPathCut.Find('/')); + + CSingleLock lock(m_critSection); + for (unsigned int iBusPtr = 0; iBusPtr < m_busses.size(); iBusPtr++) + { + if (strBus.Equals(PeripheralTypeTranslator::BusTypeToString(m_busses.at(iBusPtr)->Type()))) + return m_busses.at(iBusPtr)->GetByPath(strPath); + } + + return NULL; +} diff --git a/xbmc/peripherals/Peripherals.h b/xbmc/peripherals/Peripherals.h new file mode 100644 index 0000000000..96a3b1f07d --- /dev/null +++ b/xbmc/peripherals/Peripherals.h @@ -0,0 +1,161 @@ +#pragma once +/* + * Copyright (C) 2005-2011 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "bus/PeripheralBus.h" +#include "devices/Peripheral.h" +#include "threads/CriticalSection.h" +#include "threads/Thread.h" + +class CFileItemList; +class CSetting; +class CSettingsCategory; +class TiXmlElement; + +namespace PERIPHERALS +{ + #define g_peripherals CPeripherals::Get() + + class CPeripherals + { + public: + static CPeripherals &Get(void); + virtual ~CPeripherals(void); + + /*! + * @brief Initialise the peripherals manager. + */ + virtual void Initialise(void); + + /*! + * @brief Clear all data known by the peripherals manager. + */ + virtual void Clear(void); + + /*! + * @brief Get the instance of the peripheral at the given location. + * @param strLocation The location. + * @param busType The bus to query. Default (PERIPHERAL_BUS_UNKNOWN) searches all busses. + * @return The peripheral or NULL if it wasn't found. + */ + virtual CPeripheral *GetPeripheralAtLocation(const CStdString &strLocation, PeripheralBusType busType = PERIPHERAL_BUS_UNKNOWN) const; + + /*! + * @brief Check whether a peripheral is present at the given location. + * @param strLocation The location. + * @param busType The bus to query. Default (PERIPHERAL_BUS_UNKNOWN) searches all busses. + * @return True when a peripheral was found, false otherwise. + */ + virtual bool HasPeripheralAtLocation(const CStdString &strLocation, PeripheralBusType busType = PERIPHERAL_BUS_UNKNOWN) const; + + /*! + * @brief Get the bus that holds the device with the given location. + * @param strLocation The location. + * @return The bus or NULL if no device was found. + */ + virtual CPeripheralBus *GetBusWithDevice(const CStdString &strLocation) const; + + /*! + * @brief Get all peripheral instances that have the given feature. + * @param results The list of results. + * @param feature The feature to search for. + * @param busType The bus to query. Default (PERIPHERAL_BUS_UNKNOWN) searches all busses. + * @return The number of devices that have been found. + */ + virtual int GetPeripheralsWithFeature(std::vector<CPeripheral *> &results, const PeripheralFeature feature, PeripheralBusType busType = PERIPHERAL_BUS_UNKNOWN) const; + + /*! + * @brief Check whether there is at least one device present with the given feature. + * @param feature The feature to check for. + * @param busType The bus to query. Default (PERIPHERAL_BUS_UNKNOWN) searches all busses. + * @return True when at least one device was found with this feature, false otherwise. + */ + virtual bool HasPeripheralWithFeature(const PeripheralFeature feature, PeripheralBusType busType = PERIPHERAL_BUS_UNKNOWN) const; + + /*! + * @brief Called when a device has been added to a bus. + * @param bus The bus the device was added to. + * @param strLocation The path of the fileitem. + */ + virtual void OnDeviceAdded(const CPeripheralBus &bus, const CStdString &strLocation); + + /*! + * @brief Called when a device has been deleted from a bus. + * @param bus The bus from which the device removed. + * @param strLocation The path of the fileitem. + */ + virtual void OnDeviceDeleted(const CPeripheralBus &bus, const CStdString &strLocation); + + /*! + * @brief Creates a new instance of a peripheral. + * @param bus The bus on which this peripheral is present. + * @param type The type of the new peripheral. + * @param strLocation The location on the bus. + * @return The new peripheral or NULL if it could not be created. + */ + CPeripheral *CreatePeripheral(CPeripheralBus &bus, const PeripheralType type, const CStdString &strLocation, int iVendorId = 0, int iProductId = 0); + + /*! + * @brief Add the settings that are defined in the mappings file to the peripheral (if there is anything defined). + * @param peripheral The peripheral to get the settings for. + */ + void GetSettingsFromMapping(CPeripheral &peripheral) const; + + /*! + * @brief Trigger a device scan on all known busses + */ + virtual void TriggerDeviceScan(const PeripheralBusType type = PERIPHERAL_BUS_UNKNOWN); + + /*! + * @brief Get the instance of a bus given it's type. + * @param type The bus type. + * @return The bus or NULL if it wasn't found. + */ + virtual CPeripheralBus *GetBusByType(const PeripheralBusType type) const; + + /*! + * @brief Get all fileitems for a path. + * @param strPath The path to the directory to get the items from. + * @param items The item list. + */ + virtual void GetDirectory(const CStdString &strPath, CFileItemList &items) const; + + /*! + * @brief Get the instance of a peripheral given it's path. + * @param strPath The path to the peripheral. + * @return The peripheral or NULL if it wasn't found. + */ + virtual CPeripheral *GetByPath(const CStdString &strPath) const; + + private: + CPeripherals(void); + bool LoadMappings(void); + int GetMappingForDevice(const CPeripheralBus &bus, const PeripheralType classType, int iVendorId, int iProductId) const; + static void GetSettingsFromMappingsFile(TiXmlElement *xmlNode, std::map<CStdString, CSetting *> &m_settings); + + bool m_bInitialised; + bool m_bIsStarted; + std::vector<CPeripheralBus *> m_busses; + std::vector<PeripheralDeviceMapping> m_mappings; + CSettingsCategory * m_settings; + CCriticalSection m_critSection; + }; +} diff --git a/xbmc/peripherals/bus/Makefile.in b/xbmc/peripherals/bus/Makefile.in new file mode 100644 index 0000000000..0831e9d665 --- /dev/null +++ b/xbmc/peripherals/bus/Makefile.in @@ -0,0 +1,14 @@ +SRCS=PeripheralBus.cpp + +ifeq (@HAVE_LIBUSB@,1) +SRCS+=linux/PeripheralBusUSB.cpp +endif + +ifeq ($(findstring osx,@ARCH@),osx) +SRCS+=osx/PeripheralBusUSB.cpp +endif + +LIB=peripheral-bus.a + +include ../../../Makefile.include +-include $(patsubst %.cpp,%.P,$(patsubst %.c,%.P,$(SRCS))) diff --git a/xbmc/peripherals/bus/PeripheralBus.cpp b/xbmc/peripherals/bus/PeripheralBus.cpp new file mode 100644 index 0000000000..bea0517573 --- /dev/null +++ b/xbmc/peripherals/bus/PeripheralBus.cpp @@ -0,0 +1,336 @@ +/* + * Copyright (C) 2005-2011 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "PeripheralBus.h" +#include "peripherals/Peripherals.h" +#include "utils/log.h" +#include "FileItem.h" + +using namespace std; +using namespace PERIPHERALS; + +#define PERIPHERAL_DEFAULT_RESCAN_INTERVAL 1000 + +bool PeripheralScanResult::operator ==(const PeripheralScanResult &right) const +{ + return m_iVendorId == right.m_iVendorId && + m_iProductId == right.m_iProductId && + m_type == right.m_type && + m_strLocation.Equals(right.m_strLocation); +} + +bool PeripheralScanResult::operator !=(const PeripheralScanResult &right) const +{ + return !(*this == right); +} + +bool PeripheralScanResult::operator ==(const CPeripheral &right) const +{ + return m_iVendorId == right.VendorId() && + m_iProductId == right.ProductId() && + m_type == right.Type() && + m_strLocation.Equals(right.Location()); +} + +bool PeripheralScanResult::operator !=(const CPeripheral &right) const +{ + return !(*this == right); +} + +bool PeripheralScanResults::GetDeviceOnLocation(const CStdString &strLocation, PeripheralScanResult *result) const +{ + bool bReturn(false); + + for (unsigned int iDevicePtr = 0; iDevicePtr < m_results.size(); iDevicePtr++) + { + if (m_results.at(iDevicePtr).m_strLocation == strLocation) + { + *result = m_results.at(iDevicePtr); + bReturn = true; + break; + } + } + + return bReturn; +} + +bool PeripheralScanResults::ContainsResult(const PeripheralScanResult &result) const +{ + bool bReturn(false); + + for (unsigned int iDevicePtr = 0; iDevicePtr < m_results.size(); iDevicePtr++) + { + if (m_results.at(iDevicePtr) == result) + { + bReturn = true; + break; + } + } + + return bReturn; +} + +CPeripheralBus::CPeripheralBus(CPeripherals *manager, PeripheralBusType type) : + CThread("XBMC Peripherals"), + m_iRescanTime(PERIPHERAL_DEFAULT_RESCAN_INTERVAL), + m_bInitialised(false), + m_bIsStarted(false), + m_bNeedsPolling(true), + m_manager(manager), + m_type(type), + m_triggerEvent(true) +{ +} + +void CPeripheralBus::OnDeviceAdded(const CStdString &strLocation) +{ + ScanForDevices(); +} + +void CPeripheralBus::OnDeviceChanged(const CStdString &strLocation) +{ + ScanForDevices(); +} + +void CPeripheralBus::OnDeviceRemoved(const CStdString &strLocation) +{ + ScanForDevices(); +} + +void CPeripheralBus::Clear(void) +{ + if (m_bNeedsPolling) + { + m_bStop = true; + m_triggerEvent.Set(); + StopThread(true); + } + + CSingleLock lock(m_critSection); + for (unsigned int iPeripheralPtr = 0; iPeripheralPtr < m_peripherals.size(); iPeripheralPtr++) + delete m_peripherals.at(iPeripheralPtr); + m_peripherals.clear(); +} + +void CPeripheralBus::UnregisterRemovedDevices(const PeripheralScanResults &results) +{ + CSingleLock lock(m_critSection); + for (int iDevicePtr = (int) m_peripherals.size() - 1; iDevicePtr >= 0; iDevicePtr--) + { + CPeripheral *peripheral = m_peripherals.at(iDevicePtr); + PeripheralScanResult updatedDevice; + if (!results.GetDeviceOnLocation(peripheral->Location(), &updatedDevice) || + updatedDevice != *peripheral) + { + /* device removed */ + if (peripheral->Type() != PERIPHERAL_UNKNOWN) + CLog::Log(LOGNOTICE, "%s - device removed from %s/%s: %s (%s:%s)", __FUNCTION__, PeripheralTypeTranslator::TypeToString(peripheral->Type()), peripheral->Location().c_str(), peripheral->DeviceName().c_str(), peripheral->VendorIdAsString(), peripheral->ProductIdAsString()); + m_manager->OnDeviceDeleted(*this, peripheral->FileLocation()); + delete peripheral; + m_peripherals.erase(m_peripherals.begin() + iDevicePtr); + } + } +} + +void CPeripheralBus::RegisterNewDevices(const PeripheralScanResults &results) +{ + CSingleLock lock(m_critSection); + for (unsigned int iResultPtr = 0; iResultPtr < results.m_results.size(); iResultPtr++) + { + PeripheralScanResult result = results.m_results.at(iResultPtr); + if (!HasPeripheral(result.m_strLocation) && result.m_type != PERIPHERAL_UNKNOWN) + g_peripherals.CreatePeripheral(*this, result.m_type, result.m_strLocation, result.m_iVendorId, result.m_iProductId); + } +} + +bool CPeripheralBus::ScanForDevices(void) +{ + bool bReturn(false); + + PeripheralScanResults results; + if (PerformDeviceScan(results)) + { + UnregisterRemovedDevices(results); + RegisterNewDevices(results); + + bReturn = true; + } + + m_bInitialised = true; + return bReturn; +} + +bool CPeripheralBus::HasFeature(const PeripheralFeature feature) const +{ + bool bReturn(false); + CSingleLock lock(m_critSection); + for (unsigned int iPeripheralPtr = 0; iPeripheralPtr < m_peripherals.size(); iPeripheralPtr++) + { + if (m_peripherals.at(iPeripheralPtr)->HasFeature(feature)) + { + bReturn = true; + break; + } + } + return bReturn; +} + +void CPeripheralBus::GetFeatures(std::vector<PeripheralFeature> &features) const +{ + CSingleLock lock(m_critSection); + for (unsigned int iPeripheralPtr = 0; iPeripheralPtr < m_peripherals.size(); iPeripheralPtr++) + m_peripherals.at(iPeripheralPtr)->GetFeatures(features); +} + +CPeripheral *CPeripheralBus::GetPeripheral(const CStdString &strLocation) const +{ + CPeripheral *peripheral(NULL); + CSingleLock lock(m_critSection); + for (unsigned int iPeripheralPtr = 0; iPeripheralPtr < m_peripherals.size(); iPeripheralPtr++) + { + if (m_peripherals.at(iPeripheralPtr)->Location() == strLocation) + { + peripheral = m_peripherals.at(iPeripheralPtr); + break; + } + } + return peripheral; +} + +int CPeripheralBus::GetPeripheralsWithFeature(vector<CPeripheral *> &results, const PeripheralFeature feature) const +{ + int iReturn(0); + CSingleLock lock(m_critSection); + for (unsigned int iPeripheralPtr = 0; iPeripheralPtr < m_peripherals.size(); iPeripheralPtr++) + { + if (m_peripherals.at(iPeripheralPtr)->HasFeature(feature)) + { + results.push_back(m_peripherals.at(iPeripheralPtr)); + ++iReturn; + } + } + + return iReturn; +} + +void CPeripheralBus::Process(void) +{ + while (!m_bStop) + { + m_triggerEvent.Reset(); + + if (!ScanForDevices()) + break; + + if (!m_bStop) + m_triggerEvent.WaitMSec(m_iRescanTime); + } + + m_bIsStarted = false; +} + +bool CPeripheralBus::Initialise(void) +{ + CSingleLock lock(m_critSection); + if (!m_bIsStarted) + { + /* do an initial scan of the bus */ + m_bIsStarted = ScanForDevices(); + + if (m_bIsStarted && m_bNeedsPolling) + { + lock.Leave(); + m_triggerEvent.Reset(); + Create(); + SetPriority(-1); + } + } + + return m_bIsStarted; +} + +void CPeripheralBus::Register(CPeripheral *peripheral) +{ + if (!peripheral) + return; + + CSingleLock lock(m_critSection); + if (!HasPeripheral(peripheral->Location())) + { + m_peripherals.push_back(peripheral); + m_manager->OnDeviceAdded(*this, peripheral->FileLocation()); + CLog::Log(LOGNOTICE, "%s - new %s device registered on %s->%s: %s (%s:%s)", __FUNCTION__, PeripheralTypeTranslator::TypeToString(peripheral->Type()), PeripheralTypeTranslator::BusTypeToString(m_type), peripheral->Location().c_str(), peripheral->DeviceName().c_str(), peripheral->VendorIdAsString(), peripheral->ProductIdAsString()); + } +} + +void CPeripheralBus::TriggerDeviceScan(void) +{ + CSingleLock lock(m_critSection); + if (m_bNeedsPolling) + { + lock.Leave(); + m_triggerEvent.Set(); + } + else + { + lock.Leave(); + ScanForDevices(); + } +} + +bool CPeripheralBus::HasPeripheral(const CStdString &strLocation) const +{ + return (GetPeripheral(strLocation) != NULL); +} + +void CPeripheralBus::GetDirectory(const CStdString &strPath, CFileItemList &items) const +{ + CStdString strDevPath; + CSingleLock lock(m_critSection); + for (unsigned int iDevicePtr = 0; iDevicePtr < m_peripherals.size(); iDevicePtr++) + { + const CPeripheral *peripheral = m_peripherals.at(iDevicePtr); + if (peripheral->IsHidden()) + continue; + + CFileItemPtr peripheralFile(new CFileItem(peripheral->DeviceName())); + peripheralFile->SetPath(peripheral->FileLocation()); + peripheralFile->SetProperty("vendor", peripheral->VendorIdAsString()); + peripheralFile->SetProperty("product", peripheral->ProductIdAsString()); + peripheralFile->SetProperty("bus", PeripheralTypeTranslator::BusTypeToString(peripheral->GetBusType())); + peripheralFile->SetProperty("location", peripheral->Location()); + peripheralFile->SetProperty("class", PeripheralTypeTranslator::TypeToString(peripheral->Type())); + items.Add(peripheralFile); + } +} + +CPeripheral *CPeripheralBus::GetByPath(const CStdString &strPath) const +{ + CStdString strDevPath; + CSingleLock lock(m_critSection); + for (unsigned int iDevicePtr = 0; iDevicePtr < m_peripherals.size(); iDevicePtr++) + { + if (strPath.Equals(m_peripherals.at(iDevicePtr)->FileLocation())) + return m_peripherals.at(iDevicePtr); + } + + return NULL; +} diff --git a/xbmc/peripherals/bus/PeripheralBus.h b/xbmc/peripherals/bus/PeripheralBus.h new file mode 100644 index 0000000000..28ddfe318c --- /dev/null +++ b/xbmc/peripherals/bus/PeripheralBus.h @@ -0,0 +1,191 @@ +#pragma once +/* + * Copyright (C) 2005-2011 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include <vector> +#include "utils/StdString.h" +#include "threads/Thread.h" +#include "peripherals/PeripheralTypes.h" +#include "peripherals/devices/Peripheral.h" + +class CFileItemList; + +namespace PERIPHERALS +{ + class CPeripherals; + + struct PeripheralScanResult + { + bool operator ==(const PeripheralScanResult &right) const; + bool operator !=(const PeripheralScanResult &right) const; + + bool operator ==(const CPeripheral &right) const; + bool operator !=(const CPeripheral &right) const; + + PeripheralType m_type; + CStdString m_strLocation; + int m_iVendorId; + int m_iProductId; + }; + + struct PeripheralScanResults + { + bool GetDeviceOnLocation(const CStdString &strLocation, PeripheralScanResult *result) const; + bool ContainsResult(const PeripheralScanResult &result) const; + + std::vector<PeripheralScanResult> m_results; + }; + + /*! + * @class CPeripheralBus + * This represents a bus on the system. By default, this bus instance will scan for changes every second. + * If this bus only has to be updated after a notification sent by the system, set m_bNeedsPolling to false + * in the constructor, and implement the OnDeviceAdded(), OnDeviceChanged() and OnDeviceRemoved() methods. + * + * The PerformDeviceScan() method has to be implemented by each specific bus implementation. + */ + class CPeripheralBus : protected CThread + { + public: + CPeripheralBus(CPeripherals *manager, PeripheralBusType type); + virtual ~CPeripheralBus(void) { Clear(); } + + /*! + * @return The bus type + */ + const PeripheralBusType Type(void) const { return m_type; } + + /*! + * @return True if this bus needs to be polled for changes, false if this bus performs updates via callbacks + */ + bool NeedsPolling(void) const { return m_bNeedsPolling; } + + /*! + * @brief Get the instance of the peripheral at the given location. + * @param strLocation The location. + * @return The peripheral or NULL if it wasn't found. + */ + virtual CPeripheral *GetPeripheral(const CStdString &strLocation) const; + + /*! + * @brief Check whether a peripheral is present at the given location. + * @param strLocation The location. + * @return True when a peripheral was found, false otherwise. + */ + virtual bool HasPeripheral(const CStdString &strLocation) const; + + /*! + * @brief Get the first instance of a peripheral that has the given feature. + * @param feature The feature to search for. + * @return The peripheral or NULL if it wasn't found. + */ + virtual int GetPeripheralsWithFeature(std::vector<CPeripheral *> &results, const PeripheralFeature feature) const; + + /*! + * @brief Get all features that are supported by devices on this bus. + * @param features All features. + */ + virtual void GetFeatures(std::vector<PeripheralFeature> &features) const; + + /*! + * @brief Check whether there is at least one device present with the given feature. + * @param feature The feature to check for. + * @return True when at least one device was found with this feature, false otherwise. + */ + virtual bool HasFeature(const PeripheralFeature feature) const; + + /*! + * @brief Callback method for when a device has been added. Will perform a device scan. + * @param strLocation The location of the device that has been added. + */ + virtual void OnDeviceAdded(const CStdString &strLocation); + + /*! + * @brief Callback method for when a device has been changed. Will perform a device scan. + * @param strLocation The location of the device that has been changed. + */ + virtual void OnDeviceChanged(const CStdString &strLocation); + + /*! + * @brief Callback method for when a device has been removed. Will perform a device scan. + * @param strLocation The location of the device that has been removed. + */ + virtual void OnDeviceRemoved(const CStdString &strLocation); + + /*! + * @brief Initialise this bus and start a polling thread if this bus needs polling. + */ + virtual bool Initialise(void); + + /*! + * @brief Stop the polling thread and clear all known devices on this bus. + */ + virtual void Clear(void); + + /*! + * @brief Scan for devices. + */ + virtual void TriggerDeviceScan(void); + + /*! + * @brief Get all fileitems for a path. + * @param strPath The path to the directory to get the items from. + * @param items The item list. + */ + virtual void GetDirectory(const CStdString &strPath, CFileItemList &items) const; + + /*! + * @brief Get the instance of a peripheral given it's path. + * @param strPath The path to the peripheral. + * @return The peripheral or NULL if it wasn't found. + */ + virtual CPeripheral *GetByPath(const CStdString &strPath) const; + + /*! + * @brief Register a new peripheral on this bus. + * @param peripheral The peripheral to register. + */ + virtual void Register(CPeripheral *peripheral); + + protected: + virtual void Process(void); + virtual bool ScanForDevices(void); + virtual void UnregisterRemovedDevices(const PeripheralScanResults &results); + virtual void RegisterNewDevices(const PeripheralScanResults &results); + + /*! + * @brief Scan for devices on this bus and add them to the results list. This will have to be implemented for each bus. + * @param results The result list. + * @return True when the scan was successful, false otherwise. + */ + virtual bool PerformDeviceScan(PeripheralScanResults &results) = 0; + + std::vector<CPeripheral *> m_peripherals; + int m_iRescanTime; + bool m_bInitialised; + bool m_bIsStarted; + bool m_bNeedsPolling; /*!< true when this bus needs to be polled for new devices, false when it uses callbacks to notify this bus of changed */ + CPeripherals * m_manager; + PeripheralBusType m_type; + CCriticalSection m_critSection; + CEvent m_triggerEvent; + }; +} diff --git a/xbmc/peripherals/bus/linux/PeripheralBusUSB.cpp b/xbmc/peripherals/bus/linux/PeripheralBusUSB.cpp new file mode 100644 index 0000000000..4a5faf7d48 --- /dev/null +++ b/xbmc/peripherals/bus/linux/PeripheralBusUSB.cpp @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2005-2011 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "PeripheralBusUSB.h" +#include "peripherals/Peripherals.h" +#include <usb.h> +#if defined(HAVE_LIBUDEV) +#include <libudev.h> +#include <poll.h> +#include "utils/log.h" +#endif + +using namespace PERIPHERALS; + +CPeripheralBusUSB::CPeripheralBusUSB(CPeripherals *manager) : + CPeripheralBus(manager, PERIPHERAL_BUS_USB) +{ + usb_init(); + usb_find_busses(); + m_busses = usb_get_busses(); + +#if defined(HAVE_LIBUDEV) + InitialiseUdev(); +#endif +} + +bool CPeripheralBusUSB::PerformDeviceScan(PeripheralScanResults &results) +{ + struct usb_bus *bus; + usb_find_devices(); + for (bus = m_busses; bus; bus = bus->next) + { + struct usb_device *dev; + for (dev = bus->devices; dev; dev = dev->next) + { + PeripheralScanResult result; + result.m_iVendorId = dev->descriptor.idVendor; + result.m_iProductId = dev->descriptor.idProduct; + result.m_type = (dev->descriptor.bDeviceClass == USB_CLASS_PER_INTERFACE && dev->descriptor.bNumConfigurations > 0 && + dev->config[0].bNumInterfaces > 0 && dev->config[0].interface[0].num_altsetting > 0) ? + GetType(dev->config[0].interface[0].altsetting[0].bInterfaceClass) : + GetType(dev->descriptor.bDeviceClass); + result.m_strLocation.Format("/bus%s/dev%s", bus->dirname, dev->filename); + + if (!results.ContainsResult(result)) + results.m_results.push_back(result); + } + } + + return true; +} + +const PeripheralType CPeripheralBusUSB::GetType(int iDeviceClass) +{ + switch (iDeviceClass) + { + case USB_CLASS_HID: + return PERIPHERAL_HID; + case USB_CLASS_COMM: + return PERIPHERAL_NIC; + case USB_CLASS_MASS_STORAGE: + return PERIPHERAL_DISK; + case USB_CLASS_PER_INTERFACE: + case USB_CLASS_AUDIO: + case USB_CLASS_PRINTER: + case USB_CLASS_PTP: + case USB_CLASS_HUB: + case USB_CLASS_DATA: + case USB_CLASS_VENDOR_SPEC: + default: + return PERIPHERAL_UNKNOWN; + } +} + +#if defined(HAVE_LIBUDEV) +void CPeripheralBusUSB::Process(void) +{ + bool bUpdated(false); + ScanForDevices(); + while (!m_bStop) + { + bUpdated = WaitForUpdate(); + if (bUpdated && !m_bStop) + ScanForDevices(); + } + + m_bIsStarted = false; +} + +void CPeripheralBusUSB::Clear(void) +{ + StopThread(false); + if (m_udevFd != -1) + close(m_udevFd); + + udev_unref(m_udev); + + CPeripheralBus::Clear(); +} + +void CPeripheralBusUSB::InitialiseUdev(void) +{ + m_udev = NULL; + m_udevMon = NULL; + m_udevFd = -1; + + if (!(m_udev = udev_new())) + { + CLog::Log(LOGERROR, "%s - failed to allocate udev context", __FUNCTION__); + return; + } + + /* set up a devices monitor that listen for any device change */ + m_udevMon = udev_monitor_new_from_netlink(m_udev, "udev"); + udev_monitor_enable_receiving(m_udevMon); + m_udevFd = udev_monitor_get_fd(m_udevMon); + + CLog::Log(LOGDEBUG, "%s - initialised udev monitor: %d", __FUNCTION__, m_udevFd); +} + +bool CPeripheralBusUSB::WaitForUpdate() +{ + if (!m_udevFd) + return false; + + /* poll for udev changes */ + struct pollfd pollFd; + pollFd.fd = m_udevFd; + pollFd.events = POLLIN; + int iPollResult; + while (!m_bStop && ((iPollResult = poll(&pollFd, 1, 100)) <= 0)) + if (errno != EINTR && iPollResult != 0) + break; + + /* the thread is being stopped, so just return false */ + if (m_bStop) + return false; + + /* we have to read the message from the queue, even though we're not actually using it */ + struct udev_device *dev = udev_monitor_receive_device(m_udevMon); + if (dev) + udev_device_unref(dev); + else + { + CLog::Log(LOGERROR, "%s - failed to get device from udev_monitor_receive_device()", __FUNCTION__); + Clear(); + return false; + } + + return true; +} +#endif diff --git a/xbmc/peripherals/bus/linux/PeripheralBusUSB.h b/xbmc/peripherals/bus/linux/PeripheralBusUSB.h new file mode 100644 index 0000000000..28b6175021 --- /dev/null +++ b/xbmc/peripherals/bus/linux/PeripheralBusUSB.h @@ -0,0 +1,65 @@ +#pragma once +/* + * Copyright (C) 2005-2011 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "peripherals/bus/PeripheralBus.h" +#include "peripherals/devices/Peripheral.h" + +struct usb_bus; + +#if defined(HAVE_LIBUDEV) +struct udev; +struct udev_monitor; +#endif + +namespace PERIPHERALS +{ + class CPeripherals; + + class CPeripheralBusUSB : public CPeripheralBus + { + public: + CPeripheralBusUSB(CPeripherals *manager); + +#if defined(HAVE_LIBUDEV) + virtual void Clear(void); +#endif + + /*! + * @see PeripheralBus::PerformDeviceScan() + */ + bool PerformDeviceScan(PeripheralScanResults &results); + + protected: + static const PeripheralType GetType(int iDeviceClass); + struct usb_bus *m_busses; + +#if defined(HAVE_LIBUDEV) + virtual void Process(void); + void InitialiseUdev(void); + bool WaitForUpdate(void); + + struct udev * m_udev; + struct udev_monitor *m_udevMon; + int m_udevFd; +#endif + }; +} diff --git a/xbmc/peripherals/bus/osx/PeripheralBusUSB.cpp b/xbmc/peripherals/bus/osx/PeripheralBusUSB.cpp new file mode 100644 index 0000000000..f2333ea474 --- /dev/null +++ b/xbmc/peripherals/bus/osx/PeripheralBusUSB.cpp @@ -0,0 +1,278 @@ +/* + * Copyright (C) 2005-2011 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "PeripheralBusUSB.h" +#include "peripherals/Peripherals.h" +#include "utils/log.h" + +#ifdef TARGET_DARWIN_OSX +#include <IOKit/IOCFPlugIn.h> +#include <IOKit/usb/IOUSBLib.h> +#include <IOKit/hid/IOHIDLib.h> +#include <IOKit/hid/IOHIDKeys.h> + +typedef struct USBDevicePrivateData { + CPeripheralBusUSB *refCon; + CStdString deviceName; + io_object_t notification; + PeripheralScanResult result; +} USBDevicePrivateData; +#endif + +using namespace PERIPHERALS; + +CPeripheralBusUSB::CPeripheralBusUSB(CPeripherals *manager) : + CPeripheralBus(manager, PERIPHERAL_BUS_USB) +{ + m_bNeedsPolling = false; + +#ifdef TARGET_DARWIN_OSX + //set up the matching criteria for the devices we're interested in + //interested in instances of class IOUSBDevice and its subclasses + // match any usb device by not creating matching values in the dict + CFMutableDictionaryRef matching_dict = IOServiceMatching(kIOUSBDeviceClassName); + + m_notify_port = IONotificationPortCreate(kIOMasterPortDefault); + CFRunLoopSourceRef run_loop_source = IONotificationPortGetRunLoopSource(m_notify_port); + CFRunLoopAddSource(CFRunLoopGetCurrent(), run_loop_source, kCFRunLoopCommonModes); + + //add a notification callback for attach event + IOReturn result = IOServiceAddMatchingNotification(m_notify_port, + kIOFirstMatchNotification, matching_dict, + (IOServiceMatchingCallback)DeviceAttachCallback, this, &m_attach_iterator); + if (result == kIOReturnSuccess) + { + //call the callback to 'arm' the notification + DeviceAttachCallback(this, m_attach_iterator); + } +#endif +} + +CPeripheralBusUSB::~CPeripheralBusUSB() +{ +#ifdef TARGET_DARWIN_OSX + if (m_notify_port) + { + // remove the sleep notification port from the application runloop + CFRunLoopRemoveSource( CFRunLoopGetCurrent(), + IONotificationPortGetRunLoopSource(m_notify_port), kCFRunLoopDefaultMode ); + IONotificationPortDestroy(m_notify_port); + m_notify_port = 0; + } + if (m_attach_iterator) + { + IOObjectRelease(m_attach_iterator); + m_attach_iterator = 0; + } +#endif +} + +bool CPeripheralBusUSB::PerformDeviceScan(PeripheralScanResults &results) +{ + results = m_scan_results; + return true; +} + +#ifdef TARGET_DARWIN_OSX +const PeripheralType CPeripheralBusUSB::GetType(int iDeviceClass) +{ + switch (iDeviceClass) + { + case kUSBHIDClass: + return PERIPHERAL_HID; + case kUSBCommClass: + return PERIPHERAL_NIC; + case kUSBMassStorageClass: + return PERIPHERAL_DISK; + //case USB_CLASS_PER_INTERFACE: + case kUSBAudioClass: + case kUSBPrintingClass: + //case USB_CLASS_PTP: + case kUSBHubClass: + case kUSBDataClass: + case kUSBVendorSpecificClass: + default: + return PERIPHERAL_UNKNOWN; + } +} + +void CPeripheralBusUSB::DeviceDetachCallback(void *refCon, io_service_t service, natural_t messageType, void *messageArgument) +{ + if (messageType == kIOMessageServiceIsTerminated) + { + IOReturn result; + + USBDevicePrivateData *privateDataRef = (USBDevicePrivateData*)refCon; + + std::vector<PeripheralScanResult>::iterator it = privateDataRef->refCon->m_scan_results.m_results.begin(); + while(it != privateDataRef->refCon->m_scan_results.m_results.end()) + { + if (privateDataRef->result.m_strLocation == it->m_strLocation) + privateDataRef->refCon->m_scan_results.m_results.erase(it); + else + it++; + } + privateDataRef->refCon->ScanForDevices(); + + CLog::Log(LOGDEBUG, "HID Device Detach:%s, %s\n", + privateDataRef->deviceName.c_str(), privateDataRef->result.m_strLocation.c_str()); + result = IOObjectRelease(privateDataRef->notification); + delete privateDataRef; + //release the service + result = IOObjectRelease(service); + } +} + +void CPeripheralBusUSB::DeviceAttachCallback(CPeripheralBusUSB* refCon, io_iterator_t iterator) +{ + io_service_t usbDevice; + while ((usbDevice = IOIteratorNext(iterator))) + { + IOReturn result; + + io_name_t deviceName; + result = IORegistryEntryGetName(usbDevice, deviceName); + if (result != KERN_SUCCESS) + deviceName[0] = '\0'; + + SInt32 deviceScore; + IOCFPlugInInterface **devicePlugin; + result = IOCreatePlugInInterfaceForService(usbDevice, + kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &devicePlugin, &deviceScore); + if (result != kIOReturnSuccess) + { + IOObjectRelease(usbDevice); + continue; + } + + IOUSBDeviceInterface **deviceInterface; + // Use the plugin interface to retrieve the device interface. + result = (*devicePlugin)->QueryInterface(devicePlugin, + CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (LPVOID*)&deviceInterface); + if (result != kIOReturnSuccess) + { + IODestroyPlugInInterface(devicePlugin); + IOObjectRelease(usbDevice); + continue; + } + + // get vendor/product ids + UInt16 vendorId; + UInt16 productId; + UInt32 locationId; + UInt8 bDeviceClass; + + result = (*deviceInterface)->GetDeviceVendor( deviceInterface, &vendorId); + result = (*deviceInterface)->GetDeviceProduct(deviceInterface, &productId); + result = (*deviceInterface)->GetLocationID( deviceInterface, &locationId); + result = (*deviceInterface)->GetDeviceClass( deviceInterface, &bDeviceClass); + + // we only care about usb devices with an HID interface class + io_service_t usbInterface; + io_iterator_t interface_iterator; + IOUSBFindInterfaceRequest request; + request.bInterfaceClass = kUSBHIDInterfaceClass; + request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare; + request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare; + request.bAlternateSetting = kIOUSBFindInterfaceDontCare; + result = (*deviceInterface)->CreateInterfaceIterator(deviceInterface, &request, &interface_iterator); + while ((usbInterface = IOIteratorNext(interface_iterator))) + { + SInt32 interfaceScore; + IOCFPlugInInterface **interfacePlugin; + //create intermediate plugin for interface access + result = IOCreatePlugInInterfaceForService(usbInterface, + kIOUSBInterfaceUserClientTypeID, kIOCFPlugInInterfaceID, &interfacePlugin, &interfaceScore); + if (result != kIOReturnSuccess) + { + IOObjectRelease(usbInterface); + continue; + } + IOUSBInterfaceInterface** interfaceInterface; + result = (*interfacePlugin)->QueryInterface(interfacePlugin, + CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID), (void**)&interfaceInterface); + if (result != kIOReturnSuccess) + { + IODestroyPlugInInterface(interfacePlugin); + IOObjectRelease(usbInterface); + continue; + } + + // finally we can get to bInterfaceClass/bInterfaceProtocol + // we should also check for kHIDKeyboardInterfaceProtocol but + // some IR remotes that emulate an HID keyboard do not report this. + UInt8 bInterfaceClass; + result = (*interfaceInterface)->GetInterfaceClass(interfaceInterface, &bInterfaceClass); + if (bInterfaceClass == kUSBHIDInterfaceClass) + { + USBDevicePrivateData *privateDataRef; + privateDataRef = new USBDevicePrivateData; + // save the device info to our private data. + privateDataRef->refCon = refCon; + privateDataRef->deviceName = deviceName; + privateDataRef->result.m_iVendorId = vendorId; + privateDataRef->result.m_iProductId = productId; + privateDataRef->result.m_strLocation.Format("%d", locationId); + + if (bDeviceClass == kUSBCompositeClass) + privateDataRef->result.m_type = refCon->GetType(bInterfaceClass); + else + privateDataRef->result.m_type = refCon->GetType(bDeviceClass); + + if (!refCon->m_scan_results.ContainsResult(privateDataRef->result)) + { + // register this usb device for an interest notification callback. + result = IOServiceAddInterestNotification(refCon->m_notify_port, + usbDevice, // service + kIOGeneralInterest, // interestType + (IOServiceInterestCallback)DeviceDetachCallback, // callback + privateDataRef, // refCon + &privateDataRef->notification); // notification + + if (result == kIOReturnSuccess) + { + refCon->m_scan_results.m_results.push_back(privateDataRef->result); + CLog::Log(LOGDEBUG, "HID Device Attach:%s, %s\n", + deviceName, privateDataRef->result.m_strLocation.c_str()); + } + else + { + delete privateDataRef; + } + } + else + { + delete privateDataRef; + } + // done with this device, only need one notification per device. + IODestroyPlugInInterface(interfacePlugin); + IOObjectRelease(usbInterface); + break; + } + IODestroyPlugInInterface(interfacePlugin); + IOObjectRelease(usbInterface); + } + IODestroyPlugInInterface(devicePlugin); + IOObjectRelease(usbDevice); + } + refCon->ScanForDevices(); +} +#endif diff --git a/xbmc/peripherals/bus/osx/PeripheralBusUSB.h b/xbmc/peripherals/bus/osx/PeripheralBusUSB.h new file mode 100644 index 0000000000..2c08a902da --- /dev/null +++ b/xbmc/peripherals/bus/osx/PeripheralBusUSB.h @@ -0,0 +1,58 @@ +#pragma once +/* + * Copyright (C) 2005-2011 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "peripherals/bus/PeripheralBus.h" +#include "peripherals/devices/Peripheral.h" + +#ifdef TARGET_DARWIN_OSX +#include <IOKit/IOKitLib.h> +#include <IOKit/IOMessage.h> +#endif + +namespace PERIPHERALS +{ + class CPeripherals; + + class CPeripheralBusUSB : public CPeripheralBus + { + public: + CPeripheralBusUSB(CPeripherals *manager); + virtual ~CPeripheralBusUSB(); + + /*! + * @see PeripheralBus::PerformDeviceScan() + */ + bool PerformDeviceScan(PeripheralScanResults &results); + + protected: + PeripheralScanResults m_scan_results; + #ifdef TARGET_DARWIN_OSX + static const PeripheralType GetType(int iDeviceClass); + static void DeviceDetachCallback(void *refCon, io_service_t service, natural_t messageType, void *messageArgument); + static void DeviceAttachCallback(CPeripheralBusUSB* refCon, io_iterator_t iterator); + + IONotificationPortRef m_notify_port; + io_iterator_t m_attach_iterator; + #endif + }; + +} diff --git a/xbmc/peripherals/bus/win32/PeripheralBusUSB.cpp b/xbmc/peripherals/bus/win32/PeripheralBusUSB.cpp new file mode 100644 index 0000000000..f537296b7a --- /dev/null +++ b/xbmc/peripherals/bus/win32/PeripheralBusUSB.cpp @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2005-2011 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "PeripheralBusUSB.h" +#include "peripherals/Peripherals.h" +#include "utils/log.h" +#include "utils/StringUtils.h" + +static GUID USB_RAW_GUID = { 0xA5DCBF10, 0x6530, 0x11D2, { 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED } }; +static GUID USB_HID_GUID = { 0x4D1E55B2, 0xF16F, 0x11CF, { 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30 } }; +static GUID USB_DISK_GUID = { 0x53F56307, 0xB6BF, 0x11D0, { 0x94, 0xF2, 0x00, 0xA0, 0xC9, 0x1E, 0xFB, 0x8B } }; +static GUID USB_NIC_GUID = { 0xAD498944, 0x762F, 0x11D0, { 0x8D, 0xCB, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C } }; + +using namespace PERIPHERALS; + +CPeripheralBusUSB::CPeripheralBusUSB(CPeripherals *manager) : + CPeripheralBus(manager, PERIPHERAL_BUS_USB) +{ + /* device removals aren't always triggering OnDeviceRemoved events, so poll for changes every 5 seconds to be sure we don't miss anything */ + m_iRescanTime = 5000; +} + +bool CPeripheralBusUSB::PerformDeviceScan(PeripheralScanResults &results) +{ + bool bReturn(true); + + /* add device scans for non-generic devices here */ + + bReturn |= PerformDeviceScan(&USB_HID_GUID, PERIPHERAL_HID, results); + bReturn |= PerformDeviceScan(&USB_DISK_GUID, PERIPHERAL_DISK, results); + + return bReturn; +} + +bool CPeripheralBusUSB::PerformDeviceScan(const GUID *guid, const PeripheralType type, PeripheralScanResults &results) +{ + bool bReturn(false); + HDEVINFO hDevHandle; + DWORD required = 0, iMemberIndex = 0; + int nBufferSize = 0; + + SP_DEVICE_INTERFACE_DATA deviceInterfaceData; + deviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); + + SP_DEVINFO_DATA devInfoData; + devInfoData.cbSize = sizeof(SP_DEVINFO_DATA); + + if ((hDevHandle = SetupDiGetClassDevs(guid, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE)) == INVALID_HANDLE_VALUE) + { + CLog::Log(LOGWARNING, "%s - cannot query USB devices: invalid handle", __FUNCTION__); + return bReturn; + } + + bReturn = true; + BOOL bResult = true; + TCHAR *buffer = NULL; + PSP_DEVICE_INTERFACE_DETAIL_DATA devicedetailData; + while(bResult) + { + bResult = SetupDiEnumDeviceInfo(hDevHandle, iMemberIndex, &devInfoData); + + if (bResult) + bResult = SetupDiEnumDeviceInterfaces(hDevHandle, 0, guid, iMemberIndex, &deviceInterfaceData); + + if(!bResult) + { + SetupDiDestroyDeviceInfoList(hDevHandle); + delete []buffer; + buffer = NULL; + return bReturn; + } + + iMemberIndex++; + BOOL bDetailResult = false; + { + // As per MSDN, Get the required buffer size. Call SetupDiGetDeviceInterfaceDetail with a + // NULL DeviceInterfaceDetailData pointer, a DeviceInterfaceDetailDataSize of zero, + // and a valid RequiredSize variable. In response to such a call, this function returns + // the required buffer size at RequiredSize and fails with GetLastError returning + // ERROR_INSUFFICIENT_BUFFER. + // Allocate an appropriately sized buffer and call the function again to get the interface details. + + SetupDiGetDeviceInterfaceDetail(hDevHandle, &deviceInterfaceData, NULL, 0, &required, NULL); + + buffer = new TCHAR[required]; + devicedetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) buffer; + devicedetailData->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA); + nBufferSize = required; + } + + bDetailResult = SetupDiGetDeviceInterfaceDetail(hDevHandle, &deviceInterfaceData, devicedetailData, nBufferSize , &required, NULL); + if(!bDetailResult) + continue; + + CStdString strVendorId(StringUtils::EmptyString); + CStdString strProductId(StringUtils::EmptyString); + if (type == PERIPHERAL_HID) + { + CStdString strTmp(devicedetailData->DevicePath); + strVendorId = strTmp.substr(strTmp.Find("vid_") + 4, 4); + strProductId = strTmp.substr(strTmp.Find("pid_") + 4, 4); + if (strTmp.Find("&mi_") >= 0 && strTmp.Find("&mi_00") < 0) + continue; + } + + PeripheralScanResult prevDevice; + if (!results.GetDeviceOnLocation(devicedetailData->DevicePath, &prevDevice)) + { + PeripheralScanResult result; + result.m_strLocation = devicedetailData->DevicePath; + result.m_type = type; + result.m_iVendorId = PeripheralTypeTranslator::HexStringToInt(strVendorId.c_str()); + result.m_iProductId = PeripheralTypeTranslator::HexStringToInt(strProductId.c_str()); + + results.m_results.push_back(result); + } + } + + return bReturn; +} diff --git a/xbmc/peripherals/bus/win32/PeripheralBusUSB.h b/xbmc/peripherals/bus/win32/PeripheralBusUSB.h new file mode 100644 index 0000000000..4491120fc2 --- /dev/null +++ b/xbmc/peripherals/bus/win32/PeripheralBusUSB.h @@ -0,0 +1,45 @@ +#pragma once +/* + * Copyright (C) 2005-2011 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "peripherals/bus/PeripheralBus.h" +#include "peripherals/devices/Peripheral.h" +#include <setupapi.h> //needed for GUID + +namespace PERIPHERALS +{ + class CPeripherals; + + class CPeripheralBusUSB : public CPeripheralBus + { + public: + CPeripheralBusUSB(CPeripherals *manager); + + /*! + * @see PeripheralBus::PerformDeviceScan() + */ + bool PerformDeviceScan(PeripheralScanResults &results); + + private: + bool PerformDeviceScan(const GUID *guid, const PeripheralType type, PeripheralScanResults &results); + bool GetProductAndVendorId(const PeripheralType type, const CStdString &strDeviceLocation, int *iVendorId, int *iProductId); + }; +} diff --git a/xbmc/peripherals/devices/Makefile b/xbmc/peripherals/devices/Makefile new file mode 100644 index 0000000000..85246df537 --- /dev/null +++ b/xbmc/peripherals/devices/Makefile @@ -0,0 +1,13 @@ +SRCS=Peripheral.cpp \ + PeripheralBluetooth.cpp \ + PeripheralCecAdapter.cpp \ + PeripheralDisk.cpp \ + PeripheralHID.cpp \ + PeripheralNIC.cpp \ + PeripheralNyxboard.cpp \ + PeripheralTuner.cpp + +LIB=peripheral-devices.a + +include ../../../Makefile.include +-include $(patsubst %.cpp,%.P,$(patsubst %.c,%.P,$(SRCS))) diff --git a/xbmc/peripherals/devices/Peripheral.cpp b/xbmc/peripherals/devices/Peripheral.cpp new file mode 100644 index 0000000000..fba7735061 --- /dev/null +++ b/xbmc/peripherals/devices/Peripheral.cpp @@ -0,0 +1,474 @@ +/* + * Copyright (C) 2005-2011 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "Peripheral.h" +#include "peripherals/Peripherals.h" +#include "utils/log.h" +#include "utils/StringUtils.h" +#include "settings/GUISettings.h" +#include "lib/tinyXML/tinyxml.h" +#include "utils/URIUtils.h" + +using namespace PERIPHERALS; +using namespace std; + +CPeripheral::CPeripheral(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId) : + m_type(type), + m_busType(busType), + m_strLocation(strLocation), + m_strDeviceName(strDeviceName), + m_strFileLocation(StringUtils::EmptyString), + m_iVendorId(iVendorId), + m_strVendorId(PeripheralTypeTranslator::IntToHexString(iVendorId)), + m_iProductId(iProductId), + m_strProductId(PeripheralTypeTranslator::IntToHexString(iProductId)), + m_bInitialised(false), + m_bHidden(false) +{ + m_strFileLocation.Format("peripherals://%s/%s.dev", PeripheralTypeTranslator::BusTypeToString(busType), strLocation.c_str()); +} + +CPeripheral::CPeripheral(void) : + m_type(PERIPHERAL_UNKNOWN), + m_busType(PERIPHERAL_BUS_UNKNOWN), + m_strLocation(StringUtils::EmptyString), + m_strDeviceName(StringUtils::EmptyString), + m_strFileLocation(StringUtils::EmptyString), + m_iVendorId(0), + m_strVendorId(PeripheralTypeTranslator::IntToHexString(0)), + m_iProductId(0), + m_strProductId(PeripheralTypeTranslator::IntToHexString(0)), + m_bInitialised(false), + m_bHidden(false) +{ +} + +CPeripheral::~CPeripheral(void) +{ + PersistSettings(); + + for (unsigned int iSubdevicePtr = 0; iSubdevicePtr < m_subDevices.size(); iSubdevicePtr++) + delete m_subDevices.at(iSubdevicePtr); + m_subDevices.clear(); + + ClearSettings(); +} + +bool CPeripheral::operator ==(const CPeripheral &right) const +{ + return m_type == right.m_type && + m_strLocation == right.m_strLocation && + m_iVendorId == right.m_iVendorId && + m_iProductId == right.m_iProductId; +} + +bool CPeripheral::operator !=(const CPeripheral &right) const +{ + return !(*this == right); +} + +bool CPeripheral::HasFeature(const PeripheralFeature feature) const +{ + bool bReturn(false); + + for (unsigned int iFeaturePtr = 0; iFeaturePtr < m_features.size(); iFeaturePtr++) + { + if (m_features.at(iFeaturePtr) == feature) + { + bReturn = true; + break; + } + } + + if (!bReturn) + { + for (unsigned int iSubdevicePtr = 0; iSubdevicePtr < m_subDevices.size(); iSubdevicePtr++) + { + if (m_subDevices.at(iSubdevicePtr)->HasFeature(feature)) + { + bReturn = true; + break; + } + } + } + + return bReturn; +} + +void CPeripheral::GetFeatures(std::vector<PeripheralFeature> &features) const +{ + for (unsigned int iFeaturePtr = 0; iFeaturePtr < m_features.size(); iFeaturePtr++) + features.push_back(m_features.at(iFeaturePtr)); + + for (unsigned int iSubdevicePtr = 0; iSubdevicePtr < m_subDevices.size(); iSubdevicePtr++) + m_subDevices.at(iSubdevicePtr)->GetFeatures(features); +} + +bool CPeripheral::Initialise(void) +{ + bool bReturn(true); + if (m_bInitialised) + return bReturn; + + g_peripherals.GetSettingsFromMapping(*this); + m_strSettingsFile.Format("special://profile/peripheral_data/%s_%s_%s.xml", PeripheralTypeTranslator::BusTypeToString(m_busType), m_strVendorId, m_strProductId); + LoadPersistedSettings(); + + for (unsigned int iFeaturePtr = 0; iFeaturePtr < m_features.size(); iFeaturePtr++) + { + PeripheralFeature feature = m_features.at(iFeaturePtr); + bReturn &= InitialiseFeature(feature); + } + + for (unsigned int iSubdevicePtr = 0; iSubdevicePtr < m_subDevices.size(); iSubdevicePtr++) + bReturn &= m_subDevices.at(iSubdevicePtr)->Initialise(); + + if (bReturn) + { + CLog::Log(LOGDEBUG, "%s - initialised peripheral on '%s' with %d features and %d sub devices", __FUNCTION__, m_strLocation.c_str(), m_features.size(), m_subDevices.size()); + m_bInitialised = true; + } + + return bReturn; +} + +void CPeripheral::GetSubdevices(vector<CPeripheral *> &subDevices) const +{ + for (unsigned int iSubdevicePtr = 0; iSubdevicePtr < m_subDevices.size(); iSubdevicePtr++) + subDevices.push_back(m_subDevices.at(iSubdevicePtr)); +} + +bool CPeripheral::IsMultiFunctional(void) const +{ + return m_subDevices.size() > 0; +} + +void CPeripheral::AddSetting(const CStdString &strKey, const CSetting *setting) +{ + if (!setting) + { + CLog::Log(LOGERROR, "%s - invalid setting", __FUNCTION__); + return; + } + + if (!HasSetting(strKey)) + { + switch(setting->GetType()) + { + case SETTINGS_TYPE_BOOL: + { + const CSettingBool *mappedSetting = (const CSettingBool *) setting; + CSettingBool *boolSetting = new CSettingBool(0, strKey.c_str(), mappedSetting->GetLabel(), mappedSetting->GetData(), mappedSetting->GetControlType()); + if (boolSetting) + { + boolSetting->SetVisible(mappedSetting->IsVisible()); + m_settings.insert(make_pair(strKey, boolSetting)); + } + } + break; + case SETTINGS_TYPE_INT: + { + const CSettingInt *mappedSetting = (const CSettingInt *) setting; + CSettingInt *intSetting = new CSettingInt(0, strKey.c_str(), mappedSetting->GetLabel(), mappedSetting->GetData(), mappedSetting->m_iMin, mappedSetting->m_iStep, mappedSetting->m_iMax, mappedSetting->GetControlType(), mappedSetting->m_strFormat); + if (intSetting) + { + intSetting->SetVisible(mappedSetting->IsVisible()); + m_settings.insert(make_pair(strKey, intSetting)); + } + } + break; + case SETTINGS_TYPE_FLOAT: + { + const CSettingFloat *mappedSetting = (const CSettingFloat *) setting; + CSettingFloat *floatSetting = new CSettingFloat(0, strKey.c_str(), mappedSetting->GetLabel(), mappedSetting->GetData(), mappedSetting->m_fMin, mappedSetting->m_fStep, mappedSetting->m_fMax, mappedSetting->GetControlType()); + if (floatSetting) + { + floatSetting->SetVisible(mappedSetting->IsVisible()); + m_settings.insert(make_pair(strKey, floatSetting)); + } + } + break; + case SETTINGS_TYPE_STRING: + { + const CSettingString *mappedSetting = (const CSettingString *) setting; + CSettingString *stringSetting = new CSettingString(0, strKey.c_str(), mappedSetting->GetLabel(), mappedSetting->GetData().c_str(), mappedSetting->GetControlType(), mappedSetting->m_bAllowEmpty, mappedSetting->m_iHeadingString); + if (stringSetting) + { + stringSetting->SetVisible(mappedSetting->IsVisible()); + m_settings.insert(make_pair(strKey, stringSetting)); + } + } + break; + default: + //TODO add more types if needed + break; + } + } +} + +bool CPeripheral::HasSetting(const CStdString &strKey) const +{ + map<CStdString, CSetting *>:: const_iterator it = m_settings.find(strKey); + return it != m_settings.end(); +} + +bool CPeripheral::HasSettings(void) const +{ + return m_settings.size() > 0; +} + +bool CPeripheral::HasConfigurableSettings(void) const +{ + bool bReturn(false); + map<CStdString, CSetting *>::const_iterator it = m_settings.begin(); + while (it != m_settings.end() && !bReturn) + { + if ((*it).second->IsVisible()) + { + bReturn = true; + break; + } + + ++it; + } + + return bReturn; +} + +bool CPeripheral::GetSettingBool(const CStdString &strKey) const +{ + map<CStdString, CSetting *>::const_iterator it = m_settings.find(strKey); + if (it != m_settings.end() && (*it).second->GetType() == SETTINGS_TYPE_BOOL) + { + CSettingBool *boolSetting = (CSettingBool *) (*it).second; + if (boolSetting) + return boolSetting->GetData(); + } + + return false; +} + +int CPeripheral::GetSettingInt(const CStdString &strKey) const +{ + map<CStdString, CSetting *>::const_iterator it = m_settings.find(strKey); + if (it != m_settings.end() && (*it).second->GetType() == SETTINGS_TYPE_INT) + { + CSettingInt *intSetting = (CSettingInt *) (*it).second; + if (intSetting) + return intSetting->GetData(); + } + + return 0; +} + +float CPeripheral::GetSettingFloat(const CStdString &strKey) const +{ + map<CStdString, CSetting *>::const_iterator it = m_settings.find(strKey); + if (it != m_settings.end() && (*it).second->GetType() == SETTINGS_TYPE_FLOAT) + { + CSettingFloat *floatSetting = (CSettingFloat *) (*it).second; + if (floatSetting) + return floatSetting->GetData(); + } + + return 0; +} + +const CStdString CPeripheral::GetSettingString(const CStdString &strKey) const +{ + map<CStdString, CSetting *>::const_iterator it = m_settings.find(strKey); + if (it != m_settings.end() && (*it).second->GetType() == SETTINGS_TYPE_STRING) + { + CSettingString *stringSetting = (CSettingString *) (*it).second; + if (stringSetting) + return stringSetting->GetData(); + } + + return StringUtils::EmptyString; +} + +void CPeripheral::SetSetting(const CStdString &strKey, bool bValue) +{ + map<CStdString, CSetting *>::iterator it = m_settings.find(strKey); + if (it != m_settings.end() && (*it).second->GetType() == SETTINGS_TYPE_BOOL) + { + CSettingBool *boolSetting = (CSettingBool *) (*it).second; + if (boolSetting) + { + bool bChanged(boolSetting->GetData() != bValue); + boolSetting->SetData(bValue); + if (bChanged) + OnSettingChanged(strKey); + } + } +} + +void CPeripheral::SetSetting(const CStdString &strKey, int iValue) +{ + map<CStdString, CSetting *>::iterator it = m_settings.find(strKey); + if (it != m_settings.end() && (*it).second->GetType() == SETTINGS_TYPE_INT) + { + CSettingInt *intSetting = (CSettingInt *) (*it).second; + if (intSetting) + { + bool bChanged(intSetting->GetData() != iValue); + intSetting->SetData(iValue); + if (bChanged) + OnSettingChanged(strKey); + } + } +} + +void CPeripheral::SetSetting(const CStdString &strKey, float fValue) +{ + map<CStdString, CSetting *>::iterator it = m_settings.find(strKey); + if (it != m_settings.end() && (*it).second->GetType() == SETTINGS_TYPE_FLOAT) + { + CSettingFloat *floatSetting = (CSettingFloat *) (*it).second; + if (floatSetting) + { + bool bChanged(floatSetting->GetData() != fValue); + floatSetting->SetData(fValue); + if (bChanged) + OnSettingChanged(strKey); + } + } +} + +void CPeripheral::SetSetting(const CStdString &strKey, const CStdString &strValue) +{ + map<CStdString, CSetting *>::iterator it = m_settings.find(strKey); + if (it != m_settings.end()) + { + if ((*it).second->GetType() == SETTINGS_TYPE_STRING) + { + CSettingString *stringSetting = (CSettingString *) (*it).second; + if (stringSetting) + { + bool bChanged(!stringSetting->GetData().Equals(strValue)); + stringSetting->SetData(strValue); + if (bChanged) + OnSettingChanged(strKey); + } + } + else if ((*it).second->GetType() == SETTINGS_TYPE_INT) + SetSetting(strKey, (int) (strValue.IsEmpty() ? 0 : atoi(strValue.c_str()))); + else if ((*it).second->GetType() == SETTINGS_TYPE_FLOAT) + SetSetting(strKey, (float) (strValue.IsEmpty() ? 0 : atof(strValue.c_str()))); + else if ((*it).second->GetType() == SETTINGS_TYPE_BOOL) + SetSetting(strKey, strValue.Equals("1")); + } +} + +void CPeripheral::PersistSettings(void) const +{ + TiXmlDocument doc; + TiXmlElement node("settings"); + doc.InsertEndChild(node); + for (map<CStdString, CSetting *>::const_iterator itr = m_settings.begin(); itr != m_settings.end(); itr++) + { + TiXmlElement nodeSetting("setting"); + nodeSetting.SetAttribute("id", itr->first.c_str()); + CStdString strValue; + switch ((*itr).second->GetType()) + { + case SETTINGS_TYPE_STRING: + { + CSettingString *stringSetting = (CSettingString *) (*itr).second; + if (stringSetting) + strValue = stringSetting->GetData(); + } + break; + case SETTINGS_TYPE_INT: + { + CSettingInt *intSetting = (CSettingInt *) (*itr).second; + if (intSetting) + strValue.Format("%d", intSetting->GetData()); + } + break; + case SETTINGS_TYPE_FLOAT: + { + CSettingFloat *floatSetting = (CSettingFloat *) (*itr).second; + if (floatSetting) + strValue.Format("%.2f", floatSetting->GetData()); + } + break; + case SETTINGS_TYPE_BOOL: + { + CSettingBool *boolSetting = (CSettingBool *) (*itr).second; + if (boolSetting) + strValue.Format("%d", boolSetting->GetData() ? 1:0); + } + break; + default: + break; + } + nodeSetting.SetAttribute("value", strValue.c_str()); + doc.RootElement()->InsertEndChild(nodeSetting); + } + + doc.SaveFile(m_strSettingsFile); +} + +void CPeripheral::LoadPersistedSettings(void) +{ + TiXmlDocument doc; + if (doc.LoadFile(m_strSettingsFile)) + { + const TiXmlElement *setting = doc.RootElement()->FirstChildElement("setting"); + while (setting) + { + CStdString strId(setting->Attribute("id")); + CStdString strValue(setting->Attribute("value")); + SetSetting(strId, strValue); + + setting = setting->NextSiblingElement("setting"); + } + } +} + +void CPeripheral::ResetDefaultSettings(void) +{ + ClearSettings(); + g_peripherals.GetSettingsFromMapping(*this); + OnSettingsChanged(); +} + +void CPeripheral::ClearSettings(void) +{ + map<CStdString, CSetting *>::iterator it = m_settings.begin(); + while (it != m_settings.end()) + { + delete (*it).second; + ++it; + } + m_settings.clear(); +} + +void CPeripheral::OnSettingsChanged(void) +{ + map<CStdString, CSetting *>::iterator it = m_settings.begin(); + while (it != m_settings.end()) + { + OnSettingChanged((*it).first); + ++it; + } +} diff --git a/xbmc/peripherals/devices/Peripheral.h b/xbmc/peripherals/devices/Peripheral.h new file mode 100644 index 0000000000..f0881c1f98 --- /dev/null +++ b/xbmc/peripherals/devices/Peripheral.h @@ -0,0 +1,169 @@ +#pragma once +/* + * Copyright (C) 2005-2011 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include <vector> +#include "utils/StdString.h" +#include "peripherals/PeripheralTypes.h" + +class TiXmlDocument; + +namespace PERIPHERALS +{ + class CGUIDialogPeripheralSettings; + + class CPeripheral + { + friend class CGUIDialogPeripheralSettings;; + + public: + CPeripheral(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId); + CPeripheral(void); + virtual ~CPeripheral(void); + + bool operator ==(const CPeripheral &right) const; + bool operator !=(const CPeripheral &right) const; + + const CStdString &FileLocation(void) const { return m_strFileLocation; } + const CStdString &Location(void) const { return m_strLocation; } + int VendorId(void) const { return m_iVendorId; } + const char *VendorIdAsString(void) const { return m_strVendorId; } + int ProductId(void) const { return m_iProductId; } + const char *ProductIdAsString(void) const { return m_strProductId; } + const PeripheralType Type(void) const { return m_type; } + const PeripheralBusType GetBusType(void) const { return m_busType; }; + const CStdString &DeviceName(void) const { return m_strDeviceName; } + bool IsHidden(void) const { return m_bHidden; } + void SetHidden(bool bSetTo = true) { m_bHidden = bSetTo; } + + /*! + * @brief Check whether this device has the given feature. + * @param feature The feature to check for. + * @return True when the device has the feature, false otherwise. + */ + bool HasFeature(const PeripheralFeature feature) const; + + /*! + * @brief Get all features that are supported by this device. + * @param features The features. + */ + void GetFeatures(std::vector<PeripheralFeature> &features) const; + + /*! + * @brief Initialises the peripheral. + * @return True when the peripheral has been initialised succesfully, false otherwise. + */ + bool Initialise(void); + + /*! + * @brief Initialise one of the features of this peripheral. + * @param feature The feature to initialise. + * @return True when the feature has been initialised succesfully, false otherwise. + */ + virtual bool InitialiseFeature(const PeripheralFeature feature) { return true; } + + /*! + * @brief Called when a setting changed. + * @param strChangedSetting The changed setting. + */ + virtual void OnSettingChanged(const CStdString &strChangedSetting) {}; + + /*! + * @brief Called when one or more settings changed. Calls OnSettingChanged for every setting. + */ + virtual void OnSettingsChanged(void); + + /*! + * @brief Get all subdevices if this device is multifunctional. + * @param subDevices The subdevices. + */ + virtual void GetSubdevices(std::vector<CPeripheral *> &subDevices) const; + + /*! + * @return True when this device is multifunctional, false otherwise. + */ + virtual bool IsMultiFunctional(void) const; + + /*! + * @brief Add a setting to this peripheral. This will overwrite a previous setting with the same key. + * @param strKey The key of the setting. + * @param setting The setting. + */ + virtual void AddSetting(const CStdString &strKey, const CSetting *setting); + + /*! + * @brief Check whether a setting is known with the given key. + * @param strKey The key to search. + * @return True when found, false otherwise. + */ + virtual bool HasSetting(const CStdString &strKey) const; + + /*! + * @return True when this device has any settings, false otherwise. + */ + virtual bool HasSettings(void) const; + + /*! + * @return True when this device has any configurable settings, false otherwise. + */ + virtual bool HasConfigurableSettings(void) const; + + /*! + * @brief Get the value of a setting. + * @param strKey The key to search. + * @return The value or an empty string if it wasn't found. + */ + virtual const CStdString GetSettingString(const CStdString &strKey) const; + virtual void SetSetting(const CStdString &strKey, const CStdString &strValue); + + virtual int GetSettingInt(const CStdString &strKey) const; + virtual void SetSetting(const CStdString &strKey, int iValue); + + virtual bool GetSettingBool(const CStdString &strKey) const; + virtual void SetSetting(const CStdString &strKey, bool bValue); + + virtual float GetSettingFloat(const CStdString &strKey) const; + virtual void SetSetting(const CStdString &strKey, float fValue); + + virtual void PersistSettings(void) const; + virtual void LoadPersistedSettings(void); + virtual void ResetDefaultSettings(void); + + protected: + virtual void ClearSettings(void); + + PeripheralType m_type; + PeripheralBusType m_busType; + CStdString m_strLocation; + CStdString m_strDeviceName; + CStdString m_strSettingsFile; + CStdString m_strFileLocation; + int m_iVendorId; + char * m_strVendorId; + int m_iProductId; + char * m_strProductId; + bool m_bInitialised; + bool m_bHidden; + std::vector<PeripheralFeature> m_features; + std::vector<CPeripheral *> m_subDevices; + std::map<CStdString, CSetting *> m_settings; + }; +} diff --git a/xbmc/peripherals/devices/PeripheralBluetooth.cpp b/xbmc/peripherals/devices/PeripheralBluetooth.cpp new file mode 100644 index 0000000000..745bba6c87 --- /dev/null +++ b/xbmc/peripherals/devices/PeripheralBluetooth.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2005-2011 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "PeripheralBluetooth.h" +#include "utils/log.h" + +using namespace PERIPHERALS; + +CPeripheralBluetooth::CPeripheralBluetooth(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId) : + CPeripheral(type, busType, strLocation, strDeviceName, iVendorId, iProductId) +{ + m_features.push_back(FEATURE_BLUETOOTH); +} diff --git a/xbmc/input/KeymapLoader.h b/xbmc/peripherals/devices/PeripheralBluetooth.h index 4c57ef5e91..7a11cd4adc 100644 --- a/xbmc/input/KeymapLoader.h +++ b/xbmc/peripherals/devices/PeripheralBluetooth.h @@ -20,17 +20,14 @@ * */ -#include <map> -#include "utils/StdString.h" +#include "Peripheral.h" -class CKeymapLoader +namespace PERIPHERALS { + class CPeripheralBluetooth : public CPeripheral + { public: - static void DeviceRemoved(const CStdString& deviceID); - static void DeviceAdded(const CStdString& deviceID); - static CStdString ParseWin32HIDName(const CStdString& deviceLongName); - private: - static void ParseDeviceMappings(); - static bool FindMappedDevice(const CStdString& deviceId, CStdString& keymapName); - static bool parsedMappings; -};
\ No newline at end of file + CPeripheralBluetooth(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId); + virtual ~CPeripheralBluetooth(void) {}; + }; +} diff --git a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp new file mode 100644 index 0000000000..a78e24dc6e --- /dev/null +++ b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2005-2011 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "PeripheralCecAdapter.h" +#include "utils/log.h" + +using namespace PERIPHERALS; +using namespace ANNOUNCEMENT; + +CPeripheralCecAdapter::CPeripheralCecAdapter(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId) : + CPeripheral(type, busType, strLocation, strDeviceName, iVendorId, iProductId) +{ + m_features.push_back(FEATURE_CEC); +} + +CPeripheralCecAdapter::~CPeripheralCecAdapter(void) +{ + CAnnouncementManager::RemoveAnnouncer(this); +} + +void CPeripheralCecAdapter::Announce(EAnnouncementFlag flag, const char *sender, const char *message, const CVariant &data) +{ + if (flag == System && !strcmp(sender, "xbmc") && !strcmp(message, "ApplicationStop")) + { + ScreenSetPower(false); + } +} + +bool CPeripheralCecAdapter::ScreenSetPower(bool bSetTo) +{ + // TODO + return false; +} + +bool CPeripheralCecAdapter::InitialiseFeature(const PeripheralFeature feature) +{ + if (feature == FEATURE_CEC) + CAnnouncementManager::AddAnnouncer(this); + + return CPeripheral::InitialiseFeature(feature); +} diff --git a/xbmc/peripherals/devices/PeripheralCecAdapter.h b/xbmc/peripherals/devices/PeripheralCecAdapter.h new file mode 100644 index 0000000000..8b8c6c8d8c --- /dev/null +++ b/xbmc/peripherals/devices/PeripheralCecAdapter.h @@ -0,0 +1,40 @@ +#pragma once +/* + * Copyright (C) 2005-2011 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "Peripheral.h" +#include "interfaces/AnnouncementManager.h" + +namespace PERIPHERALS +{ + class CPeripheralCecAdapter : public CPeripheral, public ANNOUNCEMENT::IAnnouncer + { + public: + CPeripheralCecAdapter(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId); + virtual ~CPeripheralCecAdapter(void); + + virtual void Announce(ANNOUNCEMENT::EAnnouncementFlag flag, const char *sender, const char *message, const CVariant &data); + bool ScreenSetPower(bool bSetTo); + + protected: + virtual bool InitialiseFeature(const PeripheralFeature feature); + }; +} diff --git a/xbmc/peripherals/devices/PeripheralDisk.cpp b/xbmc/peripherals/devices/PeripheralDisk.cpp new file mode 100644 index 0000000000..f15ab16e2e --- /dev/null +++ b/xbmc/peripherals/devices/PeripheralDisk.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2005-2011 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "PeripheralDisk.h" +#include "guilib/LocalizeStrings.h" + +using namespace PERIPHERALS; + +CPeripheralDisk::CPeripheralDisk(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId) : + CPeripheral(type, busType, strLocation, strDeviceName.IsEmpty() ? g_localizeStrings.Get(35003) : strDeviceName, iVendorId, iProductId) +{ + m_features.push_back(FEATURE_DISK); +} diff --git a/xbmc/peripherals/devices/PeripheralDisk.h b/xbmc/peripherals/devices/PeripheralDisk.h new file mode 100644 index 0000000000..196b9cab83 --- /dev/null +++ b/xbmc/peripherals/devices/PeripheralDisk.h @@ -0,0 +1,33 @@ +#pragma once +/* + * Copyright (C) 2005-2011 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "Peripheral.h" + +namespace PERIPHERALS +{ + class CPeripheralDisk : public CPeripheral + { + public: + CPeripheralDisk(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId); + virtual ~CPeripheralDisk(void) {}; + }; +} diff --git a/xbmc/peripherals/devices/PeripheralHID.cpp b/xbmc/peripherals/devices/PeripheralHID.cpp new file mode 100644 index 0000000000..da590d54ff --- /dev/null +++ b/xbmc/peripherals/devices/PeripheralHID.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2005-2011 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "PeripheralHID.h" +#include "utils/log.h" +#include "settings/Settings.h" +#include "guilib/LocalizeStrings.h" + +using namespace PERIPHERALS; +using namespace std; + +CPeripheralHID::CPeripheralHID(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId) : + CPeripheral(type, busType, strLocation, strDeviceName.IsEmpty() ? g_localizeStrings.Get(35001) : strDeviceName, iVendorId, iProductId), + m_bInitialised(false) +{ + m_features.push_back(FEATURE_HID); +} + +CPeripheralHID::~CPeripheralHID(void) +{ + if (!m_strKeymap.IsEmpty() && GetSettingBool("keymap_enabled") && g_settings.m_activeKeyboardMapping.Equals(m_strKeymap)) + { + CLog::Log(LOGDEBUG, "%s - switching active keymapping to: default", __FUNCTION__); + g_settings.m_activeKeyboardMapping = "default"; + } +} + +bool CPeripheralHID::InitialiseFeature(const PeripheralFeature feature) +{ + if (feature == FEATURE_HID && !m_bInitialised) + { + m_bInitialised = true; + + if (HasSetting("keymap")) + m_strKeymap = GetSettingString("keymap"); + + if (m_strKeymap.IsEmpty()) + { + m_strKeymap.Format("v%sp%s", VendorIdAsString(), ProductIdAsString()); + SetSetting("keymap", m_strKeymap); + } + + if (!m_strKeymap.IsEmpty()) + { + bool bKeymapEnabled(GetSettingBool("keymap_enabled")); + if (bKeymapEnabled) + { + CLog::Log(LOGDEBUG, "%s - switching active keymapping to: %s", __FUNCTION__, m_strKeymap.c_str()); + g_settings.m_activeKeyboardMapping = m_strKeymap; + } + else if (!bKeymapEnabled && g_settings.m_activeKeyboardMapping.Equals(m_strKeymap)) + { + CLog::Log(LOGDEBUG, "%s - switching active keymapping to: default", __FUNCTION__); + g_settings.m_activeKeyboardMapping = "default"; + } + } + + CLog::Log(LOGDEBUG, "%s - initialised HID device (%s:%s)", __FUNCTION__, m_strVendorId, m_strProductId); + } + + return CPeripheral::InitialiseFeature(feature); +} + +void CPeripheralHID::OnSettingChanged(const CStdString &strChangedSetting) +{ + if (m_bInitialised && ((strChangedSetting.Equals("keymap") && GetSettingBool("keymap_enabled")) || strChangedSetting.Equals("keymap_enabled"))) + { + m_bInitialised = false; + InitialiseFeature(FEATURE_HID); + } +} + diff --git a/xbmc/peripherals/devices/PeripheralHID.h b/xbmc/peripherals/devices/PeripheralHID.h new file mode 100644 index 0000000000..93515c88ff --- /dev/null +++ b/xbmc/peripherals/devices/PeripheralHID.h @@ -0,0 +1,41 @@ +#pragma once +/* + * Copyright (C) 2005-2011 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "Peripheral.h" +#include "input/XBMC_keyboard.h" + +namespace PERIPHERALS +{ + class CPeripheralHID : public CPeripheral + { + public: + CPeripheralHID(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId); + virtual ~CPeripheralHID(void); + virtual bool InitialiseFeature(const PeripheralFeature feature); + virtual bool LookupSymAndUnicode(XBMC_keysym &keysym, uint8_t *key, char *unicode) { return false; } + virtual void OnSettingChanged(const CStdString &strChangedSetting); + + protected: + bool m_bInitialised; + CStdString m_strKeymap; + }; +} diff --git a/xbmc/peripherals/devices/PeripheralNIC.cpp b/xbmc/peripherals/devices/PeripheralNIC.cpp new file mode 100644 index 0000000000..02210c8fab --- /dev/null +++ b/xbmc/peripherals/devices/PeripheralNIC.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2005-2011 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "PeripheralNIC.h" +#include "utils/log.h" +#include "guilib/LocalizeStrings.h" + +using namespace PERIPHERALS; +using namespace std; + +CPeripheralNIC::CPeripheralNIC(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId) : + CPeripheral(type, busType, strLocation, strDeviceName.IsEmpty() ? g_localizeStrings.Get(35002) : strDeviceName, iVendorId, iProductId) +{ + m_features.push_back(FEATURE_NIC); +} diff --git a/xbmc/peripherals/devices/PeripheralNIC.h b/xbmc/peripherals/devices/PeripheralNIC.h new file mode 100644 index 0000000000..f645a729f1 --- /dev/null +++ b/xbmc/peripherals/devices/PeripheralNIC.h @@ -0,0 +1,33 @@ +#pragma once +/* + * Copyright (C) 2005-2011 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "Peripheral.h" + +namespace PERIPHERALS +{ + class CPeripheralNIC : public CPeripheral + { + public: + CPeripheralNIC(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId); + virtual ~CPeripheralNIC(void) {}; + }; +} diff --git a/xbmc/peripherals/devices/PeripheralNyxboard.cpp b/xbmc/peripherals/devices/PeripheralNyxboard.cpp new file mode 100644 index 0000000000..4ba895b1a4 --- /dev/null +++ b/xbmc/peripherals/devices/PeripheralNyxboard.cpp @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2005-2011 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "PeripheralNyxboard.h" +#include "PeripheralHID.h" +#include "guilib/Key.h" +#include "utils/log.h" +#include "interfaces/Builtins.h" + +using namespace PERIPHERALS; +using namespace std; + +CPeripheralNyxboard::CPeripheralNyxboard(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId) : + CPeripheralHID(type, busType, strLocation, strDeviceName, iVendorId, iProductId) +{ + m_features.push_back(FEATURE_NYXBOARD); +} + +bool CPeripheralNyxboard::LookupSymAndUnicode(XBMC_keysym &keysym, uint8_t *key, char *unicode) +{ + CStdString strCommand; + if (keysym.sym == XBMCK_F7 && keysym.mod == XBMCKMOD_NONE && GetSettingBool("enable_flip_commands")) + { + /* switched to keyboard side */ + CLog::Log(LOGDEBUG, "%s - switched to keyboard side", __FUNCTION__); + strCommand = GetSettingString("flip_keyboard"); + } + else if (keysym.sym == XBMCK_F7 && keysym.mod == XBMCKMOD_LCTRL && GetSettingBool("enable_flip_commands")) + { + /* switched to remote side */ + CLog::Log(LOGDEBUG, "%s - switched to remote side", __FUNCTION__); + strCommand = GetSettingString("flip_remote"); + } + else if (keysym.sym == XBMCK_F4 && keysym.mod == XBMCKMOD_NONE) + { + /* 'user' key pressed */ + CLog::Log(LOGDEBUG, "%s - 'user' key pressed", __FUNCTION__); + strCommand = GetSettingString("key_user"); + } + + if (!strCommand.IsEmpty()) + { + CLog::Log(LOGDEBUG, "%s - executing command '%s'", __FUNCTION__, strCommand.c_str()); + CBuiltins::Execute(strCommand); + + *key = 0; + *unicode = (char) 0; + return true; + } + + return false; +} diff --git a/xbmc/peripherals/devices/PeripheralNyxboard.h b/xbmc/peripherals/devices/PeripheralNyxboard.h new file mode 100644 index 0000000000..cec51e64ee --- /dev/null +++ b/xbmc/peripherals/devices/PeripheralNyxboard.h @@ -0,0 +1,34 @@ +#pragma once +/* + * Copyright (C) 2005-2011 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "PeripheralHID.h" + +namespace PERIPHERALS +{ + class CPeripheralNyxboard : public CPeripheralHID + { + public: + CPeripheralNyxboard(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId); + virtual ~CPeripheralNyxboard(void) {}; + virtual bool LookupSymAndUnicode(XBMC_keysym &keysym, uint8_t *key, char *unicode); + }; +} diff --git a/xbmc/peripherals/devices/PeripheralTuner.cpp b/xbmc/peripherals/devices/PeripheralTuner.cpp new file mode 100644 index 0000000000..3a147d5050 --- /dev/null +++ b/xbmc/peripherals/devices/PeripheralTuner.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2005-2011 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "PeripheralTuner.h" +#include "utils/log.h" + +using namespace PERIPHERALS; + +CPeripheralTuner::CPeripheralTuner(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId) : + CPeripheral(type, busType, strLocation, strDeviceName, iVendorId, iProductId) +{ + m_features.push_back(FEATURE_TUNER); +} diff --git a/xbmc/peripherals/devices/PeripheralTuner.h b/xbmc/peripherals/devices/PeripheralTuner.h new file mode 100644 index 0000000000..08d8f74fe9 --- /dev/null +++ b/xbmc/peripherals/devices/PeripheralTuner.h @@ -0,0 +1,33 @@ +#pragma once +/* + * Copyright (C) 2005-2011 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "Peripheral.h" + +namespace PERIPHERALS +{ + class CPeripheralTuner : public CPeripheral + { + public: + CPeripheralTuner(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId); + virtual ~CPeripheralTuner(void) {}; + }; +} diff --git a/xbmc/peripherals/dialogs/GUIDialogPeripheralManager.cpp b/xbmc/peripherals/dialogs/GUIDialogPeripheralManager.cpp new file mode 100644 index 0000000000..599bacbb16 --- /dev/null +++ b/xbmc/peripherals/dialogs/GUIDialogPeripheralManager.cpp @@ -0,0 +1,206 @@ +/* + * Copyright (C) 2005-2011 Team XBMC + * http://www.xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "GUIDialogPeripheralManager.h" +#include "GUIDialogPeripheralSettings.h" +#include "guilib/GUIWindowManager.h" +#include "peripherals/Peripherals.h" +#include "FileItem.h" +#include "guilib/Key.h" +#include "utils/log.h" + +#define BUTTON_CLOSE 10 +#define BUTTON_SETTINGS 11 +#define CONTROL_LIST 20 + +using namespace std; +using namespace PERIPHERALS; + +CGUIDialogPeripheralManager::CGUIDialogPeripheralManager(void) : + CGUIDialog(WINDOW_DIALOG_PERIPHERAL_MANAGER, "DialogPeripheralManager.xml"), + m_iSelected(0), + m_peripheralItems(new CFileItemList) +{ +} + +CGUIDialogPeripheralManager::~CGUIDialogPeripheralManager(void) +{ + delete m_peripheralItems; +} + +bool CGUIDialogPeripheralManager::OnAction(const CAction &action) +{ + int iActionId = action.GetID(); + if (iActionId == ACTION_PREVIOUS_MENU || iActionId == ACTION_PARENT_DIR) + { + Close(); + return true; + } + else if (GetFocusedControlID() == CONTROL_LIST && + (iActionId == ACTION_MOVE_DOWN || iActionId == ACTION_MOVE_UP || + iActionId == ACTION_PAGE_DOWN || iActionId == ACTION_PAGE_UP)) + { + CGUIDialog::OnAction(action); + int iSelected = m_viewControl.GetSelectedItem(); + if (iSelected != m_iSelected) + m_iSelected = iSelected; + UpdateButtons(); + return true; + } + + return CGUIDialog::OnAction(action); +} + +bool CGUIDialogPeripheralManager::OnMessageInit(CGUIMessage &message) +{ + CGUIWindow::OnMessage(message); + m_iSelected = 0; + Update(); + + return true; +} + +bool CGUIDialogPeripheralManager::OnClickList(CGUIMessage &message) +{ + if (CurrentItemHasSettings()) + return OpenSettingsDialog(); + + return true; +} + +bool CGUIDialogPeripheralManager::OnClickButtonClose(CGUIMessage &message) +{ + Close(); + return true; +} + +bool CGUIDialogPeripheralManager::OnClickButtonSettings(CGUIMessage &message) +{ + return OpenSettingsDialog(); +} + +bool CGUIDialogPeripheralManager::OpenSettingsDialog(void) +{ + CGUIDialogPeripheralSettings *dialog = (CGUIDialogPeripheralSettings *)g_windowManager.GetWindow(WINDOW_DIALOG_PERIPHERAL_SETTINGS); + if (dialog) + { + dialog->SetFileItem(GetCurrentListItem()); + dialog->DoModal(); + return true; + } + + return false; +} + +bool CGUIDialogPeripheralManager::OnMessageClick(CGUIMessage &message) +{ + int iControl = message.GetSenderId(); + switch(iControl) + { + case CONTROL_LIST: + return OnClickList(message); + case BUTTON_CLOSE: + return OnClickButtonClose(message); + case BUTTON_SETTINGS: + return OnClickButtonSettings(message); + default: + return false; + } +} + +bool CGUIDialogPeripheralManager::OnMessage(CGUIMessage& message) +{ + unsigned int iMessage = message.GetMessage(); + + switch (iMessage) + { + case GUI_MSG_WINDOW_DEINIT: + Clear(); + break; + case GUI_MSG_ITEM_SELECT: + return true; + case GUI_MSG_WINDOW_INIT: + return OnMessageInit(message); + case GUI_MSG_CLICKED: + return OnMessageClick(message); + } + + return CGUIDialog::OnMessage(message); +} + +void CGUIDialogPeripheralManager::OnWindowLoaded(void) +{ + CGUIDialog::OnWindowLoaded(); + + m_viewControl.Reset(); + m_viewControl.SetParentWindow(GetID()); + const CGUIControl *list = GetControl(CONTROL_LIST); + m_viewControl.AddView(list); +} + +void CGUIDialogPeripheralManager::OnWindowUnload(void) +{ + CGUIDialog::OnWindowUnload(); + m_viewControl.Reset(); +} + +CFileItemPtr CGUIDialogPeripheralManager::GetCurrentListItem(void) const +{ + return m_peripheralItems->Get(m_iSelected); +} + +void CGUIDialogPeripheralManager::Update() +{ + CSingleLock lock(g_graphicsContext); + + m_viewControl.SetCurrentView(CONTROL_LIST); + Clear(); + g_peripherals.GetDirectory("peripherals://all/", *m_peripheralItems); + m_viewControl.SetItems(*m_peripheralItems); + m_viewControl.SetSelectedItem(m_iSelected); + + UpdateButtons(); + CGUIControl *list = (CGUIControl *) GetControl(CONTROL_LIST); + if (list) + list->SetInvalid(); +} + +void CGUIDialogPeripheralManager::Clear(void) +{ + m_viewControl.Clear(); + m_peripheralItems->Clear(); +} + +bool CGUIDialogPeripheralManager::CurrentItemHasSettings(void) const +{ + CSingleLock lock(g_graphicsContext); + CFileItemPtr currentItem = GetCurrentListItem(); + if (!currentItem) + return false; + + CPeripheral *peripheral = g_peripherals.GetByPath(currentItem.get()->GetPath()); + return peripheral && peripheral->HasConfigurableSettings(); +} + +void CGUIDialogPeripheralManager::UpdateButtons(void) +{ + CONTROL_ENABLE_ON_CONDITION(BUTTON_SETTINGS, CurrentItemHasSettings()); +} diff --git a/xbmc/peripherals/dialogs/GUIDialogPeripheralManager.h b/xbmc/peripherals/dialogs/GUIDialogPeripheralManager.h new file mode 100644 index 0000000000..d682f42a3e --- /dev/null +++ b/xbmc/peripherals/dialogs/GUIDialogPeripheralManager.h @@ -0,0 +1,59 @@ +#pragma once +/* + * Copyright (C) 2005-2011 Team XBMC + * http://www.xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "guilib/GUIDialog.h" +#include "GUIViewControl.h" + +namespace PERIPHERALS +{ + class CGUIDialogPeripheralManager : public CGUIDialog + { + public: + CGUIDialogPeripheralManager(void); + virtual ~CGUIDialogPeripheralManager(void); + virtual bool OnMessage(CGUIMessage& message); + virtual bool OnAction(const CAction& action); + virtual void OnWindowLoaded(void); + virtual void OnWindowUnload(void); + virtual bool HasListItems() const { return true; }; + virtual CFileItemPtr GetCurrentListItem(void) const; + virtual void Update(void); + + protected: + virtual bool OnMessageInit(CGUIMessage &message); + virtual bool OnMessageClick(CGUIMessage &message); + + virtual bool OnClickList(CGUIMessage &message); + virtual bool OnClickButtonClose(CGUIMessage &message); + virtual bool OnClickButtonSettings(CGUIMessage &message); + virtual bool OpenSettingsDialog(void); + virtual bool CurrentItemHasSettings(void) const; + + private: + void Clear(void); + void UpdateButtons(void); + + int m_iSelected; + CFileItemList* m_peripheralItems; + CGUIViewControl m_viewControl; + }; +} diff --git a/xbmc/peripherals/dialogs/GUIDialogPeripheralSettings.cpp b/xbmc/peripherals/dialogs/GUIDialogPeripheralSettings.cpp new file mode 100644 index 0000000000..8018d54503 --- /dev/null +++ b/xbmc/peripherals/dialogs/GUIDialogPeripheralSettings.cpp @@ -0,0 +1,222 @@ +/* + * Copyright (C) 2005-2008 Team XBMC + * http://www.xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "GUIDialogPeripheralSettings.h" +#include "addons/Skin.h" +#include "peripherals/Peripherals.h" +#include "settings/GUISettings.h" +#include "utils/log.h" +#include "video/dialogs/GUIDialogVideoSettings.h" + +using namespace std; +using namespace PERIPHERALS; + +#define BUTTON_DEFAULTS 50 + +CGUIDialogPeripheralSettings::CGUIDialogPeripheralSettings(void) : + CGUIDialogSettings(WINDOW_DIALOG_PERIPHERAL_SETTINGS, "DialogPeripheralSettings.xml"), + m_item(NULL), + m_bIsInitialising(true) +{ +} + +CGUIDialogPeripheralSettings::~CGUIDialogPeripheralSettings(void) +{ + if (m_item) + delete m_item; +} + +void CGUIDialogPeripheralSettings::SetFileItem(CFileItemPtr item) +{ + if (m_item) + { + delete m_item; + m_boolSettings.clear(); + m_intSettings.clear(); + m_floatSettings.clear(); + m_stringSettings.clear(); + m_settings.clear(); + } + + m_item = new CFileItem(*item.get()); +} + +void CGUIDialogPeripheralSettings::CreateSettings() +{ + m_bIsInitialising = true; + m_usePopupSliders = g_SkinInfo->HasSkinFile("DialogSlider.xml"); + + if (m_item) + { + int iIndex = 1; + CPeripheral *peripheral = g_peripherals.GetByPath(m_item->GetPath()); + if (peripheral) + { + map<CStdString, CSetting *>::iterator it = peripheral->m_settings.begin(); + while (it != peripheral->m_settings.end()) + { + CSetting *setting = (*it).second; + if (!setting->IsVisible()) + { + ++it; + CLog::Log(LOGDEBUG, "%s - invisible", __FUNCTION__); + continue; + } + + switch(setting->GetType()) + { + case SETTINGS_TYPE_BOOL: + { + CSettingBool *boolSetting = (CSettingBool *) setting; + if (boolSetting) + { + m_boolSettings.insert(make_pair(CStdString(boolSetting->GetSetting()), boolSetting->GetData())); + AddBool(iIndex++, boolSetting->GetLabel(), &m_boolSettings[boolSetting->GetSetting()], true); + } + } + break; + case SETTINGS_TYPE_INT: + { + CSettingInt *intSetting = (CSettingInt *) setting; + if (intSetting) + { + m_intSettings.insert(make_pair(CStdString(intSetting->GetSetting()), (float) intSetting->GetData())); + AddSlider(iIndex++, intSetting->GetLabel(), &m_intSettings[intSetting->GetSetting()], intSetting->m_iMin, intSetting->m_iStep, intSetting->m_iMax, CGUIDialogVideoSettings::FormatInteger, false); + } + } + break; + case SETTINGS_TYPE_FLOAT: + { + CSettingFloat *floatSetting = (CSettingFloat *) setting; + if (floatSetting) + { + m_floatSettings.insert(make_pair(CStdString(floatSetting->GetSetting()), floatSetting->GetData())); + AddSlider(iIndex++, floatSetting->GetLabel(), &m_floatSettings[floatSetting->GetSetting()], floatSetting->m_fMin, floatSetting->m_fStep, floatSetting->m_fMax, CGUIDialogVideoSettings::FormatFloat, false); + } + } + break; + case SETTINGS_TYPE_STRING: + { + CSettingString *stringSetting = (CSettingString *) setting; + if (stringSetting) + { + m_stringSettings.insert(make_pair(CStdString(stringSetting->GetSetting()), stringSetting->GetData())); + AddString(iIndex, stringSetting->GetLabel(), &m_stringSettings[stringSetting->GetSetting()]); + } + } + break; + default: + //TODO add more types if needed + CLog::Log(LOGDEBUG, "%s - unknown type", __FUNCTION__); + break; + } + ++it; + } + } + else + { + CLog::Log(LOGDEBUG, "%s - no peripheral", __FUNCTION__); + } + } + + m_bIsInitialising = false; +} + +void CGUIDialogPeripheralSettings::UpdatePeripheralSettings(void) +{ + if (!m_item || m_bIsInitialising) + return; + + CPeripheral *peripheral = g_peripherals.GetByPath(m_item->GetPath()); + if (!peripheral) + return; + + map<CStdString, bool>::iterator boolItr = m_boolSettings.begin(); + while (boolItr != m_boolSettings.end()) + { + peripheral->SetSetting((*boolItr).first, (*boolItr).second); + ++boolItr; + } + + map<CStdString, float>::iterator intItr = m_intSettings.begin(); + while (intItr != m_intSettings.end()) + { + peripheral->SetSetting((*intItr).first, (int) (*intItr).second); + ++intItr; + } + + map<CStdString, float>::iterator floatItr = m_floatSettings.begin(); + while (floatItr != m_floatSettings.end()) + { + peripheral->SetSetting((*floatItr).first, (*floatItr).second); + ++floatItr; + } + + map<CStdString, CStdString>::iterator stringItr = m_stringSettings.begin(); + while (stringItr != m_stringSettings.end()) + { + peripheral->SetSetting((*stringItr).first, (*stringItr).second); + ++stringItr; + } +} + +bool CGUIDialogPeripheralSettings::OnMessage(CGUIMessage &message) +{ + if (message.GetMessage() == GUI_MSG_CLICKED && + message.GetSenderId() == BUTTON_DEFAULTS) + { + ResetDefaultSettings(); + return true; + } + + return CGUIDialogSettings::OnMessage(message); +} + +void CGUIDialogPeripheralSettings::OnOkay(void) +{ + UpdatePeripheralSettings(); +} + +void CGUIDialogPeripheralSettings::ResetDefaultSettings(void) +{ + if (m_item) + { + CPeripheral *peripheral = g_peripherals.GetByPath(m_item->GetPath()); + if (!peripheral) + return; + + /* reset the settings in the peripheral */ + peripheral->ResetDefaultSettings(); + + CSingleLock lock(g_graphicsContext); + + /* clear the settings */ + m_boolSettings.clear(); + m_intSettings.clear(); + m_floatSettings.clear(); + m_stringSettings.clear(); + m_settings.clear(); + + /* reinit the window */ + CreateSettings(); + SetupPage(); // will clear the previous controls first + } +} diff --git a/xbmc/peripherals/dialogs/GUIDialogPeripheralSettings.h b/xbmc/peripherals/dialogs/GUIDialogPeripheralSettings.h new file mode 100644 index 0000000000..9511e842ba --- /dev/null +++ b/xbmc/peripherals/dialogs/GUIDialogPeripheralSettings.h @@ -0,0 +1,50 @@ +#pragma once +/* + * Copyright (C) 2005-2011 Team XBMC + * http://www.xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "guilib/GUIDialog.h" +#include "settings/GUIDialogSettings.h" +#include "FileItem.h" + +namespace PERIPHERALS +{ + class CGUIDialogPeripheralSettings : public CGUIDialogSettings + { + public: + CGUIDialogPeripheralSettings(void); + virtual ~CGUIDialogPeripheralSettings(void); + + virtual void SetFileItem(CFileItemPtr item); + virtual bool OnMessage(CGUIMessage &message); + protected: + virtual void CreateSettings(); + virtual void OnOkay(void); + virtual void ResetDefaultSettings(void); + virtual void UpdatePeripheralSettings(void); + + CFileItem * m_item; + bool m_bIsInitialising; + std::map<CStdString, bool> m_boolSettings; + std::map<CStdString, float> m_intSettings; + std::map<CStdString, float> m_floatSettings; + std::map<CStdString, CStdString> m_stringSettings; + }; +} diff --git a/xbmc/peripherals/dialogs/Makefile b/xbmc/peripherals/dialogs/Makefile new file mode 100644 index 0000000000..4aa6331efd --- /dev/null +++ b/xbmc/peripherals/dialogs/Makefile @@ -0,0 +1,7 @@ +SRCS=GUIDialogPeripheralSettings.cpp \ + GUIDialogPeripheralManager.cpp + +LIB=peripheral-dialogs.a + +include ../../../Makefile.include +-include $(patsubst %.cpp,%.P,$(patsubst %.c,%.P,$(SRCS))) diff --git a/xbmc/settings/GUIDialogSettings.cpp b/xbmc/settings/GUIDialogSettings.cpp index a1ac08d63f..609a299904 100644 --- a/xbmc/settings/GUIDialogSettings.cpp +++ b/xbmc/settings/GUIDialogSettings.cpp @@ -28,6 +28,7 @@ #include "guilib/LocalizeStrings.h" #include "GUISettings.h" #include "utils/log.h" +#include "dialogs/GUIDialogKeyboard.h" #define CONTROL_GROUP_LIST 5 #define CONTROL_SETTINGS_LABEL 2 @@ -190,6 +191,14 @@ void CGUIDialogSettings::UpdateSetting(unsigned int id) if (m_usePopupSliders && setting.data && setting.formatFunction) SET_CONTROL_LABEL2(controlID,setting.formatFunction(*(float *)setting.data, setting.interval)); } + else if (setting.type == SettingInfo::STRING) + { + SET_CONTROL_LABEL(controlID, setting.name); + string strNewValue = string(*(CStdString *)setting.data); + if (strNewValue.empty()) + strNewValue = "-"; + SET_CONTROL_LABEL2(controlID, strNewValue); + } if (setting.enabled) { @@ -251,6 +260,14 @@ void CGUIDialogSettings::OnClick(int iID) if (setting.formatFunction) SET_CONTROL_LABEL2(iID, setting.formatFunction(*(float *)setting.data, setting.interval)); } + else if (setting.type == SettingInfo::STRING) + { + CGUIDialogKeyboard::ShowAndGetInput(*(CStdString *) setting.data, true); + string strNewValue = string(*(CStdString *)setting.data); + if (strNewValue.empty()) + strNewValue = "-"; + SET_CONTROL_LABEL2(iID, strNewValue); + } OnSettingChanged(setting); } @@ -317,6 +334,17 @@ void CGUIDialogSettings::AddSetting(SettingInfo &setting, float width, int iCont ((CGUISettingsSliderControl *)pControl)->SetFloatInterval(setting.interval); if (setting.data) ((CGUISettingsSliderControl *)pControl)->SetFloatValue(*(float *)setting.data); } + if (setting.type == SettingInfo::STRING && m_pOriginalSettingsButton) + { + pControl = new CGUIButtonControl(*m_pOriginalSettingsButton); + if (!pControl) return ; + ((CGUIButtonControl *)pControl)->SetLabel(setting.name); + string strValue = string(*(CStdString *)setting.data); + if (strValue.empty()) + strValue = "-"; + ((CGUIButtonControl *)pControl)->SetLabel2(strValue); + pControl->SetWidth(width); + } if (!pControl) return; pControl->SetID(iControlID); @@ -346,6 +374,17 @@ void CGUIDialogSettings::AddButton(unsigned int id, int label, float *current, f m_settings.push_back(setting); } +void CGUIDialogSettings::AddString(unsigned int id, int label, CStdString *current) +{ + SettingInfo setting; + setting.id = id; + setting.name = g_localizeStrings.Get(label); + setting.type = SettingInfo::STRING; + setting.data = current; + setting.enabled = true; + m_settings.push_back(setting); +} + void CGUIDialogSettings::AddBool(unsigned int id, int label, bool *on, bool enabled) { SettingInfo setting; diff --git a/xbmc/settings/GUIDialogSettings.h b/xbmc/settings/GUIDialogSettings.h index 628c90705b..9768bf3a5b 100644 --- a/xbmc/settings/GUIDialogSettings.h +++ b/xbmc/settings/GUIDialogSettings.h @@ -35,7 +35,7 @@ typedef CStdString (*FORMATFUNCTION) (float value, float min); class SettingInfo { public: - enum SETTING_TYPE { NONE=0, BUTTON, CHECK, CHECK_UCHAR, SPIN, SLIDER, SEPARATOR }; + enum SETTING_TYPE { NONE=0, BUTTON, CHECK, CHECK_UCHAR, SPIN, SLIDER, SEPARATOR, STRING }; SettingInfo() { id = 0; @@ -85,6 +85,7 @@ protected: void AddButton(unsigned int id, int label, float *current = NULL, float min = 0, float interval = 0, float max = 0, FORMATFUNCTION function = NULL); void AddBool(unsigned int id, int label, bool *on, bool enabled = true); + void AddString(unsigned int id, int label, CStdString *current); void AddSpin(unsigned int id, int label, int *current, unsigned int max, const int *entries); void AddSpin(unsigned int id, int label, int *current, unsigned int min, unsigned int max, const char* minLabel = NULL); void AddSpin(unsigned int id, int label, int *current, std::vector<std::pair<int, CStdString> > &values); diff --git a/xbmc/settings/GUISettings.cpp b/xbmc/settings/GUISettings.cpp index c94e9d9626..9acee6fb6d 100644 --- a/xbmc/settings/GUISettings.cpp +++ b/xbmc/settings/GUISettings.cpp @@ -85,7 +85,7 @@ void CSettingBool::FromString(const CStdString &strValue) m_bData = (strValue == "true"); } -CStdString CSettingBool::ToString() +CStdString CSettingBool::ToString() const { return m_bData ? "true" : "false"; } @@ -109,7 +109,7 @@ void CSettingFloat::FromString(const CStdString &strValue) SetData((float)atof(strValue.c_str())); } -CStdString CSettingFloat::ToString() +CStdString CSettingFloat::ToString() const { CStdString strValue; strValue.Format("%f", m_fData); @@ -162,7 +162,7 @@ void CSettingInt::FromString(const CStdString &strValue) SetData(id); } -CStdString CSettingInt::ToString() +CStdString CSettingInt::ToString() const { CStdString strValue; strValue.Format("%i", m_iData); @@ -176,7 +176,7 @@ void CSettingHex::FromString(const CStdString &strValue) SetData(iHexValue); } -CStdString CSettingHex::ToString() +CStdString CSettingHex::ToString() const { CStdString strValue; strValue.Format("%x", m_iData); @@ -196,7 +196,7 @@ void CSettingString::FromString(const CStdString &strValue) m_strData = strValue; } -CStdString CSettingString::ToString() +CStdString CSettingString::ToString() const { return m_strData; } @@ -467,6 +467,7 @@ void CGUISettings::Initialize() #endif CSettingsCategory* in = AddCategory(4, "input", 14094); + AddString(in, "input.peripherals", 35000, "", BUTTON_CONTROL_STANDARD); #if defined(__APPLE__) map<int,int> remotemode; remotemode.insert(make_pair(13610,APPLE_REMOTE_DISABLED)); @@ -1085,7 +1086,7 @@ void CGUISettings::AddDefaultAddon(CSettingsCategory* cat, const char *strSettin settingsMap.insert(pair<CStdString, CSetting*>(CStdString(strSetting).ToLower(), pSetting)); } -const CStdString &CGUISettings::GetString(const char *strSetting, bool bPrompt) const +const CStdString &CGUISettings::GetString(const char *strSetting, bool bPrompt /* = true */) const { ASSERT(settingsMap.size()); constMapIter it = settingsMap.find(CStdString(strSetting).ToLower()); diff --git a/xbmc/settings/GUISettings.h b/xbmc/settings/GUISettings.h index 6925bdc849..869e3361fd 100644 --- a/xbmc/settings/GUISettings.h +++ b/xbmc/settings/GUISettings.h @@ -221,19 +221,20 @@ public: m_visible = true; }; virtual ~CSetting() {}; - virtual int GetType() { return 0; }; - int GetControlType() { return m_iControlType; }; + virtual int GetType() const { return 0; }; + int GetControlType() const { return m_iControlType; }; virtual void FromString(const CStdString &strValue) {}; - virtual CStdString ToString() { return ""; }; - const char *GetSetting() { return m_strSetting.c_str(); }; - int GetLabel() { return m_iLabel; }; + virtual CStdString ToString() const { return ""; }; + const char *GetSetting() const { return m_strSetting.c_str(); }; + int GetLabel() const { return m_iLabel; }; int GetOrder() const { return m_iOrder; }; + void SetOrder(int iOrder) { m_iOrder = iOrder; }; void SetAdvanced() { m_advanced = true; }; - bool IsAdvanced() { return m_advanced; }; + bool IsAdvanced() const { return m_advanced; }; // A setting might be invisible in the current session, yet carried over // in the config file. void SetVisible(bool visible) { m_visible = visible; } - bool IsVisible() { return m_visible; } + bool IsVisible() const { return m_visible; } private: int m_iControlType; int m_iLabel; @@ -249,9 +250,9 @@ public: CSettingBool(int iOrder, const char *strSetting, int iLabel, bool bData, int iControlType): CSetting(iOrder, strSetting, iLabel, iControlType) { m_bData = bData; }; virtual ~CSettingBool() {}; - virtual int GetType() { return SETTINGS_TYPE_BOOL; }; + virtual int GetType() const { return SETTINGS_TYPE_BOOL; }; virtual void FromString(const CStdString &strValue); - virtual CStdString ToString(); + virtual CStdString ToString() const; void SetData(bool bData) { m_bData = bData; }; bool GetData() const { return m_bData; }; @@ -266,12 +267,12 @@ public: CSettingFloat(int iOrder, const char *strSetting, int iLabel, float fData, float fMin, float fStep, float fMax, int iControlType); virtual ~CSettingFloat() {}; - virtual int GetType() { return SETTINGS_TYPE_FLOAT; }; + virtual int GetType() const { return SETTINGS_TYPE_FLOAT; }; virtual void FromString(const CStdString &strValue); - virtual CStdString ToString(); + virtual CStdString ToString() const; void SetData(float fData) { m_fData = fData; if (m_fData < m_fMin) m_fData = m_fMin; if (m_fData > m_fMax) m_fData = m_fMax;}; -float GetData() const { return m_fData; }; + float GetData() const { return m_fData; }; float m_fMin; float m_fStep; @@ -289,9 +290,9 @@ public: CSettingInt(int iOrder, const char *strSetting, int iLabel, int iData, const std::map<int,int>& entries, int iControlType); virtual ~CSettingInt() {}; - virtual int GetType() { return SETTINGS_TYPE_INT; }; + virtual int GetType() const { return SETTINGS_TYPE_INT; }; virtual void FromString(const CStdString &strValue); - virtual CStdString ToString(); + virtual CStdString ToString() const; void SetData(int iData) { @@ -335,8 +336,8 @@ public: : CSettingInt(iOrder, strSetting, iLabel, iData, iMin, iStep, iMax, iControlType, strFormat) {}; virtual ~CSettingHex() {}; virtual void FromString(const CStdString &strValue); - virtual CStdString ToString(); - virtual int GetType() { return SETTINGS_TYPE_HEX; }; + virtual CStdString ToString() const; + virtual int GetType() const { return SETTINGS_TYPE_HEX; }; }; class CSettingString : public CSetting @@ -345,9 +346,9 @@ public: CSettingString(int iOrder, const char *strSetting, int iLabel, const char *strData, int iControlType, bool bAllowEmpty, int iHeadingString); virtual ~CSettingString() {}; - virtual int GetType() { return SETTINGS_TYPE_STRING; }; + virtual int GetType() const { return SETTINGS_TYPE_STRING; }; virtual void FromString(const CStdString &strValue); - virtual CStdString ToString(); + virtual CStdString ToString() const; void SetData(const char *strData) { m_strData = strData; }; const CStdString &GetData() const { return m_strData; }; @@ -364,7 +365,7 @@ public: CSettingPath(int iOrder, const char *strSetting, int iLabel, const char *strData, int iControlType, bool bAllowEmpty, int iHeadingString); virtual ~CSettingPath() {}; - virtual int GetType() { return SETTINGS_TYPE_PATH; }; + virtual int GetType() const { return SETTINGS_TYPE_PATH; }; }; class CSettingAddon : public CSettingString @@ -372,7 +373,7 @@ class CSettingAddon : public CSettingString public: CSettingAddon(int iOrder, const char *strSetting, int iLabel, const char *strData, const ADDON::TYPE type); virtual ~CSettingAddon() {}; - virtual int GetType() { return SETTINGS_TYPE_ADDON; }; + virtual int GetType() const { return SETTINGS_TYPE_ADDON; }; const ADDON::TYPE m_type; }; @@ -383,7 +384,7 @@ public: CSettingSeparator(int iOrder, const char *strSetting); virtual ~CSettingSeparator() {}; - virtual int GetType() { return SETTINGS_TYPE_SEPARATOR; }; + virtual int GetType() const { return SETTINGS_TYPE_SEPARATOR; }; }; class CSettingsCategory diff --git a/xbmc/settings/GUIWindowSettingsCategory.cpp b/xbmc/settings/GUIWindowSettingsCategory.cpp index ab69a9c135..e977e0cd24 100644 --- a/xbmc/settings/GUIWindowSettingsCategory.cpp +++ b/xbmc/settings/GUIWindowSettingsCategory.cpp @@ -91,6 +91,8 @@ #include "filesystem/SpecialProtocol.h" #include "network/Zeroconf.h" +#include "peripherals/Peripherals.h" +#include "peripherals/dialogs/GUIDialogPeripheralManager.h" #ifdef _WIN32 #include "WIN32Util.h" @@ -117,6 +119,7 @@ using namespace std; using namespace XFILE; using namespace ADDON; +using namespace PERIPHERALS; #define CONTROL_GROUP_BUTTONS 0 #define CONTROL_GROUP_SETTINGS 1 @@ -1022,6 +1025,13 @@ void CGUIWindowSettingsCategory::OnClick(CBaseSettingControl *pSettingControl) else return; } + else if (strSetting.Equals("input.peripherals")) + { + CGUIDialogPeripheralManager *dialog = (CGUIDialogPeripheralManager *)g_windowManager.GetWindow(WINDOW_DIALOG_PERIPHERAL_MANAGER); + if (dialog) + dialog->DoModal(); + return; + } // if OnClick() returns false, the setting hasn't changed or doesn't // require immediate update diff --git a/xbmc/video/windows/GUIWindowVideoBase.cpp b/xbmc/video/windows/GUIWindowVideoBase.cpp index 9ce661af67..f1559e7484 100644 --- a/xbmc/video/windows/GUIWindowVideoBase.cpp +++ b/xbmc/video/windows/GUIWindowVideoBase.cpp @@ -62,7 +62,7 @@ #include "utils/log.h" #include "utils/FileUtils.h" #include "utils/URIUtils.h" - +#include "GUIUserMessages.h" #include "addons/Skin.h" using namespace std; @@ -217,6 +217,9 @@ bool CGUIWindowVideoBase::OnMessage(CGUIMessage& message) } } break; + case GUI_MSG_SEARCH: + OnSearch(); + break; } return CGUIMediaWindow::OnMessage(message); } diff --git a/xbmc/win32/WIN32USBScan.cpp b/xbmc/win32/WIN32USBScan.cpp deleted file mode 100644 index b382c3161e..0000000000 --- a/xbmc/win32/WIN32USBScan.cpp +++ /dev/null @@ -1,74 +0,0 @@ -#include <setupapi.h> -#include "WIN32USBScan.h" -#include "input/KeymapLoader.h" - -static GUID USB_HID_GUID = { 0x4D1E55B2, 0xF16F, 0x11CF, { 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30 } }; - -CWIN32USBScan::CWIN32USBScan() -{ - HDEVINFO hDevHandle; - SP_DEVICE_INTERFACE_DATA deviceInterfaceData; - DWORD required = 0; - deviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); - - int nBufferSize = 0; - - SP_DEVINFO_DATA devInfoData; - devInfoData.cbSize = sizeof(SP_DEVINFO_DATA); - - DWORD MemberIndex = 0; - BOOL Result; - - hDevHandle = SetupDiGetClassDevs(&USB_HID_GUID, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); - - if (hDevHandle == INVALID_HANDLE_VALUE) - return; - - bool bStart = false; - TCHAR *buffer = NULL; - PSP_DEVICE_INTERFACE_DETAIL_DATA devicedetailData; - do - { - Result = SetupDiEnumDeviceInfo(hDevHandle, MemberIndex, &devInfoData); - - if (Result) - Result = SetupDiEnumDeviceInterfaces(hDevHandle, 0, &USB_HID_GUID, MemberIndex, &deviceInterfaceData); - - if(!Result) - { - SetupDiDestroyDeviceInfoList(hDevHandle); - delete []buffer; - buffer = NULL; - return; - } - - MemberIndex++; - BOOL detailResult = false; - - if(!bStart) - { - // As per MSDN, Get the required buffer size. Call SetupDiGetDeviceInterfaceDetail with a - // NULL DeviceInterfaceDetailData pointer, a DeviceInterfaceDetailDataSize of zero, - // and a valid RequiredSize variable. In response to such a call, this function returns - // the required buffer size at RequiredSize and fails with GetLastError returning - // ERROR_INSUFFICIENT_BUFFER. - // Allocate an appropriately sized buffer and call the function again to get the interface details. - - SetupDiGetDeviceInterfaceDetail(hDevHandle, &deviceInterfaceData, NULL, 0, &required, NULL); - - buffer = new TCHAR[required]; - devicedetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) buffer; - devicedetailData->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA); - nBufferSize = required; - bStart = true; - } - - detailResult = SetupDiGetDeviceInterfaceDetail(hDevHandle, &deviceInterfaceData, devicedetailData, nBufferSize , &required, NULL); - - CKeymapLoader::DeviceAdded(CKeymapLoader::ParseWin32HIDName(devicedetailData->DevicePath)); - - if(!detailResult) - continue; - - } while(Result); -}
\ No newline at end of file diff --git a/xbmc/win32/WIN32USBScan.h b/xbmc/win32/WIN32USBScan.h deleted file mode 100644 index f580911b55..0000000000 --- a/xbmc/win32/WIN32USBScan.h +++ /dev/null @@ -1,5 +0,0 @@ -class CWIN32USBScan -{ - public: - CWIN32USBScan(); -};
\ No newline at end of file diff --git a/xbmc/windowing/osx/WinEventsOSX.h b/xbmc/windowing/osx/WinEventsOSX.h index e390f3bbe6..886fcf5f2e 100644 --- a/xbmc/windowing/osx/WinEventsOSX.h +++ b/xbmc/windowing/osx/WinEventsOSX.h @@ -30,7 +30,4 @@ public: ~CWinEventsOSX(); static bool MessagePump(); -private: - void Initialize(void); - }; diff --git a/xbmc/windowing/osx/WinEventsOSX.mm b/xbmc/windowing/osx/WinEventsOSX.mm index efb7bcc50b..3a1ebbdc21 100644 --- a/xbmc/windowing/osx/WinEventsOSX.mm +++ b/xbmc/windowing/osx/WinEventsOSX.mm @@ -22,7 +22,6 @@ #define BOOL XBMC_BOOL #include "system.h" #include "utils/log.h" -#include "input/KeymapLoader.h" #include "windowing/WinEventsSDL.h" #include "windowing/osx/WinEventsOSX.h" #undef BOOL @@ -39,194 +38,15 @@ // place holder for future native osx event handler -typedef struct USBDevicePrivateData { - UInt16 vendorId; - UInt16 productId; - CStdString deviceName; - CStdString keymapDeviceId; - io_object_t notification; -} USBDevicePrivateData; - -static IONotificationPortRef g_notify_port = 0; -static io_iterator_t g_attach_iterator = 0; - CWinEventsOSX::CWinEventsOSX() { - Initialize(); } CWinEventsOSX::~CWinEventsOSX() { - if (g_notify_port) - { - // remove the sleep notification port from the application runloop - CFRunLoopRemoveSource( CFRunLoopGetCurrent(), - IONotificationPortGetRunLoopSource(g_notify_port), kCFRunLoopDefaultMode ); - IONotificationPortDestroy(g_notify_port); - g_notify_port = 0; - } - if (g_attach_iterator) - { - IOObjectRelease(g_attach_iterator); - g_attach_iterator = 0; - } } bool CWinEventsOSX::MessagePump() { return CWinEventsSDL::MessagePump(); } - -static void DeviceDetachCallback(void *refCon, io_service_t service, natural_t messageType, void *messageArgument) -{ - if (messageType == kIOMessageServiceIsTerminated) - { - IOReturn result; - - USBDevicePrivateData *privateDataRef = (USBDevicePrivateData*)refCon; - CKeymapLoader().DeviceRemoved(privateDataRef->keymapDeviceId); - CLog::Log(LOGDEBUG, "HID Device Detach:%s, %s\n", - privateDataRef->deviceName.c_str(), privateDataRef->keymapDeviceId.c_str()); - result = IOObjectRelease(privateDataRef->notification); - delete privateDataRef; - //release the service - result = IOObjectRelease(service); - } -} - -static void DeviceAttachCallback(void* refCon, io_iterator_t iterator) -{ - io_service_t usbDevice; - while ((usbDevice = IOIteratorNext(iterator))) - { - IOReturn result; - - io_name_t deviceName; - result = IORegistryEntryGetName(usbDevice, deviceName); - if (result != KERN_SUCCESS) - deviceName[0] = '\0'; - - SInt32 deviceScore; - IOCFPlugInInterface **devicePlugin; - result = IOCreatePlugInInterfaceForService(usbDevice, - kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &devicePlugin, &deviceScore); - if (result != kIOReturnSuccess) - { - IOObjectRelease(usbDevice); - continue; - } - - IOUSBDeviceInterface **deviceInterface; - // Use the plugin interface to retrieve the device interface. - result = (*devicePlugin)->QueryInterface(devicePlugin, - CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (LPVOID*)&deviceInterface); - if (result != kIOReturnSuccess) - { - IODestroyPlugInInterface(devicePlugin); - IOObjectRelease(usbDevice); - continue; - } - - // get vendor/product ids - UInt16 vendorId; - UInt16 productId; - result = (*deviceInterface)->GetDeviceVendor( deviceInterface, &vendorId); - result = (*deviceInterface)->GetDeviceProduct(deviceInterface, &productId); - - // we only care about usb devices with an HID interface class - io_service_t usbInterface; - io_iterator_t interface_iterator; - IOUSBFindInterfaceRequest request; - request.bInterfaceClass = kUSBHIDInterfaceClass; - request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare; - request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare; - request.bAlternateSetting = kIOUSBFindInterfaceDontCare; - result = (*deviceInterface)->CreateInterfaceIterator(deviceInterface, &request, &interface_iterator); - while ((usbInterface = IOIteratorNext(interface_iterator))) - { - SInt32 interfaceScore; - IOCFPlugInInterface **interfacePlugin; - //create intermediate plugin for interface access - result = IOCreatePlugInInterfaceForService(usbInterface, - kIOUSBInterfaceUserClientTypeID, kIOCFPlugInInterfaceID, &interfacePlugin, &interfaceScore); - if (result != kIOReturnSuccess) - { - IOObjectRelease(usbInterface); - continue; - } - IOUSBInterfaceInterface** interfaceInterface; - result = (*interfacePlugin)->QueryInterface(interfacePlugin, - CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID), (void**)&interfaceInterface); - if (result != kIOReturnSuccess) - { - IODestroyPlugInInterface(interfacePlugin); - IOObjectRelease(usbInterface); - continue; - } - - // finally we can get to bInterfaceClass/bInterfaceProtocol - // we should also check for kHIDKeyboardInterfaceProtocol but - // some IR remotes that emulate an HID keyboard do not report this. - UInt8 bInterfaceClass; - result = (*interfaceInterface)->GetInterfaceClass(interfaceInterface, &bInterfaceClass); - if (bInterfaceClass == kUSBHIDInterfaceClass) - { - USBDevicePrivateData *privateDataRef; - privateDataRef = new USBDevicePrivateData; - // save some device info to our private data. - privateDataRef->vendorId = vendorId; - privateDataRef->productId = productId; - privateDataRef->deviceName = deviceName; - privateDataRef->keymapDeviceId.Format("HID#VID_%04X&PID_%04X", vendorId, productId); - // register this usb device for an interest notification callback. - result = IOServiceAddInterestNotification(g_notify_port, - usbDevice, // service - kIOGeneralInterest, // interestType - DeviceDetachCallback, // callback - privateDataRef, // refCon - &privateDataRef->notification // notification - ); - if (result == kIOReturnSuccess) - { - CKeymapLoader().DeviceAdded(privateDataRef->keymapDeviceId); - CLog::Log(LOGDEBUG, "HID Device Attach:%s, %s\n", - deviceName, privateDataRef->keymapDeviceId.c_str()); - } - - // done with this device, only need one notification per device. - IODestroyPlugInInterface(interfacePlugin); - IOObjectRelease(usbInterface); - break; - } - IODestroyPlugInInterface(interfacePlugin); - IOObjectRelease(usbInterface); - } - IODestroyPlugInInterface(devicePlugin); - IOObjectRelease(usbDevice); - } -} - -void CWinEventsOSX::Initialize(void) -{ - IOReturn result; - - //set up the matching criteria for the devices we're interested in - //interested in instances of class IOUSBDevice and its subclasses - // match any usb device by not creating matching values in the dict - CFMutableDictionaryRef matching_dict = IOServiceMatching(kIOUSBDeviceClassName); - - g_notify_port = IONotificationPortCreate(kIOMasterPortDefault); - CFRunLoopSourceRef run_loop_source = IONotificationPortGetRunLoopSource(g_notify_port); - CFRunLoopAddSource(CFRunLoopGetCurrent(), run_loop_source, kCFRunLoopCommonModes); - - //add a notification callback for attach event - result = IOServiceAddMatchingNotification(g_notify_port, - kIOFirstMatchNotification, matching_dict, DeviceAttachCallback, NULL, &g_attach_iterator); - if (result == kIOReturnSuccess) - { - //call the callback to 'arm' the notification - DeviceAttachCallback(NULL, g_attach_iterator); - } -} - - diff --git a/xbmc/windowing/windows/WinEventsWin32.cpp b/xbmc/windowing/windows/WinEventsWin32.cpp index 08877d1df5..4113ff1890 100644 --- a/xbmc/windowing/windows/WinEventsWin32.cpp +++ b/xbmc/windowing/windows/WinEventsWin32.cpp @@ -27,12 +27,10 @@ #include "Application.h" #include "input/XBMC_vkeys.h" #include "input/MouseStat.h" -#include "input/KeymapLoader.h" #include "storage/MediaManager.h" #include "windowing/WindowingFactory.h" #include <dbt.h> #include "guilib/LocalizeStrings.h" -#include "input/KeymapLoader.h" #include "input/KeyboardStat.h" #include "guilib/GUIWindowManager.h" #include "guilib/GUIControl.h" // for EVENT_RESULT @@ -40,9 +38,12 @@ #include "Shlobj.h" #include "settings/Settings.h" #include "settings/AdvancedSettings.h" +#include "peripherals/Peripherals.h" #ifdef _WIN32 +using namespace PERIPHERALS; + #define XBMC_arraysize(array) (sizeof(array)/sizeof(array[0])) /* Masks for processing the windows KEYDOWN and KEYUP messages */ @@ -658,19 +659,12 @@ LRESULT CALLBACK CWinEventsWin32::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, L case WM_DEVICECHANGE: { PDEV_BROADCAST_DEVICEINTERFACE b = (PDEV_BROADCAST_DEVICEINTERFACE) lParam; - CStdString dbcc_name(b->dbcc_name); - dbcc_name = CKeymapLoader::ParseWin32HIDName(b->dbcc_name); switch (wParam) { case DBT_DEVICEARRIVAL: - CKeymapLoader().DeviceAdded(dbcc_name); - break; case DBT_DEVICEREMOVECOMPLETE: - CKeymapLoader().DeviceRemoved(dbcc_name); - break; case DBT_DEVNODES_CHANGED: - //CLog::Log(LOGDEBUG, "HID Device Changed"); - //We generally don't care about Change notifications, only need to know if a device is removed or added to rescan the device list + g_peripherals.TriggerDeviceScan(PERIPHERAL_BUS_USB); break; } break; |