mirror of
https://github.com/LibreELEC/LibreELEC.tv.git
synced 2025-07-29 13:46:49 +00:00
kodi: add multitouch support patch, borrowed by popcornmix
Signed-off-by: Stephan Raue <stephan@openelec.tv>
This commit is contained in:
parent
651fa5f390
commit
3bc0e8d287
@ -0,0 +1,337 @@
|
||||
From 8ff131750e527416274e4f21685312785a8d0bb2 Mon Sep 17 00:00:00 2001
|
||||
From: Floris Bos <bos@je-eigen-domein.nl>
|
||||
Date: Wed, 23 Sep 2015 22:34:20 +0200
|
||||
Subject: [PATCH 1/3] Fix Linux touchscreen support
|
||||
|
||||
Touch devices tend to send a key event first and coordinates later.
|
||||
|
||||
==
|
||||
Event: type 1 (EV_KEY), code 330 (BTN_TOUCH), value 1
|
||||
Event: type 3 (EV_ABS), code 0 (ABS_X), value 45
|
||||
Event: type 3 (EV_ABS), code 1 (ABS_Y), value 27
|
||||
==
|
||||
|
||||
This does not go along well with the XBMC mouse handling code that
|
||||
expects to already have the coordinates when processing the EV_KEY.
|
||||
Fetch the current coordinates with ioctl() as workaround.
|
||||
|
||||
Signed-off-by: Floris Bos <bos@je-eigen-domein.nl>
|
||||
---
|
||||
xbmc/input/linux/LinuxInputDevices.cpp | 24 ++++++++++++++++++++++++
|
||||
1 file changed, 24 insertions(+)
|
||||
|
||||
diff --git a/xbmc/input/linux/LinuxInputDevices.cpp b/xbmc/input/linux/LinuxInputDevices.cpp
|
||||
index b028cd1..b8f13d3 100644
|
||||
--- a/xbmc/input/linux/LinuxInputDevices.cpp
|
||||
+++ b/xbmc/input/linux/LinuxInputDevices.cpp
|
||||
@@ -275,6 +275,7 @@ typedef enum
|
||||
LI_CAPS_KEYS = 1,
|
||||
LI_CAPS_BUTTONS = 2,
|
||||
LI_CAPS_AXES = 4,
|
||||
+ LI_CAPS_ABS = 8
|
||||
} LinuxInputCapsType;
|
||||
|
||||
static char remoteStatus = 0xFF; // paired, battery OK
|
||||
@@ -470,6 +471,23 @@ bool CLinuxInputDevice::KeyEvent(const struct input_event& levt, XBMC_Event& dev
|
||||
if (levt.value == 2)
|
||||
return false;
|
||||
|
||||
+ /* touch devices tend to send the key event before the coordinates, so we
|
||||
+ cannot rely on m_mouseX and m_mouseY already having the correct values */
|
||||
+ if (m_deviceCaps & LI_CAPS_ABS)
|
||||
+ {
|
||||
+ struct input_absinfo absinfo;
|
||||
+
|
||||
+ if (ioctl(m_fd, EVIOCGABS(ABS_X), &absinfo) == 0)
|
||||
+ {
|
||||
+ m_mouseX = absinfo.value;
|
||||
+ }
|
||||
+
|
||||
+ if (ioctl(m_fd, EVIOCGABS(ABS_Y), &absinfo) == 0)
|
||||
+ {
|
||||
+ m_mouseY = absinfo.value;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
devt.type = levt.value ? XBMC_MOUSEBUTTONDOWN : XBMC_MOUSEBUTTONUP;
|
||||
devt.button.state = levt.value ? XBMC_PRESSED : XBMC_RELEASED;
|
||||
devt.button.type = devt.type;
|
||||
@@ -954,6 +972,12 @@ void CLinuxInputDevice::GetInfo(int fd)
|
||||
m_deviceMaxAxis = std::max(num_rels, num_abs) - 1;
|
||||
}
|
||||
|
||||
+ /* Absolute X,Y coordinates */
|
||||
+ if (num_abs >= 2 && num_rels == 0)
|
||||
+ {
|
||||
+ m_deviceCaps |= LI_CAPS_ABS;
|
||||
+ }
|
||||
+
|
||||
/* Decide which primary input device to be. */
|
||||
if (m_deviceType & LI_DEVICE_KEYBOARD)
|
||||
m_devicePreferredId = LI_DEVICE_KEYBOARD;
|
||||
|
||||
From a7b5f1489dbfcb577e12c747626fe7d45ff2009d Mon Sep 17 00:00:00 2001
|
||||
From: Floris Bos <bos@je-eigen-domein.nl>
|
||||
Date: Fri, 25 Sep 2015 01:07:30 +0200
|
||||
Subject: [PATCH 2/3] LinuxInputDevice: add support for multi-touch devices
|
||||
|
||||
Adds support for multi-touch devices on Linux.
|
||||
Support is limited to devices that are capable of
|
||||
tracking identifiable contacts, and use the type B events of:
|
||||
|
||||
https://www.kernel.org/doc/Documentation/input/multi-touch-protocol.txt
|
||||
|
||||
Signed-off-by: Floris Bos <bos@je-eigen-domein.nl>
|
||||
---
|
||||
Makefile.in | 2 +
|
||||
xbmc/input/linux/LinuxInputDevices.cpp | 109 ++++++++++++++++++++++++++++++++-
|
||||
xbmc/input/linux/LinuxInputDevices.h | 8 +++
|
||||
xbmc/input/touch/ITouchInputHandler.h | 1 +
|
||||
xbmc/windowing/WinEventsLinux.cpp | 5 ++
|
||||
xbmc/windowing/WinEventsLinux.h | 1 +
|
||||
6 files changed, 125 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Makefile.in b/Makefile.in
|
||||
index d579e11..2d4b1c8 100644
|
||||
--- a/Makefile.in
|
||||
+++ b/Makefile.in
|
||||
@@ -157,6 +157,8 @@ DIRECTORY_ARCHIVES += xbmc/storage/android/storage_android.a
|
||||
DIRECTORY_ARCHIVES += xbmc/windowing/X11/windowing_X11.a
|
||||
else
|
||||
DIRECTORY_ARCHIVES += xbmc/input/linux/input_linux.a
|
||||
+DIRECTORY_ARCHIVES += xbmc/input/touch/input_touch.a
|
||||
+DIRECTORY_ARCHIVES += xbmc/input/touch/generic/input_touch_generic.a
|
||||
DIRECTORY_ARCHIVES += xbmc/network/linux/network_linux.a
|
||||
DIRECTORY_ARCHIVES += xbmc/powermanagement/linux/powermanagement_linux.a
|
||||
DIRECTORY_ARCHIVES += xbmc/storage/linux/storage_linux.a
|
||||
diff --git a/xbmc/input/linux/LinuxInputDevices.cpp b/xbmc/input/linux/LinuxInputDevices.cpp
|
||||
index b8f13d3..6e1cd1d 100644
|
||||
--- a/xbmc/input/linux/LinuxInputDevices.cpp
|
||||
+++ b/xbmc/input/linux/LinuxInputDevices.cpp
|
||||
@@ -96,6 +96,8 @@ typedef unsigned long kernel_ulong_t;
|
||||
#include "LinuxInputDevices.h"
|
||||
#include "input/MouseStat.h"
|
||||
#include "utils/log.h"
|
||||
+#include "input/touch/generic/GenericTouchActionHandler.h"
|
||||
+#include "input/touch/generic/GenericTouchInputHandler.h"
|
||||
|
||||
#ifndef BITS_PER_LONG
|
||||
#define BITS_PER_LONG (sizeof(long) * 8)
|
||||
@@ -267,7 +269,8 @@ typedef enum
|
||||
LI_DEVICE_MOUSE = 1,
|
||||
LI_DEVICE_JOYSTICK = 2,
|
||||
LI_DEVICE_KEYBOARD = 4,
|
||||
- LI_DEVICE_REMOTE = 8
|
||||
+ LI_DEVICE_REMOTE = 8,
|
||||
+ LI_DEVICE_MULTITOUCH = 16
|
||||
} LinuxInputDeviceType;
|
||||
|
||||
typedef enum
|
||||
@@ -302,6 +305,10 @@ CLinuxInputDevice::CLinuxInputDevice(const std::string& fileName, int index):
|
||||
m_deviceMaxKeyCode = 0;
|
||||
m_deviceMaxAxis = 0;
|
||||
m_bUnplugged = false;
|
||||
+ m_mt_currentSlot = 0;
|
||||
+ memset(&m_mt_x, 0, sizeof(m_mt_x));
|
||||
+ memset(&m_mt_y, 0, sizeof(m_mt_y));
|
||||
+ memset(&m_mt_event, 0, sizeof(m_mt_event));
|
||||
|
||||
Open();
|
||||
}
|
||||
@@ -681,11 +688,102 @@ bool CLinuxInputDevice::AbsEvent(const struct input_event& levt, XBMC_Event& dev
|
||||
}
|
||||
|
||||
/*
|
||||
+ * Process multi-touch absolute events
|
||||
+ * Only store the information, do not fire event until we receive an EV_SYN
|
||||
+ */
|
||||
+bool CLinuxInputDevice::mtAbsEvent(const struct input_event& levt)
|
||||
+{
|
||||
+ switch (levt.code)
|
||||
+ {
|
||||
+ case ABS_MT_SLOT:
|
||||
+ m_mt_currentSlot = levt.value;
|
||||
+ break;
|
||||
+
|
||||
+ case ABS_MT_TRACKING_ID:
|
||||
+ if (m_mt_currentSlot < TOUCH_MAX_POINTERS)
|
||||
+ {
|
||||
+ if (levt.value == -1)
|
||||
+ m_mt_event[m_mt_currentSlot] = TouchInputUp;
|
||||
+ else
|
||||
+ m_mt_event[m_mt_currentSlot] = TouchInputDown;
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
+ case ABS_MT_POSITION_X:
|
||||
+ if (m_mt_currentSlot < TOUCH_MAX_POINTERS)
|
||||
+ {
|
||||
+ m_mt_x[m_mt_currentSlot] = levt.value;
|
||||
+ if (m_mt_event[m_mt_currentSlot] == TouchInputUnchanged)
|
||||
+ m_mt_event[m_mt_currentSlot] = TouchInputMove;
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
+ case ABS_MT_POSITION_Y:
|
||||
+ if (m_mt_currentSlot < TOUCH_MAX_POINTERS)
|
||||
+ {
|
||||
+ m_mt_y[m_mt_currentSlot] = levt.value;
|
||||
+ if (m_mt_event[m_mt_currentSlot] == TouchInputUnchanged)
|
||||
+ m_mt_event[m_mt_currentSlot] = TouchInputMove;
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Process stored multi-touch events
|
||||
+ */
|
||||
+bool CLinuxInputDevice::mtSynEvent(const struct input_event& levt)
|
||||
+{
|
||||
+ float size = 10.0f;
|
||||
+ int64_t nanotime = levt.time.tv_sec * 1000000000LL + levt.time.tv_usec * 1000LL;
|
||||
+
|
||||
+ for (int ptr=0; ptr < TOUCH_MAX_POINTERS; ptr++)
|
||||
+ {
|
||||
+ /* While the comments of ITouchInputHandler::UpdateTouchPointer() say
|
||||
+ "If there's an event for every touch action this method does not need to be called at all"
|
||||
+ gesture detection currently doesn't work properly without this call. */
|
||||
+ CGenericTouchInputHandler::Get().UpdateTouchPointer(ptr, m_mt_x[ptr], m_mt_y[ptr], nanotime, size);
|
||||
+ }
|
||||
+
|
||||
+ for (int ptr=0; ptr < TOUCH_MAX_POINTERS; ptr++)
|
||||
+ {
|
||||
+ if (m_mt_event[ptr] != TouchInputUnchanged)
|
||||
+ {
|
||||
+ CGenericTouchInputHandler::Get().HandleTouchInput(m_mt_event[ptr], m_mt_x[ptr], m_mt_y[ptr], nanotime, ptr, size);
|
||||
+ m_mt_event[ptr] = TouchInputUnchanged;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
* Translates a Linux input event into a DirectFB input event.
|
||||
*/
|
||||
bool CLinuxInputDevice::TranslateEvent(const struct input_event& levt,
|
||||
XBMC_Event& devt)
|
||||
{
|
||||
+ if (m_devicePreferredId == LI_DEVICE_MULTITOUCH)
|
||||
+ {
|
||||
+ switch (levt.type)
|
||||
+ {
|
||||
+ case EV_ABS:
|
||||
+ return mtAbsEvent(levt);
|
||||
+
|
||||
+ case EV_SYN:
|
||||
+ return mtSynEvent(levt);
|
||||
+
|
||||
+ default:
|
||||
+ // Ignore legacy (key) events
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
switch (levt.type)
|
||||
{
|
||||
case EV_KEY:
|
||||
@@ -930,6 +1028,10 @@ void CLinuxInputDevice::GetInfo(int fd)
|
||||
for (i = 0; i < ABS_PRESSURE; i++)
|
||||
if (test_bit( i, absbit ))
|
||||
num_abs++;
|
||||
+
|
||||
+ /* test if it is a multi-touch type B device */
|
||||
+ if (test_bit(ABS_MT_SLOT, absbit))
|
||||
+ m_deviceType |= LI_DEVICE_MULTITOUCH;
|
||||
}
|
||||
|
||||
/* Mouse, Touchscreen or Smartpad ? */
|
||||
@@ -981,6 +1083,11 @@ void CLinuxInputDevice::GetInfo(int fd)
|
||||
/* Decide which primary input device to be. */
|
||||
if (m_deviceType & LI_DEVICE_KEYBOARD)
|
||||
m_devicePreferredId = LI_DEVICE_KEYBOARD;
|
||||
+ else if (m_deviceType & LI_DEVICE_MULTITOUCH)
|
||||
+ {
|
||||
+ m_devicePreferredId = LI_DEVICE_MULTITOUCH;
|
||||
+ CGenericTouchInputHandler::Get().RegisterHandler(&CGenericTouchActionHandler::Get());
|
||||
+ }
|
||||
else if (m_deviceType & LI_DEVICE_REMOTE)
|
||||
m_devicePreferredId = LI_DEVICE_REMOTE;
|
||||
else if (m_deviceType & LI_DEVICE_JOYSTICK)
|
||||
diff --git a/xbmc/input/linux/LinuxInputDevices.h b/xbmc/input/linux/LinuxInputDevices.h
|
||||
index 954d823..8c88a1d 100644
|
||||
--- a/xbmc/input/linux/LinuxInputDevices.h
|
||||
+++ b/xbmc/input/linux/LinuxInputDevices.h
|
||||
@@ -26,6 +26,8 @@
|
||||
#include "windowing/XBMC_events.h"
|
||||
#include "input/XBMC_keyboard.h"
|
||||
#include "threads/SingleLock.h"
|
||||
+#include "input/touch/ITouchInputHandler.h"
|
||||
+#include "input/touch/generic/IGenericTouchGestureDetector.h"
|
||||
|
||||
struct KeymapEntry
|
||||
{
|
||||
@@ -60,6 +62,8 @@ class CLinuxInputDevice
|
||||
XBMCMod UpdateModifiers(XBMC_Event& devt);
|
||||
bool GetKeymapEntry(KeymapEntry& entry);
|
||||
int KeyboardGetSymbol(unsigned short value);
|
||||
+ bool mtAbsEvent(const struct input_event& levt);
|
||||
+ bool mtSynEvent(const struct input_event& levt);
|
||||
|
||||
int m_fd;
|
||||
int m_vt_fd;
|
||||
@@ -81,6 +85,10 @@ class CLinuxInputDevice
|
||||
bool m_bSkipNonKeyEvents;
|
||||
bool m_bUnplugged;
|
||||
std::deque<XBMC_Event> m_equeue;
|
||||
+ int m_mt_currentSlot;
|
||||
+ int m_mt_x[TOUCH_MAX_POINTERS];
|
||||
+ int m_mt_y[TOUCH_MAX_POINTERS];
|
||||
+ TouchInput m_mt_event[TOUCH_MAX_POINTERS];
|
||||
};
|
||||
|
||||
class CLinuxInputDevices
|
||||
diff --git a/xbmc/input/touch/ITouchInputHandler.h b/xbmc/input/touch/ITouchInputHandler.h
|
||||
index 6ea47db..43c7a76 100644
|
||||
--- a/xbmc/input/touch/ITouchInputHandler.h
|
||||
+++ b/xbmc/input/touch/ITouchInputHandler.h
|
||||
@@ -28,6 +28,7 @@
|
||||
* \brief Touch input event
|
||||
*/
|
||||
typedef enum {
|
||||
+ TouchInputUnchanged = 0,
|
||||
TouchInputAbort,
|
||||
TouchInputDown,
|
||||
TouchInputUp,
|
||||
diff --git a/xbmc/windowing/WinEventsLinux.cpp b/xbmc/windowing/WinEventsLinux.cpp
|
||||
index 89aca2b..04e3544 100644
|
||||
--- a/xbmc/windowing/WinEventsLinux.cpp
|
||||
+++ b/xbmc/windowing/WinEventsLinux.cpp
|
||||
@@ -241,4 +241,9 @@ size_t CWinEventsLinux::GetQueueSize()
|
||||
return m_devices.Size();
|
||||
}
|
||||
|
||||
+void CWinEventsLinux::MessagePush(XBMC_Event *ev)
|
||||
+{
|
||||
+ g_application.OnEvent(*ev);
|
||||
+}
|
||||
+
|
||||
#endif
|
||||
diff --git a/xbmc/windowing/WinEventsLinux.h b/xbmc/windowing/WinEventsLinux.h
|
||||
index 5c2b583..dc73b39 100644
|
||||
--- a/xbmc/windowing/WinEventsLinux.h
|
||||
+++ b/xbmc/windowing/WinEventsLinux.h
|
||||
@@ -31,6 +31,7 @@ class CWinEventsLinux : public IWinEvents
|
||||
CWinEventsLinux();
|
||||
bool MessagePump();
|
||||
size_t GetQueueSize();
|
||||
+ void MessagePush(XBMC_Event *ev);
|
||||
void RefreshDevices();
|
||||
void Notify(const Observable &obs, const ObservableMessage msg)
|
||||
{
|
Loading…
x
Reference in New Issue
Block a user