Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Commit

Permalink
1.Moved all xinput2 functionality to its own file
Browse files Browse the repository at this point in the history
2.Implement touch events using Xinput2.Leave evtouch as a fallback when xinput2 is not supported
  • Loading branch information
zenios committed May 31, 2012
1 parent 870b726 commit 40bf560
Show file tree
Hide file tree
Showing 13 changed files with 410 additions and 184 deletions.
17 changes: 17 additions & 0 deletions configure.in
Expand Up @@ -1192,6 +1192,23 @@ AC_HELP_STRING([--enable-video-x11-xinput], [enable X11 XInput extension for man
fi
if test x$definitely_enable_video_x11_xinput = xyes; then
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
AC_ARG_ENABLE(video-x11-xrandr,
AC_HELP_STRING([--enable-video-x11-xrandr], [enable X11 Xrandr extension for fullscreen [[default=yes]]]),
Expand Down
1 change: 1 addition & 0 deletions include/SDL_config.h.in
Expand Up @@ -264,6 +264,7 @@
#undef SDL_VIDEO_DRIVER_X11_XCURSOR
#undef SDL_VIDEO_DRIVER_X11_XINERAMA
#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_XSCRNSAVER
#undef SDL_VIDEO_DRIVER_X11_XSHAPE
Expand Down
1 change: 1 addition & 0 deletions include/SDL_config_macosx.h
Expand Up @@ -140,6 +140,7 @@
#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_XINPUT2 1
#define SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH 1
#define SDL_VIDEO_DRIVER_X11_XRANDR 1
#define SDL_VIDEO_DRIVER_X11_XSCRNSAVER 1
#define SDL_VIDEO_DRIVER_X11_XSHAPE 1
Expand Down
46 changes: 7 additions & 39 deletions src/video/x11/SDL_x11events.c
Expand Up @@ -30,6 +30,7 @@

#include "SDL_x11video.h"
#include "SDL_x11touch.h"
#include "SDL_x11xinput2.h"
#include "../../events/SDL_events_c.h"
#include "../../events/SDL_mouse_c.h"
#include "../../events/SDL_touch_c.h"
Expand Down Expand Up @@ -94,50 +95,13 @@ static SDL_bool X11_IsWheelEvent(Display * display,XEvent * event,int * ticks)
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
static void X11_HandleGenericEvent(SDL_VideoData *videodata,XEvent event)
{
XGenericEventCookie *cookie = &event.xcookie;
XGetEventData(videodata->display, cookie);
#if SDL_VIDEO_DRIVER_X11_XINPUT2
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
X11_HandleXinput2Event(videodata,cookie);
XFreeEventData(videodata->display,cookie);
}
#endif /* SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS */
Expand Down Expand Up @@ -605,9 +569,13 @@ X11_PumpEvents(_THIS)
while (X11_Pending(data->display)) {
X11_DispatchEvent(_this);
}
/*Dont process evtouch events if XInput2 multitouch is supported*/
if(X11_Xinput2IsMutitouchSupported()) {
return;
}

#ifdef SDL_INPUT_LINUXEV
/* Process Touch events - TODO When X gets touch support, use that instead*/
/* Process Touch events*/
int i = 0,rd;
struct input_event ev[64];
int size = sizeof (struct input_event);
Expand Down
7 changes: 4 additions & 3 deletions src/video/x11/SDL_x11mouse.c
Expand Up @@ -25,6 +25,7 @@
#include "SDL_assert.h"
#include "SDL_x11video.h"
#include "SDL_x11mouse.h"
#include "SDL_x11xinput2.h"
#include "../../events/SDL_mouse_c.h"


Expand Down Expand Up @@ -273,12 +274,12 @@ static int
X11_SetRelativeMouseMode(SDL_bool enabled)
{
#if SDL_VIDEO_DRIVER_X11_XINPUT2
/* FIXME: Need to remember from init if XInput2 is actually supported */
return 0;
if(X11_Xinput2IsInitialized())
return 0;
#else
SDL_Unsupported();
return -1;
#endif
return -1;
}

void
Expand Down
154 changes: 80 additions & 74 deletions src/video/x11/SDL_x11touch.c
Expand Up @@ -24,6 +24,7 @@

#include "SDL_x11video.h"
#include "SDL_x11touch.h"
#include "SDL_x11xinput2.h"
#include "../../events/SDL_touch_c.h"


Expand All @@ -35,82 +36,87 @@
void
X11_InitTouch(_THIS)
{
#ifdef SDL_INPUT_LINUXEV
FILE *fd;
fd = fopen("/proc/bus/input/devices","r");

int i = 0;
int tsfd;
char line[256];
char tstr[256];
int vendor = -1,product = -1,event = -1;
while(!feof(fd)) {
if(fgets(line,256,fd) <=0) continue;
if(line[0] == '\n') {
if(vendor == 1386 || vendor==1) {

sprintf(tstr,"/dev/input/event%i",event);

tsfd = open( tstr, O_RDONLY | O_NONBLOCK );
if ( tsfd == -1 )
continue; /* Maybe not enough permissions ? */

SDL_Touch touch;
touch.pressure_max = 0;
touch.pressure_min = 0;
touch.id = event;

touch.driverdata = SDL_malloc(sizeof(EventTouchData));
EventTouchData* data = (EventTouchData*)(touch.driverdata);

data->x = -1;
data->y = -1;
data->pressure = -1;
data->finger = 0;
data->up = SDL_FALSE;
data->down = SDL_FALSE;

data->eventStream = tsfd;
ioctl (data->eventStream, EVIOCGNAME (sizeof (tstr)), tstr);

int abs[5];
ioctl(data->eventStream,EVIOCGABS(0),abs);
touch.x_min = abs[1];
touch.x_max = abs[2];
touch.native_xres = touch.x_max - touch.x_min;
ioctl(data->eventStream,EVIOCGABS(ABS_Y),abs);
touch.y_min = abs[1];
touch.y_max = abs[2];
touch.native_yres = touch.y_max - touch.y_min;
ioctl(data->eventStream,EVIOCGABS(ABS_PRESSURE),abs);
touch.pressure_min = abs[1];
touch.pressure_max = abs[2];
touch.native_pressureres = touch.pressure_max - touch.pressure_min;

SDL_AddTouch(&touch, tstr);
}
vendor = -1;
product = -1;
event = -1;
}
else if(line[0] == 'I') {
i = 1;
while(line[i]) {
sscanf(&line[i],"Vendor=%x",&vendor);
sscanf(&line[i],"Product=%x",&product);
i++;
}
/*Initilized Xinput2 multitouch
* and return in order to not initialize
* evtouch also*/
if(X11_Xinput2IsMutitouchSupported()) {
X11_InitXinput2Multitouch(_this);
return;
}
else if(line[0] == 'H') {
i = 1;
while(line[i]) {
sscanf(&line[i],"event%d",&event);
i++;
}
#ifdef SDL_INPUT_LINUXEV
FILE *fd;
fd = fopen("/proc/bus/input/devices","r");

int i = 0;
int tsfd;
char line[256];
char tstr[256];
int vendor = -1,product = -1,event = -1;
while(!feof(fd)) {
if(fgets(line,256,fd) <=0) continue;
if(line[0] == '\n') {
if(vendor == 1386 || vendor==1) {
sprintf(tstr,"/dev/input/event%i",event);

tsfd = open( tstr, O_RDONLY | O_NONBLOCK );
if ( tsfd == -1 )
continue; /* Maybe not enough permissions ? */

SDL_Touch touch;
touch.pressure_max = 0;
touch.pressure_min = 0;
touch.id = event;

touch.driverdata = SDL_malloc(sizeof(EventTouchData));
EventTouchData* data = (EventTouchData*)(touch.driverdata);

data->x = -1;
data->y = -1;
data->pressure = -1;
data->finger = 0;
data->up = SDL_FALSE;
data->down = SDL_FALSE;

data->eventStream = tsfd;
ioctl (data->eventStream, EVIOCGNAME (sizeof (tstr)), tstr);

int abs[5];
ioctl(data->eventStream,EVIOCGABS(0),abs);
touch.x_min = abs[1];
touch.x_max = abs[2];
touch.native_xres = touch.x_max - touch.x_min;
ioctl(data->eventStream,EVIOCGABS(ABS_Y),abs);
touch.y_min = abs[1];
touch.y_max = abs[2];
touch.native_yres = touch.y_max - touch.y_min;
ioctl(data->eventStream,EVIOCGABS(ABS_PRESSURE),abs);
touch.pressure_min = abs[1];
touch.pressure_max = abs[2];
touch.native_pressureres = touch.pressure_max - touch.pressure_min;

SDL_AddTouch(&touch, tstr);
}
vendor = -1;
product = -1;
event = -1;
}
else if(line[0] == 'I') {
i = 1;
while(line[i]) {
sscanf(&line[i],"Vendor=%x",&vendor);
sscanf(&line[i],"Product=%x",&product);
i++;
}
}
else if(line[0] == 'H') {
i = 1;
while(line[i]) {
sscanf(&line[i],"event%d",&event);
i++;
}
}
}
}

fclose(fd);
fclose(fd);
#endif
}

Expand Down
6 changes: 0 additions & 6 deletions src/video/x11/SDL_x11touch.h
Expand Up @@ -23,12 +23,6 @@
#ifndef _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
typedef struct EventTouchData
{
Expand Down
53 changes: 2 additions & 51 deletions src/video/x11/SDL_x11video.c
Expand Up @@ -33,6 +33,7 @@
#include "SDL_x11framebuffer.h"
#include "SDL_x11shape.h"
#include "SDL_x11touch.h"
#include "SDL_x11xinput2.h"

#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
#include "SDL_x11opengles.h"
Expand Down Expand Up @@ -320,56 +321,6 @@ X11_CheckWindowManager(_THIS)
#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
X11_VideoInit(_THIS)
{
Expand Down Expand Up @@ -409,7 +360,7 @@ X11_VideoInit(_THIS)
return -1;
}

X11_CheckXInput2(_this);
X11_InitXinput2(_this);

if (X11_InitKeyboard(_this) != 0) {
return -1;
Expand Down

0 comments on commit 40bf560

Please sign in to comment.