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/debug.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(wintab32);
32 WINE_DECLARE_DEBUG_CHANNEL(event);
34 typedef struct tagWTI_CURSORS_INFO
37 /* a displayable zero-terminated string containing the name of the
41 /* whether the cursor is currently connected. */
43 /* a bit mask indicating the packet data items supported when this
44 * cursor is connected.
47 /* the number of buttons on this cursor. */
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.
57 /* a 32 byte array of logical button numbers, one for each physical
61 /* a 32 byte array of button action codes, one for each logical
65 /* the physical button number of the button that is controlled by normal
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.
74 /* an array of UINTs describing the pressure response curve for normal
78 /* the physical button number of the button that is controlled by
79 * tangential pressure.
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.
87 /* an array of UINTs describing the pressure response curve for
88 * tangential pressure.
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
99 /* the cursor mode number of this cursor type, if this cursor type has
100 * the CRC_MULTIMODE capability.
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.
107 /* the minimum number of buttons of physical cursors in the cursor type,
108 * if this cursor type has the CRC_AGGREGATE capability.
111 /* flags indicating cursor capabilities, as defined below:
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
118 Indicates this cursor type describes several physical cursors
119 that cannot be distinguished by software.
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.
126 /* Manufacturer Unique id for the item type */
127 } WTI_CURSORS_INFO, *LPWTI_CURSORS_INFO;
130 typedef struct tagWTI_DEVICES_INFO
133 /* a displayable null- terminated string describing the device,
134 * manufacturer, and revision level.
137 /* flags indicating hardware and driver capabilities, as defined
140 Indicates that the display and digitizer share the same surface.
142 Indicates that the cursor must be in physical contact with the
143 device to report position.
145 Indicates that device can generate events when the cursor is
146 entering and leaving the physical detection range.
148 Indicates that device can uniquely identify the active cursor in
152 /* the number of supported cursor types.*/
154 /* the first cursor type number for the device. */
156 /* the maximum packet report rate in Hertz. */
158 /* a bit mask indicating which packet data items are always available.*/
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.
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.
172 /* the size of tablet context margins in tablet native coordinates, in
173 * the x, y, and z directions, respectively.
178 /* the tablet's range and resolution capabilities, in the x, y, and z
179 * axes, respectively.
183 /* the tablet's range and resolution capabilities, for the normal and
184 * tangential pressure inputs, respectively.
187 /* a 3-element array describing the tablet's orientation range and
188 * resolution capabilities.
191 /* a 3-element array describing the tablet's rotation range and
192 * resolution capabilities.
195 /* a null-terminated string containing the devices Plug and Play ID.*/
196 } WTI_DEVICES_INFO, *LPWTI_DEVICES_INFO;
198 typedef struct tagWTPACKET {
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 = -1;
222 static int button_press_type = -1;
223 static int button_release_type = -1;
224 static int key_press_type = -1;
225 static int key_release_type = -1;
226 static int proximity_in_type = -1;
227 static int proximity_out_type = -1;
229 static HWND hwndTabletDefault;
230 static WTPACKET gMsgPacket;
231 static DWORD gSerial;
232 static INT button_state[10];
236 static LOGCONTEXTA gSysContext;
237 static WTI_DEVICES_INFO gSysDevice;
238 static WTI_CURSORS_INFO gSysCursor[CURSORMAX];
239 static INT gNumCursors;
243 #define SONAME_LIBXI "libXi.so"
247 static void *xinput_handle;
249 #define MAKE_FUNCPTR(f) static typeof(f) * p##f;
250 MAKE_FUNCPTR(XListInputDevices)
251 MAKE_FUNCPTR(XOpenDevice)
252 MAKE_FUNCPTR(XQueryDeviceState)
253 MAKE_FUNCPTR(XGetDeviceButtonMapping)
254 MAKE_FUNCPTR(XCloseDevice)
255 MAKE_FUNCPTR(XSelectExtensionEvent)
256 MAKE_FUNCPTR(XFreeDeviceState)
259 static INT X11DRV_XInput_Init(void)
261 xinput_handle = wine_dlopen(SONAME_LIBXI, RTLD_NOW, NULL, 0);
264 #define LOAD_FUNCPTR(f) if((p##f = wine_dlsym(xinput_handle, #f, NULL, 0)) == NULL) goto sym_not_found;
265 LOAD_FUNCPTR(XListInputDevices)
266 LOAD_FUNCPTR(XOpenDevice)
267 LOAD_FUNCPTR(XGetDeviceButtonMapping)
268 LOAD_FUNCPTR(XCloseDevice)
269 LOAD_FUNCPTR(XSelectExtensionEvent)
270 LOAD_FUNCPTR(XQueryDeviceState)
271 LOAD_FUNCPTR(XFreeDeviceState)
279 void X11DRV_LoadTabletInfo(HWND hwnddefault)
281 struct x11drv_thread_data *data = x11drv_thread_data();
285 XDeviceInfo *devices;
286 XDeviceInfo *target = NULL;
287 BOOL axis_read_complete= FALSE;
290 XButtonInfoPtr Button;
291 XValuatorInfoPtr Val;
296 if (!X11DRV_XInput_Init())
298 ERR("Unable to initialized the XInput library.\n");
302 hwndTabletDefault = hwnddefault;
304 /* Do base initializaion */
305 strcpy(gSysContext.lcName, "Wine Tablet Context");
306 strcpy(gSysDevice.NAME,"Wine Tablet Device");
308 gSysContext.lcOptions = CXO_SYSTEM | CXO_MESSAGES | CXO_CSRMESSAGES;
309 gSysContext.lcLocks = CXL_INSIZE | CXL_INASPECT | CXL_MARGIN |
310 CXL_SENSITIVITY | CXL_SYSOUT;
312 gSysContext.lcMsgBase= WT_DEFBASE;
313 gSysContext.lcDevice = 0;
314 gSysContext.lcPktData =
315 PK_CONTEXT | PK_STATUS | PK_SERIAL_NUMBER| PK_TIME | PK_CURSOR |
316 PK_BUTTONS | PK_X | PK_Y | PK_NORMAL_PRESSURE | PK_ORIENTATION;
317 gSysContext.lcMoveMask=
318 PK_BUTTONS | PK_X | PK_Y | PK_NORMAL_PRESSURE | PK_ORIENTATION;
319 gSysContext.lcStatus = CXS_ONTOP;
320 gSysContext.lcPktRate = 100;
321 gSysContext.lcBtnDnMask = 0xffffffff;
322 gSysContext.lcBtnUpMask = 0xffffffff;
323 gSysContext.lcSensX = 65536;
324 gSysContext.lcSensY = 65536;
325 gSysContext.lcSensX = 65536;
326 gSysContext.lcSensZ = 65536;
327 gSysContext.lcSysSensX= 65536;
328 gSysContext.lcSysSensY= 65536;
330 /* Device Defaults */
331 gSysDevice.HARDWARE = HWC_HARDPROX|HWC_PHYSID_CURSORS;
332 gSysDevice.FIRSTCSR= 0;
333 gSysDevice.PKTRATE = 100;
335 PK_CONTEXT | PK_STATUS | PK_SERIAL_NUMBER| PK_TIME | PK_CURSOR |
336 PK_BUTTONS | PK_X | PK_Y | PK_NORMAL_PRESSURE | PK_ORIENTATION;
337 strcpy(gSysDevice.PNPID,"non-pluginplay");
342 devices = pXListInputDevices(data->display, &num_devices);
345 WARN("XInput Extenstions reported as not avalable\n");
349 for (loop=0; loop < num_devices; loop++)
353 TRACE("Trying device %i(%s)\n",loop,devices[loop].name);
354 if (devices[loop].use == IsXExtensionDevice)
356 LPWTI_CURSORS_INFO cursor;
358 TRACE("Is Extension Device\n");
360 target = &devices[loop];
361 cursor = &gSysCursor[cursor_target];
363 opendevice = pXOpenDevice(data->display,target->id);
366 unsigned char map[32];
370 pXGetDeviceButtonMapping(data->display, opendevice, map, 32);
372 for (i=0; i< cursor->BUTTONS; i++,shft++)
374 cursor->BUTTONMAP[i] = map[i];
375 cursor->SYSBTNMAP[i] = (1<<shft);
377 pXCloseDevice(data->display, opendevice);
381 WARN("Unable to open device %s\n",target->name);
386 strcpy(cursor->NAME,target->name);
389 cursor->PKTDATA = PK_TIME | PK_CURSOR | PK_BUTTONS | PK_X | PK_Y |
390 PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE |
393 cursor->PHYSID = cursor_target;
394 cursor->NPBUTTON = 1;
395 cursor->NPBTNMARKS[0] = 0 ;
396 cursor->NPBTNMARKS[1] = 1 ;
397 cursor->CAPABILITIES = 1;
398 if (strcasecmp(cursor->NAME,"stylus")==0)
399 cursor->TYPE = 0x4825;
400 if (strcasecmp(cursor->NAME,"eraser")==0)
401 cursor->TYPE = 0xc85a;
404 any = (XAnyClassPtr) (target->inputclassinfo);
406 for (class_loop = 0; class_loop < target->num_classes; class_loop++)
411 if (!axis_read_complete)
413 Val = (XValuatorInfoPtr) any;
414 Axis = (XAxisInfoPtr) ((char *) Val + sizeof
417 if (Val->num_axes>=1)
420 gSysDevice.X.axMin = Axis->min_value;
421 gSysDevice.X.axMax= Axis->max_value;
422 gSysDevice.X.axUnits = 1;
423 gSysDevice.X.axResolution = Axis->resolution;
424 gSysContext.lcInOrgX = Axis->min_value;
425 gSysContext.lcSysOrgX = Axis->min_value;
426 gSysContext.lcInExtX = Axis->max_value;
427 gSysContext.lcSysExtX = Axis->max_value;
430 if (Val->num_axes>=2)
433 gSysDevice.Y.axMin = Axis->min_value;
434 gSysDevice.Y.axMax= Axis->max_value;
435 gSysDevice.Y.axUnits = 1;
436 gSysDevice.Y.axResolution = Axis->resolution;
437 gSysContext.lcInOrgY = Axis->min_value;
438 gSysContext.lcSysOrgY = Axis->min_value;
439 gSysContext.lcInExtY = Axis->max_value;
440 gSysContext.lcSysExtY = Axis->max_value;
443 if (Val->num_axes>=3)
445 /* Axis 3 is Normal Pressure */
446 gSysDevice.NPRESSURE.axMin = Axis->min_value;
447 gSysDevice.NPRESSURE.axMax= Axis->max_value;
448 gSysDevice.NPRESSURE.axUnits = 1;
449 gSysDevice.NPRESSURE.axResolution =
453 if (Val->num_axes >= 5)
455 /* Axis 4 and 5 are X and Y tilt */
456 XAxisInfoPtr XAxis = Axis;
458 if (max (abs(Axis->max_value),
459 abs(XAxis->max_value)))
461 gSysDevice.ORIENTATION[0].axMin = 0;
462 gSysDevice.ORIENTATION[0].axMax = 3600;
463 gSysDevice.ORIENTATION[0].axUnits = 1;
464 gSysDevice.ORIENTATION[0].axResolution =
466 gSysDevice.ORIENTATION[1].axMin = -1000;
467 gSysDevice.ORIENTATION[1].axMax = 1000;
468 gSysDevice.ORIENTATION[1].axUnits = 1;
469 gSysDevice.ORIENTATION[1].axResolution =
474 axis_read_complete = TRUE;
479 CHAR *ptr = cursor->BTNNAMES;
482 Button = (XButtonInfoPtr) any;
483 cursor->BUTTONS = Button->num_buttons;
484 for (i = 0; i < cursor->BUTTONS; i++)
486 strcpy(ptr,cursor->NAME);
492 any = (XAnyClassPtr) ((char*) any + any->length);
497 gSysDevice.NCSRTYPES = cursor_target+1;
498 gNumCursors = cursor_target+1;
501 static int figure_deg(int x, int y)
507 rc = (int) 10 * (atan( (FLOAT)abs(y) / (FLOAT)abs(x)) / (3.1415 / 180));
534 static int get_button_state(int deviceid)
536 return button_state[deviceid];
539 static void set_button_state(XID deviceid)
541 struct x11drv_thread_data *data = x11drv_thread_data();
549 device = pXOpenDevice(data->display,deviceid);
550 state = pXQueryDeviceState(data->display,device);
555 for (loop = 0; loop < state->num_classes; loop++)
557 if (class->class == ButtonClass)
560 XButtonState *button_state = (XButtonState*)class;
561 for (loop2 = 1; loop2 <= button_state->num_buttons; loop2++)
563 if (button_state->buttons[loop2 / 8] & (1 << (loop2 % 8)))
565 rc |= (1<<(loop2-1));
569 class = (XInputClass *) ((char *) class + class->length);
572 pXFreeDeviceState(state);
574 button_state[deviceid] = rc;
577 int X11DRV_ProcessTabletEvent(HWND hwnd, XEvent *event)
579 memset(&gMsgPacket,0,sizeof(WTPACKET));
581 if(event->type == motion_type)
583 XDeviceMotionEvent *motion = (XDeviceMotionEvent *)event;
585 TRACE_(event)("Received tablet motion event (%p)\n",hwnd);
586 TRACE("Received tablet motion event (%p)\n",hwnd);
587 gMsgPacket.pkTime = motion->time;
588 gMsgPacket.pkSerialNumber = gSerial++;
589 gMsgPacket.pkCursor = motion->deviceid;
590 gMsgPacket.pkX = motion->axis_data[0];
591 gMsgPacket.pkY = motion->axis_data[1];
592 gMsgPacket.pkOrientation.orAzimuth =
593 figure_deg(motion->axis_data[3],motion->axis_data[4]);
594 gMsgPacket.pkOrientation.orAltitude = 1000 - 15 * max
595 (abs(motion->axis_data[3]),abs(motion->axis_data[4]));
596 gMsgPacket.pkNormalPressure = motion->axis_data[2];
597 gMsgPacket.pkButtons = get_button_state(motion->deviceid);
598 SendMessageW(hwndTabletDefault,WT_PACKET,0,(LPARAM)hwnd);
600 else if ((event->type == button_press_type)||(event->type ==
601 button_release_type))
603 XDeviceButtonEvent *button = (XDeviceButtonEvent *) event;
605 TRACE_(event)("Received tablet button event\n");
606 TRACE("Received tablet button %s event\n", (event->type ==
607 button_press_type)?"press":"release");
609 set_button_state(button->deviceid);
611 else if (event->type == key_press_type)
613 TRACE_(event)("Received tablet key press event\n");
614 FIXME("Received tablet key press event\n");
616 else if (event->type == key_release_type)
618 TRACE_(event)("Received tablet key release event\n");
619 FIXME("Received tablet key release event\n");
621 else if ((event->type == proximity_in_type) ||
622 (event->type == proximity_out_type))
624 TRACE_(event)("Received tablet proximity event\n");
625 TRACE("Received tablet proximity event\n");
626 gMsgPacket.pkStatus = (event->type==proximity_out_type)?TPS_PROXIMITY:0;
627 SendMessageW(hwndTabletDefault, WT_PROXIMITY,
628 (event->type==proximity_out_type)?0:1, (LPARAM)hwnd);
636 int X11DRV_AttachEventQueueToTablet(HWND hOwner)
638 struct x11drv_thread_data *data = x11drv_thread_data();
642 XDeviceInfo *devices;
643 XDeviceInfo *target = NULL;
646 XEventClass event_list[7];
647 Window win = X11DRV_get_whole_window( hOwner );
651 TRACE("Creating context for window %p (%lx) %i cursors\n", hOwner, win, gNumCursors);
654 devices = pXListInputDevices(data->display, &num_devices);
656 for (cur_loop=0; cur_loop < gNumCursors; cur_loop++)
660 for (loop=0; loop < num_devices; loop ++)
661 if (strcmp(devices[loop].name,gSysCursor[cur_loop].NAME)==0)
662 target = &devices[loop];
664 TRACE("Opening cursor %i id %i\n",cur_loop,(INT)target->id);
666 the_device = pXOpenDevice(data->display, target->id);
670 WARN("Unable to Open device\n");
674 if (the_device->num_classes > 0)
676 for (ip = the_device->classes, loop=0; loop < target->num_classes;
679 switch(ip->input_class)
682 DeviceKeyPress(the_device, key_press_type,
683 event_list[event_number]);
685 DeviceKeyRelease(the_device, key_release_type,
686 event_list[event_number]);
690 DeviceButtonPress(the_device, button_press_type,
691 event_list[event_number]);
693 DeviceButtonRelease(the_device, button_release_type,
694 event_list[event_number]);
698 DeviceMotionNotify(the_device, motion_type,
699 event_list[event_number]);
701 ProximityIn(the_device, proximity_in_type,
702 event_list[event_number]);
704 ProximityOut(the_device, proximity_out_type,
705 event_list[event_number]);
709 ERR("unknown class\n");
713 if (pXSelectExtensionEvent(data->display, win, event_list, event_number))
715 ERR( "error selecting extended events\n");
726 int X11DRV_GetCurrentPacket(LPWTPACKET *packet)
728 memcpy(packet,&gMsgPacket,sizeof(WTPACKET));
733 int static inline CopyTabletData(LPVOID target, LPVOID src, INT size)
735 memcpy(target,src,size);
739 /***********************************************************************
740 * X11DRV_WTInfoA (X11DRV.@)
742 UINT X11DRV_WTInfoA(UINT wCategory, UINT nIndex, LPVOID lpOutput)
745 LPWTI_CURSORS_INFO tgtcursor;
746 TRACE("(%u, %u, %p)\n", wCategory, nIndex, lpOutput);
751 /* return largest necessary buffer */
752 TRACE("%i cursors\n",gNumCursors);
755 FIXME("Return proper size\n");
766 strcpy(lpOutput,"Wine Wintab 1.1");
769 case IFC_SPECVERSION:
770 version = (0x01) | (0x01 << 8);
771 rc = CopyTabletData(lpOutput, &version,sizeof(WORD));
773 case IFC_IMPLVERSION:
774 version = (0x00) | (0x01 << 8);
775 rc = CopyTabletData(lpOutput, &version,sizeof(WORD));
778 FIXME("WTI_INTERFACE unhandled index %i\n",nIndex);
788 memcpy(lpOutput, &gSysContext,
789 sizeof(LOGCONTEXTA));
790 rc = sizeof(LOGCONTEXTA);
793 rc = CopyTabletData(lpOutput, &gSysContext.lcName,
794 strlen(gSysContext.lcName)+1);
797 rc = CopyTabletData(lpOutput, &gSysContext.lcOptions,
801 rc = CopyTabletData(lpOutput, &gSysContext.lcStatus,
805 rc= CopyTabletData (lpOutput, &gSysContext.lcLocks,
809 rc = CopyTabletData(lpOutput, &gSysContext.lcMsgBase,
813 rc = CopyTabletData(lpOutput, &gSysContext.lcDevice,
817 rc = CopyTabletData(lpOutput, &gSysContext.lcPktRate,
821 rc = CopyTabletData(lpOutput, &gSysContext.lcPktMode,
825 rc = CopyTabletData(lpOutput, &gSysContext.lcMoveMask,
829 rc = CopyTabletData(lpOutput, &gSysContext.lcBtnDnMask,
833 rc = CopyTabletData(lpOutput, &gSysContext.lcBtnUpMask,
837 rc = CopyTabletData(lpOutput, &gSysContext.lcInOrgX,
841 rc = CopyTabletData(lpOutput, &gSysContext.lcInOrgY,
845 rc = CopyTabletData(lpOutput, &gSysContext.lcInOrgZ,
849 rc = CopyTabletData(lpOutput, &gSysContext.lcInExtX,
853 rc = CopyTabletData(lpOutput, &gSysContext.lcInExtY,
857 rc = CopyTabletData(lpOutput, &gSysContext.lcInExtZ,
861 rc = CopyTabletData(lpOutput, &gSysContext.lcOutOrgX,
865 rc = CopyTabletData(lpOutput, &gSysContext.lcOutOrgY,
869 rc = CopyTabletData(lpOutput, &gSysContext.lcOutOrgZ,
873 rc = CopyTabletData(lpOutput, &gSysContext.lcOutExtX,
877 rc = CopyTabletData(lpOutput, &gSysContext.lcOutExtY,
881 rc = CopyTabletData(lpOutput, &gSysContext.lcOutExtZ,
885 rc = CopyTabletData(lpOutput, &gSysContext.lcSensX,
889 rc = CopyTabletData(lpOutput, &gSysContext.lcSensY,
893 rc = CopyTabletData(lpOutput, &gSysContext.lcSensZ,
897 rc = CopyTabletData(lpOutput, &gSysContext.lcSysMode,
901 rc = CopyTabletData(lpOutput, &gSysContext.lcSysOrgX,
905 rc = CopyTabletData(lpOutput, &gSysContext.lcSysOrgY,
909 rc = CopyTabletData(lpOutput, &gSysContext.lcSysExtX,
913 rc = CopyTabletData(lpOutput, &gSysContext.lcSysExtY,
917 rc = CopyTabletData(lpOutput, &gSysContext.lcSysSensX,
921 rc = CopyTabletData(lpOutput, &gSysContext.lcSysSensY,
925 FIXME("WTI_DEFSYSCTX unhandled index %i\n",nIndex);
940 tgtcursor = &gSysCursor[wCategory - WTI_CURSORS];
944 rc = CopyTabletData(lpOutput, &tgtcursor->NAME,
945 strlen(tgtcursor->NAME)+1);
948 rc = CopyTabletData(lpOutput,&tgtcursor->ACTIVE,
952 rc = CopyTabletData(lpOutput,&tgtcursor->PKTDATA,
956 rc = CopyTabletData(lpOutput,&tgtcursor->BUTTONS,
960 rc = CopyTabletData(lpOutput,&tgtcursor->BUTTONBITS,
964 FIXME("Button Names not returned correctly\n");
965 rc = CopyTabletData(lpOutput,&tgtcursor->BTNNAMES,
966 strlen(tgtcursor->BTNNAMES)+1);
969 rc = CopyTabletData(lpOutput,&tgtcursor->BUTTONMAP,
973 rc = CopyTabletData(lpOutput,&tgtcursor->SYSBTNMAP,
977 memcpy(lpOutput,&tgtcursor->NPBTNMARKS,sizeof(UINT)*2);
981 rc = CopyTabletData(lpOutput,&tgtcursor->NPBUTTON,
985 FIXME("Not returning CSR_NPRESPONSE correctly\n");
989 rc = CopyTabletData(lpOutput,&tgtcursor->TPBUTTON,
993 memcpy(lpOutput,&tgtcursor->TPBTNMARKS,sizeof(UINT)*2);
997 FIXME("Not returning CSR_TPRESPONSE correctly\n");
1003 rc = CopyTabletData(&id,&tgtcursor->PHYSID,
1005 id += (wCategory - WTI_CURSORS);
1006 memcpy(lpOutput,&id,sizeof(DWORD));
1010 rc = CopyTabletData(lpOutput,&tgtcursor->MODE,sizeof(UINT));
1012 case CSR_MINPKTDATA:
1013 rc = CopyTabletData(lpOutput,&tgtcursor->MINPKTDATA,
1016 case CSR_MINBUTTONS:
1017 rc = CopyTabletData(lpOutput,&tgtcursor->MINBUTTONS,
1020 case CSR_CAPABILITIES:
1021 rc = CopyTabletData(lpOutput,&tgtcursor->CAPABILITIES,
1025 rc = CopyTabletData(lpOutput,&tgtcursor->TYPE,
1029 FIXME("WTI_CURSORS unhandled index %i\n",nIndex);
1037 rc = CopyTabletData(lpOutput,gSysDevice.NAME,
1038 strlen(gSysDevice.NAME)+1);
1041 rc = CopyTabletData(lpOutput,&gSysDevice.HARDWARE,
1045 rc = CopyTabletData(lpOutput,&gSysDevice.NCSRTYPES,
1049 rc = CopyTabletData(lpOutput,&gSysDevice.FIRSTCSR,
1053 rc = CopyTabletData(lpOutput,&gSysDevice.PKTRATE,
1057 rc = CopyTabletData(lpOutput,&gSysDevice.PKTDATA,
1061 rc = CopyTabletData(lpOutput,&gSysDevice.PKTMODE,
1065 rc = CopyTabletData(lpOutput,&gSysDevice.CSRDATA,
1069 rc = CopyTabletData(lpOutput,&gSysDevice.XMARGIN,
1073 rc = CopyTabletData(lpOutput,&gSysDevice.YMARGIN,
1077 rc = 0; /* unsupported */
1079 rc = CopyTabletData(lpOutput,&gSysDevice.ZMARGIN,
1084 rc = CopyTabletData(lpOutput,&gSysDevice.X,
1088 rc = CopyTabletData(lpOutput,&gSysDevice.Y,
1092 rc = 0; /* unsupported */
1094 rc = CopyTabletData(lpOutput,&gSysDevice.Z,
1099 rc = CopyTabletData(lpOutput,&gSysDevice.NPRESSURE,
1103 rc = 0; /* unsupported */
1105 rc = CopyTabletData(lpOutput,&gSysDevice.TPRESSURE,
1109 case DVC_ORIENTATION:
1110 memcpy(lpOutput,&gSysDevice.ORIENTATION,sizeof(AXIS)*3);
1111 rc = sizeof(AXIS)*3;
1114 rc = 0; /* unsupported */
1116 memcpy(lpOutput,&gSysDevice.ROTATION,sizeof(AXIS)*3);
1117 rc = sizeof(AXIS)*3;
1121 rc = CopyTabletData(lpOutput,gSysDevice.PNPID,
1122 strlen(gSysDevice.PNPID)+1);
1125 FIXME("WTI_DEVICES unhandled index %i\n",nIndex);
1130 FIXME("Unhandled Category %i\n",wCategory);
1135 #else /* HAVE_X11_EXTENSIONS_XINPUT_H */
1137 int X11DRV_ProcessTabletEvent(HWND hwnd, XEvent *event)
1142 int X11DRV_AttachEventQueueToTablet(HWND hOwner)
1147 int X11DRV_GetCurrentPacket(LPWTPACKET *packet)
1152 void X11DRV_LoadTabletInfo(HWND hwnddefault)
1156 UINT X11DRV_WTInfoA(UINT wCategory, UINT nIndex, LPVOID lpOutput)
1161 #endif /* HAVE_X11_EXTENSIONS_XINPUT_H */