Enable Tablet support with both Tilt and Pressure.
[wine] / dlls / x11drv / wintab.c
1 /*
2  * X11 tablet driver
3  *
4  * Copyright 2003 CodeWeavers (Aric Stewart)
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include "config.h"
22 #include "wine/port.h"
23
24 #include <stdlib.h>
25
26 #include "windef.h"
27 #include "x11drv.h"
28 #include "wine/debug.h"
29 #include "wintab.h"
30
31 WINE_DEFAULT_DEBUG_CHANNEL(wintab32);
32 WINE_DECLARE_DEBUG_CHANNEL(event);
33
34 typedef struct tagWTI_CURSORS_INFO
35 {
36     CHAR   NAME[256];
37         /* a displayable zero-terminated string containing the name of the
38          * cursor.
39          */
40     BOOL    ACTIVE;
41         /* whether the cursor is currently connected. */
42     WTPKT   PKTDATA;
43         /* a bit mask indicating the packet data items supported when this
44          * cursor is connected.
45          */
46     BYTE    BUTTONS;
47         /* the number of buttons on this cursor. */
48     BYTE    BUTTONBITS;
49         /* the number of bits of raw button data returned by the hardware.*/
50     CHAR   BTNNAMES[1024]; /* FIXME: make this dynamic */
51         /* a list of zero-terminated strings containing the names of the
52          * cursor's buttons. The number of names in the list is the same as the
53          * number of buttons on the cursor. The names are separated by a single
54          * zero character; the list is terminated by two zero characters.
55          */
56     BYTE    BUTTONMAP[32];
57         /* a 32 byte array of logical button numbers, one for each physical
58          * button.
59          */
60     BYTE    SYSBTNMAP[32];
61         /* a 32 byte array of button action codes, one for each logical
62          * button.
63          */
64     BYTE    NPBUTTON;
65         /* the physical button number of the button that is controlled by normal
66          * pressure.
67          */
68     UINT    NPBTNMARKS[2];
69         /* an array of two UINTs, specifying the button marks for the normal
70          * pressure button. The first UINT contains the release mark; the second
71          * contains the press mark.
72          */
73     UINT    *NPRESPONSE;
74         /* an array of UINTs describing the pressure response curve for normal
75          * pressure.
76          */
77     BYTE    TPBUTTON;
78         /* the physical button number of the button that is controlled by
79          * tangential pressure.
80          */
81     UINT    TPBTNMARKS[2];
82         /* an array of two UINTs, specifying the button marks for the tangential
83          * pressure button. The first UINT contains the release mark; the second
84          * contains the press mark.
85          */
86     UINT    *TPRESPONSE;
87         /* an array of UINTs describing the pressure response curve for
88          * tangential pressure.
89          */
90     DWORD   PHYSID;
91          /* a manufacturer-specific physical identifier for the cursor. This
92           * value will distinguish the physical cursor from others on the same
93           * device. This physical identifier allows applications to bind
94           * functions to specific physical cursors, even if category numbers
95           * change and multiple, otherwise identical, physical cursors are
96           * present.
97           */
98     UINT    MODE;
99         /* the cursor mode number of this cursor type, if this cursor type has
100          * the CRC_MULTIMODE capability.
101          */
102     UINT    MINPKTDATA;
103         /* the minimum set of data available from a physical cursor in this
104          * cursor type, if this cursor type has the CRC_AGGREGATE capability.
105          */
106     UINT    MINBUTTONS;
107         /* the minimum number of buttons of physical cursors in the cursor type,
108          * if this cursor type has the CRC_AGGREGATE capability.
109          */
110     UINT    CAPABILITIES;
111         /* flags indicating cursor capabilities, as defined below:
112             CRC_MULTIMODE
113                 Indicates this cursor type describes one of several modes of a
114                 single physical cursor. Consecutive cursor type categories
115                 describe the modes; the CSR_MODE data item gives the mode number
116                 of each cursor type.
117             CRC_AGGREGATE
118                 Indicates this cursor type describes several physical cursors
119                 that cannot be distinguished by software.
120             CRC_INVERT
121                 Indicates this cursor type describes the physical cursor in its
122                 inverted orientation; the previous consecutive cursor type
123                 category describes the normal orientation.
124          */
125     UINT    TYPE;
126         /* Manufacturer Unique id for the item type */
127 } WTI_CURSORS_INFO, *LPWTI_CURSORS_INFO;
128
129
130 typedef struct tagWTI_DEVICES_INFO
131 {
132     CHAR   NAME[256];
133         /* a displayable null- terminated string describing the device,
134          * manufacturer, and revision level.
135          */
136     UINT    HARDWARE;
137         /* flags indicating hardware and driver capabilities, as defined
138          * below:
139             HWC_INTEGRATED:
140                 Indicates that the display and digitizer share the same surface.
141             HWC_TOUCH
142                 Indicates that the cursor must be in physical contact with the
143                 device to report position.
144             HWC_HARDPROX
145                 Indicates that device can generate events when the cursor is
146                 entering and leaving the physical detection range.
147             HWC_PHYSID_CURSORS
148                 Indicates that device can uniquely identify the active cursor in
149                 hardware.
150          */
151     UINT    NCSRTYPES;
152         /* the number of supported cursor types.*/
153     UINT    FIRSTCSR;
154         /* the first cursor type number for the device. */
155     UINT    PKTRATE;
156         /* the maximum packet report rate in Hertz. */
157     WTPKT   PKTDATA;
158         /* a bit mask indicating which packet data items are always available.*/
159     WTPKT   PKTMODE;
160         /* a bit mask indicating which packet data items are physically
161          * relative, i.e., items for which the hardware can only report change,
162          * not absolute measurement.
163          */
164     WTPKT   CSRDATA;
165         /* a bit mask indicating which packet data items are only available when
166          * certain cursors are connected. The individual cursor descriptions
167          * must be consulted to determine which cursors return which data.
168          */
169     INT     XMARGIN;
170     INT     YMARGIN;
171     INT     ZMARGIN;
172         /* the size of tablet context margins in tablet native coordinates, in
173          * the x, y, and z directions, respectively.
174          */
175     AXIS    X;
176     AXIS    Y;
177     AXIS    Z;
178         /* the tablet's range and resolution capabilities, in the x, y, and z
179          * axes, respectively.
180          */
181     AXIS    NPRESSURE;
182     AXIS    TPRESSURE;
183         /* the tablet's range and resolution capabilities, for the normal and
184          * tangential pressure inputs, respectively.
185          */
186     AXIS    ORIENTATION[3];
187         /* a 3-element array describing the tablet's orientation range and
188          * resolution capabilities.
189          */
190     AXIS    ROTATION[3];
191         /* a 3-element array describing the tablet's rotation range and
192          * resolution capabilities.
193          */
194     CHAR   PNPID[256];
195         /* a null-terminated string containing the devices Plug and Play ID.*/
196 }   WTI_DEVICES_INFO, *LPWTI_DEVICES_INFO;
197
198 typedef struct tagWTPACKET {
199         HCTX pkContext;
200         UINT pkStatus;
201         LONG pkTime;
202         WTPKT pkChanged;
203         UINT pkSerialNumber;
204         UINT pkCursor;
205         DWORD pkButtons;
206         DWORD pkX;
207         DWORD pkY;
208         DWORD pkZ;
209         UINT pkNormalPressure;
210         UINT pkTangentPressure;
211         ORIENTATION pkOrientation;
212         ROTATION pkRotation; /* 1.1 */
213 } WTPACKET, *LPWTPACKET;
214
215
216 #ifdef HAVE_X11_EXTENSIONS_XINPUT_H
217
218 #include <X11/Xlib.h>
219 #include <X11/extensions/XInput.h>
220
221 static int           motion_type = -1;
222 static int           button_press_type = -1;
223 static int           button_release_type = -1;
224 static int           key_press_type = -1;
225 static int           key_release_type = -1;
226 static int           proximity_in_type = -1;
227 static int           proximity_out_type = -1;
228
229 static HWND          hwndTabletDefault;
230 static WTPACKET      gMsgPacket;
231 static DWORD         gSerial;
232 static INT           button_state[10];
233
234 #define             CURSORMAX 10
235
236 static LOGCONTEXTA      gSysContext;
237 static WTI_DEVICES_INFO gSysDevice;
238 static WTI_CURSORS_INFO gSysCursor[CURSORMAX];
239 static INT              gNumCursors;
240
241
242 #ifndef SONAME_LIBXI
243 #define SONAME_LIBXI "libXi.so"
244 #endif
245
246 /* XInput stuff */
247 static void *xinput_handle;
248
249 #define MAKE_FUNCPTR(f) static typeof(f) * p##f;
250 MAKE_FUNCPTR(XListInputDevices)
251 MAKE_FUNCPTR(XOpenDevice)
252 MAKE_FUNCPTR(XQueryDeviceState)
253 MAKE_FUNCPTR(XGetDeviceButtonMapping)
254 MAKE_FUNCPTR(XCloseDevice)
255 MAKE_FUNCPTR(XSelectExtensionEvent)
256 MAKE_FUNCPTR(XFreeDeviceState)
257 #undef MAKE_FUNCPTR
258
259 static INT X11DRV_XInput_Init(void)
260 {
261     xinput_handle = wine_dlopen(SONAME_LIBXI, RTLD_NOW, NULL, 0);
262     if (xinput_handle)
263     {
264 #define LOAD_FUNCPTR(f) if((p##f = wine_dlsym(xinput_handle, #f, NULL, 0)) == NULL) goto sym_not_found;
265         LOAD_FUNCPTR(XListInputDevices)
266         LOAD_FUNCPTR(XOpenDevice)
267         LOAD_FUNCPTR(XGetDeviceButtonMapping)
268         LOAD_FUNCPTR(XCloseDevice)
269         LOAD_FUNCPTR(XSelectExtensionEvent)
270         LOAD_FUNCPTR(XQueryDeviceState)
271         LOAD_FUNCPTR(XFreeDeviceState)
272 #undef LOAD_FUNCPTR
273         return 1;
274     }
275 sym_not_found:
276     return 0;
277 }
278
279 void X11DRV_LoadTabletInfo(HWND hwnddefault)
280 {
281     struct x11drv_thread_data *data = x11drv_thread_data();
282     int num_devices;
283     int loop;
284     int cursor_target;
285     XDeviceInfo *devices;
286     XDeviceInfo *target = NULL;
287     BOOL    axis_read_complete= FALSE;
288
289     XAnyClassPtr        any;
290     XButtonInfoPtr      Button;
291     XValuatorInfoPtr    Val;
292     XAxisInfoPtr        Axis;
293
294     XDevice *opendevice;
295
296     if (!X11DRV_XInput_Init())
297     {
298         ERR("Unable to initialized the XInput library.\n");
299         return;
300     }
301
302     hwndTabletDefault = hwnddefault;
303
304     /* Do base initializaion */
305     strcpy(gSysContext.lcName, "Wine Tablet Context");
306     strcpy(gSysDevice.NAME,"Wine Tablet Device");
307
308     gSysContext.lcOptions = CXO_SYSTEM | CXO_MESSAGES | CXO_CSRMESSAGES;
309     gSysContext.lcLocks = CXL_INSIZE | CXL_INASPECT | CXL_MARGIN |
310                                CXL_SENSITIVITY | CXL_SYSOUT;
311
312     gSysContext.lcMsgBase= WT_DEFBASE;
313     gSysContext.lcDevice = 0;
314     gSysContext.lcPktData =
315         PK_CONTEXT | PK_STATUS | PK_SERIAL_NUMBER| PK_TIME | PK_CURSOR |
316         PK_BUTTONS |  PK_X | PK_Y | PK_NORMAL_PRESSURE | PK_ORIENTATION;
317     gSysContext.lcMoveMask=
318         PK_BUTTONS |  PK_X | PK_Y | PK_NORMAL_PRESSURE | PK_ORIENTATION;
319     gSysContext.lcStatus = CXS_ONTOP;
320     gSysContext.lcPktRate = 100;
321     gSysContext.lcBtnDnMask = 0xffffffff;
322     gSysContext.lcBtnUpMask = 0xffffffff;
323     gSysContext.lcSensX = 65536;
324     gSysContext.lcSensY = 65536;
325     gSysContext.lcSensX = 65536;
326     gSysContext.lcSensZ = 65536;
327     gSysContext.lcSysSensX= 65536;
328     gSysContext.lcSysSensY= 65536;
329
330     /* Device Defaults */
331     gSysDevice.HARDWARE = HWC_HARDPROX|HWC_PHYSID_CURSORS;
332     gSysDevice.FIRSTCSR= 0;
333     gSysDevice.PKTRATE = 100;
334     gSysDevice.PKTDATA =
335         PK_CONTEXT | PK_STATUS | PK_SERIAL_NUMBER| PK_TIME | PK_CURSOR |
336         PK_BUTTONS |  PK_X | PK_Y | PK_NORMAL_PRESSURE | PK_ORIENTATION;
337     strcpy(gSysDevice.PNPID,"non-pluginplay");
338
339     wine_tsx11_lock();
340
341     cursor_target = -1;
342     devices = pXListInputDevices(data->display, &num_devices);
343     if (!devices)
344     {
345         WARN("XInput Extenstions reported as not avalable\n");
346         wine_tsx11_unlock();
347         return;
348     }
349     for (loop=0; loop < num_devices; loop++)
350     {
351         int class_loop;
352
353         TRACE("Trying device %i(%s)\n",loop,devices[loop].name);
354         if (devices[loop].use == IsXExtensionDevice)
355         {
356             LPWTI_CURSORS_INFO cursor;
357
358             TRACE("Is Extension Device\n");
359             cursor_target++;
360             target = &devices[loop];
361             cursor = &gSysCursor[cursor_target];
362
363             opendevice = pXOpenDevice(data->display,target->id);
364             if (opendevice)
365             {
366                 unsigned char map[32];
367                 int i;
368                 int shft = 0;
369
370                 pXGetDeviceButtonMapping(data->display, opendevice, map, 32);
371
372                 for (i=0; i< cursor->BUTTONS; i++,shft++)
373                 {
374                     cursor->BUTTONMAP[i] = map[i];
375                     cursor->SYSBTNMAP[i] = (1<<shft);
376                 }
377                 pXCloseDevice(data->display, opendevice);
378             }
379             else
380             {
381                 WARN("Unable to open device %s\n",target->name);
382                 cursor_target --;
383                 continue;
384             }
385
386             strcpy(cursor->NAME,target->name);
387
388             cursor->ACTIVE = 1;
389             cursor->PKTDATA = PK_TIME | PK_CURSOR | PK_BUTTONS |  PK_X | PK_Y |
390                               PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE |
391                               PK_ORIENTATION;
392
393             cursor->PHYSID = cursor_target;
394             cursor->NPBUTTON = 1;
395             cursor->NPBTNMARKS[0] = 0 ;
396             cursor->NPBTNMARKS[1] = 1 ;
397             cursor->CAPABILITIES = 1;
398             if (strcasecmp(cursor->NAME,"stylus")==0)
399                 cursor->TYPE = 0x4825;
400             if (strcasecmp(cursor->NAME,"eraser")==0)
401                 cursor->TYPE = 0xc85a;
402
403
404             any = (XAnyClassPtr) (target->inputclassinfo);
405
406             for (class_loop = 0; class_loop < target->num_classes; class_loop++)
407             {
408                 switch (any->class)
409                 {
410                     case ValuatorClass:
411                         if (!axis_read_complete)
412                         {
413                             Val = (XValuatorInfoPtr) any;
414                             Axis = (XAxisInfoPtr) ((char *) Val + sizeof
415                                 (XValuatorInfo));
416
417                             if (Val->num_axes>=1)
418                             {
419                                 /* Axis 1 is X */
420                                 gSysDevice.X.axMin = Axis->min_value;
421                                 gSysDevice.X.axMax= Axis->max_value;
422                                 gSysDevice.X.axUnits = 1;
423                                 gSysDevice.X.axResolution = Axis->resolution;
424                                 gSysContext.lcInOrgX = Axis->min_value;
425                                 gSysContext.lcSysOrgX = Axis->min_value;
426                                 gSysContext.lcInExtX = Axis->max_value;
427                                 gSysContext.lcSysExtX = Axis->max_value;
428                                 Axis++;
429                             }
430                             if (Val->num_axes>=2)
431                             {
432                                 /* Axis 2 is Y */
433                                 gSysDevice.Y.axMin = Axis->min_value;
434                                 gSysDevice.Y.axMax= Axis->max_value;
435                                 gSysDevice.Y.axUnits = 1;
436                                 gSysDevice.Y.axResolution = Axis->resolution;
437                                 gSysContext.lcInOrgY = Axis->min_value;
438                                 gSysContext.lcSysOrgY = Axis->min_value;
439                                 gSysContext.lcInExtY = Axis->max_value;
440                                 gSysContext.lcSysExtY = Axis->max_value;
441                                 Axis++;
442                             }
443                             if (Val->num_axes>=3)
444                             {
445                                 /* Axis 3 is Normal Pressure */
446                                 gSysDevice.NPRESSURE.axMin = Axis->min_value;
447                                 gSysDevice.NPRESSURE.axMax= Axis->max_value;
448                                 gSysDevice.NPRESSURE.axUnits = 1;
449                                 gSysDevice.NPRESSURE.axResolution =
450                                                         Axis->resolution;
451                                 Axis++;
452                             }
453                             if (Val->num_axes >= 5)
454                             {
455                                 /* Axis 4 and 5 are X and Y tilt */
456                                 XAxisInfoPtr        XAxis = Axis;
457                                 Axis++;
458                                 if (max (abs(Axis->max_value),
459                                          abs(XAxis->max_value)))
460                                 {
461                                     gSysDevice.ORIENTATION[0].axMin = 0;
462                                     gSysDevice.ORIENTATION[0].axMax = 3600;
463                                     gSysDevice.ORIENTATION[0].axUnits = 1;
464                                     gSysDevice.ORIENTATION[0].axResolution =
465                                                                      235929600;
466                                     gSysDevice.ORIENTATION[1].axMin = -1000;
467                                     gSysDevice.ORIENTATION[1].axMax = 1000;
468                                     gSysDevice.ORIENTATION[1].axUnits = 1;
469                                     gSysDevice.ORIENTATION[1].axResolution =
470                                                                      235929600;
471                                     Axis++;
472                                 }
473                             }
474                             axis_read_complete = TRUE;
475                         }
476                         break;
477                     case ButtonClass:
478                     {
479                         CHAR *ptr = cursor->BTNNAMES;
480                         int i;
481
482                         Button = (XButtonInfoPtr) any;
483                         cursor->BUTTONS = Button->num_buttons;
484                         for (i = 0; i < cursor->BUTTONS; i++)
485                         {
486                             strcpy(ptr,cursor->NAME);
487                             ptr+=8;
488                         }
489                     }
490                     break;
491                 }
492                 any = (XAnyClassPtr) ((char*) any + any->length);
493             }
494         }
495     }
496     wine_tsx11_unlock();
497     gSysDevice.NCSRTYPES = cursor_target+1;
498     gNumCursors = cursor_target+1;
499 }
500
501 static int figure_deg(int x, int y)
502 {
503     int rc;
504
505     if (y != 0)
506     {
507         rc = (int) 10 * (atan( (FLOAT)abs(y) / (FLOAT)abs(x)) / (3.1415 / 180));
508         if (y>0)
509         {
510             if (x>0)
511                 rc += 900;
512             else
513                 rc = 2700 - rc;
514         }
515         else
516         {
517             if (x>0)
518                 rc = 900 - rc;
519             else
520                 rc += 2700;
521         }
522     }
523     else
524     {
525         if (x >= 0)
526             rc = 900;
527         else
528             rc = 2700;
529     }
530
531     return rc;
532 }
533
534 static int get_button_state(int deviceid)
535 {
536     return button_state[deviceid];
537 }
538
539 static void set_button_state(XID deviceid)
540 {
541     struct x11drv_thread_data *data = x11drv_thread_data();
542     XDevice *device;
543     XDeviceState *state;
544     XInputClass  *class;
545     int loop;
546     int rc = 0;
547
548     wine_tsx11_lock();
549     device = pXOpenDevice(data->display,deviceid);
550     state = pXQueryDeviceState(data->display,device);
551
552     if (state)
553     {
554         class = state->data;
555         for (loop = 0; loop < state->num_classes; loop++)
556         {
557             if (class->class == ButtonClass)
558             {
559                 int loop2;
560                 XButtonState *button_state =  (XButtonState*)class;
561                 for (loop2 = 1; loop2 <= button_state->num_buttons; loop2++)
562                 {
563                     if (button_state->buttons[loop2 / 8] & (1 << (loop2 % 8)))
564                     {
565                         rc |= (1<<(loop2-1));
566                     }
567                 }
568             }
569             class = (XInputClass *) ((char *) class + class->length);
570         }
571     }
572     pXFreeDeviceState(state);
573     wine_tsx11_unlock();
574     button_state[deviceid] = rc;
575 }
576
577 int X11DRV_ProcessTabletEvent(HWND hwnd, XEvent *event)
578 {
579     memset(&gMsgPacket,0,sizeof(WTPACKET));
580
581     if(event->type ==  motion_type)
582     {
583         XDeviceMotionEvent *motion = (XDeviceMotionEvent *)event;
584
585         TRACE_(event)("Received tablet motion event (%p)\n",hwnd);
586         TRACE("Received tablet motion event (%p)\n",hwnd);
587         gMsgPacket.pkTime = motion->time;
588         gMsgPacket.pkSerialNumber = gSerial++;
589         gMsgPacket.pkCursor = motion->deviceid;
590         gMsgPacket.pkX = motion->axis_data[0];
591         gMsgPacket.pkY = motion->axis_data[1];
592         gMsgPacket.pkOrientation.orAzimuth =
593                     figure_deg(motion->axis_data[3],motion->axis_data[4]);
594         gMsgPacket.pkOrientation.orAltitude = 1000 - 15 * max
595                     (abs(motion->axis_data[3]),abs(motion->axis_data[4]));
596         gMsgPacket.pkNormalPressure = motion->axis_data[2];
597         gMsgPacket.pkButtons = get_button_state(motion->deviceid);
598         SendMessageW(hwndTabletDefault,WT_PACKET,0,(LPARAM)hwnd);
599     }
600     else if ((event->type == button_press_type)||(event->type ==
601               button_release_type))
602     {
603         XDeviceButtonEvent *button = (XDeviceButtonEvent *) event;
604
605         TRACE_(event)("Received tablet button event\n");
606         TRACE("Received tablet button %s event\n", (event->type ==
607                                 button_press_type)?"press":"release");
608
609         set_button_state(button->deviceid);
610     }
611     else if (event->type == key_press_type)
612     {
613         TRACE_(event)("Received tablet key press event\n");
614         FIXME("Received tablet key press event\n");
615     }
616     else if (event->type == key_release_type)
617     {
618         TRACE_(event)("Received tablet key release event\n");
619         FIXME("Received tablet key release event\n");
620     }
621     else if ((event->type == proximity_in_type) ||
622              (event->type == proximity_out_type))
623     {
624         TRACE_(event)("Received tablet proximity event\n");
625         TRACE("Received tablet proximity event\n");
626         gMsgPacket.pkStatus = (event->type==proximity_out_type)?TPS_PROXIMITY:0;
627         SendMessageW(hwndTabletDefault, WT_PROXIMITY,
628                      (event->type==proximity_out_type)?0:1, (LPARAM)hwnd);
629     }
630     else
631         return 0;
632
633     return 1;
634 }
635
636 int X11DRV_AttachEventQueueToTablet(HWND hOwner)
637 {
638     struct x11drv_thread_data *data = x11drv_thread_data();
639     int             num_devices;
640     int             loop;
641     int             cur_loop;
642     XDeviceInfo     *devices;
643     XDeviceInfo     *target = NULL;
644     XDevice         *the_device;
645     XInputClassInfo *ip;
646     XEventClass     event_list[7];
647     Window          win = X11DRV_get_whole_window( hOwner );
648
649     if (!win) return 0;
650
651     TRACE("Creating context for window %p (%lx)  %i cursors\n", hOwner, win, gNumCursors);
652
653     wine_tsx11_lock();
654     devices = pXListInputDevices(data->display, &num_devices);
655
656     for (cur_loop=0; cur_loop < gNumCursors; cur_loop++)
657     {
658         int    event_number=0;
659
660         for (loop=0; loop < num_devices; loop ++)
661             if (strcmp(devices[loop].name,gSysCursor[cur_loop].NAME)==0)
662                 target = &devices[loop];
663
664         TRACE("Opening cursor %i id %i\n",cur_loop,(INT)target->id);
665
666         the_device = pXOpenDevice(data->display, target->id);
667
668         if (!the_device)
669         {
670             WARN("Unable to Open device\n");
671             continue;
672         }
673
674         if (the_device->num_classes > 0)
675         {
676             for (ip = the_device->classes, loop=0; loop < target->num_classes;
677                  ip++, loop++)
678             {
679                 switch(ip->input_class)
680                 {
681                     case KeyClass:
682                         DeviceKeyPress(the_device, key_press_type,
683                                        event_list[event_number]);
684                         event_number++;
685                         DeviceKeyRelease(the_device, key_release_type,
686                                           event_list[event_number]);
687                         event_number++;
688                         break;
689                     case ButtonClass:
690                         DeviceButtonPress(the_device, button_press_type,
691                                        event_list[event_number]);
692                         event_number++;
693                         DeviceButtonRelease(the_device, button_release_type,
694                                             event_list[event_number]);
695                         event_number++;
696                         break;
697                     case ValuatorClass:
698                         DeviceMotionNotify(the_device, motion_type,
699                                            event_list[event_number]);
700                         event_number++;
701                         ProximityIn(the_device, proximity_in_type,
702                                  event_list[event_number]);
703                         event_number++;
704                         ProximityOut(the_device, proximity_out_type,
705                                      event_list[event_number]);
706                         event_number++;
707                         break;
708                     default:
709                         ERR("unknown class\n");
710                         break;
711                 }
712             }
713             if (pXSelectExtensionEvent(data->display, win, event_list, event_number))
714             {
715                 ERR( "error selecting extended events\n");
716                 goto end;
717             }
718         }
719     }
720
721 end:
722     wine_tsx11_unlock();
723     return 0;
724 }
725
726 int X11DRV_GetCurrentPacket(LPWTPACKET *packet)
727 {
728     memcpy(packet,&gMsgPacket,sizeof(WTPACKET));
729     return 1;
730 }
731
732
733 int static inline CopyTabletData(LPVOID target, LPVOID src, INT size)
734 {
735     memcpy(target,src,size);
736     return(size);
737 }
738
739 /***********************************************************************
740  *              X11DRV_WTInfoA (X11DRV.@)
741  */
742 UINT X11DRV_WTInfoA(UINT wCategory, UINT nIndex, LPVOID lpOutput)
743 {
744     int rc = 0;
745     LPWTI_CURSORS_INFO  tgtcursor;
746     TRACE("(%u, %u, %p)\n", wCategory, nIndex, lpOutput);
747
748     switch(wCategory)
749     {
750         case 0:
751             /* return largest necessary buffer */
752             TRACE("%i cursors\n",gNumCursors);
753             if (gNumCursors>0)
754             {
755                 FIXME("Return proper size\n");
756                 return 200;
757             }
758             else
759                 return 0;
760             break;
761         case WTI_INTERFACE:
762             switch (nIndex)
763             {
764                 WORD version;
765                 case IFC_WINTABID:
766                     strcpy(lpOutput,"Wine Wintab 1.1");
767                     rc = 16;
768                     break;
769                 case IFC_SPECVERSION:
770                     version = (0x01) | (0x01 << 8);
771                     rc = CopyTabletData(lpOutput, &version,sizeof(WORD));
772                     break;
773                 case IFC_IMPLVERSION:
774                     version = (0x00) | (0x01 << 8);
775                     rc = CopyTabletData(lpOutput, &version,sizeof(WORD));
776                     break;
777                 default:
778                     FIXME("WTI_INTERFACE unhandled index %i\n",nIndex);
779                     rc = 0;
780
781             }
782         case WTI_DEFSYSCTX:
783         case WTI_DDCTXS:
784         case WTI_DEFCONTEXT:
785             switch (nIndex)
786             {
787                 case 0:
788                     memcpy(lpOutput, &gSysContext,
789                             sizeof(LOGCONTEXTA));
790                     rc = sizeof(LOGCONTEXTA);
791                     break;
792                 case CTX_NAME:
793                     rc = CopyTabletData(lpOutput, &gSysContext.lcName,
794                          strlen(gSysContext.lcName)+1);
795                     break;
796                 case CTX_OPTIONS:
797                     rc = CopyTabletData(lpOutput, &gSysContext.lcOptions,
798                                         sizeof(UINT));
799                     break;
800                 case CTX_STATUS:
801                     rc = CopyTabletData(lpOutput, &gSysContext.lcStatus,
802                                         sizeof(UINT));
803                     break;
804                 case CTX_LOCKS:
805                     rc= CopyTabletData (lpOutput, &gSysContext.lcLocks,
806                                         sizeof(UINT));
807                     break;
808                 case CTX_MSGBASE:
809                     rc = CopyTabletData(lpOutput, &gSysContext.lcMsgBase,
810                                         sizeof(UINT));
811                     break;
812                 case CTX_DEVICE:
813                     rc = CopyTabletData(lpOutput, &gSysContext.lcDevice,
814                                         sizeof(UINT));
815                     break;
816                 case CTX_PKTRATE:
817                     rc = CopyTabletData(lpOutput, &gSysContext.lcPktRate,
818                                         sizeof(UINT));
819                     break;
820                 case CTX_PKTMODE:
821                     rc = CopyTabletData(lpOutput, &gSysContext.lcPktMode,
822                                         sizeof(WTPKT));
823                     break;
824                 case CTX_MOVEMASK:
825                     rc = CopyTabletData(lpOutput, &gSysContext.lcMoveMask,
826                                         sizeof(WTPKT));
827                     break;
828                 case CTX_BTNDNMASK:
829                     rc = CopyTabletData(lpOutput, &gSysContext.lcBtnDnMask,
830                                         sizeof(DWORD));
831                     break;
832                 case CTX_BTNUPMASK:
833                     rc = CopyTabletData(lpOutput, &gSysContext.lcBtnUpMask,
834                                         sizeof(DWORD));
835                     break;
836                 case CTX_INORGX:
837                     rc = CopyTabletData(lpOutput, &gSysContext.lcInOrgX,
838                                         sizeof(LONG));
839                     break;
840                 case CTX_INORGY:
841                     rc = CopyTabletData(lpOutput, &gSysContext.lcInOrgY,
842                                         sizeof(LONG));
843                     break;
844                 case CTX_INORGZ:
845                     rc = CopyTabletData(lpOutput, &gSysContext.lcInOrgZ,
846                                         sizeof(LONG));
847                     break;
848                 case CTX_INEXTX:
849                     rc = CopyTabletData(lpOutput, &gSysContext.lcInExtX,
850                                         sizeof(LONG));
851                     break;
852                 case CTX_INEXTY:
853                      rc = CopyTabletData(lpOutput, &gSysContext.lcInExtY,
854                                         sizeof(LONG));
855                     break;
856                 case CTX_INEXTZ:
857                      rc = CopyTabletData(lpOutput, &gSysContext.lcInExtZ,
858                                         sizeof(LONG));
859                     break;
860                 case CTX_OUTORGX:
861                      rc = CopyTabletData(lpOutput, &gSysContext.lcOutOrgX,
862                                         sizeof(LONG));
863                     break;
864                 case CTX_OUTORGY:
865                       rc = CopyTabletData(lpOutput, &gSysContext.lcOutOrgY,
866                                         sizeof(LONG));
867                     break;
868                 case CTX_OUTORGZ:
869                        rc = CopyTabletData(lpOutput, &gSysContext.lcOutOrgZ,
870                                         sizeof(LONG));
871                     break;
872                case CTX_OUTEXTX:
873                       rc = CopyTabletData(lpOutput, &gSysContext.lcOutExtX,
874                                         sizeof(LONG));
875                     break;
876                 case CTX_OUTEXTY:
877                        rc = CopyTabletData(lpOutput, &gSysContext.lcOutExtY,
878                                         sizeof(LONG));
879                     break;
880                 case CTX_OUTEXTZ:
881                        rc = CopyTabletData(lpOutput, &gSysContext.lcOutExtZ,
882                                         sizeof(LONG));
883                     break;
884                 case CTX_SENSX:
885                         rc = CopyTabletData(lpOutput, &gSysContext.lcSensX,
886                                         sizeof(LONG));
887                     break;
888                 case CTX_SENSY:
889                         rc = CopyTabletData(lpOutput, &gSysContext.lcSensY,
890                                         sizeof(LONG));
891                     break;
892                 case CTX_SENSZ:
893                         rc = CopyTabletData(lpOutput, &gSysContext.lcSensZ,
894                                         sizeof(LONG));
895                     break;
896                 case CTX_SYSMODE:
897                         rc = CopyTabletData(lpOutput, &gSysContext.lcSysMode,
898                                         sizeof(LONG));
899                     break;
900                 case CTX_SYSORGX:
901                         rc = CopyTabletData(lpOutput, &gSysContext.lcSysOrgX,
902                                         sizeof(LONG));
903                     break;
904                 case CTX_SYSORGY:
905                         rc = CopyTabletData(lpOutput, &gSysContext.lcSysOrgY,
906                                         sizeof(LONG));
907                     break;
908                 case CTX_SYSEXTX:
909                         rc = CopyTabletData(lpOutput, &gSysContext.lcSysExtX,
910                                         sizeof(LONG));
911                     break;
912                 case CTX_SYSEXTY:
913                         rc = CopyTabletData(lpOutput, &gSysContext.lcSysExtY,
914                                         sizeof(LONG));
915                     break;
916                 case CTX_SYSSENSX:
917                         rc = CopyTabletData(lpOutput, &gSysContext.lcSysSensX,
918                                         sizeof(LONG));
919                     break;
920                 case CTX_SYSSENSY:
921                        rc = CopyTabletData(lpOutput, &gSysContext.lcSysSensY,
922                                         sizeof(LONG));
923                     break;
924                 default:
925                     FIXME("WTI_DEFSYSCTX unhandled index %i\n",nIndex);
926                     rc = 0;
927             }
928             break;
929         case WTI_CURSORS:
930         case WTI_CURSORS+1:
931         case WTI_CURSORS+2:
932         case WTI_CURSORS+3:
933         case WTI_CURSORS+4:
934         case WTI_CURSORS+5:
935         case WTI_CURSORS+6:
936         case WTI_CURSORS+7:
937         case WTI_CURSORS+8:
938         case WTI_CURSORS+9:
939         case WTI_CURSORS+10:
940             tgtcursor = &gSysCursor[wCategory - WTI_CURSORS];
941             switch (nIndex)
942             {
943                 case CSR_NAME:
944                     rc = CopyTabletData(lpOutput, &tgtcursor->NAME,
945                                         strlen(tgtcursor->NAME)+1);
946                     break;
947                 case CSR_ACTIVE:
948                     rc = CopyTabletData(lpOutput,&tgtcursor->ACTIVE,
949                                         sizeof(BOOL));
950                     break;
951                 case CSR_PKTDATA:
952                     rc = CopyTabletData(lpOutput,&tgtcursor->PKTDATA,
953                                         sizeof(WTPKT));
954                     break;
955                 case CSR_BUTTONS:
956                     rc = CopyTabletData(lpOutput,&tgtcursor->BUTTONS,
957                                         sizeof(BYTE));
958                     break;
959                 case CSR_BUTTONBITS:
960                     rc = CopyTabletData(lpOutput,&tgtcursor->BUTTONBITS,
961                                         sizeof(BYTE));
962                     break;
963                 case CSR_BTNNAMES:
964                     FIXME("Button Names not returned correctly\n");
965                     rc = CopyTabletData(lpOutput,&tgtcursor->BTNNAMES,
966                                         strlen(tgtcursor->BTNNAMES)+1);
967                     break;
968                 case CSR_BUTTONMAP:
969                     rc = CopyTabletData(lpOutput,&tgtcursor->BUTTONMAP,
970                                         sizeof(BYTE)*32);
971                     break;
972                 case CSR_SYSBTNMAP:
973                     rc = CopyTabletData(lpOutput,&tgtcursor->SYSBTNMAP,
974                                         sizeof(BYTE)*32);
975                     break;
976                 case CSR_NPBTNMARKS:
977                     memcpy(lpOutput,&tgtcursor->NPBTNMARKS,sizeof(UINT)*2);
978                     rc = sizeof(UINT)*2;
979                     break;
980                 case CSR_NPBUTTON:
981                     rc = CopyTabletData(lpOutput,&tgtcursor->NPBUTTON,
982                                         sizeof(BYTE));
983                     break;
984                 case CSR_NPRESPONSE:
985                     FIXME("Not returning CSR_NPRESPONSE correctly\n");
986                     rc = 0;
987                     break;
988                 case CSR_TPBUTTON:
989                     rc = CopyTabletData(lpOutput,&tgtcursor->TPBUTTON,
990                                         sizeof(BYTE));
991                     break;
992                 case CSR_TPBTNMARKS:
993                     memcpy(lpOutput,&tgtcursor->TPBTNMARKS,sizeof(UINT)*2);
994                     rc = sizeof(UINT)*2;
995                     break;
996                 case CSR_TPRESPONSE:
997                     FIXME("Not returning CSR_TPRESPONSE correctly\n");
998                     rc = 0;
999                     break;
1000                 case CSR_PHYSID:
1001                 {
1002                     DWORD id;
1003                     rc = CopyTabletData(&id,&tgtcursor->PHYSID,
1004                                         sizeof(DWORD));
1005                     id += (wCategory - WTI_CURSORS);
1006                     memcpy(lpOutput,&id,sizeof(DWORD));
1007                 }
1008                     break;
1009                 case CSR_MODE:
1010                     rc = CopyTabletData(lpOutput,&tgtcursor->MODE,sizeof(UINT));
1011                     break;
1012                 case CSR_MINPKTDATA:
1013                     rc = CopyTabletData(lpOutput,&tgtcursor->MINPKTDATA,
1014                         sizeof(UINT));
1015                     break;
1016                 case CSR_MINBUTTONS:
1017                     rc = CopyTabletData(lpOutput,&tgtcursor->MINBUTTONS,
1018                         sizeof(UINT));
1019                     break;
1020                 case CSR_CAPABILITIES:
1021                     rc = CopyTabletData(lpOutput,&tgtcursor->CAPABILITIES,
1022                         sizeof(UINT));
1023                     break;
1024                 case CSR_TYPE:
1025                     rc = CopyTabletData(lpOutput,&tgtcursor->TYPE,
1026                         sizeof(UINT));
1027                     break;
1028                 default:
1029                     FIXME("WTI_CURSORS unhandled index %i\n",nIndex);
1030                     rc = 0;
1031             }
1032             break;
1033         case WTI_DEVICES:
1034             switch (nIndex)
1035             {
1036                 case DVC_NAME:
1037                     rc = CopyTabletData(lpOutput,gSysDevice.NAME,
1038                                         strlen(gSysDevice.NAME)+1);
1039                     break;
1040                 case DVC_HARDWARE:
1041                     rc = CopyTabletData(lpOutput,&gSysDevice.HARDWARE,
1042                                         sizeof(UINT));
1043                     break;
1044                 case DVC_NCSRTYPES:
1045                     rc = CopyTabletData(lpOutput,&gSysDevice.NCSRTYPES,
1046                                         sizeof(UINT));
1047                     break;
1048                 case DVC_FIRSTCSR:
1049                     rc = CopyTabletData(lpOutput,&gSysDevice.FIRSTCSR,
1050                                         sizeof(UINT));
1051                     break;
1052                 case DVC_PKTRATE:
1053                     rc = CopyTabletData(lpOutput,&gSysDevice.PKTRATE,
1054                                         sizeof(UINT));
1055                     break;
1056                 case DVC_PKTDATA:
1057                     rc = CopyTabletData(lpOutput,&gSysDevice.PKTDATA,
1058                                         sizeof(WTPKT));
1059                     break;
1060                 case DVC_PKTMODE:
1061                     rc = CopyTabletData(lpOutput,&gSysDevice.PKTMODE,
1062                                         sizeof(WTPKT));
1063                     break;
1064                 case DVC_CSRDATA:
1065                     rc = CopyTabletData(lpOutput,&gSysDevice.CSRDATA,
1066                                         sizeof(WTPKT));
1067                     break;
1068                 case DVC_XMARGIN:
1069                     rc = CopyTabletData(lpOutput,&gSysDevice.XMARGIN,
1070                                         sizeof(INT));
1071                     break;
1072                 case DVC_YMARGIN:
1073                     rc = CopyTabletData(lpOutput,&gSysDevice.YMARGIN,
1074                                         sizeof(INT));
1075                     break;
1076                 case DVC_ZMARGIN:
1077                     rc = 0; /* unsupported */
1078                     /*
1079                     rc = CopyTabletData(lpOutput,&gSysDevice.ZMARGIN,
1080                                         sizeof(INT));
1081                     */
1082                     break;
1083                 case DVC_X:
1084                     rc = CopyTabletData(lpOutput,&gSysDevice.X,
1085                                         sizeof(AXIS));
1086                     break;
1087                 case DVC_Y:
1088                     rc = CopyTabletData(lpOutput,&gSysDevice.Y,
1089                                         sizeof(AXIS));
1090                     break;
1091                 case DVC_Z:
1092                     rc = 0; /* unsupported */
1093                     /*
1094                     rc = CopyTabletData(lpOutput,&gSysDevice.Z,
1095                                         sizeof(AXIS));
1096                     */
1097                     break;
1098                 case DVC_NPRESSURE:
1099                     rc = CopyTabletData(lpOutput,&gSysDevice.NPRESSURE,
1100                                         sizeof(AXIS));
1101                     break;
1102                 case DVC_TPRESSURE:
1103                     rc = 0; /* unsupported */
1104                     /*
1105                     rc = CopyTabletData(lpOutput,&gSysDevice.TPRESSURE,
1106                                         sizeof(AXIS));
1107                     */
1108                     break;
1109                 case DVC_ORIENTATION:
1110                     memcpy(lpOutput,&gSysDevice.ORIENTATION,sizeof(AXIS)*3);
1111                     rc = sizeof(AXIS)*3;
1112                     break;
1113                 case DVC_ROTATION:
1114                     rc = 0; /* unsupported */
1115                     /*
1116                     memcpy(lpOutput,&gSysDevice.ROTATION,sizeof(AXIS)*3);
1117                     rc = sizeof(AXIS)*3;
1118                     */
1119                     break;
1120                 case DVC_PNPID:
1121                     rc = CopyTabletData(lpOutput,gSysDevice.PNPID,
1122                                         strlen(gSysDevice.PNPID)+1);
1123                     break;
1124                 default:
1125                     FIXME("WTI_DEVICES unhandled index %i\n",nIndex);
1126                     rc = 0;
1127             }
1128             break;
1129         default:
1130             FIXME("Unhandled Category %i\n",wCategory);
1131     }
1132     return rc;
1133 }
1134
1135 #else /* HAVE_X11_EXTENSIONS_XINPUT_H */
1136
1137 int X11DRV_ProcessTabletEvent(HWND hwnd, XEvent *event)
1138 {
1139     return 0;
1140 }
1141
1142 int X11DRV_AttachEventQueueToTablet(HWND hOwner)
1143 {
1144     return 0;
1145 }
1146
1147 int X11DRV_GetCurrentPacket(LPWTPACKET *packet)
1148 {
1149     return 0;
1150 }
1151
1152 void X11DRV_LoadTabletInfo(HWND hwnddefault)
1153 {
1154 }
1155
1156 UINT X11DRV_WTInfoA(UINT wCategory, UINT nIndex, LPVOID lpOutput)
1157 {
1158     return 0;
1159 }
1160
1161 #endif /* HAVE_X11_EXTENSIONS_XINPUT_H */