[win32] Fix for problematic iMON hardware #1189

Merged
merged 10 commits into from Oct 3, 2012
+207 −17
View
8 language/English/strings.po
@@ -10823,11 +10823,17 @@ msgstr ""
#empty strings from id 35010 to 35099
+#: xbmc/settings/GUISettings.cpp
msgctxt "#35100"
msgid "Enable joystick and gamepad support"
msgstr ""
-#empty strings from id 35101 to 35499
+#: xbmc/settings/GUISettings.cpp
+msgctxt "#35101"
+msgid "Disable joystick when iMON is present"
+msgstr ""
+
+#empty strings from id 35102 to 35499
msgctxt "#35500"
msgid "Location"
View
2 project/VS2010Express/XBMC.vcxproj
@@ -864,6 +864,7 @@
<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\PeripheralImon.cpp" />
<ClCompile Include="..\..\xbmc\peripherals\devices\PeripheralTuner.cpp" />
<ClCompile Include="..\..\xbmc\peripherals\dialogs\GUIDialogPeripheralManager.cpp" />
<ClCompile Include="..\..\xbmc\peripherals\dialogs\GUIDialogPeripheralSettings.cpp" />
@@ -1189,6 +1190,7 @@
<ClInclude Include="..\..\xbmc\filesystem\ZipFile.h" />
<ClInclude Include="..\..\xbmc\filesystem\ZipManager.h" />
<ClInclude Include="..\..\xbmc\network\windows\ZeroconfBrowserWIN.h" />
+ <ClInclude Include="..\..\xbmc\peripherals\devices\PeripheralImon.h" />
<ClInclude Include="..\..\xbmc\system_gl.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug (DirectX)|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug Testsuite|Win32'">true</ExcludedFromBuild>
View
6 project/VS2010Express/XBMC.vcxproj.filters
@@ -2605,6 +2605,9 @@
<ClCompile Include="..\..\xbmc\dialogs\GUIDialogKeyboardGeneric.cpp">
<Filter>dialogs</Filter>
</ClCompile>
+ <ClCompile Include="..\..\xbmc\peripherals\devices\PeripheralImon.cpp">
+ <Filter>peripherals\devices</Filter>
+ </ClCompile>
<ClCompile Include="..\..\xbmc\video\VideoDbUrl.cpp">
<Filter>video</Filter>
</ClCompile>
@@ -5574,6 +5577,9 @@
<ClInclude Include="..\..\xbmc\dialogs\GUIDialogKeyboardGeneric.h">
<Filter>dialogs</Filter>
</ClInclude>
+ <ClInclude Include="..\..\xbmc\peripherals\devices\PeripheralImon.h">
+ <Filter>peripherals\devices</Filter>
+ </ClInclude>
<ClInclude Include="..\..\xbmc\video\VideoDbUrl.h">
<Filter>video</Filter>
</ClInclude>
View
4 system/peripherals.xml
@@ -49,4 +49,8 @@
<setting key="device_name" type="string" value="XBMC" configurable="0" />
<setting key="device_type" type="int" value="1" configurable="0" />
</peripheral>
+
+ <peripheral vendor_product="15C2:32,15C2:33,15C2:34,15C2:35,15C2:36,15C2:37,15C2:38,15C2:39,15C2:3A,15C2:3B,15C2:3C,15C2:3D,15C2:3E,15C2:3F,15C2:41,15C2:42,15C2:43,15C2:44,15C2:45,15C2:46" bus="usb" name="iMON HID device" mapTo="imon">
+ <setting key="do_not_use_custom_keymap" type="bool" value="1" label="35009" order="1" configurable="0"/>
+ </peripheral>
</peripherals>
View
4 xbmc/Application.cpp
@@ -176,6 +176,7 @@
#include "peripherals/Peripherals.h"
#include "peripherals/dialogs/GUIDialogPeripheralManager.h"
#include "peripherals/dialogs/GUIDialogPeripheralSettings.h"
+#include "peripherals/devices/PeripheralImon.h"
// Windows includes
#include "guilib/GUIWindowManager.h"
@@ -1417,7 +1418,8 @@ bool CApplication::Initialize()
ResetScreenSaver();
#ifdef HAS_SDL_JOYSTICK
- g_Joystick.SetEnabled(g_guiSettings.GetBool("input.enablejoystick"));
+ g_Joystick.SetEnabled(g_guiSettings.GetBool("input.enablejoystick") &&
+ (CPeripheralImon::GetCountOfImonsConflictWithDInput() == 0 || !g_guiSettings.GetBool("input.disablejoystickwithimon")) );
#endif
return true;
View
3 xbmc/input/windows/WINJoystick.cpp
@@ -50,6 +50,7 @@ extern HWND g_hWnd;
CJoystick::CJoystick()
{
+ CSingleLock lock(m_critSection);
Reset(true);
m_joystickEnabled = false;
m_NumAxes = 0;
@@ -73,6 +74,7 @@ CJoystick::~CJoystick()
void CJoystick::ReleaseJoysticks()
{
+ CSingleLock lock(m_critSection);
// Unacquire the device one last time just in case
// the app tried to exit while the device is still acquired.
for(std::vector<LPDIRECTINPUTDEVICE8>::iterator it = m_pJoysticks.begin(); it != m_pJoysticks.end(); ++it)
@@ -182,6 +184,7 @@ void CJoystick::Initialize()
// clear old joystick names
ReleaseJoysticks();
+ CSingleLock lock(m_critSection);
if( FAILED( hr = DirectInput8Create( GetModuleHandle( NULL ), DIRECTINPUT_VERSION, IID_IDirectInput8, ( VOID** )&m_pDI, NULL ) ) )
{
View
2 xbmc/input/windows/WINJoystick.h
@@ -21,6 +21,7 @@
#include <vector>
#include <string>
+#include "threads/CriticalSection.h"
#define JACTIVE_BUTTON 0x00000001
#define JACTIVE_AXIS 0x00000002
@@ -84,6 +85,7 @@ class CJoystick
uint8_t m_ActiveFlags;
uint32_t m_lastPressTicks;
uint32_t m_lastTicks;
+ CCriticalSection m_critSection;
LPDIRECTINPUT8 m_pDI;
std::vector<LPDIRECTINPUTDEVICE8> m_pJoysticks;
View
10 xbmc/peripherals/PeripheralTypes.h
@@ -47,7 +47,8 @@ namespace PERIPHERALS
FEATURE_NYXBOARD,
FEATURE_CEC,
FEATURE_BLUETOOTH,
- FEATURE_TUNER
+ FEATURE_TUNER,
+ FEATURE_IMON
};
enum PeripheralType
@@ -59,7 +60,8 @@ namespace PERIPHERALS
PERIPHERAL_NYXBOARD,
PERIPHERAL_CEC,
PERIPHERAL_BLUETOOTH,
- PERIPHERAL_TUNER
+ PERIPHERAL_TUNER,
+ PERIPHERAL_IMON
};
struct PeripheralID
@@ -99,6 +101,8 @@ namespace PERIPHERALS
return "nyxboard";
case PERIPHERAL_TUNER:
return "tuner";
+ case PERIPHERAL_IMON:
+ return "imon";
default:
return "unknown";
}
@@ -123,6 +127,8 @@ namespace PERIPHERALS
return PERIPHERAL_NYXBOARD;
else if (strTypeLowerCase.Equals("tuner"))
return PERIPHERAL_TUNER;
+ else if (strTypeLowerCase.Equals("imon"))
+ return PERIPHERAL_IMON;
return PERIPHERAL_UNKNOWN;
};
View
5 xbmc/peripherals/Peripherals.cpp
@@ -27,6 +27,7 @@
#include "devices/PeripheralNyxboard.h"
#include "devices/PeripheralTuner.h"
#include "devices/PeripheralCecAdapter.h"
+#include "devices/PeripheralImon.h"
#include "bus/PeripheralBusUSB.h"
#include "dialogs/GUIDialogPeripheralManager.h"
@@ -286,6 +287,10 @@ CPeripheral *CPeripherals::CreatePeripheral(CPeripheralBus &bus, const Periphera
#endif
break;
+ case PERIPHERAL_IMON:
+ peripheral = new CPeripheralImon(type, bus.Type(), strLocation, strDeviceName, iVendorId, iProductId);
+ break;
+
default:
break;
}
View
26 xbmc/peripherals/bus/PeripheralBus.cpp
@@ -133,6 +133,7 @@ void CPeripheralBus::Clear(void)
void CPeripheralBus::UnregisterRemovedDevices(const PeripheralScanResults &results)
{
CSingleLock lock(m_critSection);
+ vector<CPeripheral *> removedPeripherals;
for (int iDevicePtr = (int) m_peripherals.size() - 1; iDevicePtr >= 0; iDevicePtr--)
{
CPeripheral *peripheral = m_peripherals.at(iDevicePtr);
@@ -141,17 +142,26 @@ void CPeripheralBus::UnregisterRemovedDevices(const PeripheralScanResults &resul
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());
- peripheral->OnDeviceRemoved();
- }
+ removedPeripherals.push_back(peripheral);
m_peripherals.erase(m_peripherals.begin() + iDevicePtr);
- lock.Leave();
+ }
+ }
+ lock.Leave();
- m_manager->OnDeviceDeleted(*this, *peripheral);
- delete peripheral;
+ for (unsigned int iDevicePtr = 0; iDevicePtr < removedPeripherals.size(); iDevicePtr++)
+ {
+ CPeripheral *peripheral = removedPeripherals.at(iDevicePtr);
+ vector<PeripheralFeature> features;
+ peripheral->GetFeatures(features);
+ bool peripheralHasFeatures = features.size() > 1 || (features.size() == 1 && features.at(0) != FEATURE_UNKNOWN);
+ if (peripheral->Type() != PERIPHERAL_UNKNOWN || peripheralHasFeatures)
+ {
+ 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());
+ peripheral->OnDeviceRemoved();
}
+
+ m_manager->OnDeviceDeleted(*this, *peripheral);
+ delete peripheral;
}
}
View
5 xbmc/peripherals/bus/PeripheralBus.h
@@ -92,9 +92,10 @@ namespace PERIPHERALS
virtual bool HasPeripheral(const CStdString &strLocation) const;
/*!
- * @brief Get the first instance of a peripheral that has the given feature.
+ * @brief Get all peripheral instances that have the given feature.
+ * @param results The list of results.
* @param feature The feature to search for.
- * @return The peripheral or NULL if it wasn't found.
+ * @return The number of devices that have been found.
*/
virtual int GetPeripheralsWithFeature(std::vector<CPeripheral *> &results, const PeripheralFeature feature) const;
View
1 xbmc/peripherals/devices/Makefile.in
@@ -2,6 +2,7 @@ SRCS = Peripheral.cpp
SRCS += PeripheralBluetooth.cpp
SRCS += PeripheralDisk.cpp
SRCS += PeripheralHID.cpp
+SRCS += PeripheralImon.cpp
SRCS += PeripheralNIC.cpp
SRCS += PeripheralNyxboard.cpp
SRCS += PeripheralTuner.cpp
View
92 xbmc/peripherals/devices/PeripheralImon.cpp
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2012 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, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "PeripheralImon.h"
+#include "utils/log.h"
+#include "guilib/LocalizeStrings.h"
+#include "threads/Atomics.h"
+#include "settings/GUISettings.h"
+#if defined (TARGET_WINDOWS)
+#include "system.h" // For HAS_SDL_JOYSTICK
+#if defined (HAS_SDL_JOYSTICK)
+#include "input/windows/WINJoystick.h"
+#endif // HAS_SDL_JOYSTICK
+#endif // TARGET_WINDOWS
+
+
+using namespace PERIPHERALS;
+using namespace std;
+
+volatile long CPeripheralImon::m_CountOfImonsConflictWithDInput = 0;
+
+
+CPeripheralImon::CPeripheralImon(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId) :
+ CPeripheralHID(type, busType, strLocation, strDeviceName.IsEmpty() ? g_localizeStrings.Get(35001) : strDeviceName, iVendorId, iProductId)
+{
+ m_features.push_back(FEATURE_IMON);
+#if defined(TARGET_WINDOWS)
+ if (iProductId >= 0x34 && iProductId <= 0x46)
+ m_ImonConflictsWithDInput = true;
+ else
+#endif // TARGET_WINDOWS
+ m_ImonConflictsWithDInput = false;
+}
+
+void CPeripheralImon::OnDeviceRemoved()
+{
+ if (m_ImonConflictsWithDInput)
+ {
+ if (AtomicDecrement(&m_CountOfImonsConflictWithDInput) == 0)
+ ActionOnImonConflict(false);
+ }
+}
+
+bool CPeripheralImon::InitialiseFeature(const PeripheralFeature feature)
+{
+ if (feature == FEATURE_IMON)
+ {
+ if (m_ImonConflictsWithDInput)
+ {
+ AtomicIncrement(&m_CountOfImonsConflictWithDInput);
+ ActionOnImonConflict(true);
+ }
+ return CPeripheral::InitialiseFeature(feature);
+ }
+
+ return CPeripheralHID::InitialiseFeature(feature);
+}
+
+void CPeripheralImon::ActionOnImonConflict(bool deviceInserted /*= true*/)
+{
+ if (deviceInserted || m_CountOfImonsConflictWithDInput == 0)
+ {
+#if defined(TARGET_WINDOWS) && defined (HAS_SDL_JOYSTICK)
+ bool enableJoystickNow = (!deviceInserted || !g_guiSettings.GetBool("input.disablejoystickwithimon"))
+ && g_guiSettings.GetBool("input.enablejoystick");
+ CLog::Log(LOGNOTICE, "Problematic iMON hardware %s. Joystick usage: %s", (deviceInserted ? "detected" : "was removed"),
+ (enableJoystickNow) ? "enabled." : "disabled." );
+ g_Joystick.SetEnabled(enableJoystickNow);
+ CSetting* setting = g_guiSettings.GetSetting("input.disablejoystickwithimon");
+ if(setting)
+ setting->SetVisible(deviceInserted && !setting->IsAdvanced());
+#endif
+ }
+}
+
View
42 xbmc/peripherals/devices/PeripheralImon.h
@@ -0,0 +1,42 @@
+#pragma once
+/*
+ * Copyright (C) 2012 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, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "PeripheralHID.h"
+
+namespace PERIPHERALS
+{
+ class CPeripheralImon : public CPeripheralHID
+ {
+ public:
+ CPeripheralImon(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId);
+ virtual ~CPeripheralImon(void) {}
+ virtual bool InitialiseFeature(const PeripheralFeature feature);
+ virtual void OnDeviceRemoved();
+ inline bool IsImonConflictsWithDInput()
+ { return m_ImonConflictsWithDInput;}
+ static inline long GetCountOfImonsConflictWithDInput()
+ { return m_CountOfImonsConflictWithDInput; }
+ static void ActionOnImonConflict(bool deviceInserted = true);
+ private:
+ bool m_ImonConflictsWithDInput;
+ static volatile long m_CountOfImonsConflictWithDInput;
+ };
+}
View
2 xbmc/settings/GUISettings.cpp
@@ -546,6 +546,8 @@ void CGUISettings::Initialize()
#endif
#if defined(HAS_SDL_JOYSTICK)
AddBool(in, "input.enablejoystick", 35100, true);
+ AddBool(in, "input.disablejoystickwithimon", 35101, true);
+ GetSetting("input.disablejoystickwithimon")->SetVisible(false);
#endif
CSettingsCategory* net = AddCategory(SETTINGS_SYSTEM, "network", 798);
View
12 xbmc/settings/GUIWindowSettingsCategory.cpp
@@ -84,6 +84,7 @@
#include "network/Zeroconf.h"
#include "peripherals/Peripherals.h"
#include "peripherals/dialogs/GUIDialogPeripheralManager.h"
+#include "peripherals/devices/PeripheralImon.h"
#ifdef _WIN32
#include "WIN32Util.h"
@@ -261,7 +262,11 @@ bool CGUIWindowSettingsCategory::OnMessage(CGUIMessage &message)
break;
case GUI_MSG_UPDATE:
if (HasID(message.GetSenderId()))
- UpdateSettings();
+ {
+ int focusedControl = GetFocusedControlID();
+ CreateSettings();
+ SET_CONTROL_FOCUS(focusedControl, 0);
+ }
break;
case GUI_MSG_NOTIFY_ALL:
{
@@ -1432,10 +1437,11 @@ void CGUIWindowSettingsCategory::OnSettingChanged(CBaseSettingControl *pSettingC
{
g_Mouse.SetEnabled(g_guiSettings.GetBool("input.enablemouse"));
}
- else if (strSetting.Equals("input.enablejoystick"))
+ else if (strSetting.Equals("input.enablejoystick") || strSetting.Equals("input.disablejoystickwithimon"))
{
#if defined(HAS_SDL_JOYSTICK)
- g_Joystick.SetEnabled(g_guiSettings.GetBool("input.enablejoystick"));
+ g_Joystick.SetEnabled(g_guiSettings.GetBool("input.enablejoystick")
+ && (CPeripheralImon::GetCountOfImonsConflictWithDInput() == 0 || !g_guiSettings.GetBool("input.disablejoystickwithimon")) );
#endif
}
else if (strSetting.Equals("videoscreen.screen"))