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"
28 #include "wine/library.h"
29 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(wintab32);
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;
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];
236 static LOGCONTEXTA gSysContext;
237 static WTI_DEVICES_INFO gSysDevice;
238 static WTI_CURSORS_INFO gSysCursor[CURSORMAX];
239 static INT gNumCursors;
243 static void *xinput_handle;
245 #define MAKE_FUNCPTR(f) static typeof(f) * p##f;
246 MAKE_FUNCPTR(XListInputDevices)
247 MAKE_FUNCPTR(XFreeDeviceList)
248 MAKE_FUNCPTR(XOpenDevice)
249 MAKE_FUNCPTR(XQueryDeviceState)
250 MAKE_FUNCPTR(XGetDeviceButtonMapping)
251 MAKE_FUNCPTR(XCloseDevice)
252 MAKE_FUNCPTR(XSelectExtensionEvent)
253 MAKE_FUNCPTR(XFreeDeviceState)
256 static INT X11DRV_XInput_Init(void)
258 xinput_handle = wine_dlopen(SONAME_LIBXI, RTLD_NOW, NULL, 0);
261 #define LOAD_FUNCPTR(f) if((p##f = wine_dlsym(xinput_handle, #f, NULL, 0)) == NULL) goto sym_not_found;
262 LOAD_FUNCPTR(XListInputDevices)
263 LOAD_FUNCPTR(XFreeDeviceList)
264 LOAD_FUNCPTR(XOpenDevice)
265 LOAD_FUNCPTR(XGetDeviceButtonMapping)
266 LOAD_FUNCPTR(XCloseDevice)
267 LOAD_FUNCPTR(XSelectExtensionEvent)
268 LOAD_FUNCPTR(XQueryDeviceState)
269 LOAD_FUNCPTR(XFreeDeviceState)
277 static int Tablet_ErrorHandler(Display *dpy, XErrorEvent *event, void* arg)
282 void X11DRV_LoadTabletInfo(HWND hwnddefault)
284 struct x11drv_thread_data *data = x11drv_thread_data();
288 XDeviceInfo *devices;
289 XDeviceInfo *target = NULL;
290 BOOL axis_read_complete= FALSE;
293 XButtonInfoPtr Button;
294 XValuatorInfoPtr Val;
299 if (!X11DRV_XInput_Init())
301 ERR("Unable to initialized the XInput library.\n");
305 hwndTabletDefault = hwnddefault;
307 /* Do base initializaion */
308 strcpy(gSysContext.lcName, "Wine Tablet Context");
309 strcpy(gSysDevice.NAME,"Wine Tablet Device");
311 gSysContext.lcOptions = CXO_SYSTEM;
312 gSysContext.lcLocks = CXL_INSIZE | CXL_INASPECT | CXL_MARGIN |
313 CXL_SENSITIVITY | CXL_SYSOUT;
315 gSysContext.lcMsgBase= WT_DEFBASE;
316 gSysContext.lcDevice = 0;
317 gSysContext.lcPktData =
318 PK_CONTEXT | PK_STATUS | PK_SERIAL_NUMBER| PK_TIME | PK_CURSOR |
319 PK_BUTTONS | PK_X | PK_Y | PK_NORMAL_PRESSURE | PK_ORIENTATION;
320 gSysContext.lcMoveMask=
321 PK_BUTTONS | PK_X | PK_Y | PK_NORMAL_PRESSURE | PK_ORIENTATION;
322 gSysContext.lcStatus = CXS_ONTOP;
323 gSysContext.lcPktRate = 100;
324 gSysContext.lcBtnDnMask = 0xffffffff;
325 gSysContext.lcBtnUpMask = 0xffffffff;
326 gSysContext.lcSensX = 65536;
327 gSysContext.lcSensY = 65536;
328 gSysContext.lcSensX = 65536;
329 gSysContext.lcSensZ = 65536;
330 gSysContext.lcSysSensX= 65536;
331 gSysContext.lcSysSensY= 65536;
333 /* Device Defaults */
334 gSysDevice.HARDWARE = HWC_HARDPROX|HWC_PHYSID_CURSORS;
335 gSysDevice.FIRSTCSR= 0;
336 gSysDevice.PKTRATE = 100;
338 PK_CONTEXT | PK_STATUS | PK_SERIAL_NUMBER| PK_TIME | PK_CURSOR |
339 PK_BUTTONS | PK_X | PK_Y | PK_NORMAL_PRESSURE | PK_ORIENTATION;
340 strcpy(gSysDevice.PNPID,"non-pluginplay");
345 devices = pXListInputDevices(data->display, &num_devices);
348 WARN("XInput Extenstions reported as not avalable\n");
352 for (loop=0; loop < num_devices; loop++)
356 TRACE("Trying device %i(%s)\n",loop,devices[loop].name);
357 if (devices[loop].use == IsXExtensionDevice)
359 LPWTI_CURSORS_INFO cursor;
361 TRACE("Is Extension Device\n");
363 target = &devices[loop];
364 cursor = &gSysCursor[cursor_target];
366 X11DRV_expect_error(data->display, Tablet_ErrorHandler, NULL);
367 opendevice = pXOpenDevice(data->display,target->id);
368 if (!X11DRV_check_error() && opendevice)
370 unsigned char map[32];
374 X11DRV_expect_error(data->display,Tablet_ErrorHandler,NULL);
375 pXGetDeviceButtonMapping(data->display, opendevice, map, 32);
376 if (X11DRV_check_error())
378 TRACE("No buttons, Non Tablet Device\n");
379 pXCloseDevice(data->display, opendevice);
384 for (i=0; i< cursor->BUTTONS; i++,shft++)
386 cursor->BUTTONMAP[i] = map[i];
387 cursor->SYSBTNMAP[i] = (1<<shft);
389 pXCloseDevice(data->display, opendevice);
393 WARN("Unable to open device %s\n",target->name);
398 strcpy(cursor->NAME,target->name);
401 cursor->PKTDATA = PK_TIME | PK_CURSOR | PK_BUTTONS | PK_X | PK_Y |
402 PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE |
405 cursor->PHYSID = cursor_target;
406 cursor->NPBUTTON = 1;
407 cursor->NPBTNMARKS[0] = 0 ;
408 cursor->NPBTNMARKS[1] = 1 ;
409 cursor->CAPABILITIES = CRC_MULTIMODE;
410 if (strcasecmp(cursor->NAME,"stylus")==0)
411 cursor->TYPE = 0x4825;
412 if (strcasecmp(cursor->NAME,"eraser")==0)
413 cursor->TYPE = 0xc85a;
416 any = (XAnyClassPtr) (target->inputclassinfo);
418 for (class_loop = 0; class_loop < target->num_classes; class_loop++)
423 if (!axis_read_complete)
425 Val = (XValuatorInfoPtr) any;
426 Axis = (XAxisInfoPtr) ((char *) Val + sizeof
429 if (Val->num_axes>=1)
432 gSysDevice.X.axMin = Axis->min_value;
433 gSysDevice.X.axMax= Axis->max_value;
434 gSysDevice.X.axUnits = TU_INCHES;
435 gSysDevice.X.axResolution = Axis->resolution;
436 gSysContext.lcInOrgX = Axis->min_value;
437 gSysContext.lcSysOrgX = Axis->min_value;
438 gSysContext.lcInExtX = Axis->max_value;
439 gSysContext.lcSysExtX = Axis->max_value;
442 if (Val->num_axes>=2)
445 gSysDevice.Y.axMin = Axis->min_value;
446 gSysDevice.Y.axMax= Axis->max_value;
447 gSysDevice.Y.axUnits = TU_INCHES;
448 gSysDevice.Y.axResolution = Axis->resolution;
449 gSysContext.lcInOrgY = Axis->min_value;
450 gSysContext.lcSysOrgY = Axis->min_value;
451 gSysContext.lcInExtY = Axis->max_value;
452 gSysContext.lcSysExtY = Axis->max_value;
455 if (Val->num_axes>=3)
457 /* Axis 3 is Normal Pressure */
458 gSysDevice.NPRESSURE.axMin = Axis->min_value;
459 gSysDevice.NPRESSURE.axMax= Axis->max_value;
460 gSysDevice.NPRESSURE.axUnits = TU_INCHES;
461 gSysDevice.NPRESSURE.axResolution =
465 if (Val->num_axes >= 5)
467 /* Axis 4 and 5 are X and Y tilt */
468 XAxisInfoPtr XAxis = Axis;
470 if (max (abs(Axis->max_value),
471 abs(XAxis->max_value)))
473 gSysDevice.ORIENTATION[0].axMin = 0;
474 gSysDevice.ORIENTATION[0].axMax = 3600;
475 gSysDevice.ORIENTATION[0].axUnits = TU_CIRCLE;
476 gSysDevice.ORIENTATION[0].axResolution
478 gSysDevice.ORIENTATION[1].axMin = -1000;
479 gSysDevice.ORIENTATION[1].axMax = 1000;
480 gSysDevice.ORIENTATION[1].axUnits = TU_CIRCLE;
481 gSysDevice.ORIENTATION[1].axResolution
486 axis_read_complete = TRUE;
491 CHAR *ptr = cursor->BTNNAMES;
494 Button = (XButtonInfoPtr) any;
495 cursor->BUTTONS = Button->num_buttons;
496 for (i = 0; i < cursor->BUTTONS; i++)
498 strcpy(ptr,cursor->NAME);
504 any = (XAnyClassPtr) ((char*) any + any->length);
508 pXFreeDeviceList(devices);
510 gSysDevice.NCSRTYPES = cursor_target+1;
511 gNumCursors = cursor_target+1;
514 static int figure_deg(int x, int y)
520 rc = (int) 10 * (atan( (FLOAT)abs(y) / (FLOAT)abs(x)) / (3.1415 / 180));
547 static int get_button_state(int deviceid)
549 return button_state[deviceid];
552 static void set_button_state(XID deviceid)
554 struct x11drv_thread_data *data = x11drv_thread_data();
562 device = pXOpenDevice(data->display,deviceid);
563 state = pXQueryDeviceState(data->display,device);
568 for (loop = 0; loop < state->num_classes; loop++)
570 if (class->class == ButtonClass)
573 XButtonState *button_state = (XButtonState*)class;
574 for (loop2 = 0; loop2 < button_state->num_buttons; loop2++)
576 if (button_state->buttons[loop2 / 8] & (1 << (loop2 % 8)))
582 class = (XInputClass *) ((char *) class + class->length);
585 pXFreeDeviceState(state);
587 button_state[deviceid] = rc;
590 static void motion_event( HWND hwnd, XEvent *event )
592 XDeviceMotionEvent *motion = (XDeviceMotionEvent *)event;
593 LPWTI_CURSORS_INFO cursor = &gSysCursor[motion->deviceid];
595 memset(&gMsgPacket,0,sizeof(WTPACKET));
597 TRACE("Received tablet motion event (%p)\n",hwnd);
599 /* Set cursor to inverted if cursor is the eraser */
600 gMsgPacket.pkStatus = (cursor->TYPE == 0xc85a ?TPS_INVERT:0);
601 gMsgPacket.pkTime = EVENT_x11_time_to_win32_time(motion->time);
602 gMsgPacket.pkSerialNumber = gSerial++;
603 gMsgPacket.pkCursor = motion->deviceid;
604 gMsgPacket.pkX = motion->axis_data[0];
605 gMsgPacket.pkY = motion->axis_data[1];
606 gMsgPacket.pkOrientation.orAzimuth = figure_deg(motion->axis_data[3],motion->axis_data[4]);
607 gMsgPacket.pkOrientation.orAltitude = ((1000 - 15 * max
608 (abs(motion->axis_data[3]),
609 abs(motion->axis_data[4])))
610 * (gMsgPacket.pkStatus & TPS_INVERT?-1:1));
611 gMsgPacket.pkNormalPressure = motion->axis_data[2];
612 gMsgPacket.pkButtons = get_button_state(motion->deviceid);
613 SendMessageW(hwndTabletDefault,WT_PACKET,0,(LPARAM)hwnd);
616 static void button_event( HWND hwnd, XEvent *event )
618 XDeviceButtonEvent *button = (XDeviceButtonEvent *) event;
619 LPWTI_CURSORS_INFO cursor = &gSysCursor[button->deviceid];
621 memset(&gMsgPacket,0,sizeof(WTPACKET));
623 TRACE("Received tablet button %s event\n", (event->type == button_press_type)?"press":"release");
625 /* Set cursor to inverted if cursor is the eraser */
626 gMsgPacket.pkStatus = (cursor->TYPE == 0xc85a ?TPS_INVERT:0);
627 set_button_state(button->deviceid);
628 gMsgPacket.pkTime = EVENT_x11_time_to_win32_time(button->time);
629 gMsgPacket.pkSerialNumber = gSerial++;
630 gMsgPacket.pkCursor = button->deviceid;
631 gMsgPacket.pkX = button->axis_data[0];
632 gMsgPacket.pkY = button->axis_data[1];
633 gMsgPacket.pkOrientation.orAzimuth = figure_deg(button->axis_data[3],button->axis_data[4]);
634 gMsgPacket.pkOrientation.orAltitude = ((1000 - 15 * max(abs(button->axis_data[3]),
635 abs(button->axis_data[4])))
636 * (gMsgPacket.pkStatus & TPS_INVERT?-1:1));
637 gMsgPacket.pkNormalPressure = button->axis_data[2];
638 gMsgPacket.pkButtons = get_button_state(button->deviceid);
639 SendMessageW(hwndTabletDefault,WT_PACKET,0,(LPARAM)hwnd);
642 static void key_event( HWND hwnd, XEvent *event )
644 if (event->type == key_press_type)
645 FIXME("Received tablet key press event\n");
647 FIXME("Received tablet key release event\n");
650 static void proximity_event( HWND hwnd, XEvent *event )
652 XProximityNotifyEvent *proximity = (XProximityNotifyEvent *) event;
653 LPWTI_CURSORS_INFO cursor = &gSysCursor[proximity->deviceid];
655 memset(&gMsgPacket,0,sizeof(WTPACKET));
657 TRACE("Received tablet proximity event\n");
658 /* Set cursor to inverted if cursor is the eraser */
659 gMsgPacket.pkStatus = (cursor->TYPE == 0xc85a ?TPS_INVERT:0);
660 gMsgPacket.pkStatus |= (event->type==proximity_out_type)?TPS_PROXIMITY:0;
661 gMsgPacket.pkTime = EVENT_x11_time_to_win32_time(proximity->time);
662 gMsgPacket.pkSerialNumber = gSerial++;
663 gMsgPacket.pkCursor = proximity->deviceid;
664 gMsgPacket.pkX = proximity->axis_data[0];
665 gMsgPacket.pkY = proximity->axis_data[1];
666 gMsgPacket.pkOrientation.orAzimuth = figure_deg(proximity->axis_data[3],proximity->axis_data[4]);
667 gMsgPacket.pkOrientation.orAltitude = ((1000 - 15 * max(abs(proximity->axis_data[3]),
668 abs(proximity->axis_data[4])))
669 * (gMsgPacket.pkStatus & TPS_INVERT?-1:1));
670 gMsgPacket.pkNormalPressure = proximity->axis_data[2];
671 gMsgPacket.pkButtons = get_button_state(proximity->deviceid);
673 SendMessageW(hwndTabletDefault, WT_PROXIMITY, (event->type == proximity_in_type), (LPARAM)hwnd);
676 int X11DRV_AttachEventQueueToTablet(HWND hOwner)
678 struct x11drv_thread_data *data = x11drv_thread_data();
682 XDeviceInfo *devices;
683 XDeviceInfo *target = NULL;
685 XEventClass event_list[7];
686 Window win = X11DRV_get_whole_window( hOwner );
690 TRACE("Creating context for window %p (%lx) %i cursors\n", hOwner, win, gNumCursors);
693 devices = pXListInputDevices(data->display, &num_devices);
695 X11DRV_expect_error(data->display,Tablet_ErrorHandler,NULL);
696 for (cur_loop=0; cur_loop < gNumCursors; cur_loop++)
700 for (loop=0; loop < num_devices; loop ++)
701 if (strcmp(devices[loop].name,gSysCursor[cur_loop].NAME)==0)
702 target = &devices[loop];
704 TRACE("Opening cursor %i id %i\n",cur_loop,(INT)target->id);
706 the_device = pXOpenDevice(data->display, target->id);
710 WARN("Unable to Open device\n");
714 if (the_device->num_classes > 0)
716 DeviceKeyPress(the_device, key_press_type, event_list[event_number]);
717 if (event_list[event_number]) event_number++;
718 DeviceKeyRelease(the_device, key_release_type, event_list[event_number]);
719 if (event_list[event_number]) event_number++;
720 DeviceButtonPress(the_device, button_press_type, event_list[event_number]);
721 if (event_list[event_number]) event_number++;
722 DeviceButtonRelease(the_device, button_release_type, event_list[event_number]);
723 if (event_list[event_number]) event_number++;
724 DeviceMotionNotify(the_device, motion_type, event_list[event_number]);
725 if (event_list[event_number]) event_number++;
726 ProximityIn(the_device, proximity_in_type, event_list[event_number]);
727 if (event_list[event_number]) event_number++;
728 ProximityOut(the_device, proximity_out_type, event_list[event_number]);
729 if (event_list[event_number]) event_number++;
731 if (key_press_type) X11DRV_register_event_handler( key_press_type, key_event );
732 if (key_release_type) X11DRV_register_event_handler( key_release_type, key_event );
733 if (button_press_type) X11DRV_register_event_handler( button_press_type, button_event );
734 if (button_release_type) X11DRV_register_event_handler( button_release_type, button_event );
735 if (motion_type) X11DRV_register_event_handler( motion_type, motion_event );
736 if (proximity_in_type) X11DRV_register_event_handler( proximity_in_type, proximity_event );
737 if (proximity_out_type) X11DRV_register_event_handler( proximity_out_type, proximity_event );
739 pXSelectExtensionEvent(data->display, win, event_list, event_number);
742 XSync(data->display, False);
743 X11DRV_check_error();
745 if (NULL != devices) pXFreeDeviceList(devices);
750 int X11DRV_GetCurrentPacket(LPWTPACKET *packet)
752 memcpy(packet,&gMsgPacket,sizeof(WTPACKET));
757 static inline int CopyTabletData(LPVOID target, LPVOID src, INT size)
760 * It is valid to call CopyTabletData with NULL.
761 * This handles the WTInfo() case where lpOutput is null.
764 memcpy(target,src,size);
768 /***********************************************************************
769 * X11DRV_WTInfoA (X11DRV.@)
771 UINT X11DRV_WTInfoA(UINT wCategory, UINT nIndex, LPVOID lpOutput)
774 * It is valid to call WTInfoA with lpOutput == NULL, as per standard.
775 * lpOutput == NULL signifies the user only wishes
776 * to find the size of the data.
778 * From now on use CopyTabletData to fill lpOutput. memcpy will break
782 LPWTI_CURSORS_INFO tgtcursor;
783 TRACE("(%u, %u, %p)\n", wCategory, nIndex, lpOutput);
788 /* return largest necessary buffer */
789 TRACE("%i cursors\n",gNumCursors);
792 FIXME("Return proper size\n");
801 strcpy(lpOutput,"Wine Wintab 1.1");
804 case IFC_SPECVERSION:
805 version = (0x01) | (0x01 << 8);
806 rc = CopyTabletData(lpOutput, &version,sizeof(WORD));
808 case IFC_IMPLVERSION:
809 version = (0x00) | (0x01 << 8);
810 rc = CopyTabletData(lpOutput, &version,sizeof(WORD));
813 FIXME("WTI_INTERFACE unhandled index %i\n",nIndex);
823 rc = CopyTabletData(lpOutput, &gSysContext,
824 sizeof(LOGCONTEXTA));
827 rc = CopyTabletData(lpOutput, &gSysContext.lcName,
828 strlen(gSysContext.lcName)+1);
831 rc = CopyTabletData(lpOutput, &gSysContext.lcOptions,
835 rc = CopyTabletData(lpOutput, &gSysContext.lcStatus,
839 rc= CopyTabletData (lpOutput, &gSysContext.lcLocks,
843 rc = CopyTabletData(lpOutput, &gSysContext.lcMsgBase,
847 rc = CopyTabletData(lpOutput, &gSysContext.lcDevice,
851 rc = CopyTabletData(lpOutput, &gSysContext.lcPktRate,
855 rc = CopyTabletData(lpOutput, &gSysContext.lcPktMode,
859 rc = CopyTabletData(lpOutput, &gSysContext.lcMoveMask,
863 rc = CopyTabletData(lpOutput, &gSysContext.lcBtnDnMask,
867 rc = CopyTabletData(lpOutput, &gSysContext.lcBtnUpMask,
871 rc = CopyTabletData(lpOutput, &gSysContext.lcInOrgX,
875 rc = CopyTabletData(lpOutput, &gSysContext.lcInOrgY,
879 rc = CopyTabletData(lpOutput, &gSysContext.lcInOrgZ,
883 rc = CopyTabletData(lpOutput, &gSysContext.lcInExtX,
887 rc = CopyTabletData(lpOutput, &gSysContext.lcInExtY,
891 rc = CopyTabletData(lpOutput, &gSysContext.lcInExtZ,
895 rc = CopyTabletData(lpOutput, &gSysContext.lcOutOrgX,
899 rc = CopyTabletData(lpOutput, &gSysContext.lcOutOrgY,
903 rc = CopyTabletData(lpOutput, &gSysContext.lcOutOrgZ,
907 rc = CopyTabletData(lpOutput, &gSysContext.lcOutExtX,
911 rc = CopyTabletData(lpOutput, &gSysContext.lcOutExtY,
915 rc = CopyTabletData(lpOutput, &gSysContext.lcOutExtZ,
919 rc = CopyTabletData(lpOutput, &gSysContext.lcSensX,
923 rc = CopyTabletData(lpOutput, &gSysContext.lcSensY,
927 rc = CopyTabletData(lpOutput, &gSysContext.lcSensZ,
931 rc = CopyTabletData(lpOutput, &gSysContext.lcSysMode,
935 rc = CopyTabletData(lpOutput, &gSysContext.lcSysOrgX,
939 rc = CopyTabletData(lpOutput, &gSysContext.lcSysOrgY,
943 rc = CopyTabletData(lpOutput, &gSysContext.lcSysExtX,
947 rc = CopyTabletData(lpOutput, &gSysContext.lcSysExtY,
951 rc = CopyTabletData(lpOutput, &gSysContext.lcSysSensX,
955 rc = CopyTabletData(lpOutput, &gSysContext.lcSysSensY,
959 FIXME("WTI_DEFSYSCTX unhandled index %i\n",nIndex);
973 tgtcursor = &gSysCursor[wCategory - WTI_CURSORS];
977 rc = CopyTabletData(lpOutput, &tgtcursor->NAME,
978 strlen(tgtcursor->NAME)+1);
981 rc = CopyTabletData(lpOutput,&tgtcursor->ACTIVE,
985 rc = CopyTabletData(lpOutput,&tgtcursor->PKTDATA,
989 rc = CopyTabletData(lpOutput,&tgtcursor->BUTTONS,
993 rc = CopyTabletData(lpOutput,&tgtcursor->BUTTONBITS,
997 FIXME("Button Names not returned correctly\n");
998 rc = CopyTabletData(lpOutput,&tgtcursor->BTNNAMES,
999 strlen(tgtcursor->BTNNAMES)+1);
1002 rc = CopyTabletData(lpOutput,&tgtcursor->BUTTONMAP,
1006 rc = CopyTabletData(lpOutput,&tgtcursor->SYSBTNMAP,
1009 case CSR_NPBTNMARKS:
1010 rc = CopyTabletData(lpOutput,&tgtcursor->NPBTNMARKS,
1014 rc = CopyTabletData(lpOutput,&tgtcursor->NPBUTTON,
1017 case CSR_NPRESPONSE:
1018 FIXME("Not returning CSR_NPRESPONSE correctly\n");
1022 rc = CopyTabletData(lpOutput,&tgtcursor->TPBUTTON,
1025 case CSR_TPBTNMARKS:
1026 rc = CopyTabletData(lpOutput,&tgtcursor->TPBTNMARKS,
1029 case CSR_TPRESPONSE:
1030 FIXME("Not returning CSR_TPRESPONSE correctly\n");
1036 id = tgtcursor->PHYSID;
1037 id += (wCategory - WTI_CURSORS);
1038 rc = CopyTabletData(lpOutput,&id,sizeof(DWORD));
1042 rc = CopyTabletData(lpOutput,&tgtcursor->MODE,sizeof(UINT));
1044 case CSR_MINPKTDATA:
1045 rc = CopyTabletData(lpOutput,&tgtcursor->MINPKTDATA,
1048 case CSR_MINBUTTONS:
1049 rc = CopyTabletData(lpOutput,&tgtcursor->MINBUTTONS,
1052 case CSR_CAPABILITIES:
1053 rc = CopyTabletData(lpOutput,&tgtcursor->CAPABILITIES,
1057 rc = CopyTabletData(lpOutput,&tgtcursor->TYPE,
1061 FIXME("WTI_CURSORS unhandled index %i\n",nIndex);
1069 rc = CopyTabletData(lpOutput,gSysDevice.NAME,
1070 strlen(gSysDevice.NAME)+1);
1073 rc = CopyTabletData(lpOutput,&gSysDevice.HARDWARE,
1077 rc = CopyTabletData(lpOutput,&gSysDevice.NCSRTYPES,
1081 rc = CopyTabletData(lpOutput,&gSysDevice.FIRSTCSR,
1085 rc = CopyTabletData(lpOutput,&gSysDevice.PKTRATE,
1089 rc = CopyTabletData(lpOutput,&gSysDevice.PKTDATA,
1093 rc = CopyTabletData(lpOutput,&gSysDevice.PKTMODE,
1097 rc = CopyTabletData(lpOutput,&gSysDevice.CSRDATA,
1101 rc = CopyTabletData(lpOutput,&gSysDevice.XMARGIN,
1105 rc = CopyTabletData(lpOutput,&gSysDevice.YMARGIN,
1109 rc = 0; /* unsupported */
1111 rc = CopyTabletData(lpOutput,&gSysDevice.ZMARGIN,
1116 rc = CopyTabletData(lpOutput,&gSysDevice.X,
1120 rc = CopyTabletData(lpOutput,&gSysDevice.Y,
1124 rc = 0; /* unsupported */
1126 rc = CopyTabletData(lpOutput,&gSysDevice.Z,
1131 rc = CopyTabletData(lpOutput,&gSysDevice.NPRESSURE,
1135 rc = 0; /* unsupported */
1137 rc = CopyTabletData(lpOutput,&gSysDevice.TPRESSURE,
1141 case DVC_ORIENTATION:
1142 rc = CopyTabletData(lpOutput,&gSysDevice.ORIENTATION,
1146 rc = 0; /* unsupported */
1148 rc = CopyTabletData(lpOutput,&gSysDevice.ROTATION,
1153 rc = CopyTabletData(lpOutput,gSysDevice.PNPID,
1154 strlen(gSysDevice.PNPID)+1);
1157 FIXME("WTI_DEVICES unhandled index %i\n",nIndex);
1162 FIXME("Unhandled Category %i\n",wCategory);
1167 #else /* SONAME_LIBXI */
1169 /***********************************************************************
1170 * AttachEventQueueToTablet (X11DRV.@)
1172 int X11DRV_AttachEventQueueToTablet(HWND hOwner)
1177 /***********************************************************************
1178 * GetCurrentPacket (X11DRV.@)
1180 int X11DRV_GetCurrentPacket(LPWTPACKET *packet)
1185 /***********************************************************************
1186 * LoadTabletInfo (X11DRV.@)
1188 void X11DRV_LoadTabletInfo(HWND hwnddefault)
1192 /***********************************************************************
1193 * WTInfoA (X11DRV.@)
1195 UINT X11DRV_WTInfoA(UINT wCategory, UINT nIndex, LPVOID lpOutput)
1200 #endif /* SONAME_LIBXI */