1.Moved all xinput2 functionality to its own file
2.Implement touch events using Xinput2.Leave evtouch as a fallback when xinput2 is not supported
This commit is contained in:
parent
e2bd76bff4
commit
497b8deec4
13 changed files with 402 additions and 176 deletions
17
configure.in
17
configure.in
|
@ -1192,6 +1192,23 @@ AC_HELP_STRING([--enable-video-x11-xinput], [enable X11 XInput extension for man
|
||||||
fi
|
fi
|
||||||
if test x$definitely_enable_video_x11_xinput = xyes; then
|
if test x$definitely_enable_video_x11_xinput = xyes; then
|
||||||
AC_DEFINE(SDL_VIDEO_DRIVER_X11_XINPUT2, 1, [ ])
|
AC_DEFINE(SDL_VIDEO_DRIVER_X11_XINPUT2, 1, [ ])
|
||||||
|
AC_MSG_CHECKING(for xinput2 multitouch)
|
||||||
|
have_xinput2_multitouch=no
|
||||||
|
AC_TRY_COMPILE([
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/Xproto.h>
|
||||||
|
#include <X11/extensions/XInput2.h>
|
||||||
|
],[
|
||||||
|
Status
|
||||||
|
XIAllowTouchEvents(Display *a,int b,unsigned int c,Window d,int f)
|
||||||
|
{
|
||||||
|
return (Status)0;
|
||||||
|
}
|
||||||
|
],[
|
||||||
|
have_xinput2_multitouch=yes
|
||||||
|
AC_DEFINE(SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH)
|
||||||
|
])
|
||||||
|
AC_MSG_RESULT($have_xinput2_multitouch)
|
||||||
fi
|
fi
|
||||||
AC_ARG_ENABLE(video-x11-xrandr,
|
AC_ARG_ENABLE(video-x11-xrandr,
|
||||||
AC_HELP_STRING([--enable-video-x11-xrandr], [enable X11 Xrandr extension for fullscreen [[default=yes]]]),
|
AC_HELP_STRING([--enable-video-x11-xrandr], [enable X11 Xrandr extension for fullscreen [[default=yes]]]),
|
||||||
|
|
|
@ -264,6 +264,7 @@
|
||||||
#undef SDL_VIDEO_DRIVER_X11_XCURSOR
|
#undef SDL_VIDEO_DRIVER_X11_XCURSOR
|
||||||
#undef SDL_VIDEO_DRIVER_X11_XINERAMA
|
#undef SDL_VIDEO_DRIVER_X11_XINERAMA
|
||||||
#undef SDL_VIDEO_DRIVER_X11_XINPUT2
|
#undef SDL_VIDEO_DRIVER_X11_XINPUT2
|
||||||
|
#undef SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH
|
||||||
#undef SDL_VIDEO_DRIVER_X11_XRANDR
|
#undef SDL_VIDEO_DRIVER_X11_XRANDR
|
||||||
#undef SDL_VIDEO_DRIVER_X11_XSCRNSAVER
|
#undef SDL_VIDEO_DRIVER_X11_XSCRNSAVER
|
||||||
#undef SDL_VIDEO_DRIVER_X11_XSHAPE
|
#undef SDL_VIDEO_DRIVER_X11_XSHAPE
|
||||||
|
|
|
@ -140,6 +140,7 @@
|
||||||
#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE "/usr/X11R6/lib/libXxf86vm.1.dylib"
|
#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE "/usr/X11R6/lib/libXxf86vm.1.dylib"
|
||||||
#define SDL_VIDEO_DRIVER_X11_XINERAMA 1
|
#define SDL_VIDEO_DRIVER_X11_XINERAMA 1
|
||||||
#define SDL_VIDEO_DRIVER_X11_XINPUT2 1
|
#define SDL_VIDEO_DRIVER_X11_XINPUT2 1
|
||||||
|
#define SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH 1
|
||||||
#define SDL_VIDEO_DRIVER_X11_XRANDR 1
|
#define SDL_VIDEO_DRIVER_X11_XRANDR 1
|
||||||
#define SDL_VIDEO_DRIVER_X11_XSCRNSAVER 1
|
#define SDL_VIDEO_DRIVER_X11_XSCRNSAVER 1
|
||||||
#define SDL_VIDEO_DRIVER_X11_XSHAPE 1
|
#define SDL_VIDEO_DRIVER_X11_XSHAPE 1
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
#include "SDL_x11video.h"
|
#include "SDL_x11video.h"
|
||||||
#include "SDL_x11touch.h"
|
#include "SDL_x11touch.h"
|
||||||
|
#include "SDL_x11xinput2.h"
|
||||||
#include "../../events/SDL_events_c.h"
|
#include "../../events/SDL_events_c.h"
|
||||||
#include "../../events/SDL_mouse_c.h"
|
#include "../../events/SDL_mouse_c.h"
|
||||||
#include "../../events/SDL_touch_c.h"
|
#include "../../events/SDL_touch_c.h"
|
||||||
|
@ -94,50 +95,13 @@ static SDL_bool X11_IsWheelEvent(Display * display,XEvent * event,int * ticks)
|
||||||
return SDL_FALSE;
|
return SDL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SDL_VIDEO_DRIVER_X11_XINPUT2
|
|
||||||
static void X11_HandleRawMotion(SDL_VideoData *videodata,const XIRawEvent *rawev)
|
|
||||||
{
|
|
||||||
SDL_Mouse *mouse = SDL_GetMouse();
|
|
||||||
const double *values = rawev->raw_values;
|
|
||||||
int relative_cords[2] = {0,0};
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (!mouse->relative_mode) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*2 axis,X-Y*/
|
|
||||||
for (i = 0; i < 2; i++) {
|
|
||||||
if (XIMaskIsSet(rawev->valuators.mask, i)) {
|
|
||||||
const int value = (int) *values;
|
|
||||||
relative_cords[i] = value;
|
|
||||||
values++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#ifdef DEBUG_MOTION
|
|
||||||
printf("XInput relative motion: %d,%d\n", relative_cords[0],relative_cords[1]);
|
|
||||||
#endif
|
|
||||||
SDL_SendMouseMotion(mouse->focus,1,relative_cords[0],relative_cords[1]);
|
|
||||||
}
|
|
||||||
#endif /* SDL_VIDEO_DRIVER_X11_XINPUT2 */
|
|
||||||
|
|
||||||
#if SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS
|
#if SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS
|
||||||
static void X11_HandleGenericEvent(SDL_VideoData *videodata,XEvent event)
|
static void X11_HandleGenericEvent(SDL_VideoData *videodata,XEvent event)
|
||||||
{
|
{
|
||||||
XGenericEventCookie *cookie = &event.xcookie;
|
XGenericEventCookie *cookie = &event.xcookie;
|
||||||
XGetEventData(videodata->display, cookie);
|
XGetEventData(videodata->display, cookie);
|
||||||
#if SDL_VIDEO_DRIVER_X11_XINPUT2
|
X11_HandleXinput2Event(videodata,cookie);
|
||||||
if(cookie->extension == videodata->xinput_opcode) {
|
|
||||||
switch(cookie->evtype) {
|
|
||||||
case XI_RawMotion: {
|
|
||||||
const XIRawEvent *rawev = (const XIRawEvent*)cookie->data;
|
|
||||||
X11_HandleRawMotion(videodata,rawev);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
XFreeEventData(videodata->display,cookie);
|
XFreeEventData(videodata->display,cookie);
|
||||||
}
|
}
|
||||||
#endif /* SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS */
|
#endif /* SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS */
|
||||||
|
@ -605,9 +569,13 @@ X11_PumpEvents(_THIS)
|
||||||
while (X11_Pending(data->display)) {
|
while (X11_Pending(data->display)) {
|
||||||
X11_DispatchEvent(_this);
|
X11_DispatchEvent(_this);
|
||||||
}
|
}
|
||||||
|
/*Dont process evtouch events if XInput2 multitouch is supported*/
|
||||||
|
if(X11_Xinput2IsMutitouchSupported()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef SDL_INPUT_LINUXEV
|
#ifdef SDL_INPUT_LINUXEV
|
||||||
/* Process Touch events - TODO When X gets touch support, use that instead*/
|
/* Process Touch events*/
|
||||||
int i = 0,rd;
|
int i = 0,rd;
|
||||||
struct input_event ev[64];
|
struct input_event ev[64];
|
||||||
int size = sizeof (struct input_event);
|
int size = sizeof (struct input_event);
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "SDL_assert.h"
|
#include "SDL_assert.h"
|
||||||
#include "SDL_x11video.h"
|
#include "SDL_x11video.h"
|
||||||
#include "SDL_x11mouse.h"
|
#include "SDL_x11mouse.h"
|
||||||
|
#include "SDL_x11xinput2.h"
|
||||||
#include "../../events/SDL_mouse_c.h"
|
#include "../../events/SDL_mouse_c.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -273,12 +274,12 @@ static int
|
||||||
X11_SetRelativeMouseMode(SDL_bool enabled)
|
X11_SetRelativeMouseMode(SDL_bool enabled)
|
||||||
{
|
{
|
||||||
#if SDL_VIDEO_DRIVER_X11_XINPUT2
|
#if SDL_VIDEO_DRIVER_X11_XINPUT2
|
||||||
/* FIXME: Need to remember from init if XInput2 is actually supported */
|
if(X11_Xinput2IsInitialized())
|
||||||
return 0;
|
return 0;
|
||||||
#else
|
#else
|
||||||
SDL_Unsupported();
|
SDL_Unsupported();
|
||||||
return -1;
|
|
||||||
#endif
|
#endif
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#include "SDL_x11video.h"
|
#include "SDL_x11video.h"
|
||||||
#include "SDL_x11touch.h"
|
#include "SDL_x11touch.h"
|
||||||
|
#include "SDL_x11xinput2.h"
|
||||||
#include "../../events/SDL_touch_c.h"
|
#include "../../events/SDL_touch_c.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -35,6 +36,13 @@
|
||||||
void
|
void
|
||||||
X11_InitTouch(_THIS)
|
X11_InitTouch(_THIS)
|
||||||
{
|
{
|
||||||
|
/*Initilized Xinput2 multitouch
|
||||||
|
* and return in order to not initialize
|
||||||
|
* evtouch also*/
|
||||||
|
if(X11_Xinput2IsMutitouchSupported()) {
|
||||||
|
X11_InitXinput2Multitouch(_this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
#ifdef SDL_INPUT_LINUXEV
|
#ifdef SDL_INPUT_LINUXEV
|
||||||
FILE *fd;
|
FILE *fd;
|
||||||
fd = fopen("/proc/bus/input/devices","r");
|
fd = fopen("/proc/bus/input/devices","r");
|
||||||
|
@ -48,7 +56,6 @@ X11_InitTouch(_THIS)
|
||||||
if(fgets(line,256,fd) <=0) continue;
|
if(fgets(line,256,fd) <=0) continue;
|
||||||
if(line[0] == '\n') {
|
if(line[0] == '\n') {
|
||||||
if(vendor == 1386 || vendor==1) {
|
if(vendor == 1386 || vendor==1) {
|
||||||
|
|
||||||
sprintf(tstr,"/dev/input/event%i",event);
|
sprintf(tstr,"/dev/input/event%i",event);
|
||||||
|
|
||||||
tsfd = open( tstr, O_RDONLY | O_NONBLOCK );
|
tsfd = open( tstr, O_RDONLY | O_NONBLOCK );
|
||||||
|
@ -109,7 +116,6 @@ X11_InitTouch(_THIS)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(fd);
|
fclose(fd);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,12 +23,6 @@
|
||||||
#ifndef _SDL_x11touch_h
|
#ifndef _SDL_x11touch_h
|
||||||
#define _SDL_x11touch_h
|
#define _SDL_x11touch_h
|
||||||
|
|
||||||
/*
|
|
||||||
!!! FIXME: remove the evdev code;
|
|
||||||
!!! FIXME: this should be using XInput 2.1's new multitouch API.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* What should this be? */
|
|
||||||
#ifdef SDL_INPUT_LINUXEV
|
#ifdef SDL_INPUT_LINUXEV
|
||||||
typedef struct EventTouchData
|
typedef struct EventTouchData
|
||||||
{
|
{
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include "SDL_x11framebuffer.h"
|
#include "SDL_x11framebuffer.h"
|
||||||
#include "SDL_x11shape.h"
|
#include "SDL_x11shape.h"
|
||||||
#include "SDL_x11touch.h"
|
#include "SDL_x11touch.h"
|
||||||
|
#include "SDL_x11xinput2.h"
|
||||||
|
|
||||||
#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
|
#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
|
||||||
#include "SDL_x11opengles.h"
|
#include "SDL_x11opengles.h"
|
||||||
|
@ -320,56 +321,6 @@ X11_CheckWindowManager(_THIS)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
X11_CheckXInput2(_THIS)
|
|
||||||
{
|
|
||||||
#if SDL_VIDEO_DRIVER_X11_XINPUT2
|
|
||||||
SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
|
|
||||||
|
|
||||||
if (SDL_X11_HAVE_XINPUT2) {
|
|
||||||
XIEventMask eventmask;
|
|
||||||
unsigned char mask[3] = { 0,0,0 };
|
|
||||||
int opcode, event, err;
|
|
||||||
int major = 2, minor = 0;
|
|
||||||
/*
|
|
||||||
* Initialize XInput 2
|
|
||||||
* According to http://who-t.blogspot.com/2009/05/xi2-recipes-part-1.html its better
|
|
||||||
* to inform Xserver what version of Xinput we support.The server will store the version we support.
|
|
||||||
* "As XI2 progresses it becomes important that you use this call as the server may treat the client
|
|
||||||
* differently depending on the supported version".
|
|
||||||
*
|
|
||||||
* FIXME:event and err are not needed but if not passed XQueryExtension returns SegmentationFault
|
|
||||||
*/
|
|
||||||
if (!XQueryExtension(data->display, "XInputExtension", &opcode, &event, &err)) {
|
|
||||||
SDL_SetError("XInput 2 extension not available.");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (XIQueryVersion(data->display, &major, &minor) != Success) {
|
|
||||||
SDL_SetError("Error supporting XInput 2 version");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Save the opcode for event processing */
|
|
||||||
data->xinput_opcode = opcode;
|
|
||||||
|
|
||||||
/*Enable Raw motion events for this display*/
|
|
||||||
eventmask.deviceid = XIAllMasterDevices;
|
|
||||||
eventmask.mask_len = sizeof(mask);
|
|
||||||
eventmask.mask = mask;
|
|
||||||
|
|
||||||
XISetMask(mask, XI_RawMotion);
|
|
||||||
|
|
||||||
if (XISelectEvents(data->display,DefaultRootWindow(data->display),&eventmask,1) != Success) {
|
|
||||||
SDL_SetError("Error in selecting XInput 2 Raw motion events");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
X11_VideoInit(_THIS)
|
X11_VideoInit(_THIS)
|
||||||
{
|
{
|
||||||
|
@ -409,7 +360,7 @@ X11_VideoInit(_THIS)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
X11_CheckXInput2(_this);
|
X11_InitXinput2(_this);
|
||||||
|
|
||||||
if (X11_InitKeyboard(_this) != 0) {
|
if (X11_InitKeyboard(_this) != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -93,15 +93,6 @@ typedef struct SDL_VideoData
|
||||||
|
|
||||||
SDL_Scancode key_layout[256];
|
SDL_Scancode key_layout[256];
|
||||||
SDL_bool selection_waiting;
|
SDL_bool selection_waiting;
|
||||||
|
|
||||||
/* Opcode returned XQueryExtension
|
|
||||||
* It will be used in event processing
|
|
||||||
* to know that the event came from
|
|
||||||
* this extension */
|
|
||||||
#if SDL_VIDEO_DRIVER_X11_XINPUT2
|
|
||||||
int xinput_opcode;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} SDL_VideoData;
|
} SDL_VideoData;
|
||||||
|
|
||||||
extern SDL_bool X11_UseDirectColorVisuals(void);
|
extern SDL_bool X11_UseDirectColorVisuals(void);
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include "SDL_x11video.h"
|
#include "SDL_x11video.h"
|
||||||
#include "SDL_x11mouse.h"
|
#include "SDL_x11mouse.h"
|
||||||
#include "SDL_x11shape.h"
|
#include "SDL_x11shape.h"
|
||||||
|
#include "SDL_x11xinput2.h"
|
||||||
|
|
||||||
#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
|
#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
|
||||||
#include "SDL_x11opengles.h"
|
#include "SDL_x11opengles.h"
|
||||||
|
@ -561,6 +562,8 @@ X11_CreateWindow(_THIS, SDL_Window * window)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
X11_Xinput2SelectTouch(_this, window);
|
||||||
|
|
||||||
XSelectInput(display, w,
|
XSelectInput(display, w,
|
||||||
(FocusChangeMask | EnterWindowMask | LeaveWindowMask |
|
(FocusChangeMask | EnterWindowMask | LeaveWindowMask |
|
||||||
ExposureMask | ButtonPressMask | ButtonReleaseMask |
|
ExposureMask | ButtonPressMask | ButtonReleaseMask |
|
||||||
|
|
249
src/video/x11/SDL_x11xinput2.c
Normal file
249
src/video/x11/SDL_x11xinput2.c
Normal file
|
@ -0,0 +1,249 @@
|
||||||
|
/*
|
||||||
|
Simple DirectMedia Layer
|
||||||
|
Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original software. If you use this software
|
||||||
|
in a product, an acknowledgment in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original software.
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*/
|
||||||
|
#include "SDL_config.h"
|
||||||
|
|
||||||
|
#if SDL_VIDEO_DRIVER_X11
|
||||||
|
|
||||||
|
#include "SDL_x11video.h"
|
||||||
|
#include "SDL_x11xinput2.h"
|
||||||
|
#include "../../events/SDL_mouse_c.h"
|
||||||
|
#include "../../events/SDL_touch_c.h"
|
||||||
|
|
||||||
|
#define MAX_AXIS 16
|
||||||
|
|
||||||
|
static int xinput2_initialized = 0;
|
||||||
|
static int xinput2_multitouch_supported = 0;
|
||||||
|
/* Opcode returned XQueryExtension
|
||||||
|
* It will be used in event processing
|
||||||
|
* to know that the event came from
|
||||||
|
* this extension */
|
||||||
|
static int xinput2_opcode;
|
||||||
|
|
||||||
|
|
||||||
|
#if SDL_VIDEO_DRIVER_X11_XINPUT2
|
||||||
|
static void parse_valuators(const double *input_values,unsigned char *mask,int mask_len,
|
||||||
|
double *output_values,int output_values_len) {
|
||||||
|
int i = 0,z = 0;
|
||||||
|
int top = mask_len * 8;
|
||||||
|
if (top > MAX_AXIS)
|
||||||
|
top = MAX_AXIS;
|
||||||
|
|
||||||
|
SDL_memset(output_values,0,output_values_len * sizeof(double));
|
||||||
|
for (; i < top && z < output_values_len; i++) {
|
||||||
|
if (XIMaskIsSet(mask, i)) {
|
||||||
|
const int value = (int) *input_values;
|
||||||
|
output_values[z] = value;
|
||||||
|
input_values++;
|
||||||
|
}
|
||||||
|
z++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* SDL_VIDEO_DRIVER_X11_XINPUT2 */
|
||||||
|
|
||||||
|
void
|
||||||
|
X11_InitXinput2(_THIS) {
|
||||||
|
#if SDL_VIDEO_DRIVER_X11_XINPUT2
|
||||||
|
SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
|
||||||
|
|
||||||
|
XIEventMask eventmask;
|
||||||
|
unsigned char mask[3] = { 0,0,0 };
|
||||||
|
int event, err;
|
||||||
|
int major = 2, minor = 0;
|
||||||
|
int outmajor,outminor;
|
||||||
|
#if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH
|
||||||
|
minor = 2;
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
* Initialize XInput 2
|
||||||
|
* According to http://who-t.blogspot.com/2009/05/xi2-recipes-part-1.html its better
|
||||||
|
* to inform Xserver what version of Xinput we support.The server will store the version we support.
|
||||||
|
* "As XI2 progresses it becomes important that you use this call as the server may treat the client
|
||||||
|
* differently depending on the supported version".
|
||||||
|
*
|
||||||
|
* FIXME:event and err are not needed but if not passed XQueryExtension returns SegmentationFault
|
||||||
|
*/
|
||||||
|
if (!XQueryExtension(data->display, "XInputExtension", &xinput2_opcode, &event, &err)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
outmajor = major;
|
||||||
|
outminor = minor;
|
||||||
|
if (XIQueryVersion(data->display, &outmajor, &outminor) != Success) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Check supported version*/
|
||||||
|
if(outmajor * 1000 + outminor < major * 1000 + minor) {
|
||||||
|
/*X server does not support the version we want*/
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
xinput2_initialized = 1;
|
||||||
|
#if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH
|
||||||
|
/*XInput 2.2*/
|
||||||
|
if(outmajor * 1000 + outminor >= major * 1000 + minor) {
|
||||||
|
xinput2_multitouch_supported = 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*Enable Raw motion events for this display*/
|
||||||
|
eventmask.deviceid = XIAllMasterDevices;
|
||||||
|
eventmask.mask_len = sizeof(mask);
|
||||||
|
eventmask.mask = mask;
|
||||||
|
|
||||||
|
XISetMask(mask, XI_RawMotion);
|
||||||
|
|
||||||
|
if (XISelectEvents(data->display,DefaultRootWindow(data->display),&eventmask,1) != Success) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
X11_HandleXinput2Event(SDL_VideoData *videodata,XGenericEventCookie *cookie) {
|
||||||
|
#if SDL_VIDEO_DRIVER_X11_XINPUT2
|
||||||
|
if(cookie->extension != xinput2_opcode) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
switch(cookie->evtype) {
|
||||||
|
case XI_RawMotion: {
|
||||||
|
const XIRawEvent *rawev = (const XIRawEvent*)cookie->data;
|
||||||
|
SDL_Mouse *mouse = SDL_GetMouse();
|
||||||
|
double relative_cords[2];
|
||||||
|
|
||||||
|
if (!mouse->relative_mode) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_valuators(rawev->raw_values,rawev->valuators.mask,
|
||||||
|
rawev->valuators.mask_len,relative_cords,2);
|
||||||
|
SDL_SendMouseMotion(mouse->focus,1,(int)relative_cords[0],(int)relative_cords[1]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH
|
||||||
|
case XI_TouchBegin: {
|
||||||
|
const XIDeviceEvent *xev = (const XIDeviceEvent *) cookie->data;
|
||||||
|
SDL_SendFingerDown(xev->sourceid,xev->detail,
|
||||||
|
SDL_TRUE, (int)xev->event_x, (int)xev->event_y,
|
||||||
|
1.0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case XI_TouchEnd: {
|
||||||
|
const XIDeviceEvent *xev = (const XIDeviceEvent *) cookie->data;
|
||||||
|
SDL_SendFingerDown(xev->sourceid,xev->detail,
|
||||||
|
SDL_FALSE, (int)xev->event_x, (int)xev->event_y,
|
||||||
|
1.0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case XI_TouchUpdate: {
|
||||||
|
const XIDeviceEvent *xev = (const XIDeviceEvent *) cookie->data;
|
||||||
|
SDL_SendTouchMotion(xev->sourceid,xev->detail,
|
||||||
|
SDL_FALSE, (int)xev->event_x, (int)xev->event_y,
|
||||||
|
1.0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
X11_InitXinput2Multitouch(_THIS) {
|
||||||
|
#if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH
|
||||||
|
SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
|
||||||
|
XIDeviceInfo *info;
|
||||||
|
int ndevices,i,j;
|
||||||
|
info = XIQueryDevice(data->display, XIAllMasterDevices, &ndevices);
|
||||||
|
|
||||||
|
for (i = 0; i < ndevices; i++) {
|
||||||
|
XIDeviceInfo *dev = &info[i];
|
||||||
|
for (j = 0; j < dev->num_classes; j++) {
|
||||||
|
SDL_TouchID touchId;
|
||||||
|
XIAnyClassInfo *class = dev->classes[j];
|
||||||
|
XITouchClassInfo *t = (XITouchClassInfo*)class;
|
||||||
|
|
||||||
|
/*Only touch devices*/
|
||||||
|
if (class->type != XITouchClass)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
touchId = t->sourceid;
|
||||||
|
/*Add the touch*/
|
||||||
|
if (!SDL_GetTouch(touchId)) {
|
||||||
|
SDL_Touch touch;
|
||||||
|
|
||||||
|
touch.id = touchId;
|
||||||
|
touch.x_min = 0;
|
||||||
|
touch.x_max = 1;
|
||||||
|
touch.native_xres = touch.x_max - touch.x_min;
|
||||||
|
touch.y_min = 0;
|
||||||
|
touch.y_max = 1;
|
||||||
|
touch.native_yres = touch.y_max - touch.y_min;
|
||||||
|
touch.pressure_min = 0;
|
||||||
|
touch.pressure_max = 1;
|
||||||
|
touch.native_pressureres = touch.pressure_max - touch.pressure_min;
|
||||||
|
|
||||||
|
SDL_AddTouch(&touch,dev->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
X11_Xinput2SelectTouch(_THIS, SDL_Window *window) {
|
||||||
|
#if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH
|
||||||
|
SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
|
||||||
|
XIEventMask eventmask;
|
||||||
|
unsigned char mask[3] = { 0,0,0 };
|
||||||
|
SDL_WindowData *window_data = (SDL_WindowData*)window->driverdata;
|
||||||
|
|
||||||
|
eventmask.deviceid = XIAllMasterDevices;
|
||||||
|
eventmask.mask_len = sizeof(mask);
|
||||||
|
eventmask.mask = mask;
|
||||||
|
|
||||||
|
XISetMask(mask, XI_TouchBegin);
|
||||||
|
XISetMask(mask, XI_TouchUpdate);
|
||||||
|
XISetMask(mask, XI_TouchEnd);
|
||||||
|
|
||||||
|
XISelectEvents(data->display,window_data->xwindow,&eventmask,1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
X11_Xinput2IsInitialized() {
|
||||||
|
return xinput2_initialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
X11_Xinput2IsMutitouchSupported() {
|
||||||
|
return xinput2_initialized && xinput2_multitouch_supported;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* SDL_VIDEO_DRIVER_X11 */
|
||||||
|
|
||||||
|
/* vi: set ts=4 sw=4 expandtab: */
|
42
src/video/x11/SDL_x11xinput2.h
Normal file
42
src/video/x11/SDL_x11xinput2.h
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
Simple DirectMedia Layer
|
||||||
|
Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original software. If you use this software
|
||||||
|
in a product, an acknowledgment in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original software.
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*/
|
||||||
|
#include "SDL_config.h"
|
||||||
|
|
||||||
|
#ifndef _SDL_x11xinput2_h
|
||||||
|
#define _SDL_x11xinput2_h
|
||||||
|
|
||||||
|
#ifndef SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS
|
||||||
|
/*Define XGenericEventCookie as forward declaration when
|
||||||
|
*xinput2 is not available in order to compile*/
|
||||||
|
struct XGenericEventCookie;
|
||||||
|
typedef struct XGenericEventCookie XGenericEventCookie;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern void X11_InitXinput2(_THIS);
|
||||||
|
extern void X11_InitXinput2Multitouch(_THIS);
|
||||||
|
extern int X11_HandleXinput2Event(SDL_VideoData *videodata,XGenericEventCookie *cookie);
|
||||||
|
extern int X11_Xinput2IsInitialized(void);
|
||||||
|
extern int X11_Xinput2IsMutitouchSupported(void);
|
||||||
|
extern void X11_Xinput2SelectTouch(_THIS, SDL_Window *window);
|
||||||
|
|
||||||
|
#endif /* _SDL_x11xinput2_h */
|
||||||
|
|
||||||
|
/* vi: set ts=4 sw=4 expandtab: */
|
|
@ -54,7 +54,9 @@ main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
srand((unsigned int)time(NULL));
|
srand((unsigned int)time(NULL));
|
||||||
SDL_SetRelativeMouseMode(SDL_TRUE);
|
if(SDL_SetRelativeMouseMode(SDL_TRUE) < 0) {
|
||||||
|
return 3;
|
||||||
|
};
|
||||||
|
|
||||||
rect.x = DEFAULT_WINDOW_WIDTH / 2;
|
rect.x = DEFAULT_WINDOW_WIDTH / 2;
|
||||||
rect.y = DEFAULT_WINDOW_HEIGHT / 2;
|
rect.y = DEFAULT_WINDOW_HEIGHT / 2;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue