diff --git a/changes.txt b/changes.txt index 5c874101..4413771e 100644 --- a/changes.txt +++ b/changes.txt @@ -9,6 +9,7 @@ Changes in ogl-es (not yet released - will be merged with trunk at some point) -------------------------- Changes in 1.9 (not yet released) +- Add optional multitouch support to X11 (but disabled in IrrCompileConfig by default). Thanks @TheBrokenRail for a patch proposal based on example code from esjeon (patch #322). - Slightly changed close window handling on X11 (optimized and avoids problems on some shells). Thanks @TheBrokenRail for a patch (was part of patch #322). - Add getActiveColor functions to IGUIStaticText and IGUIButton (get currently used color). - Add IGUIEnvironment::addToDeletionQueue to allow save removal of gui elements while iterating over them (like the same named function in ISceneManager). diff --git a/include/IEventReceiver.h b/include/IEventReceiver.h index 3c07f0c6..95610f01 100644 --- a/include/IEventReceiver.h +++ b/include/IEventReceiver.h @@ -37,14 +37,14 @@ namespace irr //! A touch input event. EET_TOUCH_INPUT_EVENT, - //! A accelerometer event. - EET_ACCELEROMETER_EVENT, + //! A accelerometer event. + EET_ACCELEROMETER_EVENT, - //! A gyroscope event. - EET_GYROSCOPE_EVENT, + //! A gyroscope event. + EET_GYROSCOPE_EVENT, - //! A device motion event. - EET_DEVICE_MOTION_EVENT, + //! A device motion event. + EET_DEVICE_MOTION_EVENT, //! A joystick (joypad, gamepad) input event. /** Joystick events are created by polling all connected joysticks once per @@ -354,6 +354,22 @@ struct SEvent }; + //! Any kind of touch event. + struct STouchInput + { + // Touch ID. + size_t ID; + + // X position of simple touch. + s32 X; + + // Y position of simple touch. + s32 Y; + + //! Type of touch event. + ETOUCH_INPUT_EVENT Event; + }; + //! Any kind of mouse event. struct SMouseInput { @@ -417,61 +433,58 @@ struct SEvent //! Any kind of touch event. struct STouchInput { - // Touch ID. + // Touch ID. size_t ID; - // X position of simple touch. + // X position of simple touch. f64 X; - // Y position of simple touch. + // Y position of simple touch. f64 Y; - // Number of current touches + // Number of current touches f64 touchedCount; //! Type of touch event. ETOUCH_INPUT_EVENT Event; }; - //! Any kind of accelerometer event. + //! Any kind of accelerometer event. struct SAccelerometerEvent { - - // X acceleration. + // X acceleration. f64 X; - // Y acceleration. + // Y acceleration. f64 Y; - // Z acceleration. + // Z acceleration. f64 Z; }; //! Any kind of gyroscope event. struct SGyroscopeEvent { - - // X rotation. + // X rotation. f64 X; - // Y rotation. + // Y rotation. f64 Y; - // Z rotation. + // Z rotation. f64 Z; }; - //! Any kind of device motion event. + //! Any kind of device motion event. struct SDeviceMotionEvent { - - // X angle - roll. + // X angle - roll. f64 X; - // Y angle - pitch. + // Y angle - pitch. f64 Y; - // Z angle - yaw. + // Z angle - yaw. f64 Z; }; @@ -585,10 +598,10 @@ struct SEvent struct SGUIEvent GUIEvent; struct SMouseInput MouseInput; struct SKeyInput KeyInput; - struct STouchInput TouchInput; - struct SAccelerometerEvent AccelerometerEvent; - struct SGyroscopeEvent GyroscopeEvent; - struct SDeviceMotionEvent DeviceMotionEvent; + struct STouchInput TouchInput; + struct SAccelerometerEvent AccelerometerEvent; + struct SGyroscopeEvent GyroscopeEvent; + struct SDeviceMotionEvent DeviceMotionEvent; struct SJoystickEvent JoystickEvent; struct SLogEvent LogEvent; struct SUserEvent UserEvent; diff --git a/include/IrrCompileConfig.h b/include/IrrCompileConfig.h index 1a29e8a3..eb1254fb 100644 --- a/include/IrrCompileConfig.h +++ b/include/IrrCompileConfig.h @@ -317,18 +317,22 @@ define out. */ #undef _IRR_COMPILE_WITH_X11_ #endif -//! On some Linux systems the XF86 vidmode extension or X11 RandR are missing. Use these flags -//! to remove the dependencies such that Irrlicht will compile on those systems, too. -//! If you don't need colored cursors you can also disable the Xcursor extension +//! On some Linux systems the XF86 vidmode extension, X11 RandR, or XInput2 are missing. +//! Use these defines to add/remove support for those dependencies as needed. +//! XInput2 (library called Xi) is currently only used to support touch-input. #if defined(_IRR_LINUX_PLATFORM_) && defined(_IRR_COMPILE_WITH_X11_) #define _IRR_LINUX_X11_VIDMODE_ //#define _IRR_LINUX_X11_RANDR_ +//#define _IRR_LINUX_X11_XINPUT2_ #ifdef NO_IRR_LINUX_X11_VIDMODE_ #undef _IRR_LINUX_X11_VIDMODE_ #endif #ifdef NO_IRR_LINUX_X11_RANDR_ #undef _IRR_LINUX_X11_RANDR_ #endif +#ifdef NO_IRR_LINUX_X11_XINPUT2_ +#undef _IRR_LINUX_X11_XINPUT2_ +#endif //! X11 has by default only monochrome cursors, but using the Xcursor library we can also get color cursor support. //! If you have the need for custom color cursors on X11 then enable this and make sure you also link diff --git a/source/Irrlicht/CIrrDeviceLinux.cpp b/source/Irrlicht/CIrrDeviceLinux.cpp index af54946a..68e6e336 100644 --- a/source/Irrlicht/CIrrDeviceLinux.cpp +++ b/source/Irrlicht/CIrrDeviceLinux.cpp @@ -26,6 +26,10 @@ #include #include +#if defined(_IRR_LINUX_X11_XINPUT2_) +#include +#endif + #if defined(_IRR_COMPILE_WITH_OGLES1_) || defined(_IRR_COMPILE_WITH_OGLES2_) #include "CEGLManager.h" #endif @@ -91,6 +95,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; } @@ -1103,6 +1113,28 @@ 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; + + irrevent.EventType = EET_TOUCH_INPUT_EVENT; + + irrevent.TouchInput.Event = cookie->evtype == XI_TouchUpdate ? ETIE_MOVED : (cookie->evtype == XI_TouchBegin ? ETIE_PRESSED_DOWN : ETIE_LEFT_UP); + + irrevent.TouchInput.ID = de->detail; + irrevent.TouchInput.X = de->event_x; + irrevent.TouchInput.Y = de->event_y; + + postEventFromUser(irrevent); + } + } + break; +#endif default: break; @@ -1988,6 +2020,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_ diff --git a/source/Irrlicht/CIrrDeviceLinux.h b/source/Irrlicht/CIrrDeviceLinux.h index 344149e1..67c65859 100644 --- a/source/Irrlicht/CIrrDeviceLinux.h +++ b/source/Irrlicht/CIrrDeviceLinux.h @@ -146,6 +146,8 @@ namespace irr void initXAtoms(); + void initXInput2(); + bool switchToFullscreen(bool reset=false); #ifdef _IRR_COMPILE_WITH_X11_