diff options
author | Lars Op den Kamp <lars@opdenkamp.eu> | 2011-08-29 15:04:49 +0200 |
---|---|---|
committer | Lars Op den Kamp <lars@opdenkamp.eu> | 2011-09-30 00:37:53 +0200 |
commit | 034236bf690119b2a82be1133ff328bccbdc4411 (patch) | |
tree | 73591daaadc6539cee5c71bab0325485096e79ec | |
parent | 714ad40da8b2ead338aa8e57ef6a5b6802d8a2df (diff) |
Squashed original peripherals PR #383
This is a PR for a new "peripherals manager", /xbmc/peripherals, that detects devices and automatically configures them for use with XBMC. The device mappings and configurations can be defined in system/peripherals.xml. Users can modify settings via system->system->input->peripherals.
It works as follows:
- CPeripherals contains one or more CPeripheralBus instances.
- CPeripheralBus contains the device scanning implementations for the different platforms we support.
- The implementations for the devices can be found in peripheral/devices and all devices inherit from CPeripheral.
- The devices that are detected are looked up in peripherals.xml, starting at the top of the file and going down. If no mapping was found for the device, an instance of one of the default classes will be created: CPeripheralHID, CPeripheralDisk or CPeripheralNIC.
- in peripherals.xml, devices can be matched by vendor id (vendor="xxxx"), product id (product="xxxx"), bus type (bus="xxxx"), device class (class="xxxx") or a combination of these values. The class that will be instantiated for that device is defined in mapTo="xxxx"
- the configuration for the device can be defined in peripherals.xml as well. Have a look at system/peripherals.xml, where you can find the possible settings in the demo entry at the bottom. When a device is inserted and there are any settings with configurable="true" present for that device, these settings will be added to the settings dialog, under system->system->input->peripherals.
- an example of how these settings can be used can be found in CPeripheralHID, which checks for a "keymap" setting and will automatically switch the keymap XBMC uses to the one that is defined in the setting.
TODO:
- keep separate configs when the same device is found more than once
- general review of this code.
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; |