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