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
22 #include "wine/port.h"
28 #include "wine/library.h"
29 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(wintab32);
33 WINE_DECLARE_DEBUG_CHANNEL(event);
35 typedef struct tagWTI_CURSORS_INFO
38 /* a displayable zero-terminated string containing the name of the
42 /* whether the cursor is currently connected. */
44 /* a bit mask indicating the packet data items supported when this
45 * cursor is connected.
48 /* the number of buttons on this cursor. */
50 /* the number of bits of raw button data returned by the hardware.*/
51 CHAR BTNNAMES[1024]; /* FIXME: make this dynamic */
52 /* a list of zero-terminated strings containing the names of the
53 * cursor's buttons. The number of names in the list is the same as the
54 * number of buttons on the cursor. The names are separated by a single
55 * zero character; the list is terminated by two zero characters.
58 /* a 32 byte array of logical button numbers, one for each physical
62 /* a 32 byte array of button action codes, one for each logical
66 /* the physical button number of the button that is controlled by normal
70 /* an array of two UINTs, specifying the button marks for the normal
71 * pressure button. The first UINT contains the release mark; the second
72 * contains the press mark.
75 /* an array of UINTs describing the pressure response curve for normal
79 /* the physical button number of the button that is controlled by
80 * tangential pressure.
83 /* an array of two UINTs, specifying the button marks for the tangential
84 * pressure button. The first UINT contains the release mark; the second
85 * contains the press mark.
88 /* an array of UINTs describing the pressure response curve for
89 * tangential pressure.
92 /* a manufacturer-specific physical identifier for the cursor. This
93 * value will distinguish the physical cursor from others on the same
94 * device. This physical identifier allows applications to bind
95 * functions to specific physical cursors, even if category numbers
96 * change and multiple, otherwise identical, physical cursors are
100 /* the cursor mode number of this cursor type, if this cursor type has
101 * the CRC_MULTIMODE capability.
104 /* the minimum set of data available from a physical cursor in this
105 * cursor type, if this cursor type has the CRC_AGGREGATE capability.
108 /* the minimum number of buttons of physical cursors in the cursor type,
109 * if this cursor type has the CRC_AGGREGATE capability.
112 /* flags indicating cursor capabilities, as defined below:
114 Indicates this cursor type describes one of several modes of a
115 single physical cursor. Consecutive cursor type categories
116 describe the modes; the CSR_MODE data item gives the mode number
119 Indicates this cursor type describes several physical cursors
120 that cannot be distinguished by software.
122 Indicates this cursor type describes the physical cursor in its
123 inverted orientation; the previous consecutive cursor type
124 category describes the normal orientation.
127 /* Manufacturer Unique id for the item type */
128 } WTI_CURSORS_INFO, *LPWTI_CURSORS_INFO;
131 typedef struct tagWTI_DEVICES_INFO
134 /* a displayable null- terminated string describing the device,
135 * manufacturer, and revision level.
138 /* flags indicating hardware and driver capabilities, as defined
141 Indicates that the display and digitizer share the same surface.
143 Indicates that the cursor must be in physical contact with the
144 device to report position.
146 Indicates that device can generate events when the cursor is
147 entering and leaving the physical detection range.
149 Indicates that device can uniquely identify the active cursor in
153 /* the number of supported cursor types.*/
155 /* the first cursor type number for the device. */
157 /* the maximum packet report rate in Hertz. */
159 /* a bit mask indicating which packet data items are always available.*/
161 /* a bit mask indicating which packet data items are physically
162 * relative, i.e., items for which the hardware can only report change,
163 * not absolute measurement.
166 /* a bit mask indicating which packet data items are only available when
167 * certain cursors are connected. The individual cursor descriptions
168 * must be consulted to determine which cursors return which data.
173 /* the size of tablet context margins in tablet native coordinates, in
174 * the x, y, and z directions, respectively.
179 /* the tablet's range and resolution capabilities, in the x, y, and z
180 * axes, respectively.
184 /* the tablet's range and resolution capabilities, for the normal and
185 * tangential pressure inputs, respectively.
188 /* a 3-element array describing the tablet's orientation range and
189 * resolution capabilities.
192 /* a 3-element array describing the tablet's rotation range and
193 * resolution capabilities.
196 /* a null-terminated string containing the devices Plug and Play ID.*/
197 } WTI_DEVICES_INFO, *LPWTI_DEVICES_INFO;
199 typedef struct tagWTPACKET {
210 UINT pkNormalPressure;
211 UINT pkTangentPressure;
212 ORIENTATION pkOrientation;
213 ROTATION pkRotation; /* 1.1 */
214 } WTPACKET, *LPWTPACKET;
217 #ifdef HAVE_X11_EXTENSIONS_XINPUT_H
219 #include <X11/Xlib.h>
220 #include <X11/extensions/XInput.h>
222 static int motion_type;
223 static int button_press_type;
224 static int button_release_type;
225 static int key_press_type;
226 static int key_release_type;
227 static int proximity_in_type;
228 static int proximity_out_type;
230 static HWND hwndTabletDefault;
231 static WTPACKET gMsgPacket;
232 static DWORD gSerial;
233 static INT button_state[10];
237 static LOGCONTEXTA gSysContext;
238 static WTI_DEVICES_INFO gSysDevice;
239 static WTI_CURSORS_INFO gSysCursor[CURSORMAX];
240 static INT gNumCursors;
244 #define SONAME_LIBXI "libXi.so"
248 static void *xinput_handle;
250 #define MAKE_FUNCPTR(f) static typeof(f) * p##f;
251 MAKE_FUNCPTR(XListInputDevices)
252 MAKE_FUNCPTR(XFreeDeviceList)
253 MAKE_FUNCPTR(XOpenDevice)
254 MAKE_FUNCPTR(XQueryDeviceState)
255 MAKE_FUNCPTR(XGetDeviceButtonMapping)
256 MAKE_FUNCPTR(XCloseDevice)
257 MAKE_FUNCPTR(XSelectExtensionEvent)
258 MAKE_FUNCPTR(XFreeDeviceState)
261 static INT X11DRV_XInput_Init(void)
263 xinput_handle = wine_dlopen(SONAME_LIBXI, RTLD_NOW, NULL, 0);
266 #define LOAD_FUNCPTR(f) if((p##f = wine_dlsym(xinput_handle, #f, NULL, 0)) == NULL) goto sym_not_found;
267 LOAD_FUNCPTR(XListInputDevices)
268 LOAD_FUNCPTR(XFreeDeviceList)
269 LOAD_FUNCPTR(XOpenDevice)
270 LOAD_FUNCPTR(XGetDeviceButtonMapping)
271 LOAD_FUNCPTR(XCloseDevice)
272 LOAD_FUNCPTR(XSelectExtensionEvent)
273 LOAD_FUNCPTR(XQueryDeviceState)
274 LOAD_FUNCPTR(XFreeDeviceState)
282 static int Tablet_ErrorHandler(Display *dpy, XErrorEvent *event, void* arg)
287 void X11DRV_LoadTabletInfo(HWND hwnddefault)
289 struct x11drv_thread_data *data = x11drv_thread_data();
293 XDeviceInfo *devices;
294 XDeviceInfo *target = NULL;
295 BOOL axis_read_complete= FALSE;
298 XButtonInfoPtr Button;
299 XValuatorInfoPtr Val;
304 if (!X11DRV_XInput_Init())
306 ERR("Unable to initialized the XInput library.\n");
310 hwndTabletDefault = hwnddefault;
312 /* Do base initializaion */
313 strcpy(gSysContext.lcName, "Wine Tablet Context");
314 strcpy(gSysDevice.NAME,"Wine Tablet Device");
316 gSysContext.lcOptions = CXO_SYSTEM;
317 gSysContext.lcLocks = CXL_INSIZE | CXL_INASPECT | CXL_MARGIN |
318 CXL_SENSITIVITY | CXL_SYSOUT;
320 gSysContext.lcMsgBase= WT_DEFBASE;
321 gSysContext.lcDevice = 0;
322 gSysContext.lcPktData =
323 PK_CONTEXT | PK_STATUS | PK_SERIAL_NUMBER| PK_TIME | PK_CURSOR |
324 PK_BUTTONS | PK_X | PK_Y | PK_NORMAL_PRESSURE | PK_ORIENTATION;
325 gSysContext.lcMoveMask=
326 PK_BUTTONS | PK_X | PK_Y | PK_NORMAL_PRESSURE | PK_ORIENTATION;
327 gSysContext.lcStatus = CXS_ONTOP;
328 gSysContext.lcPktRate = 100;
329 gSysContext.lcBtnDnMask = 0xffffffff;
330 gSysContext.lcBtnUpMask = 0xffffffff;
331 gSysContext.lcSensX = 65536;
332 gSysContext.lcSensY = 65536;
333 gSysContext.lcSensX = 65536;
334 gSysContext.lcSensZ = 65536;
335 gSysContext.lcSysSensX= 65536;
336 gSysContext.lcSysSensY= 65536;
338 /* Device Defaults */
339 gSysDevice.HARDWARE = HWC_HARDPROX|HWC_PHYSID_CURSORS;
340 gSysDevice.FIRSTCSR= 0;
341 gSysDevice.PKTRATE = 100;
343 PK_CONTEXT | PK_STATUS | PK_SERIAL_NUMBER| PK_TIME | PK_CURSOR |
344 PK_BUTTONS | PK_X | PK_Y | PK_NORMAL_PRESSURE | PK_ORIENTATION;
345 strcpy(gSysDevice.PNPID,"non-pluginplay");
350 devices = pXListInputDevices(data->display, &num_devices);
353 WARN("XInput Extenstions reported as not avalable\n");
357 for (loop=0; loop < num_devices; loop++)
361 TRACE("Trying device %i(%s)\n",loop,devices[loop].name);
362 if (devices[loop].use == IsXExtensionDevice)
364 LPWTI_CURSORS_INFO cursor;
366 TRACE("Is Extension Device\n");
368 target = &devices[loop];
369 cursor = &gSysCursor[cursor_target];
371 opendevice = pXOpenDevice(data->display,target->id);
374 unsigned char map[32];
378 X11DRV_expect_error(data->display,Tablet_ErrorHandler,NULL);
379 pXGetDeviceButtonMapping(data->display, opendevice, map, 32);
380 if (X11DRV_check_error())
382 TRACE("No buttons, Non Tablet Device\n");
383 pXCloseDevice(data->display, opendevice);
388 for (i=0; i< cursor->BUTTONS; i++,shft++)
390 cursor->BUTTONMAP[i] = map[i];
391 cursor->SYSBTNMAP[i] = (1<<shft);
393 pXCloseDevice(data->display, opendevice);
397 WARN("Unable to open device %s\n",target->name);
402 strcpy(cursor->NAME,target->name);
405 cursor->PKTDATA = PK_TIME | PK_CURSOR | PK_BUTTONS | PK_X | PK_Y |
406 PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE |
409 cursor->PHYSID = cursor_target;
410 cursor->NPBUTTON = 1;
411 cursor->NPBTNMARKS[0] = 0 ;
412 cursor->NPBTNMARKS[1] = 1 ;
413 cursor->CAPABILITIES = CRC_MULTIMODE;
414 if (strcasecmp(cursor->NAME,"stylus")==0)
415 cursor->TYPE = 0x4825;
416 if (strcasecmp(cursor->NAME,"eraser")==0)
417 cursor->TYPE = 0xc85a;
420 any = (XAnyClassPtr) (target->inputclassinfo);
422 for (class_loop = 0; class_loop < target->num_classes; class_loop++)
427 if (!axis_read_complete)
429 Val = (XValuatorInfoPtr) any;
430 Axis = (XAxisInfoPtr) ((char *) Val + sizeof
433 if (Val->num_axes>=1)
436 gSysDevice.X.axMin = Axis->min_value;
437 gSysDevice.X.axMax= Axis->max_value;
438 gSysDevice.X.axUnits = TU_INCHES;
439 gSysDevice.X.axResolution = Axis->resolution;
440 gSysContext.lcInOrgX = Axis->min_value;
441 gSysContext.lcSysOrgX = Axis->min_value;
442 gSysContext.lcInExtX = Axis->max_value;
443 gSysContext.lcSysExtX = Axis->max_value;
446 if (Val->num_axes>=2)
449 gSysDevice.Y.axMin = Axis->min_value;
450 gSysDevice.Y.axMax= Axis->max_value;
451 gSysDevice.Y.axUnits = TU_INCHES;
452 gSysDevice.Y.axResolution = Axis->resolution;
453 gSysContext.lcInOrgY = Axis->min_value;
454 gSysContext.lcSysOrgY = Axis->min_value;
455 gSysContext.lcInExtY = Axis->max_value;
456 gSysContext.lcSysExtY = Axis->max_value;
459 if (Val->num_axes>=3)
461 /* Axis 3 is Normal Pressure */
462 gSysDevice.NPRESSURE.axMin = Axis->min_value;
463 gSysDevice.NPRESSURE.axMax= Axis->max_value;
464 gSysDevice.NPRESSURE.axUnits = TU_INCHES;
465 gSysDevice.NPRESSURE.axResolution =
469 if (Val->num_axes >= 5)
471 /* Axis 4 and 5 are X and Y tilt */
472 XAxisInfoPtr XAxis = Axis;
474 if (max (abs(Axis->max_value),
475 abs(XAxis->max_value)))
477 gSysDevice.ORIENTATION[0].axMin = 0;
478 gSysDevice.ORIENTATION[0].axMax = 3600;
479 gSysDevice.ORIENTATION[0].axUnits = TU_CIRCLE;
480 gSysDevice.ORIENTATION[0].axResolution
482 gSysDevice.ORIENTATION[1].axMin = -1000;
483 gSysDevice.ORIENTATION[1].axMax = 1000;
484 gSysDevice.ORIENTATION[1].axUnits = TU_CIRCLE;
485 gSysDevice.ORIENTATION[1].axResolution
490 axis_read_complete = TRUE;
495 CHAR *ptr = cursor->BTNNAMES;
498 Button = (XButtonInfoPtr) any;
499 cursor->BUTTONS = Button->num_buttons;
500 for (i = 0; i < cursor->BUTTONS; i++)
502 strcpy(ptr,cursor->NAME);
508 any = (XAnyClassPtr) ((char*) any + any->length);
512 pXFreeDeviceList(devices);
514 gSysDevice.NCSRTYPES = cursor_target+1;
515 gNumCursors = cursor_target+1;
518 static int figure_deg(int x, int y)
524 rc = (int) 10 * (atan( (FLOAT)abs(y) / (FLOAT)abs(x)) / (3.1415 / 180));
551 static int get_button_state(int deviceid)
553 return button_state[deviceid];
556 static void set_button_state(XID deviceid)
558 struct x11drv_thread_data *data = x11drv_thread_data();
566 device = pXOpenDevice(data->display,deviceid);
567 state = pXQueryDeviceState(data->display,device);
572 for (loop = 0; loop < state->num_classes; loop++)
574 if (class->class == ButtonClass)
577 XButtonState *button_state = (XButtonState*)class;
578 for (loop2 = 1; loop2 <= button_state->num_buttons; loop2++)
580 if (button_state->buttons[loop2 / 8] & (1 << (loop2 % 8)))
582 rc |= (1<<(loop2-1));
586 class = (XInputClass *) ((char *) class + class->length);
589 pXFreeDeviceState(state);
591 button_state[deviceid] = rc;
594 static void motion_event( HWND hwnd, XEvent *event )
596 XDeviceMotionEvent *motion = (XDeviceMotionEvent *)event;
597 LPWTI_CURSORS_INFO cursor = &gSysCursor[motion->deviceid];
599 memset(&gMsgPacket,0,sizeof(WTPACKET));
601 TRACE("Received tablet motion event (%p)\n",hwnd);
603 /* Set cursor to inverted if cursor is the eraser */
604 gMsgPacket.pkStatus = (cursor->TYPE == 0xc85a ?TPS_INVERT:0);
605 gMsgPacket.pkTime = EVENT_x11_time_to_win32_time(motion->time);
606 gMsgPacket.pkSerialNumber = gSerial++;
607 gMsgPacket.pkCursor = motion->deviceid;
608 gMsgPacket.pkX = motion->axis_data[0];
609 gMsgPacket.pkY = motion->axis_data[1];
610 gMsgPacket.pkOrientation.orAzimuth = figure_deg(motion->axis_data[3],motion->axis_data[4]);
611 gMsgPacket.pkOrientation.orAltitude = ((1000 - 15 * max
612 (abs(motion->axis_data[3]),
613 abs(motion->axis_data[4])))
614 * (gMsgPacket.pkStatus & TPS_INVERT?-1:1));
615 gMsgPacket.pkNormalPressure = motion->axis_data[2];
616 gMsgPacket.pkButtons = get_button_state(motion->deviceid);
617 SendMessageW(hwndTabletDefault,WT_PACKET,0,(LPARAM)hwnd);
620 static void button_event( HWND hwnd, XEvent *event )
622 XDeviceButtonEvent *button = (XDeviceButtonEvent *) event;
623 LPWTI_CURSORS_INFO cursor = &gSysCursor[button->deviceid];
625 memset(&gMsgPacket,0,sizeof(WTPACKET));
627 TRACE("Received tablet button %s event\n", (event->type == button_press_type)?"press":"release");
629 /* Set cursor to inverted if cursor is the eraser */
630 gMsgPacket.pkStatus = (cursor->TYPE == 0xc85a ?TPS_INVERT:0);
631 set_button_state(button->deviceid);
632 gMsgPacket.pkTime = EVENT_x11_time_to_win32_time(button->time);
633 gMsgPacket.pkSerialNumber = gSerial++;
634 gMsgPacket.pkCursor = button->deviceid;
635 gMsgPacket.pkX = button->axis_data[0];
636 gMsgPacket.pkY = button->axis_data[1];
637 gMsgPacket.pkOrientation.orAzimuth = figure_deg(button->axis_data[3],button->axis_data[4]);
638 gMsgPacket.pkOrientation.orAltitude = ((1000 - 15 * max(abs(button->axis_data[3]),
639 abs(button->axis_data[4])))
640 * (gMsgPacket.pkStatus & TPS_INVERT?-1:1));
641 gMsgPacket.pkNormalPressure = button->axis_data[2];
642 gMsgPacket.pkButtons = get_button_state(button->deviceid);
643 SendMessageW(hwndTabletDefault,WT_PACKET,0,(LPARAM)hwnd);
646 static void key_event( HWND hwnd, XEvent *event )
648 if (event->type == key_press_type)
649 FIXME("Received tablet key press event\n");
651 FIXME("Received tablet key release event\n");
654 static void proximity_event( HWND hwnd, XEvent *event )
656 XProximityNotifyEvent *proximity = (XProximityNotifyEvent *) event;
657 LPWTI_CURSORS_INFO cursor = &gSysCursor[proximity->deviceid];
659 memset(&gMsgPacket,0,sizeof(WTPACKET));
661 TRACE("Received tablet proximity event\n");
662 /* Set cursor to inverted if cursor is the eraser */
663 gMsgPacket.pkStatus = (cursor->TYPE == 0xc85a ?TPS_INVERT:0);
664 gMsgPacket.pkStatus |= (event->type==proximity_out_type)?TPS_PROXIMITY:0;
665 gMsgPacket.pkTime = EVENT_x11_time_to_win32_time(proximity->time);
666 gMsgPacket.pkSerialNumber = gSerial++;
667 gMsgPacket.pkCursor = proximity->deviceid;
668 gMsgPacket.pkX = proximity->axis_data[0];
669 gMsgPacket.pkY = proximity->axis_data[1];
670 gMsgPacket.pkOrientation.orAzimuth = figure_deg(proximity->axis_data[3],proximity->axis_data[4]);
671 gMsgPacket.pkOrientation.orAltitude = ((1000 - 15 * max(abs(proximity->axis_data[3]),
672 abs(proximity->axis_data[4])))
673 * (gMsgPacket.pkStatus & TPS_INVERT?-1:1));
674 gMsgPacket.pkNormalPressure = proximity->axis_data[2];
675 gMsgPacket.pkButtons = get_button_state(proximity->deviceid);
677 SendMessageW(hwndTabletDefault, WT_PROXIMITY, (event->type == proximity_in_type), (LPARAM)hwnd);
680 int X11DRV_AttachEventQueueToTablet(HWND hOwner)
682 struct x11drv_thread_data *data = x11drv_thread_data();
686 XDeviceInfo *devices;
687 XDeviceInfo *target = NULL;
689 XEventClass event_list[7];
690 Window win = X11DRV_get_whole_window( hOwner );
694 TRACE("Creating context for window %p (%lx) %i cursors\n", hOwner, win, gNumCursors);
697 devices = pXListInputDevices(data->display, &num_devices);
699 X11DRV_expect_error(data->display,Tablet_ErrorHandler,NULL);
700 for (cur_loop=0; cur_loop < gNumCursors; cur_loop++)
704 for (loop=0; loop < num_devices; loop ++)
705 if (strcmp(devices[loop].name,gSysCursor[cur_loop].NAME)==0)
706 target = &devices[loop];
708 TRACE("Opening cursor %i id %i\n",cur_loop,(INT)target->id);
710 the_device = pXOpenDevice(data->display, target->id);
714 WARN("Unable to Open device\n");
718 if (the_device->num_classes > 0)
720 DeviceKeyPress(the_device, key_press_type, event_list[event_number]);
721 if (event_list[event_number]) event_number++;
722 DeviceKeyRelease(the_device, key_release_type, event_list[event_number]);
723 if (event_list[event_number]) event_number++;
724 DeviceButtonPress(the_device, button_press_type, event_list[event_number]);
725 if (event_list[event_number]) event_number++;
726 DeviceButtonRelease(the_device, button_release_type, event_list[event_number]);
727 if (event_list[event_number]) event_number++;
728 DeviceMotionNotify(the_device, motion_type, event_list[event_number]);
729 if (event_list[event_number]) event_number++;
730 ProximityIn(the_device, proximity_in_type, event_list[event_number]);
731 if (event_list[event_number]) event_number++;
732 ProximityOut(the_device, proximity_out_type, event_list[event_number]);
733 if (event_list[event_number]) event_number++;
735 if (key_press_type) X11DRV_register_event_handler( key_press_type, key_event );
736 if (key_release_type) X11DRV_register_event_handler( key_release_type, key_event );
737 if (button_press_type) X11DRV_register_event_handler( button_press_type, button_event );
738 if (button_release_type) X11DRV_register_event_handler( button_release_type, button_event );
739 if (motion_type) X11DRV_register_event_handler( motion_type, motion_event );
740 if (proximity_in_type) X11DRV_register_event_handler( proximity_in_type, proximity_event );
741 if (proximity_out_type) X11DRV_register_event_handler( proximity_out_type, proximity_event );
743 pXSelectExtensionEvent(data->display, win, event_list, event_number);
746 XSync(data->display, False);
747 X11DRV_check_error();
749 if (NULL != devices) pXFreeDeviceList(devices);
754 int X11DRV_GetCurrentPacket(LPWTPACKET *packet)
756 memcpy(packet,&gMsgPacket,sizeof(WTPACKET));
761 int static inline CopyTabletData(LPVOID target, LPVOID src, INT size)
764 * It is valid to call CopyTabletData with NULL.
765 * This handles the WTInfo() case where lpOutput is null.
768 memcpy(target,src,size);
772 /***********************************************************************
773 * X11DRV_WTInfoA (X11DRV.@)
775 UINT X11DRV_WTInfoA(UINT wCategory, UINT nIndex, LPVOID lpOutput)
778 * It is valid to call WTInfoA with lpOutput == NULL, as per standard.
779 * lpOutput == NULL signifies the user only wishes
780 * to find the size of the data.
782 * From now on use CopyTabletData to fill lpOutput. memcpy will break
786 LPWTI_CURSORS_INFO tgtcursor;
787 TRACE("(%u, %u, %p)\n", wCategory, nIndex, lpOutput);
792 /* return largest necessary buffer */
793 TRACE("%i cursors\n",gNumCursors);
796 FIXME("Return proper size\n");
805 strcpy(lpOutput,"Wine Wintab 1.1");
808 case IFC_SPECVERSION:
809 version = (0x01) | (0x01 << 8);
810 rc = CopyTabletData(lpOutput, &version,sizeof(WORD));
812 case IFC_IMPLVERSION:
813 version = (0x00) | (0x01 << 8);
814 rc = CopyTabletData(lpOutput, &version,sizeof(WORD));
817 FIXME("WTI_INTERFACE unhandled index %i\n",nIndex);
827 rc = CopyTabletData(lpOutput, &gSysContext,
828 sizeof(LOGCONTEXTA));
831 rc = CopyTabletData(lpOutput, &gSysContext.lcName,
832 strlen(gSysContext.lcName)+1);
835 rc = CopyTabletData(lpOutput, &gSysContext.lcOptions,
839 rc = CopyTabletData(lpOutput, &gSysContext.lcStatus,
843 rc= CopyTabletData (lpOutput, &gSysContext.lcLocks,
847 rc = CopyTabletData(lpOutput, &gSysContext.lcMsgBase,
851 rc = CopyTabletData(lpOutput, &gSysContext.lcDevice,
855 rc = CopyTabletData(lpOutput, &gSysContext.lcPktRate,
859 rc = CopyTabletData(lpOutput, &gSysContext.lcPktMode,
863 rc = CopyTabletData(lpOutput, &gSysContext.lcMoveMask,
867 rc = CopyTabletData(lpOutput, &gSysContext.lcBtnDnMask,
871 rc = CopyTabletData(lpOutput, &gSysContext.lcBtnUpMask,
875 rc = CopyTabletData(lpOutput, &gSysContext.lcInOrgX,
879 rc = CopyTabletData(lpOutput, &gSysContext.lcInOrgY,
883 rc = CopyTabletData(lpOutput, &gSysContext.lcInOrgZ,
887 rc = CopyTabletData(lpOutput, &gSysContext.lcInExtX,
891 rc = CopyTabletData(lpOutput, &gSysContext.lcInExtY,
895 rc = CopyTabletData(lpOutput, &gSysContext.lcInExtZ,
899 rc = CopyTabletData(lpOutput, &gSysContext.lcOutOrgX,
903 rc = CopyTabletData(lpOutput, &gSysContext.lcOutOrgY,
907 rc = CopyTabletData(lpOutput, &gSysContext.lcOutOrgZ,
911 rc = CopyTabletData(lpOutput, &gSysContext.lcOutExtX,
915 rc = CopyTabletData(lpOutput, &gSysContext.lcOutExtY,
919 rc = CopyTabletData(lpOutput, &gSysContext.lcOutExtZ,
923 rc = CopyTabletData(lpOutput, &gSysContext.lcSensX,
927 rc = CopyTabletData(lpOutput, &gSysContext.lcSensY,
931 rc = CopyTabletData(lpOutput, &gSysContext.lcSensZ,
935 rc = CopyTabletData(lpOutput, &gSysContext.lcSysMode,
939 rc = CopyTabletData(lpOutput, &gSysContext.lcSysOrgX,
943 rc = CopyTabletData(lpOutput, &gSysContext.lcSysOrgY,
947 rc = CopyTabletData(lpOutput, &gSysContext.lcSysExtX,
951 rc = CopyTabletData(lpOutput, &gSysContext.lcSysExtY,
955 rc = CopyTabletData(lpOutput, &gSysContext.lcSysSensX,
959 rc = CopyTabletData(lpOutput, &gSysContext.lcSysSensY,
963 FIXME("WTI_DEFSYSCTX unhandled index %i\n",nIndex);
978 tgtcursor = &gSysCursor[wCategory - WTI_CURSORS];
982 rc = CopyTabletData(lpOutput, &tgtcursor->NAME,
983 strlen(tgtcursor->NAME)+1);
986 rc = CopyTabletData(lpOutput,&tgtcursor->ACTIVE,
990 rc = CopyTabletData(lpOutput,&tgtcursor->PKTDATA,
994 rc = CopyTabletData(lpOutput,&tgtcursor->BUTTONS,
998 rc = CopyTabletData(lpOutput,&tgtcursor->BUTTONBITS,
1002 FIXME("Button Names not returned correctly\n");
1003 rc = CopyTabletData(lpOutput,&tgtcursor->BTNNAMES,
1004 strlen(tgtcursor->BTNNAMES)+1);
1007 rc = CopyTabletData(lpOutput,&tgtcursor->BUTTONMAP,
1011 rc = CopyTabletData(lpOutput,&tgtcursor->SYSBTNMAP,
1014 case CSR_NPBTNMARKS:
1015 rc = CopyTabletData(lpOutput,&tgtcursor->NPBTNMARKS,
1019 rc = CopyTabletData(lpOutput,&tgtcursor->NPBUTTON,
1022 case CSR_NPRESPONSE:
1023 FIXME("Not returning CSR_NPRESPONSE correctly\n");
1027 rc = CopyTabletData(lpOutput,&tgtcursor->TPBUTTON,
1030 case CSR_TPBTNMARKS:
1031 rc = CopyTabletData(lpOutput,&tgtcursor->TPBTNMARKS,
1034 case CSR_TPRESPONSE:
1035 FIXME("Not returning CSR_TPRESPONSE correctly\n");
1041 id = tgtcursor->PHYSID;
1042 id += (wCategory - WTI_CURSORS);
1043 rc = CopyTabletData(lpOutput,&id,sizeof(DWORD));
1047 rc = CopyTabletData(lpOutput,&tgtcursor->MODE,sizeof(UINT));
1049 case CSR_MINPKTDATA:
1050 rc = CopyTabletData(lpOutput,&tgtcursor->MINPKTDATA,
1053 case CSR_MINBUTTONS:
1054 rc = CopyTabletData(lpOutput,&tgtcursor->MINBUTTONS,
1057 case CSR_CAPABILITIES:
1058 rc = CopyTabletData(lpOutput,&tgtcursor->CAPABILITIES,
1062 rc = CopyTabletData(lpOutput,&tgtcursor->TYPE,
1066 FIXME("WTI_CURSORS unhandled index %i\n",nIndex);
1074 rc = CopyTabletData(lpOutput,gSysDevice.NAME,
1075 strlen(gSysDevice.NAME)+1);
1078 rc = CopyTabletData(lpOutput,&gSysDevice.HARDWARE,
1082 rc = CopyTabletData(lpOutput,&gSysDevice.NCSRTYPES,
1086 rc = CopyTabletData(lpOutput,&gSysDevice.FIRSTCSR,
1090 rc = CopyTabletData(lpOutput,&gSysDevice.PKTRATE,
1094 rc = CopyTabletData(lpOutput,&gSysDevice.PKTDATA,
1098 rc = CopyTabletData(lpOutput,&gSysDevice.PKTMODE,
1102 rc = CopyTabletData(lpOutput,&gSysDevice.CSRDATA,
1106 rc = CopyTabletData(lpOutput,&gSysDevice.XMARGIN,
1110 rc = CopyTabletData(lpOutput,&gSysDevice.YMARGIN,
1114 rc = 0; /* unsupported */
1116 rc = CopyTabletData(lpOutput,&gSysDevice.ZMARGIN,
1121 rc = CopyTabletData(lpOutput,&gSysDevice.X,
1125 rc = CopyTabletData(lpOutput,&gSysDevice.Y,
1129 rc = 0; /* unsupported */
1131 rc = CopyTabletData(lpOutput,&gSysDevice.Z,
1136 rc = CopyTabletData(lpOutput,&gSysDevice.NPRESSURE,
1140 rc = 0; /* unsupported */
1142 rc = CopyTabletData(lpOutput,&gSysDevice.TPRESSURE,
1146 case DVC_ORIENTATION:
1147 rc = CopyTabletData(lpOutput,&gSysDevice.ORIENTATION,
1151 rc = 0; /* unsupported */
1153 rc = CopyTabletData(lpOutput,&gSysDevice.ROTATION,
1158 rc = CopyTabletData(lpOutput,gSysDevice.PNPID,
1159 strlen(gSysDevice.PNPID)+1);
1162 FIXME("WTI_DEVICES unhandled index %i\n",nIndex);
1167 FIXME("Unhandled Category %i\n",wCategory);
1172 #else /* HAVE_X11_EXTENSIONS_XINPUT_H */
1174 /***********************************************************************
1175 * AttachEventQueueToTablet (X11DRV.@)
1177 int X11DRV_AttachEventQueueToTablet(HWND hOwner)
1182 /***********************************************************************
1183 * GetCurrentPacket (X11DRV.@)
1185 int X11DRV_GetCurrentPacket(LPWTPACKET *packet)
1190 /***********************************************************************
1191 * LoadTabletInfo (X11DRV.@)
1193 void X11DRV_LoadTabletInfo(HWND hwnddefault)
1197 /***********************************************************************
1198 * WTInfoA (X11DRV.@)
1200 UINT X11DRV_WTInfoA(UINT wCategory, UINT nIndex, LPVOID lpOutput)
1205 #endif /* HAVE_X11_EXTENSIONS_XINPUT_H */