Don't leak a list of visuals (with advice of Jacek Caban).
[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;
223 static int           button_press_type;
224 static int           button_release_type;
225 static int           key_press_type;
226 static int           key_release_type;
227 static int           proximity_in_type;
228 static int           proximity_out_type;
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(XFreeDeviceList)
253 MAKE_FUNCPTR(XOpenDevice)
254 MAKE_FUNCPTR(XQueryDeviceState)
255 MAKE_FUNCPTR(XGetDeviceButtonMapping)
256 MAKE_FUNCPTR(XCloseDevice)
257 MAKE_FUNCPTR(XSelectExtensionEvent)
258 MAKE_FUNCPTR(XFreeDeviceState)
259 #undef MAKE_FUNCPTR
260
261 static INT X11DRV_XInput_Init(void)
262 {
263     xinput_handle = wine_dlopen(SONAME_LIBXI, RTLD_NOW, NULL, 0);
264     if (xinput_handle)
265     {
266 #define LOAD_FUNCPTR(f) if((p##f = wine_dlsym(xinput_handle, #f, NULL, 0)) == NULL) goto sym_not_found;
267         LOAD_FUNCPTR(XListInputDevices)
268         LOAD_FUNCPTR(XFreeDeviceList)
269         LOAD_FUNCPTR(XOpenDevice)
270         LOAD_FUNCPTR(XGetDeviceButtonMapping)
271         LOAD_FUNCPTR(XCloseDevice)
272         LOAD_FUNCPTR(XSelectExtensionEvent)
273         LOAD_FUNCPTR(XQueryDeviceState)
274         LOAD_FUNCPTR(XFreeDeviceState)
275 #undef LOAD_FUNCPTR
276         return 1;
277     }
278 sym_not_found:
279     return 0;
280 }
281
282 static int Tablet_ErrorHandler(Display *dpy, XErrorEvent *event, void* arg)
283 {
284     return 1;
285 }
286
287 void X11DRV_LoadTabletInfo(HWND hwnddefault)
288 {
289     struct x11drv_thread_data *data = x11drv_thread_data();
290     int num_devices;
291     int loop;
292     int cursor_target;
293     XDeviceInfo *devices;
294     XDeviceInfo *target = NULL;
295     BOOL    axis_read_complete= FALSE;
296
297     XAnyClassPtr        any;
298     XButtonInfoPtr      Button;
299     XValuatorInfoPtr    Val;
300     XAxisInfoPtr        Axis;
301
302     XDevice *opendevice;
303
304     if (!X11DRV_XInput_Init())
305     {
306         ERR("Unable to initialized the XInput library.\n");
307         return;
308     }
309
310     hwndTabletDefault = hwnddefault;
311
312     /* Do base initializaion */
313     strcpy(gSysContext.lcName, "Wine Tablet Context");
314     strcpy(gSysDevice.NAME,"Wine Tablet Device");
315
316     gSysContext.lcOptions = CXO_SYSTEM;
317     gSysContext.lcLocks = CXL_INSIZE | CXL_INASPECT | CXL_MARGIN |
318                                CXL_SENSITIVITY | CXL_SYSOUT;
319
320     gSysContext.lcMsgBase= WT_DEFBASE;
321     gSysContext.lcDevice = 0;
322     gSysContext.lcPktData =
323         PK_CONTEXT | PK_STATUS | PK_SERIAL_NUMBER| PK_TIME | PK_CURSOR |
324         PK_BUTTONS |  PK_X | PK_Y | PK_NORMAL_PRESSURE | PK_ORIENTATION;
325     gSysContext.lcMoveMask=
326         PK_BUTTONS |  PK_X | PK_Y | PK_NORMAL_PRESSURE | PK_ORIENTATION;
327     gSysContext.lcStatus = CXS_ONTOP;
328     gSysContext.lcPktRate = 100;
329     gSysContext.lcBtnDnMask = 0xffffffff;
330     gSysContext.lcBtnUpMask = 0xffffffff;
331     gSysContext.lcSensX = 65536;
332     gSysContext.lcSensY = 65536;
333     gSysContext.lcSensX = 65536;
334     gSysContext.lcSensZ = 65536;
335     gSysContext.lcSysSensX= 65536;
336     gSysContext.lcSysSensY= 65536;
337
338     /* Device Defaults */
339     gSysDevice.HARDWARE = HWC_HARDPROX|HWC_PHYSID_CURSORS;
340     gSysDevice.FIRSTCSR= 0;
341     gSysDevice.PKTRATE = 100;
342     gSysDevice.PKTDATA =
343         PK_CONTEXT | PK_STATUS | PK_SERIAL_NUMBER| PK_TIME | PK_CURSOR |
344         PK_BUTTONS |  PK_X | PK_Y | PK_NORMAL_PRESSURE | PK_ORIENTATION;
345     strcpy(gSysDevice.PNPID,"non-pluginplay");
346
347     wine_tsx11_lock();
348
349     cursor_target = -1;
350     devices = pXListInputDevices(data->display, &num_devices);
351     if (!devices)
352     {
353         WARN("XInput Extenstions reported as not avalable\n");
354         wine_tsx11_unlock();
355         return;
356     }
357     for (loop=0; loop < num_devices; loop++)
358     {
359         int class_loop;
360
361         TRACE("Trying device %i(%s)\n",loop,devices[loop].name);
362         if (devices[loop].use == IsXExtensionDevice)
363         {
364             LPWTI_CURSORS_INFO cursor;
365
366             TRACE("Is Extension Device\n");
367             cursor_target++;
368             target = &devices[loop];
369             cursor = &gSysCursor[cursor_target];
370
371             opendevice = pXOpenDevice(data->display,target->id);
372             if (opendevice)
373             {
374                 unsigned char map[32];
375                 int i;
376                 int shft = 0;
377
378                 X11DRV_expect_error(data->display,Tablet_ErrorHandler,NULL);
379                 pXGetDeviceButtonMapping(data->display, opendevice, map, 32);
380                 if (X11DRV_check_error())
381                 {
382                     TRACE("No buttons, Non Tablet Device\n");
383                     pXCloseDevice(data->display, opendevice);
384                     cursor_target --;
385                     continue;
386                 }
387
388                 for (i=0; i< cursor->BUTTONS; i++,shft++)
389                 {
390                     cursor->BUTTONMAP[i] = map[i];
391                     cursor->SYSBTNMAP[i] = (1<<shft);
392                 }
393                 pXCloseDevice(data->display, opendevice);
394             }
395             else
396             {
397                 WARN("Unable to open device %s\n",target->name);
398                 cursor_target --;
399                 continue;
400             }
401
402             strcpy(cursor->NAME,target->name);
403
404             cursor->ACTIVE = 1;
405             cursor->PKTDATA = PK_TIME | PK_CURSOR | PK_BUTTONS |  PK_X | PK_Y |
406                               PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE |
407                               PK_ORIENTATION;
408
409             cursor->PHYSID = cursor_target;
410             cursor->NPBUTTON = 1;
411             cursor->NPBTNMARKS[0] = 0 ;
412             cursor->NPBTNMARKS[1] = 1 ;
413             cursor->CAPABILITIES = CRC_MULTIMODE;
414             if (strcasecmp(cursor->NAME,"stylus")==0)
415                 cursor->TYPE = 0x4825;
416             if (strcasecmp(cursor->NAME,"eraser")==0)
417                 cursor->TYPE = 0xc85a;
418
419
420             any = (XAnyClassPtr) (target->inputclassinfo);
421
422             for (class_loop = 0; class_loop < target->num_classes; class_loop++)
423             {
424                 switch (any->class)
425                 {
426                     case ValuatorClass:
427                         if (!axis_read_complete)
428                         {
429                             Val = (XValuatorInfoPtr) any;
430                             Axis = (XAxisInfoPtr) ((char *) Val + sizeof
431                                 (XValuatorInfo));
432
433                             if (Val->num_axes>=1)
434                             {
435                                 /* Axis 1 is X */
436                                 gSysDevice.X.axMin = Axis->min_value;
437                                 gSysDevice.X.axMax= Axis->max_value;
438                                 gSysDevice.X.axUnits = TU_INCHES;
439                                 gSysDevice.X.axResolution = Axis->resolution;
440                                 gSysContext.lcInOrgX = Axis->min_value;
441                                 gSysContext.lcSysOrgX = Axis->min_value;
442                                 gSysContext.lcInExtX = Axis->max_value;
443                                 gSysContext.lcSysExtX = Axis->max_value;
444                                 Axis++;
445                             }
446                             if (Val->num_axes>=2)
447                             {
448                                 /* Axis 2 is Y */
449                                 gSysDevice.Y.axMin = Axis->min_value;
450                                 gSysDevice.Y.axMax= Axis->max_value;
451                                 gSysDevice.Y.axUnits = TU_INCHES;
452                                 gSysDevice.Y.axResolution = Axis->resolution;
453                                 gSysContext.lcInOrgY = Axis->min_value;
454                                 gSysContext.lcSysOrgY = Axis->min_value;
455                                 gSysContext.lcInExtY = Axis->max_value;
456                                 gSysContext.lcSysExtY = Axis->max_value;
457                                 Axis++;
458                             }
459                             if (Val->num_axes>=3)
460                             {
461                                 /* Axis 3 is Normal Pressure */
462                                 gSysDevice.NPRESSURE.axMin = Axis->min_value;
463                                 gSysDevice.NPRESSURE.axMax= Axis->max_value;
464                                 gSysDevice.NPRESSURE.axUnits = TU_INCHES;
465                                 gSysDevice.NPRESSURE.axResolution =
466                                                         Axis->resolution;
467                                 Axis++;
468                             }
469                             if (Val->num_axes >= 5)
470                             {
471                                 /* Axis 4 and 5 are X and Y tilt */
472                                 XAxisInfoPtr        XAxis = Axis;
473                                 Axis++;
474                                 if (max (abs(Axis->max_value),
475                                          abs(XAxis->max_value)))
476                                 {
477                                     gSysDevice.ORIENTATION[0].axMin = 0;
478                                     gSysDevice.ORIENTATION[0].axMax = 3600;
479                                     gSysDevice.ORIENTATION[0].axUnits = TU_CIRCLE;
480                                     gSysDevice.ORIENTATION[0].axResolution
481                                                                 = CASTFIX32(3600);
482                                     gSysDevice.ORIENTATION[1].axMin = -1000;
483                                     gSysDevice.ORIENTATION[1].axMax = 1000;
484                                     gSysDevice.ORIENTATION[1].axUnits = TU_CIRCLE;
485                                     gSysDevice.ORIENTATION[1].axResolution
486                                                                 = CASTFIX32(3600);
487                                     Axis++;
488                                 }
489                             }
490                             axis_read_complete = TRUE;
491                         }
492                         break;
493                     case ButtonClass:
494                     {
495                         CHAR *ptr = cursor->BTNNAMES;
496                         int i;
497
498                         Button = (XButtonInfoPtr) any;
499                         cursor->BUTTONS = Button->num_buttons;
500                         for (i = 0; i < cursor->BUTTONS; i++)
501                         {
502                             strcpy(ptr,cursor->NAME);
503                             ptr+=8;
504                         }
505                     }
506                     break;
507                 }
508                 any = (XAnyClassPtr) ((char*) any + any->length);
509             }
510         }
511     }
512     pXFreeDeviceList(devices);
513     wine_tsx11_unlock();
514     gSysDevice.NCSRTYPES = cursor_target+1;
515     gNumCursors = cursor_target+1;
516 }
517
518 static int figure_deg(int x, int y)
519 {
520     int rc;
521
522     if (y != 0)
523     {
524         rc = (int) 10 * (atan( (FLOAT)abs(y) / (FLOAT)abs(x)) / (3.1415 / 180));
525         if (y>0)
526         {
527             if (x>0)
528                 rc += 900;
529             else
530                 rc = 2700 - rc;
531         }
532         else
533         {
534             if (x>0)
535                 rc = 900 - rc;
536             else
537                 rc += 2700;
538         }
539     }
540     else
541     {
542         if (x >= 0)
543             rc = 900;
544         else
545             rc = 2700;
546     }
547
548     return rc;
549 }
550
551 static int get_button_state(int deviceid)
552 {
553     return button_state[deviceid];
554 }
555
556 static void set_button_state(XID deviceid)
557 {
558     struct x11drv_thread_data *data = x11drv_thread_data();
559     XDevice *device;
560     XDeviceState *state;
561     XInputClass  *class;
562     int loop;
563     int rc = 0;
564
565     wine_tsx11_lock();
566     device = pXOpenDevice(data->display,deviceid);
567     state = pXQueryDeviceState(data->display,device);
568
569     if (state)
570     {
571         class = state->data;
572         for (loop = 0; loop < state->num_classes; loop++)
573         {
574             if (class->class == ButtonClass)
575             {
576                 int loop2;
577                 XButtonState *button_state =  (XButtonState*)class;
578                 for (loop2 = 1; loop2 <= button_state->num_buttons; loop2++)
579                 {
580                     if (button_state->buttons[loop2 / 8] & (1 << (loop2 % 8)))
581                     {
582                         rc |= (1<<(loop2-1));
583                     }
584                 }
585             }
586             class = (XInputClass *) ((char *) class + class->length);
587         }
588     }
589     pXFreeDeviceState(state);
590     wine_tsx11_unlock();
591     button_state[deviceid] = rc;
592 }
593
594 static void motion_event( HWND hwnd, XEvent *event )
595 {
596     XDeviceMotionEvent *motion = (XDeviceMotionEvent *)event;
597     LPWTI_CURSORS_INFO cursor = &gSysCursor[motion->deviceid];
598
599     memset(&gMsgPacket,0,sizeof(WTPACKET));
600
601     TRACE("Received tablet motion event (%p)\n",hwnd);
602
603     /* Set cursor to inverted if cursor is the eraser */
604     gMsgPacket.pkStatus = (cursor->TYPE == 0xc85a ?TPS_INVERT:0);
605     gMsgPacket.pkTime = EVENT_x11_time_to_win32_time(motion->time);
606     gMsgPacket.pkSerialNumber = gSerial++;
607     gMsgPacket.pkCursor = motion->deviceid;
608     gMsgPacket.pkX = motion->axis_data[0];
609     gMsgPacket.pkY = motion->axis_data[1];
610     gMsgPacket.pkOrientation.orAzimuth = figure_deg(motion->axis_data[3],motion->axis_data[4]);
611     gMsgPacket.pkOrientation.orAltitude = ((1000 - 15 * max
612                                             (abs(motion->axis_data[3]),
613                                              abs(motion->axis_data[4])))
614                                            * (gMsgPacket.pkStatus & TPS_INVERT?-1:1));
615     gMsgPacket.pkNormalPressure = motion->axis_data[2];
616     gMsgPacket.pkButtons = get_button_state(motion->deviceid);
617     SendMessageW(hwndTabletDefault,WT_PACKET,0,(LPARAM)hwnd);
618 }
619
620 static void button_event( HWND hwnd, XEvent *event )
621 {
622     XDeviceButtonEvent *button = (XDeviceButtonEvent *) event;
623     LPWTI_CURSORS_INFO cursor = &gSysCursor[button->deviceid];
624
625     memset(&gMsgPacket,0,sizeof(WTPACKET));
626
627     TRACE("Received tablet button %s event\n", (event->type == button_press_type)?"press":"release");
628
629     /* Set cursor to inverted if cursor is the eraser */
630     gMsgPacket.pkStatus = (cursor->TYPE == 0xc85a ?TPS_INVERT:0);
631     set_button_state(button->deviceid);
632     gMsgPacket.pkTime = EVENT_x11_time_to_win32_time(button->time);
633     gMsgPacket.pkSerialNumber = gSerial++;
634     gMsgPacket.pkCursor = button->deviceid;
635     gMsgPacket.pkX = button->axis_data[0];
636     gMsgPacket.pkY = button->axis_data[1];
637     gMsgPacket.pkOrientation.orAzimuth = figure_deg(button->axis_data[3],button->axis_data[4]);
638     gMsgPacket.pkOrientation.orAltitude = ((1000 - 15 * max(abs(button->axis_data[3]),
639                                                             abs(button->axis_data[4])))
640                                            * (gMsgPacket.pkStatus & TPS_INVERT?-1:1));
641     gMsgPacket.pkNormalPressure = button->axis_data[2];
642     gMsgPacket.pkButtons = get_button_state(button->deviceid);
643     SendMessageW(hwndTabletDefault,WT_PACKET,0,(LPARAM)hwnd);
644 }
645
646 static void key_event( HWND hwnd, XEvent *event )
647 {
648     if (event->type == key_press_type)
649         FIXME("Received tablet key press event\n");
650     else
651         FIXME("Received tablet key release event\n");
652 }
653
654 static void proximity_event( HWND hwnd, XEvent *event )
655 {
656     XProximityNotifyEvent *proximity = (XProximityNotifyEvent *) event;
657     LPWTI_CURSORS_INFO cursor = &gSysCursor[proximity->deviceid];
658
659     memset(&gMsgPacket,0,sizeof(WTPACKET));
660
661     TRACE("Received tablet proximity event\n");
662     /* Set cursor to inverted if cursor is the eraser */
663     gMsgPacket.pkStatus = (cursor->TYPE == 0xc85a ?TPS_INVERT:0);
664     gMsgPacket.pkStatus |= (event->type==proximity_out_type)?TPS_PROXIMITY:0;
665     gMsgPacket.pkTime = EVENT_x11_time_to_win32_time(proximity->time);
666     gMsgPacket.pkSerialNumber = gSerial++;
667     gMsgPacket.pkCursor = proximity->deviceid;
668     gMsgPacket.pkX = proximity->axis_data[0];
669     gMsgPacket.pkY = proximity->axis_data[1];
670     gMsgPacket.pkOrientation.orAzimuth = figure_deg(proximity->axis_data[3],proximity->axis_data[4]);
671     gMsgPacket.pkOrientation.orAltitude = ((1000 - 15 * max(abs(proximity->axis_data[3]),
672                                                             abs(proximity->axis_data[4])))
673                                            * (gMsgPacket.pkStatus & TPS_INVERT?-1:1));
674     gMsgPacket.pkNormalPressure = proximity->axis_data[2];
675     gMsgPacket.pkButtons = get_button_state(proximity->deviceid);
676
677     SendMessageW(hwndTabletDefault, WT_PROXIMITY, (event->type == proximity_in_type), (LPARAM)hwnd);
678 }
679
680 int X11DRV_AttachEventQueueToTablet(HWND hOwner)
681 {
682     struct x11drv_thread_data *data = x11drv_thread_data();
683     int             num_devices;
684     int             loop;
685     int             cur_loop;
686     XDeviceInfo     *devices;
687     XDeviceInfo     *target = NULL;
688     XDevice         *the_device;
689     XEventClass     event_list[7];
690     Window          win = X11DRV_get_whole_window( hOwner );
691
692     if (!win) return 0;
693
694     TRACE("Creating context for window %p (%lx)  %i cursors\n", hOwner, win, gNumCursors);
695
696     wine_tsx11_lock();
697     devices = pXListInputDevices(data->display, &num_devices);
698
699     X11DRV_expect_error(data->display,Tablet_ErrorHandler,NULL);
700     for (cur_loop=0; cur_loop < gNumCursors; cur_loop++)
701     {
702         int    event_number=0;
703
704         for (loop=0; loop < num_devices; loop ++)
705             if (strcmp(devices[loop].name,gSysCursor[cur_loop].NAME)==0)
706                 target = &devices[loop];
707
708         TRACE("Opening cursor %i id %i\n",cur_loop,(INT)target->id);
709
710         the_device = pXOpenDevice(data->display, target->id);
711
712         if (!the_device)
713         {
714             WARN("Unable to Open device\n");
715             continue;
716         }
717
718         if (the_device->num_classes > 0)
719         {
720             DeviceKeyPress(the_device, key_press_type, event_list[event_number]);
721             if (event_list[event_number]) event_number++;
722             DeviceKeyRelease(the_device, key_release_type, event_list[event_number]);
723             if (event_list[event_number]) event_number++;
724             DeviceButtonPress(the_device, button_press_type, event_list[event_number]);
725             if (event_list[event_number]) event_number++;
726             DeviceButtonRelease(the_device, button_release_type, event_list[event_number]);
727             if (event_list[event_number]) event_number++;
728             DeviceMotionNotify(the_device, motion_type, event_list[event_number]);
729             if (event_list[event_number]) event_number++;
730             ProximityIn(the_device, proximity_in_type, event_list[event_number]);
731             if (event_list[event_number]) event_number++;
732             ProximityOut(the_device, proximity_out_type, event_list[event_number]);
733             if (event_list[event_number]) event_number++;
734
735             if (key_press_type) X11DRV_register_event_handler( key_press_type, key_event );
736             if (key_release_type) X11DRV_register_event_handler( key_release_type, key_event );
737             if (button_press_type) X11DRV_register_event_handler( button_press_type, button_event );
738             if (button_release_type) X11DRV_register_event_handler( button_release_type, button_event );
739             if (motion_type) X11DRV_register_event_handler( motion_type, motion_event );
740             if (proximity_in_type) X11DRV_register_event_handler( proximity_in_type, proximity_event );
741             if (proximity_out_type) X11DRV_register_event_handler( proximity_out_type, proximity_event );
742
743             pXSelectExtensionEvent(data->display, win, event_list, event_number);
744         }
745     }
746     XSync(data->display, False);
747     X11DRV_check_error();
748
749     if (NULL != devices) pXFreeDeviceList(devices);
750     wine_tsx11_unlock();
751     return 0;
752 }
753
754 int X11DRV_GetCurrentPacket(LPWTPACKET *packet)
755 {
756     memcpy(packet,&gMsgPacket,sizeof(WTPACKET));
757     return 1;
758 }
759
760
761 int static inline CopyTabletData(LPVOID target, LPVOID src, INT size)
762 {
763     /*
764      * It is valid to call CopyTabletData with NULL.
765      * This handles the WTInfo() case where lpOutput is null.
766      */
767     if(target != NULL)
768         memcpy(target,src,size);
769     return(size);
770 }
771
772 /***********************************************************************
773  *              X11DRV_WTInfoA (X11DRV.@)
774  */
775 UINT X11DRV_WTInfoA(UINT wCategory, UINT nIndex, LPVOID lpOutput)
776 {
777     /*
778      * It is valid to call WTInfoA with lpOutput == NULL, as per standard.
779      * lpOutput == NULL signifies the user only wishes
780      * to find the size of the data.
781      * NOTE:
782      * From now on use CopyTabletData to fill lpOutput. memcpy will break
783      * the code.
784      */
785     int rc = 0;
786     LPWTI_CURSORS_INFO  tgtcursor;
787     TRACE("(%u, %u, %p)\n", wCategory, nIndex, lpOutput);
788
789     switch(wCategory)
790     {
791         case 0:
792             /* return largest necessary buffer */
793             TRACE("%i cursors\n",gNumCursors);
794             if (gNumCursors>0)
795             {
796                 FIXME("Return proper size\n");
797                 rc = 200;
798             }
799             break;
800         case WTI_INTERFACE:
801             switch (nIndex)
802             {
803                 WORD version;
804                 case IFC_WINTABID:
805                     strcpy(lpOutput,"Wine Wintab 1.1");
806                     rc = 16;
807                     break;
808                 case IFC_SPECVERSION:
809                     version = (0x01) | (0x01 << 8);
810                     rc = CopyTabletData(lpOutput, &version,sizeof(WORD));
811                     break;
812                 case IFC_IMPLVERSION:
813                     version = (0x00) | (0x01 << 8);
814                     rc = CopyTabletData(lpOutput, &version,sizeof(WORD));
815                     break;
816                 default:
817                     FIXME("WTI_INTERFACE unhandled index %i\n",nIndex);
818                     rc = 0;
819
820             }
821         case WTI_DEFSYSCTX:
822         case WTI_DDCTXS:
823         case WTI_DEFCONTEXT:
824             switch (nIndex)
825             {
826                 case 0:
827                     rc = CopyTabletData(lpOutput, &gSysContext,
828                             sizeof(LOGCONTEXTA));
829                     break;
830                 case CTX_NAME:
831                     rc = CopyTabletData(lpOutput, &gSysContext.lcName,
832                          strlen(gSysContext.lcName)+1);
833                     break;
834                 case CTX_OPTIONS:
835                     rc = CopyTabletData(lpOutput, &gSysContext.lcOptions,
836                                         sizeof(UINT));
837                     break;
838                 case CTX_STATUS:
839                     rc = CopyTabletData(lpOutput, &gSysContext.lcStatus,
840                                         sizeof(UINT));
841                     break;
842                 case CTX_LOCKS:
843                     rc= CopyTabletData (lpOutput, &gSysContext.lcLocks,
844                                         sizeof(UINT));
845                     break;
846                 case CTX_MSGBASE:
847                     rc = CopyTabletData(lpOutput, &gSysContext.lcMsgBase,
848                                         sizeof(UINT));
849                     break;
850                 case CTX_DEVICE:
851                     rc = CopyTabletData(lpOutput, &gSysContext.lcDevice,
852                                         sizeof(UINT));
853                     break;
854                 case CTX_PKTRATE:
855                     rc = CopyTabletData(lpOutput, &gSysContext.lcPktRate,
856                                         sizeof(UINT));
857                     break;
858                 case CTX_PKTMODE:
859                     rc = CopyTabletData(lpOutput, &gSysContext.lcPktMode,
860                                         sizeof(WTPKT));
861                     break;
862                 case CTX_MOVEMASK:
863                     rc = CopyTabletData(lpOutput, &gSysContext.lcMoveMask,
864                                         sizeof(WTPKT));
865                     break;
866                 case CTX_BTNDNMASK:
867                     rc = CopyTabletData(lpOutput, &gSysContext.lcBtnDnMask,
868                                         sizeof(DWORD));
869                     break;
870                 case CTX_BTNUPMASK:
871                     rc = CopyTabletData(lpOutput, &gSysContext.lcBtnUpMask,
872                                         sizeof(DWORD));
873                     break;
874                 case CTX_INORGX:
875                     rc = CopyTabletData(lpOutput, &gSysContext.lcInOrgX,
876                                         sizeof(LONG));
877                     break;
878                 case CTX_INORGY:
879                     rc = CopyTabletData(lpOutput, &gSysContext.lcInOrgY,
880                                         sizeof(LONG));
881                     break;
882                 case CTX_INORGZ:
883                     rc = CopyTabletData(lpOutput, &gSysContext.lcInOrgZ,
884                                         sizeof(LONG));
885                     break;
886                 case CTX_INEXTX:
887                     rc = CopyTabletData(lpOutput, &gSysContext.lcInExtX,
888                                         sizeof(LONG));
889                     break;
890                 case CTX_INEXTY:
891                      rc = CopyTabletData(lpOutput, &gSysContext.lcInExtY,
892                                         sizeof(LONG));
893                     break;
894                 case CTX_INEXTZ:
895                      rc = CopyTabletData(lpOutput, &gSysContext.lcInExtZ,
896                                         sizeof(LONG));
897                     break;
898                 case CTX_OUTORGX:
899                      rc = CopyTabletData(lpOutput, &gSysContext.lcOutOrgX,
900                                         sizeof(LONG));
901                     break;
902                 case CTX_OUTORGY:
903                       rc = CopyTabletData(lpOutput, &gSysContext.lcOutOrgY,
904                                         sizeof(LONG));
905                     break;
906                 case CTX_OUTORGZ:
907                        rc = CopyTabletData(lpOutput, &gSysContext.lcOutOrgZ,
908                                         sizeof(LONG));
909                     break;
910                case CTX_OUTEXTX:
911                       rc = CopyTabletData(lpOutput, &gSysContext.lcOutExtX,
912                                         sizeof(LONG));
913                     break;
914                 case CTX_OUTEXTY:
915                        rc = CopyTabletData(lpOutput, &gSysContext.lcOutExtY,
916                                         sizeof(LONG));
917                     break;
918                 case CTX_OUTEXTZ:
919                        rc = CopyTabletData(lpOutput, &gSysContext.lcOutExtZ,
920                                         sizeof(LONG));
921                     break;
922                 case CTX_SENSX:
923                         rc = CopyTabletData(lpOutput, &gSysContext.lcSensX,
924                                         sizeof(LONG));
925                     break;
926                 case CTX_SENSY:
927                         rc = CopyTabletData(lpOutput, &gSysContext.lcSensY,
928                                         sizeof(LONG));
929                     break;
930                 case CTX_SENSZ:
931                         rc = CopyTabletData(lpOutput, &gSysContext.lcSensZ,
932                                         sizeof(LONG));
933                     break;
934                 case CTX_SYSMODE:
935                         rc = CopyTabletData(lpOutput, &gSysContext.lcSysMode,
936                                         sizeof(LONG));
937                     break;
938                 case CTX_SYSORGX:
939                         rc = CopyTabletData(lpOutput, &gSysContext.lcSysOrgX,
940                                         sizeof(LONG));
941                     break;
942                 case CTX_SYSORGY:
943                         rc = CopyTabletData(lpOutput, &gSysContext.lcSysOrgY,
944                                         sizeof(LONG));
945                     break;
946                 case CTX_SYSEXTX:
947                         rc = CopyTabletData(lpOutput, &gSysContext.lcSysExtX,
948                                         sizeof(LONG));
949                     break;
950                 case CTX_SYSEXTY:
951                         rc = CopyTabletData(lpOutput, &gSysContext.lcSysExtY,
952                                         sizeof(LONG));
953                     break;
954                 case CTX_SYSSENSX:
955                         rc = CopyTabletData(lpOutput, &gSysContext.lcSysSensX,
956                                         sizeof(LONG));
957                     break;
958                 case CTX_SYSSENSY:
959                        rc = CopyTabletData(lpOutput, &gSysContext.lcSysSensY,
960                                         sizeof(LONG));
961                     break;
962                 default:
963                     FIXME("WTI_DEFSYSCTX unhandled index %i\n",nIndex);
964                     rc = 0;
965             }
966             break;
967         case WTI_CURSORS:
968         case WTI_CURSORS+1:
969         case WTI_CURSORS+2:
970         case WTI_CURSORS+3:
971         case WTI_CURSORS+4:
972         case WTI_CURSORS+5:
973         case WTI_CURSORS+6:
974         case WTI_CURSORS+7:
975         case WTI_CURSORS+8:
976         case WTI_CURSORS+9:
977         case WTI_CURSORS+10:
978             tgtcursor = &gSysCursor[wCategory - WTI_CURSORS];
979             switch (nIndex)
980             {
981                 case CSR_NAME:
982                     rc = CopyTabletData(lpOutput, &tgtcursor->NAME,
983                                         strlen(tgtcursor->NAME)+1);
984                     break;
985                 case CSR_ACTIVE:
986                     rc = CopyTabletData(lpOutput,&tgtcursor->ACTIVE,
987                                         sizeof(BOOL));
988                     break;
989                 case CSR_PKTDATA:
990                     rc = CopyTabletData(lpOutput,&tgtcursor->PKTDATA,
991                                         sizeof(WTPKT));
992                     break;
993                 case CSR_BUTTONS:
994                     rc = CopyTabletData(lpOutput,&tgtcursor->BUTTONS,
995                                         sizeof(BYTE));
996                     break;
997                 case CSR_BUTTONBITS:
998                     rc = CopyTabletData(lpOutput,&tgtcursor->BUTTONBITS,
999                                         sizeof(BYTE));
1000                     break;
1001                 case CSR_BTNNAMES:
1002                     FIXME("Button Names not returned correctly\n");
1003                     rc = CopyTabletData(lpOutput,&tgtcursor->BTNNAMES,
1004                                         strlen(tgtcursor->BTNNAMES)+1);
1005                     break;
1006                 case CSR_BUTTONMAP:
1007                     rc = CopyTabletData(lpOutput,&tgtcursor->BUTTONMAP,
1008                                         sizeof(BYTE)*32);
1009                     break;
1010                 case CSR_SYSBTNMAP:
1011                     rc = CopyTabletData(lpOutput,&tgtcursor->SYSBTNMAP,
1012                                         sizeof(BYTE)*32);
1013                     break;
1014                 case CSR_NPBTNMARKS:
1015                     rc = CopyTabletData(lpOutput,&tgtcursor->NPBTNMARKS,
1016                                         sizeof(UINT)*2);
1017                     break;
1018                 case CSR_NPBUTTON:
1019                     rc = CopyTabletData(lpOutput,&tgtcursor->NPBUTTON,
1020                                         sizeof(BYTE));
1021                     break;
1022                 case CSR_NPRESPONSE:
1023                     FIXME("Not returning CSR_NPRESPONSE correctly\n");
1024                     rc = 0;
1025                     break;
1026                 case CSR_TPBUTTON:
1027                     rc = CopyTabletData(lpOutput,&tgtcursor->TPBUTTON,
1028                                         sizeof(BYTE));
1029                     break;
1030                 case CSR_TPBTNMARKS:
1031                     rc = CopyTabletData(lpOutput,&tgtcursor->TPBTNMARKS,
1032                                         sizeof(UINT)*2);
1033                     break;
1034                 case CSR_TPRESPONSE:
1035                     FIXME("Not returning CSR_TPRESPONSE correctly\n");
1036                     rc = 0;
1037                     break;
1038                 case CSR_PHYSID:
1039                 {
1040                     DWORD id;
1041                     id = tgtcursor->PHYSID;
1042                     id += (wCategory - WTI_CURSORS);
1043                     rc = CopyTabletData(lpOutput,&id,sizeof(DWORD));
1044                 }
1045                     break;
1046                 case CSR_MODE:
1047                     rc = CopyTabletData(lpOutput,&tgtcursor->MODE,sizeof(UINT));
1048                     break;
1049                 case CSR_MINPKTDATA:
1050                     rc = CopyTabletData(lpOutput,&tgtcursor->MINPKTDATA,
1051                         sizeof(UINT));
1052                     break;
1053                 case CSR_MINBUTTONS:
1054                     rc = CopyTabletData(lpOutput,&tgtcursor->MINBUTTONS,
1055                         sizeof(UINT));
1056                     break;
1057                 case CSR_CAPABILITIES:
1058                     rc = CopyTabletData(lpOutput,&tgtcursor->CAPABILITIES,
1059                         sizeof(UINT));
1060                     break;
1061                 case CSR_TYPE:
1062                     rc = CopyTabletData(lpOutput,&tgtcursor->TYPE,
1063                         sizeof(UINT));
1064                     break;
1065                 default:
1066                     FIXME("WTI_CURSORS unhandled index %i\n",nIndex);
1067                     rc = 0;
1068             }
1069             break;
1070         case WTI_DEVICES:
1071             switch (nIndex)
1072             {
1073                 case DVC_NAME:
1074                     rc = CopyTabletData(lpOutput,gSysDevice.NAME,
1075                                         strlen(gSysDevice.NAME)+1);
1076                     break;
1077                 case DVC_HARDWARE:
1078                     rc = CopyTabletData(lpOutput,&gSysDevice.HARDWARE,
1079                                         sizeof(UINT));
1080                     break;
1081                 case DVC_NCSRTYPES:
1082                     rc = CopyTabletData(lpOutput,&gSysDevice.NCSRTYPES,
1083                                         sizeof(UINT));
1084                     break;
1085                 case DVC_FIRSTCSR:
1086                     rc = CopyTabletData(lpOutput,&gSysDevice.FIRSTCSR,
1087                                         sizeof(UINT));
1088                     break;
1089                 case DVC_PKTRATE:
1090                     rc = CopyTabletData(lpOutput,&gSysDevice.PKTRATE,
1091                                         sizeof(UINT));
1092                     break;
1093                 case DVC_PKTDATA:
1094                     rc = CopyTabletData(lpOutput,&gSysDevice.PKTDATA,
1095                                         sizeof(WTPKT));
1096                     break;
1097                 case DVC_PKTMODE:
1098                     rc = CopyTabletData(lpOutput,&gSysDevice.PKTMODE,
1099                                         sizeof(WTPKT));
1100                     break;
1101                 case DVC_CSRDATA:
1102                     rc = CopyTabletData(lpOutput,&gSysDevice.CSRDATA,
1103                                         sizeof(WTPKT));
1104                     break;
1105                 case DVC_XMARGIN:
1106                     rc = CopyTabletData(lpOutput,&gSysDevice.XMARGIN,
1107                                         sizeof(INT));
1108                     break;
1109                 case DVC_YMARGIN:
1110                     rc = CopyTabletData(lpOutput,&gSysDevice.YMARGIN,
1111                                         sizeof(INT));
1112                     break;
1113                 case DVC_ZMARGIN:
1114                     rc = 0; /* unsupported */
1115                     /*
1116                     rc = CopyTabletData(lpOutput,&gSysDevice.ZMARGIN,
1117                                         sizeof(INT));
1118                     */
1119                     break;
1120                 case DVC_X:
1121                     rc = CopyTabletData(lpOutput,&gSysDevice.X,
1122                                         sizeof(AXIS));
1123                     break;
1124                 case DVC_Y:
1125                     rc = CopyTabletData(lpOutput,&gSysDevice.Y,
1126                                         sizeof(AXIS));
1127                     break;
1128                 case DVC_Z:
1129                     rc = 0; /* unsupported */
1130                     /*
1131                     rc = CopyTabletData(lpOutput,&gSysDevice.Z,
1132                                         sizeof(AXIS));
1133                     */
1134                     break;
1135                 case DVC_NPRESSURE:
1136                     rc = CopyTabletData(lpOutput,&gSysDevice.NPRESSURE,
1137                                         sizeof(AXIS));
1138                     break;
1139                 case DVC_TPRESSURE:
1140                     rc = 0; /* unsupported */
1141                     /*
1142                     rc = CopyTabletData(lpOutput,&gSysDevice.TPRESSURE,
1143                                         sizeof(AXIS));
1144                     */
1145                     break;
1146                 case DVC_ORIENTATION:
1147                     rc = CopyTabletData(lpOutput,&gSysDevice.ORIENTATION,
1148                                         sizeof(AXIS)*3);
1149                     break;
1150                 case DVC_ROTATION:
1151                     rc = 0; /* unsupported */
1152                     /*
1153                     rc = CopyTabletData(lpOutput,&gSysDevice.ROTATION,
1154                                         sizeof(AXIS)*3);
1155                     */
1156                     break;
1157                 case DVC_PNPID:
1158                     rc = CopyTabletData(lpOutput,gSysDevice.PNPID,
1159                                         strlen(gSysDevice.PNPID)+1);
1160                     break;
1161                 default:
1162                     FIXME("WTI_DEVICES unhandled index %i\n",nIndex);
1163                     rc = 0;
1164             }
1165             break;
1166         default:
1167             FIXME("Unhandled Category %i\n",wCategory);
1168     }
1169     return rc;
1170 }
1171
1172 #else /* HAVE_X11_EXTENSIONS_XINPUT_H */
1173
1174 /***********************************************************************
1175  *              AttachEventQueueToTablet (X11DRV.@)
1176  */
1177 int X11DRV_AttachEventQueueToTablet(HWND hOwner)
1178 {
1179     return 0;
1180 }
1181
1182 /***********************************************************************
1183  *              GetCurrentPacket (X11DRV.@)
1184  */
1185 int X11DRV_GetCurrentPacket(LPWTPACKET *packet)
1186 {
1187     return 0;
1188 }
1189
1190 /***********************************************************************
1191  *              LoadTabletInfo (X11DRV.@)
1192  */
1193 void X11DRV_LoadTabletInfo(HWND hwnddefault)
1194 {
1195 }
1196
1197 /***********************************************************************
1198  *              WTInfoA (X11DRV.@)
1199  */
1200 UINT X11DRV_WTInfoA(UINT wCategory, UINT nIndex, LPVOID lpOutput)
1201 {
1202     return 0;
1203 }
1204
1205 #endif /* HAVE_X11_EXTENSIONS_XINPUT_H */