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