Add optional multitouch support to X11.

Thanks @TheBrokenRail for a patch proposal based on example code from esjeon (patch #322).
See https://sourceforge.net/p/irrlicht/patches/322
Original example code here: https://github.com/esjeon/xinput2-touch
Users have to enable _IRR_LINUX_X11_XINPUT2_ in IrrCompileConfig and link with Xi to make this work.
I rewrote the patch a bit and have no system for testing here, so this still needs some testing.
I also backported EET_TOUCH_INPUT_EVENT for this from the ogl-es branch.


git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@6178 dfc29bdd-3216-0410-991c-e03cc46cb475
This commit is contained in:
cutealien
2020-12-29 02:15:27 +00:00
parent 0e56aca052
commit e92ed55afa
6 changed files with 137 additions and 3 deletions

View File

@ -441,6 +441,7 @@ bool CGUIListBox::OnEvent(const SEvent& event)
}
}
break;
case EET_TOUCH_INPUT_EVENT:
case EET_LOG_TEXT_EVENT:
case EET_USER_EVENT:
case EET_JOYSTICK_INPUT_EVENT:

View File

@ -25,6 +25,10 @@
#include <X11/XKBlib.h>
#include <X11/Xatom.h>
#if defined(_IRR_LINUX_X11_XINPUT2_)
#include <X11/extensions/XInput2.h>
#endif
#if defined(_IRR_COMPILE_WITH_OPENGL_)
#include "CGLXManager.h"
#endif
@ -74,6 +78,10 @@ namespace
Atom X_ATOM_NETWM_STATE;
Atom X_ATOM_WM_DELETE_WINDOW;
#if defined(_IRR_LINUX_X11_XINPUT2_)
int XI_EXTENSIONS_OPCODE;
#endif
};
namespace irr
@ -568,6 +576,8 @@ bool CIrrDeviceLinux::createWindow()
if (WMCheck != None)
HasNetWM = true;
initXInput2();
#endif // #ifdef _IRR_COMPILE_WITH_X11_
return true;
}
@ -1055,6 +1065,29 @@ bool CIrrDeviceLinux::run()
XFlush (XDisplay);
}
break;
#if defined(_IRR_LINUX_X11_XINPUT2_)
case GenericEvent:
{
XGenericEventCookie *cookie = &event.xcookie;
if (XGetEventData(XDisplay, cookie) && cookie->extension == XI_EXTENSIONS_OPCODE && XI_EXTENSIONS_OPCODE
&& (cookie->evtype == XI_TouchUpdate || cookie->evtype == XI_TouchBegin || cookie->evtype == XI_TouchEnd))
{
XIDeviceEvent *de = (XIDeviceEvent *) cookie->data;
SEvent ret_event;
ret_event.EventType = EET_TOUCH_INPUT_EVENT;
ret_event.TouchInput.Event = cookie->evtype == XI_TouchUpdate ? ETIE_MOVED : (cookie->evtype == XI_TouchBegin ? ETIE_PRESSED_DOWN : ETIE_LEFT_UP);
ret_event.TouchInput.ID = de->detail;
ret_event.TouchInput.X = de->event_x;
ret_event.TouchInput.Y = de->event_y;
postEventFromUser(ret_event);
}
}
break;
#endif
default:
break;
@ -1940,6 +1973,62 @@ void CIrrDeviceLinux::initXAtoms()
#endif
}
void CIrrDeviceLinux::initXInput2()
{
#if defined(_IRR_LINUX_X11_XINPUT2_)
int ev=0;
int err=0;
if (!XQueryExtension(XDisplay, "XInputExtension", &XI_EXTENSIONS_OPCODE, &ev, &err))
{
os::Printer::log("X Input extension not available.", ELL_WARNING);
return;
}
int major = 2;
int minor = 3;
int rc = XIQueryVersion(XDisplay, &major, &minor);
if ( rc != Success )
{
os::Printer::log("No XI2 support.", ELL_WARNING);
return;
}
int cnt = 0;
XIDeviceInfo *di = XIQueryDevice(XDisplay, XIAllDevices, &cnt);
if ( di )
{
for (int i = 0; i < cnt; ++i)
{
bool hasTouchClass = false;
XIDeviceInfo *dev = &di[i];
for (int j = 0; j < dev->num_classes; ++j)
{
if (dev->classes[j]->type == XITouchClass)
{
hasTouchClass = true;
break;
}
}
if ( hasTouchClass )
{
XIEventMask eventMask;
unsigned char mask[XIMaskLen(XI_TouchEnd)];
memset(mask, 0, sizeof(mask));
eventMask.deviceid = dev->deviceid;
eventMask.mask_len = sizeof(mask);
eventMask.mask = mask;
XISetMask(eventMask.mask, XI_TouchBegin);
XISetMask(eventMask.mask, XI_TouchUpdate);
XISetMask(eventMask.mask, XI_TouchEnd);
XISelectEvents(XDisplay, XWindow, &eventMask, 1);
}
}
XIFreeDeviceInfo(di);
}
#endif
}
#ifdef _IRR_COMPILE_WITH_X11_

View File

@ -155,6 +155,8 @@ namespace irr
void initXAtoms();
void initXInput2();
bool switchToFullscreen(bool reset=false);
#ifdef _IRR_COMPILE_WITH_X11_