Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Added hotplug support for Linux input devices. #2435

Merged
1 commit merged into from

4 participants

@dezi

I have bluetooth devices in my Raspberry running XBMC. These devices are not present, unless i wake them up.

This patch makes sure, unplugged devices are recognized and thus freeing the devices handle. New devices are scanned for every 10 seconds and integrated into the existing device configuration w/o flushing old devices.

Also i added a scan for /dev/tty1 to obtain a valid keyboard-layout, since /dev/tty0 is unconfigured in some linux flavours.

@t-nelson

Please rebase and drop the extraneous commits. You can just force push to your branch to avoid opening a new PR.

@dezi

Done.

@ghost ghost merged commit d55df9a into from
@hjheins

This is also an issue for Android. Is there some way this patch can also be applied for the Android version?

@silverhammermba

As far as I can tell, hotplugging does not work in the current XBMC version on Linux. At least not for my Xbox 360 controllers.

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Mar 18, 2013
  1. @dezi
This page is out of date. Refresh to see the latest.
View
80 xbmc/input/linux/LinuxInputDevices.cpp
@@ -338,6 +338,7 @@ CLinuxInputDevice::CLinuxInputDevice(const std::string fileName, int index)
m_deviceMinKeyCode = 0;
m_deviceMaxKeyCode = 0;
m_deviceMaxAxis = 0;
+ m_bUnplugged = false;
Open();
}
@@ -744,7 +745,15 @@ XBMC_Event CLinuxInputDevice::ReadEvent()
readlen = read(m_fd, &levt, sizeof(levt));
if (readlen <= 0)
+ {
+ if (errno == ENODEV)
+ {
+ CLog::Log(LOGINFO,"input device was unplugged %s",m_deviceName);
+ m_bUnplugged = true;
+ }
+
break;
+ }
//printf("read event readlen = %d device name %s m_fileName %s\n", readlen, m_deviceName, m_fileName.c_str());
@@ -963,6 +972,16 @@ void CLinuxInputDevice::GetInfo(int fd)
//printf("pref: %d\n", m_devicePreferredId);
}
+char* CLinuxInputDevice::GetDeviceName()
+{
+ return m_deviceName;
+}
+
+bool CLinuxInputDevice::IsUnplugged()
+{
+ return m_bUnplugged;
+}
+
bool CLinuxInputDevices::CheckDevice(const char *device)
{
int fd;
@@ -1021,6 +1040,41 @@ void CLinuxInputDevices::InitAvailable()
}
/*
+ * Check for hot plugged devices.
+ */
+void CLinuxInputDevices::CheckHotplugged()
+{
+ CSingleLock lock(m_devicesListLock);
+
+ int deviceId = m_devices.size();
+
+ /* No devices specified. Try to guess some. */
+ for (int i = 0; i < MAX_LINUX_INPUT_DEVICES; i++)
+ {
+ char buf[32];
+ bool ispresent = false;
+
+ snprintf(buf, 32, "/dev/input/event%d", i);
+
+ for (size_t j = 0; j < m_devices.size(); j++)
+ {
+ if (strcmp(m_devices[j]->GetDeviceName(),buf) == 0)
+ {
+ ispresent = true;
+ break;
+ }
+ }
+
+ if (!ispresent && CheckDevice(buf))
+ {
+ CLog::Log(LOGINFO, "Found input device %s", buf);
+ m_devices.push_back(new CLinuxInputDevice(buf, deviceId));
+ ++deviceId;
+ }
+ }
+}
+
+/*
* Open the device, fill out information about it,
* allocate and fill private data, start input thread.
*/
@@ -1076,6 +1130,9 @@ bool CLinuxInputDevice::Open()
{
if (m_vt_fd < 0)
m_vt_fd = open("/dev/tty0", O_RDWR | O_NOCTTY);
+
+ if (m_vt_fd < 0)
+ m_vt_fd = open("/dev/tty1", O_RDWR | O_NOCTTY);
if (m_vt_fd < 0)
CLog::Log(LOGWARNING, "no keymap support (requires /dev/tty0 - CONFIG_VT)");
@@ -1195,6 +1252,23 @@ void CLinuxInputDevice::Close()
XBMC_Event CLinuxInputDevices::ReadEvent()
{
+ if (m_bReInitialize)
+ {
+ InitAvailable();
+ m_bReInitialize = false;
+ }
+ else
+ {
+ time_t now;
+ time(&now);
+
+ if ((now - m_lastHotplugCheck) >= 10)
+ {
+ CheckHotplugged();
+ m_lastHotplugCheck = now;
+ }
+ }
+
CSingleLock lock(m_devicesListLock);
XBMC_Event event;
@@ -1207,6 +1281,12 @@ XBMC_Event CLinuxInputDevices::ReadEvent()
{
break;
}
+
+ if (m_devices[i]->IsUnplugged())
+ {
+ m_bReInitialize = true;
+ break;
+ }
}
return event;
View
6 xbmc/input/linux/LinuxInputDevices.h
@@ -41,6 +41,8 @@ class CLinuxInputDevice
CLinuxInputDevice(const std::string fileName, int index);
~CLinuxInputDevice();
XBMC_Event ReadEvent();
+ char* GetDeviceName();
+ bool IsUnplugged();
private:
void SetupKeyboardAutoRepeat(int fd);
@@ -76,12 +78,14 @@ class CLinuxInputDevice
int m_deviceMaxKeyCode;
int m_deviceMaxAxis;
bool m_bSkipNonKeyEvents;
+ bool m_bUnplugged;
};
class CLinuxInputDevices
{
public:
void InitAvailable();
+ void CheckHotplugged();
XBMC_Event ReadEvent();
bool IsRemoteLowBattery();
bool IsRemoteNotPaired();
@@ -89,6 +93,8 @@ class CLinuxInputDevices
CCriticalSection m_devicesListLock;
bool CheckDevice(const char *device);
std::vector<CLinuxInputDevice*> m_devices;
+ bool m_bReInitialize;
+ time_t m_lastHotplugCheck;
};
#endif /* LINUXINPUTDEVICES_H_ */
Something went wrong with that request. Please try again.