server: Avoid hang on process startup.
[wine/multimedia.git] / dlls / x11drv / wintab.c
blob5037f589dfd2c70baaddeffc323cc7ababdbe6de
1 /*
2 * X11 tablet driver
4 * Copyright 2003 CodeWeavers (Aric Stewart)
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.
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.
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
21 #include "config.h"
22 #include "wine/port.h"
24 #include <stdlib.h>
26 #include "windef.h"
27 #include "x11drv.h"
28 #include "wine/library.h"
29 #include "wine/debug.h"
30 #include "wintab.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(wintab32);
34 typedef struct tagWTI_CURSORS_INFO
36 CHAR NAME[256];
37 /* a displayable zero-terminated string containing the name of the
38 * cursor.
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.
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.
56 BYTE BUTTONMAP[32];
57 /* a 32 byte array of logical button numbers, one for each physical
58 * button.
60 BYTE SYSBTNMAP[32];
61 /* a 32 byte array of button action codes, one for each logical
62 * button.
64 BYTE NPBUTTON;
65 /* the physical button number of the button that is controlled by normal
66 * pressure.
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.
73 UINT *NPRESPONSE;
74 /* an array of UINTs describing the pressure response curve for normal
75 * pressure.
77 BYTE TPBUTTON;
78 /* the physical button number of the button that is controlled by
79 * tangential pressure.
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.
86 UINT *TPRESPONSE;
87 /* an array of UINTs describing the pressure response curve for
88 * tangential pressure.
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.
98 UINT MODE;
99 /* the cursor mode number of this cursor type, if this cursor type has
100 * the CRC_MULTIMODE capability.
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.
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.
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.
125 UINT TYPE;
126 /* Manufacturer Unique id for the item type */
127 } WTI_CURSORS_INFO, *LPWTI_CURSORS_INFO;
130 typedef struct tagWTI_DEVICES_INFO
132 CHAR NAME[256];
133 /* a displayable null- terminated string describing the device,
134 * manufacturer, and revision level.
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.
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.
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.
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.
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.
181 AXIS NPRESSURE;
182 AXIS TPRESSURE;
183 /* the tablet's range and resolution capabilities, for the normal and
184 * tangential pressure inputs, respectively.
186 AXIS ORIENTATION[3];
187 /* a 3-element array describing the tablet's orientation range and
188 * resolution capabilities.
190 AXIS ROTATION[3];
191 /* a 3-element array describing the tablet's rotation range and
192 * resolution capabilities.
194 CHAR PNPID[256];
195 /* a null-terminated string containing the devices Plug and Play ID.*/
196 } WTI_DEVICES_INFO, *LPWTI_DEVICES_INFO;
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;
216 #ifdef HAVE_X11_EXTENSIONS_XINPUT_H
218 #include <X11/Xlib.h>
219 #include <X11/extensions/XInput.h>
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;
229 static HWND hwndTabletDefault;
230 static WTPACKET gMsgPacket;
231 static DWORD gSerial;
232 static INT button_state[10];
234 #define CURSORMAX 10
236 static LOGCONTEXTA gSysContext;
237 static WTI_DEVICES_INFO gSysDevice;
238 static WTI_CURSORS_INFO gSysCursor[CURSORMAX];
239 static INT gNumCursors;
242 #ifndef SONAME_LIBXI
243 #define SONAME_LIBXI "libXi.so"
244 #endif
246 /* XInput stuff */
247 static void *xinput_handle;
249 #define MAKE_FUNCPTR(f) static typeof(f) * p##f;
250 MAKE_FUNCPTR(XListInputDevices)
251 MAKE_FUNCPTR(XFreeDeviceList)
252 MAKE_FUNCPTR(XOpenDevice)
253 MAKE_FUNCPTR(XQueryDeviceState)
254 MAKE_FUNCPTR(XGetDeviceButtonMapping)
255 MAKE_FUNCPTR(XCloseDevice)
256 MAKE_FUNCPTR(XSelectExtensionEvent)
257 MAKE_FUNCPTR(XFreeDeviceState)
258 #undef MAKE_FUNCPTR
260 static INT X11DRV_XInput_Init(void)
262 xinput_handle = wine_dlopen(SONAME_LIBXI, RTLD_NOW, NULL, 0);
263 if (xinput_handle)
265 #define LOAD_FUNCPTR(f) if((p##f = wine_dlsym(xinput_handle, #f, NULL, 0)) == NULL) goto sym_not_found;
266 LOAD_FUNCPTR(XListInputDevices)
267 LOAD_FUNCPTR(XFreeDeviceList)
268 LOAD_FUNCPTR(XOpenDevice)
269 LOAD_FUNCPTR(XGetDeviceButtonMapping)
270 LOAD_FUNCPTR(XCloseDevice)
271 LOAD_FUNCPTR(XSelectExtensionEvent)
272 LOAD_FUNCPTR(XQueryDeviceState)
273 LOAD_FUNCPTR(XFreeDeviceState)
274 #undef LOAD_FUNCPTR
275 return 1;
277 sym_not_found:
278 return 0;
281 static int Tablet_ErrorHandler(Display *dpy, XErrorEvent *event, void* arg)
283 return 1;
286 void X11DRV_LoadTabletInfo(HWND hwnddefault)
288 struct x11drv_thread_data *data = x11drv_thread_data();
289 int num_devices;
290 int loop;
291 int cursor_target;
292 XDeviceInfo *devices;
293 XDeviceInfo *target = NULL;
294 BOOL axis_read_complete= FALSE;
296 XAnyClassPtr any;
297 XButtonInfoPtr Button;
298 XValuatorInfoPtr Val;
299 XAxisInfoPtr Axis;
301 XDevice *opendevice;
303 if (!X11DRV_XInput_Init())
305 ERR("Unable to initialized the XInput library.\n");
306 return;
309 hwndTabletDefault = hwnddefault;
311 /* Do base initializaion */
312 strcpy(gSysContext.lcName, "Wine Tablet Context");
313 strcpy(gSysDevice.NAME,"Wine Tablet Device");
315 gSysContext.lcOptions = CXO_SYSTEM;
316 gSysContext.lcLocks = CXL_INSIZE | CXL_INASPECT | CXL_MARGIN |
317 CXL_SENSITIVITY | CXL_SYSOUT;
319 gSysContext.lcMsgBase= WT_DEFBASE;
320 gSysContext.lcDevice = 0;
321 gSysContext.lcPktData =
322 PK_CONTEXT | PK_STATUS | PK_SERIAL_NUMBER| PK_TIME | PK_CURSOR |
323 PK_BUTTONS | PK_X | PK_Y | PK_NORMAL_PRESSURE | PK_ORIENTATION;
324 gSysContext.lcMoveMask=
325 PK_BUTTONS | PK_X | PK_Y | PK_NORMAL_PRESSURE | PK_ORIENTATION;
326 gSysContext.lcStatus = CXS_ONTOP;
327 gSysContext.lcPktRate = 100;
328 gSysContext.lcBtnDnMask = 0xffffffff;
329 gSysContext.lcBtnUpMask = 0xffffffff;
330 gSysContext.lcSensX = 65536;
331 gSysContext.lcSensY = 65536;
332 gSysContext.lcSensX = 65536;
333 gSysContext.lcSensZ = 65536;
334 gSysContext.lcSysSensX= 65536;
335 gSysContext.lcSysSensY= 65536;
337 /* Device Defaults */
338 gSysDevice.HARDWARE = HWC_HARDPROX|HWC_PHYSID_CURSORS;
339 gSysDevice.FIRSTCSR= 0;
340 gSysDevice.PKTRATE = 100;
341 gSysDevice.PKTDATA =
342 PK_CONTEXT | PK_STATUS | PK_SERIAL_NUMBER| PK_TIME | PK_CURSOR |
343 PK_BUTTONS | PK_X | PK_Y | PK_NORMAL_PRESSURE | PK_ORIENTATION;
344 strcpy(gSysDevice.PNPID,"non-pluginplay");
346 wine_tsx11_lock();
348 cursor_target = -1;
349 devices = pXListInputDevices(data->display, &num_devices);
350 if (!devices)
352 WARN("XInput Extenstions reported as not avalable\n");
353 wine_tsx11_unlock();
354 return;
356 for (loop=0; loop < num_devices; loop++)
358 int class_loop;
360 TRACE("Trying device %i(%s)\n",loop,devices[loop].name);
361 if (devices[loop].use == IsXExtensionDevice)
363 LPWTI_CURSORS_INFO cursor;
365 TRACE("Is Extension Device\n");
366 cursor_target++;
367 target = &devices[loop];
368 cursor = &gSysCursor[cursor_target];
370 opendevice = pXOpenDevice(data->display,target->id);
371 if (opendevice)
373 unsigned char map[32];
374 int i;
375 int shft = 0;
377 X11DRV_expect_error(data->display,Tablet_ErrorHandler,NULL);
378 pXGetDeviceButtonMapping(data->display, opendevice, map, 32);
379 if (X11DRV_check_error())
381 TRACE("No buttons, Non Tablet Device\n");
382 pXCloseDevice(data->display, opendevice);
383 cursor_target --;
384 continue;
387 for (i=0; i< cursor->BUTTONS; i++,shft++)
389 cursor->BUTTONMAP[i] = map[i];
390 cursor->SYSBTNMAP[i] = (1<<shft);
392 pXCloseDevice(data->display, opendevice);
394 else
396 WARN("Unable to open device %s\n",target->name);
397 cursor_target --;
398 continue;
401 strcpy(cursor->NAME,target->name);
403 cursor->ACTIVE = 1;
404 cursor->PKTDATA = PK_TIME | PK_CURSOR | PK_BUTTONS | PK_X | PK_Y |
405 PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE |
406 PK_ORIENTATION;
408 cursor->PHYSID = cursor_target;
409 cursor->NPBUTTON = 1;
410 cursor->NPBTNMARKS[0] = 0 ;
411 cursor->NPBTNMARKS[1] = 1 ;
412 cursor->CAPABILITIES = CRC_MULTIMODE;
413 if (strcasecmp(cursor->NAME,"stylus")==0)
414 cursor->TYPE = 0x4825;
415 if (strcasecmp(cursor->NAME,"eraser")==0)
416 cursor->TYPE = 0xc85a;
419 any = (XAnyClassPtr) (target->inputclassinfo);
421 for (class_loop = 0; class_loop < target->num_classes; class_loop++)
423 switch (any->class)
425 case ValuatorClass:
426 if (!axis_read_complete)
428 Val = (XValuatorInfoPtr) any;
429 Axis = (XAxisInfoPtr) ((char *) Val + sizeof
430 (XValuatorInfo));
432 if (Val->num_axes>=1)
434 /* Axis 1 is X */
435 gSysDevice.X.axMin = Axis->min_value;
436 gSysDevice.X.axMax= Axis->max_value;
437 gSysDevice.X.axUnits = TU_INCHES;
438 gSysDevice.X.axResolution = Axis->resolution;
439 gSysContext.lcInOrgX = Axis->min_value;
440 gSysContext.lcSysOrgX = Axis->min_value;
441 gSysContext.lcInExtX = Axis->max_value;
442 gSysContext.lcSysExtX = Axis->max_value;
443 Axis++;
445 if (Val->num_axes>=2)
447 /* Axis 2 is Y */
448 gSysDevice.Y.axMin = Axis->min_value;
449 gSysDevice.Y.axMax= Axis->max_value;
450 gSysDevice.Y.axUnits = TU_INCHES;
451 gSysDevice.Y.axResolution = Axis->resolution;
452 gSysContext.lcInOrgY = Axis->min_value;
453 gSysContext.lcSysOrgY = Axis->min_value;
454 gSysContext.lcInExtY = Axis->max_value;
455 gSysContext.lcSysExtY = Axis->max_value;
456 Axis++;
458 if (Val->num_axes>=3)
460 /* Axis 3 is Normal Pressure */
461 gSysDevice.NPRESSURE.axMin = Axis->min_value;
462 gSysDevice.NPRESSURE.axMax= Axis->max_value;
463 gSysDevice.NPRESSURE.axUnits = TU_INCHES;
464 gSysDevice.NPRESSURE.axResolution =
465 Axis->resolution;
466 Axis++;
468 if (Val->num_axes >= 5)
470 /* Axis 4 and 5 are X and Y tilt */
471 XAxisInfoPtr XAxis = Axis;
472 Axis++;
473 if (max (abs(Axis->max_value),
474 abs(XAxis->max_value)))
476 gSysDevice.ORIENTATION[0].axMin = 0;
477 gSysDevice.ORIENTATION[0].axMax = 3600;
478 gSysDevice.ORIENTATION[0].axUnits = TU_CIRCLE;
479 gSysDevice.ORIENTATION[0].axResolution
480 = CASTFIX32(3600);
481 gSysDevice.ORIENTATION[1].axMin = -1000;
482 gSysDevice.ORIENTATION[1].axMax = 1000;
483 gSysDevice.ORIENTATION[1].axUnits = TU_CIRCLE;
484 gSysDevice.ORIENTATION[1].axResolution
485 = CASTFIX32(3600);
486 Axis++;
489 axis_read_complete = TRUE;
491 break;
492 case ButtonClass:
494 CHAR *ptr = cursor->BTNNAMES;
495 int i;
497 Button = (XButtonInfoPtr) any;
498 cursor->BUTTONS = Button->num_buttons;
499 for (i = 0; i < cursor->BUTTONS; i++)
501 strcpy(ptr,cursor->NAME);
502 ptr+=8;
505 break;
507 any = (XAnyClassPtr) ((char*) any + any->length);
511 pXFreeDeviceList(devices);
512 wine_tsx11_unlock();
513 gSysDevice.NCSRTYPES = cursor_target+1;
514 gNumCursors = cursor_target+1;
517 static int figure_deg(int x, int y)
519 int rc;
521 if (y != 0)
523 rc = (int) 10 * (atan( (FLOAT)abs(y) / (FLOAT)abs(x)) / (3.1415 / 180));
524 if (y>0)
526 if (x>0)
527 rc += 900;
528 else
529 rc = 2700 - rc;
531 else
533 if (x>0)
534 rc = 900 - rc;
535 else
536 rc += 2700;
539 else
541 if (x >= 0)
542 rc = 900;
543 else
544 rc = 2700;
547 return rc;
550 static int get_button_state(int deviceid)
552 return button_state[deviceid];
555 static void set_button_state(XID deviceid)
557 struct x11drv_thread_data *data = x11drv_thread_data();
558 XDevice *device;
559 XDeviceState *state;
560 XInputClass *class;
561 int loop;
562 int rc = 0;
564 wine_tsx11_lock();
565 device = pXOpenDevice(data->display,deviceid);
566 state = pXQueryDeviceState(data->display,device);
568 if (state)
570 class = state->data;
571 for (loop = 0; loop < state->num_classes; loop++)
573 if (class->class == ButtonClass)
575 int loop2;
576 XButtonState *button_state = (XButtonState*)class;
577 for (loop2 = 1; loop2 <= button_state->num_buttons; loop2++)
579 if (button_state->buttons[loop2 / 8] & (1 << (loop2 % 8)))
581 rc |= (1<<(loop2-1));
585 class = (XInputClass *) ((char *) class + class->length);
588 pXFreeDeviceState(state);
589 wine_tsx11_unlock();
590 button_state[deviceid] = rc;
593 static void motion_event( HWND hwnd, XEvent *event )
595 XDeviceMotionEvent *motion = (XDeviceMotionEvent *)event;
596 LPWTI_CURSORS_INFO cursor = &gSysCursor[motion->deviceid];
598 memset(&gMsgPacket,0,sizeof(WTPACKET));
600 TRACE("Received tablet motion event (%p)\n",hwnd);
602 /* Set cursor to inverted if cursor is the eraser */
603 gMsgPacket.pkStatus = (cursor->TYPE == 0xc85a ?TPS_INVERT:0);
604 gMsgPacket.pkTime = EVENT_x11_time_to_win32_time(motion->time);
605 gMsgPacket.pkSerialNumber = gSerial++;
606 gMsgPacket.pkCursor = motion->deviceid;
607 gMsgPacket.pkX = motion->axis_data[0];
608 gMsgPacket.pkY = motion->axis_data[1];
609 gMsgPacket.pkOrientation.orAzimuth = figure_deg(motion->axis_data[3],motion->axis_data[4]);
610 gMsgPacket.pkOrientation.orAltitude = ((1000 - 15 * max
611 (abs(motion->axis_data[3]),
612 abs(motion->axis_data[4])))
613 * (gMsgPacket.pkStatus & TPS_INVERT?-1:1));
614 gMsgPacket.pkNormalPressure = motion->axis_data[2];
615 gMsgPacket.pkButtons = get_button_state(motion->deviceid);
616 SendMessageW(hwndTabletDefault,WT_PACKET,0,(LPARAM)hwnd);
619 static void button_event( HWND hwnd, XEvent *event )
621 XDeviceButtonEvent *button = (XDeviceButtonEvent *) event;
622 LPWTI_CURSORS_INFO cursor = &gSysCursor[button->deviceid];
624 memset(&gMsgPacket,0,sizeof(WTPACKET));
626 TRACE("Received tablet button %s event\n", (event->type == button_press_type)?"press":"release");
628 /* Set cursor to inverted if cursor is the eraser */
629 gMsgPacket.pkStatus = (cursor->TYPE == 0xc85a ?TPS_INVERT:0);
630 set_button_state(button->deviceid);
631 gMsgPacket.pkTime = EVENT_x11_time_to_win32_time(button->time);
632 gMsgPacket.pkSerialNumber = gSerial++;
633 gMsgPacket.pkCursor = button->deviceid;
634 gMsgPacket.pkX = button->axis_data[0];
635 gMsgPacket.pkY = button->axis_data[1];
636 gMsgPacket.pkOrientation.orAzimuth = figure_deg(button->axis_data[3],button->axis_data[4]);
637 gMsgPacket.pkOrientation.orAltitude = ((1000 - 15 * max(abs(button->axis_data[3]),
638 abs(button->axis_data[4])))
639 * (gMsgPacket.pkStatus & TPS_INVERT?-1:1));
640 gMsgPacket.pkNormalPressure = button->axis_data[2];
641 gMsgPacket.pkButtons = get_button_state(button->deviceid);
642 SendMessageW(hwndTabletDefault,WT_PACKET,0,(LPARAM)hwnd);
645 static void key_event( HWND hwnd, XEvent *event )
647 if (event->type == key_press_type)
648 FIXME("Received tablet key press event\n");
649 else
650 FIXME("Received tablet key release event\n");
653 static void proximity_event( HWND hwnd, XEvent *event )
655 XProximityNotifyEvent *proximity = (XProximityNotifyEvent *) event;
656 LPWTI_CURSORS_INFO cursor = &gSysCursor[proximity->deviceid];
658 memset(&gMsgPacket,0,sizeof(WTPACKET));
660 TRACE("Received tablet proximity event\n");
661 /* Set cursor to inverted if cursor is the eraser */
662 gMsgPacket.pkStatus = (cursor->TYPE == 0xc85a ?TPS_INVERT:0);
663 gMsgPacket.pkStatus |= (event->type==proximity_out_type)?TPS_PROXIMITY:0;
664 gMsgPacket.pkTime = EVENT_x11_time_to_win32_time(proximity->time);
665 gMsgPacket.pkSerialNumber = gSerial++;
666 gMsgPacket.pkCursor = proximity->deviceid;
667 gMsgPacket.pkX = proximity->axis_data[0];
668 gMsgPacket.pkY = proximity->axis_data[1];
669 gMsgPacket.pkOrientation.orAzimuth = figure_deg(proximity->axis_data[3],proximity->axis_data[4]);
670 gMsgPacket.pkOrientation.orAltitude = ((1000 - 15 * max(abs(proximity->axis_data[3]),
671 abs(proximity->axis_data[4])))
672 * (gMsgPacket.pkStatus & TPS_INVERT?-1:1));
673 gMsgPacket.pkNormalPressure = proximity->axis_data[2];
674 gMsgPacket.pkButtons = get_button_state(proximity->deviceid);
676 SendMessageW(hwndTabletDefault, WT_PROXIMITY, (event->type == proximity_in_type), (LPARAM)hwnd);
679 int X11DRV_AttachEventQueueToTablet(HWND hOwner)
681 struct x11drv_thread_data *data = x11drv_thread_data();
682 int num_devices;
683 int loop;
684 int cur_loop;
685 XDeviceInfo *devices;
686 XDeviceInfo *target = NULL;
687 XDevice *the_device;
688 XEventClass event_list[7];
689 Window win = X11DRV_get_whole_window( hOwner );
691 if (!win) return 0;
693 TRACE("Creating context for window %p (%lx) %i cursors\n", hOwner, win, gNumCursors);
695 wine_tsx11_lock();
696 devices = pXListInputDevices(data->display, &num_devices);
698 X11DRV_expect_error(data->display,Tablet_ErrorHandler,NULL);
699 for (cur_loop=0; cur_loop < gNumCursors; cur_loop++)
701 int event_number=0;
703 for (loop=0; loop < num_devices; loop ++)
704 if (strcmp(devices[loop].name,gSysCursor[cur_loop].NAME)==0)
705 target = &devices[loop];
707 TRACE("Opening cursor %i id %i\n",cur_loop,(INT)target->id);
709 the_device = pXOpenDevice(data->display, target->id);
711 if (!the_device)
713 WARN("Unable to Open device\n");
714 continue;
717 if (the_device->num_classes > 0)
719 DeviceKeyPress(the_device, key_press_type, event_list[event_number]);
720 if (event_list[event_number]) event_number++;
721 DeviceKeyRelease(the_device, key_release_type, event_list[event_number]);
722 if (event_list[event_number]) event_number++;
723 DeviceButtonPress(the_device, button_press_type, event_list[event_number]);
724 if (event_list[event_number]) event_number++;
725 DeviceButtonRelease(the_device, button_release_type, event_list[event_number]);
726 if (event_list[event_number]) event_number++;
727 DeviceMotionNotify(the_device, motion_type, event_list[event_number]);
728 if (event_list[event_number]) event_number++;
729 ProximityIn(the_device, proximity_in_type, event_list[event_number]);
730 if (event_list[event_number]) event_number++;
731 ProximityOut(the_device, proximity_out_type, event_list[event_number]);
732 if (event_list[event_number]) event_number++;
734 if (key_press_type) X11DRV_register_event_handler( key_press_type, key_event );
735 if (key_release_type) X11DRV_register_event_handler( key_release_type, key_event );
736 if (button_press_type) X11DRV_register_event_handler( button_press_type, button_event );
737 if (button_release_type) X11DRV_register_event_handler( button_release_type, button_event );
738 if (motion_type) X11DRV_register_event_handler( motion_type, motion_event );
739 if (proximity_in_type) X11DRV_register_event_handler( proximity_in_type, proximity_event );
740 if (proximity_out_type) X11DRV_register_event_handler( proximity_out_type, proximity_event );
742 pXSelectExtensionEvent(data->display, win, event_list, event_number);
745 XSync(data->display, False);
746 X11DRV_check_error();
748 if (NULL != devices) pXFreeDeviceList(devices);
749 wine_tsx11_unlock();
750 return 0;
753 int X11DRV_GetCurrentPacket(LPWTPACKET *packet)
755 memcpy(packet,&gMsgPacket,sizeof(WTPACKET));
756 return 1;
760 int static inline CopyTabletData(LPVOID target, LPVOID src, INT size)
763 * It is valid to call CopyTabletData with NULL.
764 * This handles the WTInfo() case where lpOutput is null.
766 if(target != NULL)
767 memcpy(target,src,size);
768 return(size);
771 /***********************************************************************
772 * X11DRV_WTInfoA (X11DRV.@)
774 UINT X11DRV_WTInfoA(UINT wCategory, UINT nIndex, LPVOID lpOutput)
777 * It is valid to call WTInfoA with lpOutput == NULL, as per standard.
778 * lpOutput == NULL signifies the user only wishes
779 * to find the size of the data.
780 * NOTE:
781 * From now on use CopyTabletData to fill lpOutput. memcpy will break
782 * the code.
784 int rc = 0;
785 LPWTI_CURSORS_INFO tgtcursor;
786 TRACE("(%u, %u, %p)\n", wCategory, nIndex, lpOutput);
788 switch(wCategory)
790 case 0:
791 /* return largest necessary buffer */
792 TRACE("%i cursors\n",gNumCursors);
793 if (gNumCursors>0)
795 FIXME("Return proper size\n");
796 rc = 200;
798 break;
799 case WTI_INTERFACE:
800 switch (nIndex)
802 WORD version;
803 case IFC_WINTABID:
804 strcpy(lpOutput,"Wine Wintab 1.1");
805 rc = 16;
806 break;
807 case IFC_SPECVERSION:
808 version = (0x01) | (0x01 << 8);
809 rc = CopyTabletData(lpOutput, &version,sizeof(WORD));
810 break;
811 case IFC_IMPLVERSION:
812 version = (0x00) | (0x01 << 8);
813 rc = CopyTabletData(lpOutput, &version,sizeof(WORD));
814 break;
815 default:
816 FIXME("WTI_INTERFACE unhandled index %i\n",nIndex);
817 rc = 0;
820 case WTI_DEFSYSCTX:
821 case WTI_DDCTXS:
822 case WTI_DEFCONTEXT:
823 switch (nIndex)
825 case 0:
826 rc = CopyTabletData(lpOutput, &gSysContext,
827 sizeof(LOGCONTEXTA));
828 break;
829 case CTX_NAME:
830 rc = CopyTabletData(lpOutput, &gSysContext.lcName,
831 strlen(gSysContext.lcName)+1);
832 break;
833 case CTX_OPTIONS:
834 rc = CopyTabletData(lpOutput, &gSysContext.lcOptions,
835 sizeof(UINT));
836 break;
837 case CTX_STATUS:
838 rc = CopyTabletData(lpOutput, &gSysContext.lcStatus,
839 sizeof(UINT));
840 break;
841 case CTX_LOCKS:
842 rc= CopyTabletData (lpOutput, &gSysContext.lcLocks,
843 sizeof(UINT));
844 break;
845 case CTX_MSGBASE:
846 rc = CopyTabletData(lpOutput, &gSysContext.lcMsgBase,
847 sizeof(UINT));
848 break;
849 case CTX_DEVICE:
850 rc = CopyTabletData(lpOutput, &gSysContext.lcDevice,
851 sizeof(UINT));
852 break;
853 case CTX_PKTRATE:
854 rc = CopyTabletData(lpOutput, &gSysContext.lcPktRate,
855 sizeof(UINT));
856 break;
857 case CTX_PKTMODE:
858 rc = CopyTabletData(lpOutput, &gSysContext.lcPktMode,
859 sizeof(WTPKT));
860 break;
861 case CTX_MOVEMASK:
862 rc = CopyTabletData(lpOutput, &gSysContext.lcMoveMask,
863 sizeof(WTPKT));
864 break;
865 case CTX_BTNDNMASK:
866 rc = CopyTabletData(lpOutput, &gSysContext.lcBtnDnMask,
867 sizeof(DWORD));
868 break;
869 case CTX_BTNUPMASK:
870 rc = CopyTabletData(lpOutput, &gSysContext.lcBtnUpMask,
871 sizeof(DWORD));
872 break;
873 case CTX_INORGX:
874 rc = CopyTabletData(lpOutput, &gSysContext.lcInOrgX,
875 sizeof(LONG));
876 break;
877 case CTX_INORGY:
878 rc = CopyTabletData(lpOutput, &gSysContext.lcInOrgY,
879 sizeof(LONG));
880 break;
881 case CTX_INORGZ:
882 rc = CopyTabletData(lpOutput, &gSysContext.lcInOrgZ,
883 sizeof(LONG));
884 break;
885 case CTX_INEXTX:
886 rc = CopyTabletData(lpOutput, &gSysContext.lcInExtX,
887 sizeof(LONG));
888 break;
889 case CTX_INEXTY:
890 rc = CopyTabletData(lpOutput, &gSysContext.lcInExtY,
891 sizeof(LONG));
892 break;
893 case CTX_INEXTZ:
894 rc = CopyTabletData(lpOutput, &gSysContext.lcInExtZ,
895 sizeof(LONG));
896 break;
897 case CTX_OUTORGX:
898 rc = CopyTabletData(lpOutput, &gSysContext.lcOutOrgX,
899 sizeof(LONG));
900 break;
901 case CTX_OUTORGY:
902 rc = CopyTabletData(lpOutput, &gSysContext.lcOutOrgY,
903 sizeof(LONG));
904 break;
905 case CTX_OUTORGZ:
906 rc = CopyTabletData(lpOutput, &gSysContext.lcOutOrgZ,
907 sizeof(LONG));
908 break;
909 case CTX_OUTEXTX:
910 rc = CopyTabletData(lpOutput, &gSysContext.lcOutExtX,
911 sizeof(LONG));
912 break;
913 case CTX_OUTEXTY:
914 rc = CopyTabletData(lpOutput, &gSysContext.lcOutExtY,
915 sizeof(LONG));
916 break;
917 case CTX_OUTEXTZ:
918 rc = CopyTabletData(lpOutput, &gSysContext.lcOutExtZ,
919 sizeof(LONG));
920 break;
921 case CTX_SENSX:
922 rc = CopyTabletData(lpOutput, &gSysContext.lcSensX,
923 sizeof(LONG));
924 break;
925 case CTX_SENSY:
926 rc = CopyTabletData(lpOutput, &gSysContext.lcSensY,
927 sizeof(LONG));
928 break;
929 case CTX_SENSZ:
930 rc = CopyTabletData(lpOutput, &gSysContext.lcSensZ,
931 sizeof(LONG));
932 break;
933 case CTX_SYSMODE:
934 rc = CopyTabletData(lpOutput, &gSysContext.lcSysMode,
935 sizeof(LONG));
936 break;
937 case CTX_SYSORGX:
938 rc = CopyTabletData(lpOutput, &gSysContext.lcSysOrgX,
939 sizeof(LONG));
940 break;
941 case CTX_SYSORGY:
942 rc = CopyTabletData(lpOutput, &gSysContext.lcSysOrgY,
943 sizeof(LONG));
944 break;
945 case CTX_SYSEXTX:
946 rc = CopyTabletData(lpOutput, &gSysContext.lcSysExtX,
947 sizeof(LONG));
948 break;
949 case CTX_SYSEXTY:
950 rc = CopyTabletData(lpOutput, &gSysContext.lcSysExtY,
951 sizeof(LONG));
952 break;
953 case CTX_SYSSENSX:
954 rc = CopyTabletData(lpOutput, &gSysContext.lcSysSensX,
955 sizeof(LONG));
956 break;
957 case CTX_SYSSENSY:
958 rc = CopyTabletData(lpOutput, &gSysContext.lcSysSensY,
959 sizeof(LONG));
960 break;
961 default:
962 FIXME("WTI_DEFSYSCTX unhandled index %i\n",nIndex);
963 rc = 0;
965 break;
966 case WTI_CURSORS:
967 case WTI_CURSORS+1:
968 case WTI_CURSORS+2:
969 case WTI_CURSORS+3:
970 case WTI_CURSORS+4:
971 case WTI_CURSORS+5:
972 case WTI_CURSORS+6:
973 case WTI_CURSORS+7:
974 case WTI_CURSORS+8:
975 case WTI_CURSORS+9:
976 case WTI_CURSORS+10:
977 tgtcursor = &gSysCursor[wCategory - WTI_CURSORS];
978 switch (nIndex)
980 case CSR_NAME:
981 rc = CopyTabletData(lpOutput, &tgtcursor->NAME,
982 strlen(tgtcursor->NAME)+1);
983 break;
984 case CSR_ACTIVE:
985 rc = CopyTabletData(lpOutput,&tgtcursor->ACTIVE,
986 sizeof(BOOL));
987 break;
988 case CSR_PKTDATA:
989 rc = CopyTabletData(lpOutput,&tgtcursor->PKTDATA,
990 sizeof(WTPKT));
991 break;
992 case CSR_BUTTONS:
993 rc = CopyTabletData(lpOutput,&tgtcursor->BUTTONS,
994 sizeof(BYTE));
995 break;
996 case CSR_BUTTONBITS:
997 rc = CopyTabletData(lpOutput,&tgtcursor->BUTTONBITS,
998 sizeof(BYTE));
999 break;
1000 case CSR_BTNNAMES:
1001 FIXME("Button Names not returned correctly\n");
1002 rc = CopyTabletData(lpOutput,&tgtcursor->BTNNAMES,
1003 strlen(tgtcursor->BTNNAMES)+1);
1004 break;
1005 case CSR_BUTTONMAP:
1006 rc = CopyTabletData(lpOutput,&tgtcursor->BUTTONMAP,
1007 sizeof(BYTE)*32);
1008 break;
1009 case CSR_SYSBTNMAP:
1010 rc = CopyTabletData(lpOutput,&tgtcursor->SYSBTNMAP,
1011 sizeof(BYTE)*32);
1012 break;
1013 case CSR_NPBTNMARKS:
1014 rc = CopyTabletData(lpOutput,&tgtcursor->NPBTNMARKS,
1015 sizeof(UINT)*2);
1016 break;
1017 case CSR_NPBUTTON:
1018 rc = CopyTabletData(lpOutput,&tgtcursor->NPBUTTON,
1019 sizeof(BYTE));
1020 break;
1021 case CSR_NPRESPONSE:
1022 FIXME("Not returning CSR_NPRESPONSE correctly\n");
1023 rc = 0;
1024 break;
1025 case CSR_TPBUTTON:
1026 rc = CopyTabletData(lpOutput,&tgtcursor->TPBUTTON,
1027 sizeof(BYTE));
1028 break;
1029 case CSR_TPBTNMARKS:
1030 rc = CopyTabletData(lpOutput,&tgtcursor->TPBTNMARKS,
1031 sizeof(UINT)*2);
1032 break;
1033 case CSR_TPRESPONSE:
1034 FIXME("Not returning CSR_TPRESPONSE correctly\n");
1035 rc = 0;
1036 break;
1037 case CSR_PHYSID:
1039 DWORD id;
1040 id = tgtcursor->PHYSID;
1041 id += (wCategory - WTI_CURSORS);
1042 rc = CopyTabletData(lpOutput,&id,sizeof(DWORD));
1044 break;
1045 case CSR_MODE:
1046 rc = CopyTabletData(lpOutput,&tgtcursor->MODE,sizeof(UINT));
1047 break;
1048 case CSR_MINPKTDATA:
1049 rc = CopyTabletData(lpOutput,&tgtcursor->MINPKTDATA,
1050 sizeof(UINT));
1051 break;
1052 case CSR_MINBUTTONS:
1053 rc = CopyTabletData(lpOutput,&tgtcursor->MINBUTTONS,
1054 sizeof(UINT));
1055 break;
1056 case CSR_CAPABILITIES:
1057 rc = CopyTabletData(lpOutput,&tgtcursor->CAPABILITIES,
1058 sizeof(UINT));
1059 break;
1060 case CSR_TYPE:
1061 rc = CopyTabletData(lpOutput,&tgtcursor->TYPE,
1062 sizeof(UINT));
1063 break;
1064 default:
1065 FIXME("WTI_CURSORS unhandled index %i\n",nIndex);
1066 rc = 0;
1068 break;
1069 case WTI_DEVICES:
1070 switch (nIndex)
1072 case DVC_NAME:
1073 rc = CopyTabletData(lpOutput,gSysDevice.NAME,
1074 strlen(gSysDevice.NAME)+1);
1075 break;
1076 case DVC_HARDWARE:
1077 rc = CopyTabletData(lpOutput,&gSysDevice.HARDWARE,
1078 sizeof(UINT));
1079 break;
1080 case DVC_NCSRTYPES:
1081 rc = CopyTabletData(lpOutput,&gSysDevice.NCSRTYPES,
1082 sizeof(UINT));
1083 break;
1084 case DVC_FIRSTCSR:
1085 rc = CopyTabletData(lpOutput,&gSysDevice.FIRSTCSR,
1086 sizeof(UINT));
1087 break;
1088 case DVC_PKTRATE:
1089 rc = CopyTabletData(lpOutput,&gSysDevice.PKTRATE,
1090 sizeof(UINT));
1091 break;
1092 case DVC_PKTDATA:
1093 rc = CopyTabletData(lpOutput,&gSysDevice.PKTDATA,
1094 sizeof(WTPKT));
1095 break;
1096 case DVC_PKTMODE:
1097 rc = CopyTabletData(lpOutput,&gSysDevice.PKTMODE,
1098 sizeof(WTPKT));
1099 break;
1100 case DVC_CSRDATA:
1101 rc = CopyTabletData(lpOutput,&gSysDevice.CSRDATA,
1102 sizeof(WTPKT));
1103 break;
1104 case DVC_XMARGIN:
1105 rc = CopyTabletData(lpOutput,&gSysDevice.XMARGIN,
1106 sizeof(INT));
1107 break;
1108 case DVC_YMARGIN:
1109 rc = CopyTabletData(lpOutput,&gSysDevice.YMARGIN,
1110 sizeof(INT));
1111 break;
1112 case DVC_ZMARGIN:
1113 rc = 0; /* unsupported */
1115 rc = CopyTabletData(lpOutput,&gSysDevice.ZMARGIN,
1116 sizeof(INT));
1118 break;
1119 case DVC_X:
1120 rc = CopyTabletData(lpOutput,&gSysDevice.X,
1121 sizeof(AXIS));
1122 break;
1123 case DVC_Y:
1124 rc = CopyTabletData(lpOutput,&gSysDevice.Y,
1125 sizeof(AXIS));
1126 break;
1127 case DVC_Z:
1128 rc = 0; /* unsupported */
1130 rc = CopyTabletData(lpOutput,&gSysDevice.Z,
1131 sizeof(AXIS));
1133 break;
1134 case DVC_NPRESSURE:
1135 rc = CopyTabletData(lpOutput,&gSysDevice.NPRESSURE,
1136 sizeof(AXIS));
1137 break;
1138 case DVC_TPRESSURE:
1139 rc = 0; /* unsupported */
1141 rc = CopyTabletData(lpOutput,&gSysDevice.TPRESSURE,
1142 sizeof(AXIS));
1144 break;
1145 case DVC_ORIENTATION:
1146 rc = CopyTabletData(lpOutput,&gSysDevice.ORIENTATION,
1147 sizeof(AXIS)*3);
1148 break;
1149 case DVC_ROTATION:
1150 rc = 0; /* unsupported */
1152 rc = CopyTabletData(lpOutput,&gSysDevice.ROTATION,
1153 sizeof(AXIS)*3);
1155 break;
1156 case DVC_PNPID:
1157 rc = CopyTabletData(lpOutput,gSysDevice.PNPID,
1158 strlen(gSysDevice.PNPID)+1);
1159 break;
1160 default:
1161 FIXME("WTI_DEVICES unhandled index %i\n",nIndex);
1162 rc = 0;
1164 break;
1165 default:
1166 FIXME("Unhandled Category %i\n",wCategory);
1168 return rc;
1171 #else /* HAVE_X11_EXTENSIONS_XINPUT_H */
1173 /***********************************************************************
1174 * AttachEventQueueToTablet (X11DRV.@)
1176 int X11DRV_AttachEventQueueToTablet(HWND hOwner)
1178 return 0;
1181 /***********************************************************************
1182 * GetCurrentPacket (X11DRV.@)
1184 int X11DRV_GetCurrentPacket(LPWTPACKET *packet)
1186 return 0;
1189 /***********************************************************************
1190 * LoadTabletInfo (X11DRV.@)
1192 void X11DRV_LoadTabletInfo(HWND hwnddefault)
1196 /***********************************************************************
1197 * WTInfoA (X11DRV.@)
1199 UINT X11DRV_WTInfoA(UINT wCategory, UINT nIndex, LPVOID lpOutput)
1201 return 0;
1204 #endif /* HAVE_X11_EXTENSIONS_XINPUT_H */