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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "wine/port.h"
31 #include "wine/library.h"
32 #include "wine/unicode.h"
33 #include "wine/debug.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(wintab32);
38 #define WT_MAX_NAME_LEN 256
40 typedef struct tagWTI_CURSORS_INFO
42 WCHAR NAME[WT_MAX_NAME_LEN];
43 /* a displayable zero-terminated string containing the name of the
47 /* whether the cursor is currently connected. */
49 /* a bit mask indicating the packet data items supported when this
50 * cursor is connected.
53 /* the number of buttons on this cursor. */
55 /* the number of bits of raw button data returned by the hardware.*/
58 /* a list of zero-terminated strings containing the names of the
59 * cursor's buttons. The number of names in the list is the same as the
60 * number of buttons on the cursor. The names are separated by a single
61 * zero character; the list is terminated by two zero characters.
64 /* a 32 byte array of logical button numbers, one for each physical
68 /* a 32 byte array of button action codes, one for each logical
72 /* the physical button number of the button that is controlled by normal
76 /* an array of two UINTs, specifying the button marks for the normal
77 * pressure button. The first UINT contains the release mark; the second
78 * contains the press mark.
81 /* an array of UINTs describing the pressure response curve for normal
85 /* the physical button number of the button that is controlled by
86 * tangential pressure.
89 /* an array of two UINTs, specifying the button marks for the tangential
90 * pressure button. The first UINT contains the release mark; the second
91 * contains the press mark.
94 /* an array of UINTs describing the pressure response curve for
95 * tangential pressure.
98 /* a manufacturer-specific physical identifier for the cursor. This
99 * value will distinguish the physical cursor from others on the same
100 * device. This physical identifier allows applications to bind
101 * functions to specific physical cursors, even if category numbers
102 * change and multiple, otherwise identical, physical cursors are
106 /* the cursor mode number of this cursor type, if this cursor type has
107 * the CRC_MULTIMODE capability.
110 /* the minimum set of data available from a physical cursor in this
111 * cursor type, if this cursor type has the CRC_AGGREGATE capability.
114 /* the minimum number of buttons of physical cursors in the cursor type,
115 * if this cursor type has the CRC_AGGREGATE capability.
118 /* flags indicating cursor capabilities, as defined below:
120 Indicates this cursor type describes one of several modes of a
121 single physical cursor. Consecutive cursor type categories
122 describe the modes; the CSR_MODE data item gives the mode number
125 Indicates this cursor type describes several physical cursors
126 that cannot be distinguished by software.
128 Indicates this cursor type describes the physical cursor in its
129 inverted orientation; the previous consecutive cursor type
130 category describes the normal orientation.
133 /* Manufacturer Unique id for the item type */
134 } WTI_CURSORS_INFO, *LPWTI_CURSORS_INFO;
137 typedef struct tagWTI_DEVICES_INFO
139 WCHAR NAME[WT_MAX_NAME_LEN];
140 /* a displayable null- terminated string describing the device,
141 * manufacturer, and revision level.
144 /* flags indicating hardware and driver capabilities, as defined
147 Indicates that the display and digitizer share the same surface.
149 Indicates that the cursor must be in physical contact with the
150 device to report position.
152 Indicates that device can generate events when the cursor is
153 entering and leaving the physical detection range.
155 Indicates that device can uniquely identify the active cursor in
159 /* the number of supported cursor types.*/
161 /* the first cursor type number for the device. */
163 /* the maximum packet report rate in Hertz. */
165 /* a bit mask indicating which packet data items are always available.*/
167 /* a bit mask indicating which packet data items are physically
168 * relative, i.e., items for which the hardware can only report change,
169 * not absolute measurement.
172 /* a bit mask indicating which packet data items are only available when
173 * certain cursors are connected. The individual cursor descriptions
174 * must be consulted to determine which cursors return which data.
179 /* the size of tablet context margins in tablet native coordinates, in
180 * the x, y, and z directions, respectively.
185 /* the tablet's range and resolution capabilities, in the x, y, and z
186 * axes, respectively.
190 /* the tablet's range and resolution capabilities, for the normal and
191 * tangential pressure inputs, respectively.
194 /* a 3-element array describing the tablet's orientation range and
195 * resolution capabilities.
198 /* a 3-element array describing the tablet's rotation range and
199 * resolution capabilities.
201 WCHAR PNPID[WT_MAX_NAME_LEN];
202 /* a null-terminated string containing the devices Plug and Play ID.*/
203 } WTI_DEVICES_INFO, *LPWTI_DEVICES_INFO;
205 typedef struct tagWTPACKET {
216 UINT pkNormalPressure;
217 UINT pkTangentPressure;
218 ORIENTATION pkOrientation;
219 ROTATION pkRotation; /* 1.1 */
220 } WTPACKET, *LPWTPACKET;
225 #include <X11/Xlib.h>
226 #include <X11/extensions/XInput.h>
228 static int motion_type;
229 static int button_press_type;
230 static int button_release_type;
231 static int key_press_type;
232 static int key_release_type;
233 static int proximity_in_type;
234 static int proximity_out_type;
236 static HWND hwndTabletDefault;
237 static WTPACKET gMsgPacket;
238 static DWORD gSerial;
239 static INT button_state[10];
243 static LOGCONTEXTW gSysContext;
244 static WTI_DEVICES_INFO gSysDevice;
245 static WTI_CURSORS_INFO gSysCursor[CURSORMAX];
246 static INT gNumCursors;
250 static void *xinput_handle;
252 #define MAKE_FUNCPTR(f) static typeof(f) * p##f;
253 MAKE_FUNCPTR(XListInputDevices)
254 MAKE_FUNCPTR(XFreeDeviceList)
255 MAKE_FUNCPTR(XOpenDevice)
256 MAKE_FUNCPTR(XQueryDeviceState)
257 MAKE_FUNCPTR(XGetDeviceButtonMapping)
258 MAKE_FUNCPTR(XCloseDevice)
259 MAKE_FUNCPTR(XSelectExtensionEvent)
260 MAKE_FUNCPTR(XFreeDeviceState)
263 static INT X11DRV_XInput_Init(void)
265 xinput_handle = wine_dlopen(SONAME_LIBXI, RTLD_NOW, NULL, 0);
268 #define LOAD_FUNCPTR(f) if((p##f = wine_dlsym(xinput_handle, #f, NULL, 0)) == NULL) goto sym_not_found;
269 LOAD_FUNCPTR(XListInputDevices)
270 LOAD_FUNCPTR(XFreeDeviceList)
271 LOAD_FUNCPTR(XOpenDevice)
272 LOAD_FUNCPTR(XGetDeviceButtonMapping)
273 LOAD_FUNCPTR(XCloseDevice)
274 LOAD_FUNCPTR(XSelectExtensionEvent)
275 LOAD_FUNCPTR(XQueryDeviceState)
276 LOAD_FUNCPTR(XFreeDeviceState)
284 static int Tablet_ErrorHandler(Display *dpy, XErrorEvent *event, void* arg)
289 void X11DRV_LoadTabletInfo(HWND hwnddefault)
291 const WCHAR SZ_CONTEXT_NAME[] = {'W','i','n','e',' ','T','a','b','l','e','t',' ','C','o','n','t','e','x','t',0};
292 const WCHAR SZ_DEVICE_NAME[] = {'W','i','n','e',' ','T','a','b','l','e','t',' ','D','e','v','i','c','e',0};
293 const WCHAR SZ_NON_PLUGINPLAY[] = {'n','o','n','-','p','l','u','g','i','n','p','l','a','y',0};
295 struct x11drv_thread_data *data = x11drv_thread_data();
299 XDeviceInfo *devices;
300 XDeviceInfo *target = NULL;
301 BOOL axis_read_complete= FALSE;
304 XButtonInfoPtr Button;
305 XValuatorInfoPtr Val;
310 if (!X11DRV_XInput_Init())
312 ERR("Unable to initialized the XInput library.\n");
316 hwndTabletDefault = hwnddefault;
318 /* Do base initializaion */
319 strcpyW(gSysContext.lcName, SZ_CONTEXT_NAME);
320 strcpyW(gSysDevice.NAME, SZ_DEVICE_NAME);
322 gSysContext.lcOptions = CXO_SYSTEM;
323 gSysContext.lcLocks = CXL_INSIZE | CXL_INASPECT | CXL_MARGIN |
324 CXL_SENSITIVITY | CXL_SYSOUT;
326 gSysContext.lcMsgBase= WT_DEFBASE;
327 gSysContext.lcDevice = 0;
328 gSysContext.lcPktData =
329 PK_CONTEXT | PK_STATUS | PK_SERIAL_NUMBER| PK_TIME | PK_CURSOR |
330 PK_BUTTONS | PK_X | PK_Y | PK_NORMAL_PRESSURE | PK_ORIENTATION;
331 gSysContext.lcMoveMask=
332 PK_BUTTONS | PK_X | PK_Y | PK_NORMAL_PRESSURE | PK_ORIENTATION;
333 gSysContext.lcStatus = CXS_ONTOP;
334 gSysContext.lcPktRate = 100;
335 gSysContext.lcBtnDnMask = 0xffffffff;
336 gSysContext.lcBtnUpMask = 0xffffffff;
337 gSysContext.lcSensX = 65536;
338 gSysContext.lcSensY = 65536;
339 gSysContext.lcSensX = 65536;
340 gSysContext.lcSensZ = 65536;
341 gSysContext.lcSysSensX= 65536;
342 gSysContext.lcSysSensY= 65536;
344 /* Device Defaults */
345 gSysDevice.HARDWARE = HWC_HARDPROX|HWC_PHYSID_CURSORS;
346 gSysDevice.FIRSTCSR= 0;
347 gSysDevice.PKTRATE = 100;
349 PK_CONTEXT | PK_STATUS | PK_SERIAL_NUMBER| PK_TIME | PK_CURSOR |
350 PK_BUTTONS | PK_X | PK_Y | PK_NORMAL_PRESSURE | PK_ORIENTATION;
351 strcpyW(gSysDevice.PNPID, SZ_NON_PLUGINPLAY);
356 devices = pXListInputDevices(data->display, &num_devices);
359 WARN("XInput Extenstions reported as not avalable\n");
363 for (loop=0; loop < num_devices; loop++)
367 TRACE("Trying device %i(%s)\n",loop,devices[loop].name);
368 if (devices[loop].use == IsXExtensionDevice)
370 LPWTI_CURSORS_INFO cursor;
372 TRACE("Is Extension Device\n");
374 target = &devices[loop];
375 cursor = &gSysCursor[cursor_target];
377 if (strlen(target->name) >= WT_MAX_NAME_LEN)
379 ERR("Input device '%s' name too long - skipping\n", wine_dbgstr_a(target->name));
384 X11DRV_expect_error(data->display, Tablet_ErrorHandler, NULL);
385 opendevice = pXOpenDevice(data->display,target->id);
386 if (!X11DRV_check_error() && opendevice)
388 unsigned char map[32];
392 X11DRV_expect_error(data->display,Tablet_ErrorHandler,NULL);
393 pXGetDeviceButtonMapping(data->display, opendevice, map, 32);
394 if (X11DRV_check_error())
396 TRACE("No buttons, Non Tablet Device\n");
397 pXCloseDevice(data->display, opendevice);
402 for (i=0; i< cursor->BUTTONS; i++,shft++)
404 cursor->BUTTONMAP[i] = map[i];
405 cursor->SYSBTNMAP[i] = (1<<shft);
407 pXCloseDevice(data->display, opendevice);
411 WARN("Unable to open device %s\n",target->name);
415 MultiByteToWideChar(CP_UNIXCP, 0, target->name, -1, cursor->NAME, WT_MAX_NAME_LEN);
418 cursor->PKTDATA = PK_TIME | PK_CURSOR | PK_BUTTONS | PK_X | PK_Y |
419 PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE |
422 cursor->PHYSID = cursor_target;
423 cursor->NPBUTTON = 1;
424 cursor->NPBTNMARKS[0] = 0 ;
425 cursor->NPBTNMARKS[1] = 1 ;
426 cursor->CAPABILITIES = CRC_MULTIMODE;
427 if (strcasecmp(target->name,"stylus")==0)
428 cursor->TYPE = 0x4825;
429 if (strcasecmp(target->name,"eraser")==0)
430 cursor->TYPE = 0xc85a;
433 any = (XAnyClassPtr) (target->inputclassinfo);
435 for (class_loop = 0; class_loop < target->num_classes; class_loop++)
440 if (!axis_read_complete)
442 Val = (XValuatorInfoPtr) any;
443 Axis = (XAxisInfoPtr) ((char *) Val + sizeof
446 if (Val->num_axes>=1)
449 gSysDevice.X.axMin = Axis->min_value;
450 gSysDevice.X.axMax= Axis->max_value;
451 gSysDevice.X.axUnits = TU_INCHES;
452 gSysDevice.X.axResolution = Axis->resolution;
453 gSysContext.lcInOrgX = Axis->min_value;
454 gSysContext.lcSysOrgX = Axis->min_value;
455 gSysContext.lcInExtX = Axis->max_value;
456 gSysContext.lcSysExtX = Axis->max_value;
459 if (Val->num_axes>=2)
462 gSysDevice.Y.axMin = Axis->min_value;
463 gSysDevice.Y.axMax= Axis->max_value;
464 gSysDevice.Y.axUnits = TU_INCHES;
465 gSysDevice.Y.axResolution = Axis->resolution;
466 gSysContext.lcInOrgY = Axis->min_value;
467 gSysContext.lcSysOrgY = Axis->min_value;
468 gSysContext.lcInExtY = Axis->max_value;
469 gSysContext.lcSysExtY = Axis->max_value;
472 if (Val->num_axes>=3)
474 /* Axis 3 is Normal Pressure */
475 gSysDevice.NPRESSURE.axMin = Axis->min_value;
476 gSysDevice.NPRESSURE.axMax= Axis->max_value;
477 gSysDevice.NPRESSURE.axUnits = TU_INCHES;
478 gSysDevice.NPRESSURE.axResolution =
482 if (Val->num_axes >= 5)
484 /* Axis 4 and 5 are X and Y tilt */
485 XAxisInfoPtr XAxis = Axis;
487 if (max (abs(Axis->max_value),
488 abs(XAxis->max_value)))
490 gSysDevice.ORIENTATION[0].axMin = 0;
491 gSysDevice.ORIENTATION[0].axMax = 3600;
492 gSysDevice.ORIENTATION[0].axUnits = TU_CIRCLE;
493 gSysDevice.ORIENTATION[0].axResolution
495 gSysDevice.ORIENTATION[1].axMin = -1000;
496 gSysDevice.ORIENTATION[1].axMax = 1000;
497 gSysDevice.ORIENTATION[1].axUnits = TU_CIRCLE;
498 gSysDevice.ORIENTATION[1].axResolution
503 axis_read_complete = TRUE;
512 Button = (XButtonInfoPtr) any;
513 cursor->BUTTONS = Button->num_buttons;
514 cursor->BTNNAMES = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*cchBuf);
515 for (i = 0; i < cursor->BUTTONS; i++)
517 /* FIXME - these names are probably incorrect */
518 int cch = strlenW(cursor->NAME) + 1;
519 while (cch > cchBuf - cchPos - 1) /* we want one extra byte for the last NUL */
522 cursor->BTNNAMES = HeapReAlloc(GetProcessHeap(), 0, cursor->BTNNAMES, sizeof(WCHAR)*cchBuf);
525 strcpyW(cursor->BTNNAMES + cchPos, cursor->NAME);
528 cursor->BTNNAMES[cchPos++] = 0;
529 cursor->BTNNAMES = HeapReAlloc(GetProcessHeap(), 0, cursor->BTNNAMES, sizeof(WCHAR)*cchPos);
530 cursor->cchBTNNAMES = cchPos;
534 any = (XAnyClassPtr) ((char*) any + any->length);
538 pXFreeDeviceList(devices);
540 gSysDevice.NCSRTYPES = cursor_target+1;
541 gNumCursors = cursor_target+1;
544 static int figure_deg(int x, int y)
550 rc = (int) 10 * (atan( (FLOAT)abs(y) / (FLOAT)abs(x)) / (3.1415 / 180));
577 static int get_button_state(int deviceid)
579 return button_state[deviceid];
582 static void set_button_state(XID deviceid)
584 struct x11drv_thread_data *data = x11drv_thread_data();
592 device = pXOpenDevice(data->display,deviceid);
593 state = pXQueryDeviceState(data->display,device);
598 for (loop = 0; loop < state->num_classes; loop++)
600 if (class->class == ButtonClass)
603 XButtonState *button_state = (XButtonState*)class;
604 for (loop2 = 0; loop2 < button_state->num_buttons; loop2++)
606 if (button_state->buttons[loop2 / 8] & (1 << (loop2 % 8)))
612 class = (XInputClass *) ((char *) class + class->length);
615 pXFreeDeviceState(state);
617 button_state[deviceid] = rc;
620 static void motion_event( HWND hwnd, XEvent *event )
622 XDeviceMotionEvent *motion = (XDeviceMotionEvent *)event;
623 LPWTI_CURSORS_INFO cursor = &gSysCursor[motion->deviceid];
625 memset(&gMsgPacket,0,sizeof(WTPACKET));
627 TRACE("Received tablet motion event (%p)\n",hwnd);
629 /* Set cursor to inverted if cursor is the eraser */
630 gMsgPacket.pkStatus = (cursor->TYPE == 0xc85a ?TPS_INVERT:0);
631 gMsgPacket.pkTime = EVENT_x11_time_to_win32_time(motion->time);
632 gMsgPacket.pkSerialNumber = gSerial++;
633 gMsgPacket.pkCursor = motion->deviceid;
634 gMsgPacket.pkX = motion->axis_data[0];
635 gMsgPacket.pkY = motion->axis_data[1];
636 gMsgPacket.pkOrientation.orAzimuth = figure_deg(motion->axis_data[3],motion->axis_data[4]);
637 gMsgPacket.pkOrientation.orAltitude = ((1000 - 15 * max
638 (abs(motion->axis_data[3]),
639 abs(motion->axis_data[4])))
640 * (gMsgPacket.pkStatus & TPS_INVERT?-1:1));
641 gMsgPacket.pkNormalPressure = motion->axis_data[2];
642 gMsgPacket.pkButtons = get_button_state(motion->deviceid);
643 SendMessageW(hwndTabletDefault,WT_PACKET,0,(LPARAM)hwnd);
646 static void button_event( HWND hwnd, XEvent *event )
648 XDeviceButtonEvent *button = (XDeviceButtonEvent *) event;
649 LPWTI_CURSORS_INFO cursor = &gSysCursor[button->deviceid];
651 memset(&gMsgPacket,0,sizeof(WTPACKET));
653 TRACE("Received tablet button %s event\n", (event->type == button_press_type)?"press":"release");
655 /* Set cursor to inverted if cursor is the eraser */
656 gMsgPacket.pkStatus = (cursor->TYPE == 0xc85a ?TPS_INVERT:0);
657 set_button_state(button->deviceid);
658 gMsgPacket.pkTime = EVENT_x11_time_to_win32_time(button->time);
659 gMsgPacket.pkSerialNumber = gSerial++;
660 gMsgPacket.pkCursor = button->deviceid;
661 gMsgPacket.pkX = button->axis_data[0];
662 gMsgPacket.pkY = button->axis_data[1];
663 gMsgPacket.pkOrientation.orAzimuth = figure_deg(button->axis_data[3],button->axis_data[4]);
664 gMsgPacket.pkOrientation.orAltitude = ((1000 - 15 * max(abs(button->axis_data[3]),
665 abs(button->axis_data[4])))
666 * (gMsgPacket.pkStatus & TPS_INVERT?-1:1));
667 gMsgPacket.pkNormalPressure = button->axis_data[2];
668 gMsgPacket.pkButtons = get_button_state(button->deviceid);
669 SendMessageW(hwndTabletDefault,WT_PACKET,0,(LPARAM)hwnd);
672 static void key_event( HWND hwnd, XEvent *event )
674 if (event->type == key_press_type)
675 FIXME("Received tablet key press event\n");
677 FIXME("Received tablet key release event\n");
680 static void proximity_event( HWND hwnd, XEvent *event )
682 XProximityNotifyEvent *proximity = (XProximityNotifyEvent *) event;
683 LPWTI_CURSORS_INFO cursor = &gSysCursor[proximity->deviceid];
685 memset(&gMsgPacket,0,sizeof(WTPACKET));
687 TRACE("Received tablet proximity event\n");
688 /* Set cursor to inverted if cursor is the eraser */
689 gMsgPacket.pkStatus = (cursor->TYPE == 0xc85a ?TPS_INVERT:0);
690 gMsgPacket.pkStatus |= (event->type==proximity_out_type)?TPS_PROXIMITY:0;
691 gMsgPacket.pkTime = EVENT_x11_time_to_win32_time(proximity->time);
692 gMsgPacket.pkSerialNumber = gSerial++;
693 gMsgPacket.pkCursor = proximity->deviceid;
694 gMsgPacket.pkX = proximity->axis_data[0];
695 gMsgPacket.pkY = proximity->axis_data[1];
696 gMsgPacket.pkOrientation.orAzimuth = figure_deg(proximity->axis_data[3],proximity->axis_data[4]);
697 gMsgPacket.pkOrientation.orAltitude = ((1000 - 15 * max(abs(proximity->axis_data[3]),
698 abs(proximity->axis_data[4])))
699 * (gMsgPacket.pkStatus & TPS_INVERT?-1:1));
700 gMsgPacket.pkNormalPressure = proximity->axis_data[2];
701 gMsgPacket.pkButtons = get_button_state(proximity->deviceid);
703 SendMessageW(hwndTabletDefault, WT_PROXIMITY, (event->type == proximity_in_type), (LPARAM)hwnd);
706 int X11DRV_AttachEventQueueToTablet(HWND hOwner)
708 struct x11drv_thread_data *data = x11drv_thread_data();
712 XDeviceInfo *devices;
713 XDeviceInfo *target = NULL;
715 XEventClass event_list[7];
716 Window win = X11DRV_get_whole_window( hOwner );
720 TRACE("Creating context for window %p (%lx) %i cursors\n", hOwner, win, gNumCursors);
723 devices = pXListInputDevices(data->display, &num_devices);
725 X11DRV_expect_error(data->display,Tablet_ErrorHandler,NULL);
726 for (cur_loop=0; cur_loop < gNumCursors; cur_loop++)
728 char cursorNameA[WT_MAX_NAME_LEN];
731 /* the cursor name fits in the buffer because too long names are skipped */
732 WideCharToMultiByte(CP_UNIXCP, 0, gSysCursor[cur_loop].NAME, -1, cursorNameA, WT_MAX_NAME_LEN, NULL, NULL);
733 for (loop=0; loop < num_devices; loop ++)
734 if (strcmp(devices[loop].name, cursorNameA) == 0)
735 target = &devices[loop];
737 TRACE("Opening cursor %i id %i\n",cur_loop,(INT)target->id);
739 the_device = pXOpenDevice(data->display, target->id);
743 WARN("Unable to Open device\n");
747 if (the_device->num_classes > 0)
749 DeviceKeyPress(the_device, key_press_type, event_list[event_number]);
750 if (event_list[event_number]) event_number++;
751 DeviceKeyRelease(the_device, key_release_type, event_list[event_number]);
752 if (event_list[event_number]) event_number++;
753 DeviceButtonPress(the_device, button_press_type, event_list[event_number]);
754 if (event_list[event_number]) event_number++;
755 DeviceButtonRelease(the_device, button_release_type, event_list[event_number]);
756 if (event_list[event_number]) event_number++;
757 DeviceMotionNotify(the_device, motion_type, event_list[event_number]);
758 if (event_list[event_number]) event_number++;
759 ProximityIn(the_device, proximity_in_type, event_list[event_number]);
760 if (event_list[event_number]) event_number++;
761 ProximityOut(the_device, proximity_out_type, event_list[event_number]);
762 if (event_list[event_number]) event_number++;
764 if (key_press_type) X11DRV_register_event_handler( key_press_type, key_event );
765 if (key_release_type) X11DRV_register_event_handler( key_release_type, key_event );
766 if (button_press_type) X11DRV_register_event_handler( button_press_type, button_event );
767 if (button_release_type) X11DRV_register_event_handler( button_release_type, button_event );
768 if (motion_type) X11DRV_register_event_handler( motion_type, motion_event );
769 if (proximity_in_type) X11DRV_register_event_handler( proximity_in_type, proximity_event );
770 if (proximity_out_type) X11DRV_register_event_handler( proximity_out_type, proximity_event );
772 pXSelectExtensionEvent(data->display, win, event_list, event_number);
775 XSync(data->display, False);
776 X11DRV_check_error();
778 if (NULL != devices) pXFreeDeviceList(devices);
783 int X11DRV_GetCurrentPacket(LPWTPACKET *packet)
785 memcpy(packet,&gMsgPacket,sizeof(WTPACKET));
790 static inline int CopyTabletData(LPVOID target, LPCVOID src, INT size)
793 * It is valid to call CopyTabletData with NULL.
794 * This handles the WTInfo() case where lpOutput is null.
797 memcpy(target,src,size);
801 /***********************************************************************
802 * X11DRV_WTInfoW (X11DRV.@)
804 UINT X11DRV_WTInfoW(UINT wCategory, UINT nIndex, LPVOID lpOutput)
807 * It is valid to call WTInfoA with lpOutput == NULL, as per standard.
808 * lpOutput == NULL signifies the user only wishes
809 * to find the size of the data.
811 * From now on use CopyTabletData to fill lpOutput. memcpy will break
815 LPWTI_CURSORS_INFO tgtcursor;
816 TRACE("(%u, %u, %p)\n", wCategory, nIndex, lpOutput);
821 /* return largest necessary buffer */
822 TRACE("%i cursors\n",gNumCursors);
825 FIXME("Return proper size\n");
835 static const WCHAR driver[] = {'W','i','n','e',' ','W','i','n','t','a','b',' ','1','.','1',0};
836 rc = CopyTabletData(lpOutput, driver, (strlenW(driver) + 1) * sizeof(WCHAR));
839 case IFC_SPECVERSION:
840 version = (0x01) | (0x01 << 8);
841 rc = CopyTabletData(lpOutput, &version,sizeof(WORD));
843 case IFC_IMPLVERSION:
844 version = (0x00) | (0x01 << 8);
845 rc = CopyTabletData(lpOutput, &version,sizeof(WORD));
848 FIXME("WTI_INTERFACE unhandled index %i\n",nIndex);
858 rc = CopyTabletData(lpOutput, &gSysContext,
859 sizeof(LOGCONTEXTW));
862 rc = CopyTabletData(lpOutput, &gSysContext.lcName,
863 (strlenW(gSysContext.lcName)+1) * sizeof(WCHAR));
866 rc = CopyTabletData(lpOutput, &gSysContext.lcOptions,
870 rc = CopyTabletData(lpOutput, &gSysContext.lcStatus,
874 rc= CopyTabletData (lpOutput, &gSysContext.lcLocks,
878 rc = CopyTabletData(lpOutput, &gSysContext.lcMsgBase,
882 rc = CopyTabletData(lpOutput, &gSysContext.lcDevice,
886 rc = CopyTabletData(lpOutput, &gSysContext.lcPktRate,
890 rc = CopyTabletData(lpOutput, &gSysContext.lcPktData,
894 rc = CopyTabletData(lpOutput, &gSysContext.lcPktMode,
898 rc = CopyTabletData(lpOutput, &gSysContext.lcMoveMask,
902 rc = CopyTabletData(lpOutput, &gSysContext.lcBtnDnMask,
906 rc = CopyTabletData(lpOutput, &gSysContext.lcBtnUpMask,
910 rc = CopyTabletData(lpOutput, &gSysContext.lcInOrgX,
914 rc = CopyTabletData(lpOutput, &gSysContext.lcInOrgY,
918 rc = CopyTabletData(lpOutput, &gSysContext.lcInOrgZ,
922 rc = CopyTabletData(lpOutput, &gSysContext.lcInExtX,
926 rc = CopyTabletData(lpOutput, &gSysContext.lcInExtY,
930 rc = CopyTabletData(lpOutput, &gSysContext.lcInExtZ,
934 rc = CopyTabletData(lpOutput, &gSysContext.lcOutOrgX,
938 rc = CopyTabletData(lpOutput, &gSysContext.lcOutOrgY,
942 rc = CopyTabletData(lpOutput, &gSysContext.lcOutOrgZ,
946 rc = CopyTabletData(lpOutput, &gSysContext.lcOutExtX,
950 rc = CopyTabletData(lpOutput, &gSysContext.lcOutExtY,
954 rc = CopyTabletData(lpOutput, &gSysContext.lcOutExtZ,
958 rc = CopyTabletData(lpOutput, &gSysContext.lcSensX,
962 rc = CopyTabletData(lpOutput, &gSysContext.lcSensY,
966 rc = CopyTabletData(lpOutput, &gSysContext.lcSensZ,
970 rc = CopyTabletData(lpOutput, &gSysContext.lcSysMode,
974 rc = CopyTabletData(lpOutput, &gSysContext.lcSysOrgX,
978 rc = CopyTabletData(lpOutput, &gSysContext.lcSysOrgY,
982 rc = CopyTabletData(lpOutput, &gSysContext.lcSysExtX,
986 rc = CopyTabletData(lpOutput, &gSysContext.lcSysExtY,
990 rc = CopyTabletData(lpOutput, &gSysContext.lcSysSensX,
994 rc = CopyTabletData(lpOutput, &gSysContext.lcSysSensY,
998 FIXME("WTI_DEFSYSCTX unhandled index %i\n",nIndex);
1012 tgtcursor = &gSysCursor[wCategory - WTI_CURSORS];
1016 rc = CopyTabletData(lpOutput, &tgtcursor->NAME,
1017 (strlenW(tgtcursor->NAME)+1) * sizeof(WCHAR));
1020 rc = CopyTabletData(lpOutput,&tgtcursor->ACTIVE,
1024 rc = CopyTabletData(lpOutput,&tgtcursor->PKTDATA,
1028 rc = CopyTabletData(lpOutput,&tgtcursor->BUTTONS,
1031 case CSR_BUTTONBITS:
1032 rc = CopyTabletData(lpOutput,&tgtcursor->BUTTONBITS,
1036 FIXME("Button Names not returned correctly\n");
1037 rc = CopyTabletData(lpOutput,&tgtcursor->BTNNAMES,
1038 tgtcursor->cchBTNNAMES*sizeof(WCHAR));
1041 rc = CopyTabletData(lpOutput,&tgtcursor->BUTTONMAP,
1045 rc = CopyTabletData(lpOutput,&tgtcursor->SYSBTNMAP,
1048 case CSR_NPBTNMARKS:
1049 rc = CopyTabletData(lpOutput,&tgtcursor->NPBTNMARKS,
1053 rc = CopyTabletData(lpOutput,&tgtcursor->NPBUTTON,
1056 case CSR_NPRESPONSE:
1057 FIXME("Not returning CSR_NPRESPONSE correctly\n");
1061 rc = CopyTabletData(lpOutput,&tgtcursor->TPBUTTON,
1064 case CSR_TPBTNMARKS:
1065 rc = CopyTabletData(lpOutput,&tgtcursor->TPBTNMARKS,
1068 case CSR_TPRESPONSE:
1069 FIXME("Not returning CSR_TPRESPONSE correctly\n");
1075 id = tgtcursor->PHYSID;
1076 id += (wCategory - WTI_CURSORS);
1077 rc = CopyTabletData(lpOutput,&id,sizeof(DWORD));
1081 rc = CopyTabletData(lpOutput,&tgtcursor->MODE,sizeof(UINT));
1083 case CSR_MINPKTDATA:
1084 rc = CopyTabletData(lpOutput,&tgtcursor->MINPKTDATA,
1087 case CSR_MINBUTTONS:
1088 rc = CopyTabletData(lpOutput,&tgtcursor->MINBUTTONS,
1091 case CSR_CAPABILITIES:
1092 rc = CopyTabletData(lpOutput,&tgtcursor->CAPABILITIES,
1096 rc = CopyTabletData(lpOutput,&tgtcursor->TYPE,
1100 FIXME("WTI_CURSORS unhandled index %i\n",nIndex);
1108 rc = CopyTabletData(lpOutput,gSysDevice.NAME,
1109 (strlenW(gSysDevice.NAME)+1) * sizeof(WCHAR));
1112 rc = CopyTabletData(lpOutput,&gSysDevice.HARDWARE,
1116 rc = CopyTabletData(lpOutput,&gSysDevice.NCSRTYPES,
1120 rc = CopyTabletData(lpOutput,&gSysDevice.FIRSTCSR,
1124 rc = CopyTabletData(lpOutput,&gSysDevice.PKTRATE,
1128 rc = CopyTabletData(lpOutput,&gSysDevice.PKTDATA,
1132 rc = CopyTabletData(lpOutput,&gSysDevice.PKTMODE,
1136 rc = CopyTabletData(lpOutput,&gSysDevice.CSRDATA,
1140 rc = CopyTabletData(lpOutput,&gSysDevice.XMARGIN,
1144 rc = CopyTabletData(lpOutput,&gSysDevice.YMARGIN,
1148 rc = 0; /* unsupported */
1150 rc = CopyTabletData(lpOutput,&gSysDevice.ZMARGIN,
1155 rc = CopyTabletData(lpOutput,&gSysDevice.X,
1159 rc = CopyTabletData(lpOutput,&gSysDevice.Y,
1163 rc = 0; /* unsupported */
1165 rc = CopyTabletData(lpOutput,&gSysDevice.Z,
1170 rc = CopyTabletData(lpOutput,&gSysDevice.NPRESSURE,
1174 rc = 0; /* unsupported */
1176 rc = CopyTabletData(lpOutput,&gSysDevice.TPRESSURE,
1180 case DVC_ORIENTATION:
1181 rc = CopyTabletData(lpOutput,&gSysDevice.ORIENTATION,
1185 rc = 0; /* unsupported */
1187 rc = CopyTabletData(lpOutput,&gSysDevice.ROTATION,
1192 rc = CopyTabletData(lpOutput,gSysDevice.PNPID,
1193 (strlenW(gSysDevice.PNPID)+1)*sizeof(WCHAR));
1196 FIXME("WTI_DEVICES unhandled index %i\n",nIndex);
1201 FIXME("Unhandled Category %i\n",wCategory);
1206 #else /* SONAME_LIBXI */
1208 /***********************************************************************
1209 * AttachEventQueueToTablet (X11DRV.@)
1211 int X11DRV_AttachEventQueueToTablet(HWND hOwner)
1216 /***********************************************************************
1217 * GetCurrentPacket (X11DRV.@)
1219 int X11DRV_GetCurrentPacket(LPWTPACKET *packet)
1224 /***********************************************************************
1225 * LoadTabletInfo (X11DRV.@)
1227 void X11DRV_LoadTabletInfo(HWND hwnddefault)
1231 /***********************************************************************
1232 * WTInfoW (X11DRV.@)
1234 UINT X11DRV_WTInfoW(UINT wCategory, UINT nIndex, LPVOID lpOutput)
1239 #endif /* SONAME_LIBXI */