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
= -1;
223 static int button_press_type
= -1;
224 static int button_release_type
= -1;
225 static int key_press_type
= -1;
226 static int key_release_type
= -1;
227 static int proximity_in_type
= -1;
228 static int proximity_out_type
= -1;
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(XOpenDevice
)
253 MAKE_FUNCPTR(XQueryDeviceState
)
254 MAKE_FUNCPTR(XGetDeviceButtonMapping
)
255 MAKE_FUNCPTR(XCloseDevice
)
256 MAKE_FUNCPTR(XSelectExtensionEvent
)
257 MAKE_FUNCPTR(XFreeDeviceState
)
260 static INT
X11DRV_XInput_Init(void)
262 xinput_handle
= wine_dlopen(SONAME_LIBXI
, RTLD_NOW
, NULL
, 0);
265 #define LOAD_FUNCPTR(f) if((p##f = wine_dlsym(xinput_handle, #f, NULL, 0)) == NULL) goto sym_not_found;
266 LOAD_FUNCPTR(XListInputDevices
)
267 LOAD_FUNCPTR(XOpenDevice
)
268 LOAD_FUNCPTR(XGetDeviceButtonMapping
)
269 LOAD_FUNCPTR(XCloseDevice
)
270 LOAD_FUNCPTR(XSelectExtensionEvent
)
271 LOAD_FUNCPTR(XQueryDeviceState
)
272 LOAD_FUNCPTR(XFreeDeviceState
)
280 static int Tablet_ErrorHandler(Display
*dpy
, XErrorEvent
*event
, void* arg
)
285 void X11DRV_LoadTabletInfo(HWND hwnddefault
)
287 struct x11drv_thread_data
*data
= x11drv_thread_data();
291 XDeviceInfo
*devices
;
292 XDeviceInfo
*target
= NULL
;
293 BOOL axis_read_complete
= FALSE
;
296 XButtonInfoPtr Button
;
297 XValuatorInfoPtr Val
;
302 if (!X11DRV_XInput_Init())
304 ERR("Unable to initialized the XInput library.\n");
308 hwndTabletDefault
= hwnddefault
;
310 /* Do base initializaion */
311 strcpy(gSysContext
.lcName
, "Wine Tablet Context");
312 strcpy(gSysDevice
.NAME
,"Wine Tablet Device");
314 gSysContext
.lcOptions
= CXO_SYSTEM
;
315 gSysContext
.lcLocks
= CXL_INSIZE
| CXL_INASPECT
| CXL_MARGIN
|
316 CXL_SENSITIVITY
| CXL_SYSOUT
;
318 gSysContext
.lcMsgBase
= WT_DEFBASE
;
319 gSysContext
.lcDevice
= 0;
320 gSysContext
.lcPktData
=
321 PK_CONTEXT
| PK_STATUS
| PK_SERIAL_NUMBER
| PK_TIME
| PK_CURSOR
|
322 PK_BUTTONS
| PK_X
| PK_Y
| PK_NORMAL_PRESSURE
| PK_ORIENTATION
;
323 gSysContext
.lcMoveMask
=
324 PK_BUTTONS
| PK_X
| PK_Y
| PK_NORMAL_PRESSURE
| PK_ORIENTATION
;
325 gSysContext
.lcStatus
= CXS_ONTOP
;
326 gSysContext
.lcPktRate
= 100;
327 gSysContext
.lcBtnDnMask
= 0xffffffff;
328 gSysContext
.lcBtnUpMask
= 0xffffffff;
329 gSysContext
.lcSensX
= 65536;
330 gSysContext
.lcSensY
= 65536;
331 gSysContext
.lcSensX
= 65536;
332 gSysContext
.lcSensZ
= 65536;
333 gSysContext
.lcSysSensX
= 65536;
334 gSysContext
.lcSysSensY
= 65536;
336 /* Device Defaults */
337 gSysDevice
.HARDWARE
= HWC_HARDPROX
|HWC_PHYSID_CURSORS
;
338 gSysDevice
.FIRSTCSR
= 0;
339 gSysDevice
.PKTRATE
= 100;
341 PK_CONTEXT
| PK_STATUS
| PK_SERIAL_NUMBER
| PK_TIME
| PK_CURSOR
|
342 PK_BUTTONS
| PK_X
| PK_Y
| PK_NORMAL_PRESSURE
| PK_ORIENTATION
;
343 strcpy(gSysDevice
.PNPID
,"non-pluginplay");
348 devices
= pXListInputDevices(data
->display
, &num_devices
);
351 WARN("XInput Extenstions reported as not avalable\n");
355 for (loop
=0; loop
< num_devices
; loop
++)
359 TRACE("Trying device %i(%s)\n",loop
,devices
[loop
].name
);
360 if (devices
[loop
].use
== IsXExtensionDevice
)
362 LPWTI_CURSORS_INFO cursor
;
364 TRACE("Is Extension Device\n");
366 target
= &devices
[loop
];
367 cursor
= &gSysCursor
[cursor_target
];
369 opendevice
= pXOpenDevice(data
->display
,target
->id
);
372 unsigned char map
[32];
376 X11DRV_expect_error(data
->display
,Tablet_ErrorHandler
,NULL
);
377 pXGetDeviceButtonMapping(data
->display
, opendevice
, map
, 32);
378 if (X11DRV_check_error())
380 TRACE("No buttons, Non Tablet Device\n");
381 pXCloseDevice(data
->display
, opendevice
);
386 for (i
=0; i
< cursor
->BUTTONS
; i
++,shft
++)
388 cursor
->BUTTONMAP
[i
] = map
[i
];
389 cursor
->SYSBTNMAP
[i
] = (1<<shft
);
391 pXCloseDevice(data
->display
, opendevice
);
395 WARN("Unable to open device %s\n",target
->name
);
400 strcpy(cursor
->NAME
,target
->name
);
403 cursor
->PKTDATA
= PK_TIME
| PK_CURSOR
| PK_BUTTONS
| PK_X
| PK_Y
|
404 PK_NORMAL_PRESSURE
| PK_TANGENT_PRESSURE
|
407 cursor
->PHYSID
= cursor_target
;
408 cursor
->NPBUTTON
= 1;
409 cursor
->NPBTNMARKS
[0] = 0 ;
410 cursor
->NPBTNMARKS
[1] = 1 ;
411 cursor
->CAPABILITIES
= CRC_MULTIMODE
;
412 if (strcasecmp(cursor
->NAME
,"stylus")==0)
413 cursor
->TYPE
= 0x4825;
414 if (strcasecmp(cursor
->NAME
,"eraser")==0)
415 cursor
->TYPE
= 0xc85a;
418 any
= (XAnyClassPtr
) (target
->inputclassinfo
);
420 for (class_loop
= 0; class_loop
< target
->num_classes
; class_loop
++)
425 if (!axis_read_complete
)
427 Val
= (XValuatorInfoPtr
) any
;
428 Axis
= (XAxisInfoPtr
) ((char *) Val
+ sizeof
431 if (Val
->num_axes
>=1)
434 gSysDevice
.X
.axMin
= Axis
->min_value
;
435 gSysDevice
.X
.axMax
= Axis
->max_value
;
436 gSysDevice
.X
.axUnits
= TU_INCHES
;
437 gSysDevice
.X
.axResolution
= Axis
->resolution
;
438 gSysContext
.lcInOrgX
= Axis
->min_value
;
439 gSysContext
.lcSysOrgX
= Axis
->min_value
;
440 gSysContext
.lcInExtX
= Axis
->max_value
;
441 gSysContext
.lcSysExtX
= Axis
->max_value
;
444 if (Val
->num_axes
>=2)
447 gSysDevice
.Y
.axMin
= Axis
->min_value
;
448 gSysDevice
.Y
.axMax
= Axis
->max_value
;
449 gSysDevice
.Y
.axUnits
= TU_INCHES
;
450 gSysDevice
.Y
.axResolution
= Axis
->resolution
;
451 gSysContext
.lcInOrgY
= Axis
->min_value
;
452 gSysContext
.lcSysOrgY
= Axis
->min_value
;
453 gSysContext
.lcInExtY
= Axis
->max_value
;
454 gSysContext
.lcSysExtY
= Axis
->max_value
;
457 if (Val
->num_axes
>=3)
459 /* Axis 3 is Normal Pressure */
460 gSysDevice
.NPRESSURE
.axMin
= Axis
->min_value
;
461 gSysDevice
.NPRESSURE
.axMax
= Axis
->max_value
;
462 gSysDevice
.NPRESSURE
.axUnits
= TU_INCHES
;
463 gSysDevice
.NPRESSURE
.axResolution
=
467 if (Val
->num_axes
>= 5)
469 /* Axis 4 and 5 are X and Y tilt */
470 XAxisInfoPtr XAxis
= Axis
;
472 if (max (abs(Axis
->max_value
),
473 abs(XAxis
->max_value
)))
475 gSysDevice
.ORIENTATION
[0].axMin
= 0;
476 gSysDevice
.ORIENTATION
[0].axMax
= 3600;
477 gSysDevice
.ORIENTATION
[0].axUnits
= TU_CIRCLE
;
478 gSysDevice
.ORIENTATION
[0].axResolution
480 gSysDevice
.ORIENTATION
[1].axMin
= -1000;
481 gSysDevice
.ORIENTATION
[1].axMax
= 1000;
482 gSysDevice
.ORIENTATION
[1].axUnits
= TU_CIRCLE
;
483 gSysDevice
.ORIENTATION
[1].axResolution
488 axis_read_complete
= TRUE
;
493 CHAR
*ptr
= cursor
->BTNNAMES
;
496 Button
= (XButtonInfoPtr
) any
;
497 cursor
->BUTTONS
= Button
->num_buttons
;
498 for (i
= 0; i
< cursor
->BUTTONS
; i
++)
500 strcpy(ptr
,cursor
->NAME
);
506 any
= (XAnyClassPtr
) ((char*) any
+ any
->length
);
511 gSysDevice
.NCSRTYPES
= cursor_target
+1;
512 gNumCursors
= cursor_target
+1;
515 static int figure_deg(int x
, int y
)
521 rc
= (int) 10 * (atan( (FLOAT
)abs(y
) / (FLOAT
)abs(x
)) / (3.1415 / 180));
548 static int get_button_state(int deviceid
)
550 return button_state
[deviceid
];
553 static void set_button_state(XID deviceid
)
555 struct x11drv_thread_data
*data
= x11drv_thread_data();
563 device
= pXOpenDevice(data
->display
,deviceid
);
564 state
= pXQueryDeviceState(data
->display
,device
);
569 for (loop
= 0; loop
< state
->num_classes
; loop
++)
571 if (class->class == ButtonClass
)
574 XButtonState
*button_state
= (XButtonState
*)class;
575 for (loop2
= 1; loop2
<= button_state
->num_buttons
; loop2
++)
577 if (button_state
->buttons
[loop2
/ 8] & (1 << (loop2
% 8)))
579 rc
|= (1<<(loop2
-1));
583 class = (XInputClass
*) ((char *) class + class->length
);
586 pXFreeDeviceState(state
);
588 button_state
[deviceid
] = rc
;
591 int X11DRV_ProcessTabletEvent(HWND hwnd
, XEvent
*event
)
593 memset(&gMsgPacket
,0,sizeof(WTPACKET
));
595 if(event
->type
== motion_type
)
597 XDeviceMotionEvent
*motion
= (XDeviceMotionEvent
*)event
;
598 LPWTI_CURSORS_INFO cursor
= &gSysCursor
[motion
->deviceid
];
600 TRACE_(event
)("Received tablet motion event (%p)\n",hwnd
);
601 TRACE("Received tablet motion event (%p)\n",hwnd
);
602 /* Set cursor to inverted if cursor is the eraser */
603 gMsgPacket
.pkStatus
= (cursor
->TYPE
== 0xc85a ?TPS_INVERT
:0);
604 gMsgPacket
.pkTime
= EVENT_x11_time_to_win32_time(motion
->time
);
605 gMsgPacket
.pkSerialNumber
= gSerial
++;
606 gMsgPacket
.pkCursor
= motion
->deviceid
;
607 gMsgPacket
.pkX
= motion
->axis_data
[0];
608 gMsgPacket
.pkY
= motion
->axis_data
[1];
609 gMsgPacket
.pkOrientation
.orAzimuth
=
610 figure_deg(motion
->axis_data
[3],motion
->axis_data
[4]);
611 gMsgPacket
.pkOrientation
.orAltitude
= 1000 - 15 * max
612 (abs(motion
->axis_data
[3]),abs(motion
->axis_data
[4]));
613 gMsgPacket
.pkNormalPressure
= motion
->axis_data
[2];
614 gMsgPacket
.pkButtons
= get_button_state(motion
->deviceid
);
615 SendMessageW(hwndTabletDefault
,WT_PACKET
,0,(LPARAM
)hwnd
);
617 else if ((event
->type
== button_press_type
)||(event
->type
==
618 button_release_type
))
620 XDeviceButtonEvent
*button
= (XDeviceButtonEvent
*) event
;
621 LPWTI_CURSORS_INFO cursor
= &gSysCursor
[button
->deviceid
];
623 TRACE_(event
)("Received tablet button event\n");
624 TRACE("Received tablet button %s event\n", (event
->type
==
625 button_press_type
)?"press":"release");
627 /* Set cursor to inverted if cursor is the eraser */
628 gMsgPacket
.pkStatus
= (cursor
->TYPE
== 0xc85a ?TPS_INVERT
:0);
629 set_button_state(button
->deviceid
);
630 gMsgPacket
.pkTime
= button
->time
;
631 gMsgPacket
.pkSerialNumber
= gSerial
++;
632 gMsgPacket
.pkCursor
= button
->deviceid
;
633 gMsgPacket
.pkX
= button
->axis_data
[0];
634 gMsgPacket
.pkY
= button
->axis_data
[1];
635 gMsgPacket
.pkOrientation
.orAzimuth
=
636 figure_deg(button
->axis_data
[3],button
->axis_data
[4]);
637 gMsgPacket
.pkOrientation
.orAltitude
= 1000 - 15 * max
638 (abs(button
->axis_data
[3]),abs(button
->axis_data
[4]));
639 gMsgPacket
.pkNormalPressure
= button
->axis_data
[2];
640 gMsgPacket
.pkButtons
= get_button_state(button
->deviceid
);
641 SendMessageW(hwndTabletDefault
,WT_PACKET
,0,(LPARAM
)hwnd
);
643 else if (event
->type
== key_press_type
)
645 TRACE_(event
)("Received tablet key press event\n");
646 FIXME("Received tablet key press event\n");
648 else if (event
->type
== key_release_type
)
650 TRACE_(event
)("Received tablet key release event\n");
651 FIXME("Received tablet key release event\n");
653 else if ((event
->type
== proximity_in_type
) ||
654 (event
->type
== proximity_out_type
))
656 XProximityNotifyEvent
*proximity
= (XProximityNotifyEvent
*) event
;
657 LPWTI_CURSORS_INFO cursor
= &gSysCursor
[proximity
->deviceid
];
659 TRACE_(event
)("Received tablet proximity event\n");
660 TRACE("Received tablet proximity event\n");
661 /* Set cursor to inverted if cursor is the eraser */
662 gMsgPacket
.pkStatus
= (cursor
->TYPE
== 0xc85a ?TPS_INVERT
:0);
663 gMsgPacket
.pkStatus
|= (event
->type
==proximity_out_type
)?TPS_PROXIMITY
:0;
664 gMsgPacket
.pkTime
= proximity
->time
;
665 gMsgPacket
.pkSerialNumber
= gSerial
++;
666 gMsgPacket
.pkCursor
= proximity
->deviceid
;
667 gMsgPacket
.pkX
= proximity
->axis_data
[0];
668 gMsgPacket
.pkY
= proximity
->axis_data
[1];
669 gMsgPacket
.pkOrientation
.orAzimuth
=
670 figure_deg(proximity
->axis_data
[3],proximity
->axis_data
[4]);
671 gMsgPacket
.pkOrientation
.orAltitude
= 1000 - 15 * max
672 (abs(proximity
->axis_data
[3]),abs(proximity
->axis_data
[4]));
673 gMsgPacket
.pkNormalPressure
= proximity
->axis_data
[2];
674 gMsgPacket
.pkButtons
= get_button_state(proximity
->deviceid
);
676 SendMessageW(hwndTabletDefault
, WT_PROXIMITY
,
677 (event
->type
==proximity_out_type
)?0:1, (LPARAM
)hwnd
);
685 int X11DRV_AttachEventQueueToTablet(HWND hOwner
)
687 struct x11drv_thread_data
*data
= x11drv_thread_data();
691 XDeviceInfo
*devices
;
692 XDeviceInfo
*target
= NULL
;
695 XEventClass event_list
[7];
696 Window win
= X11DRV_get_whole_window( hOwner
);
700 TRACE("Creating context for window %p (%lx) %i cursors\n", hOwner
, win
, gNumCursors
);
703 devices
= pXListInputDevices(data
->display
, &num_devices
);
705 for (cur_loop
=0; cur_loop
< gNumCursors
; cur_loop
++)
709 for (loop
=0; loop
< num_devices
; loop
++)
710 if (strcmp(devices
[loop
].name
,gSysCursor
[cur_loop
].NAME
)==0)
711 target
= &devices
[loop
];
713 TRACE("Opening cursor %i id %i\n",cur_loop
,(INT
)target
->id
);
715 the_device
= pXOpenDevice(data
->display
, target
->id
);
719 WARN("Unable to Open device\n");
723 if (the_device
->num_classes
> 0)
725 for (ip
= the_device
->classes
, loop
=0; loop
< target
->num_classes
;
728 switch(ip
->input_class
)
731 DeviceKeyPress(the_device
, key_press_type
,
732 event_list
[event_number
]);
734 DeviceKeyRelease(the_device
, key_release_type
,
735 event_list
[event_number
]);
739 DeviceButtonPress(the_device
, button_press_type
,
740 event_list
[event_number
]);
742 DeviceButtonRelease(the_device
, button_release_type
,
743 event_list
[event_number
]);
747 DeviceMotionNotify(the_device
, motion_type
,
748 event_list
[event_number
]);
750 ProximityIn(the_device
, proximity_in_type
,
751 event_list
[event_number
]);
753 ProximityOut(the_device
, proximity_out_type
,
754 event_list
[event_number
]);
758 ERR("unknown class\n");
762 if (pXSelectExtensionEvent(data
->display
, win
, event_list
, event_number
))
764 ERR( "error selecting extended events\n");
775 int X11DRV_GetCurrentPacket(LPWTPACKET
*packet
)
777 memcpy(packet
,&gMsgPacket
,sizeof(WTPACKET
));
782 int static inline CopyTabletData(LPVOID target
, LPVOID src
, INT size
)
785 * It is valid to call CopyTabletData with NULL.
786 * This handles the WTInfo() case where lpOutput is null.
789 memcpy(target
,src
,size
);
793 /***********************************************************************
794 * X11DRV_WTInfoA (X11DRV.@)
796 UINT
X11DRV_WTInfoA(UINT wCategory
, UINT nIndex
, LPVOID lpOutput
)
799 * It is valid to call WTInfoA with lpOutput == NULL, as per standard.
800 * lpOutput == NULL signifies the user only wishes
801 * to find the size of the data.
803 * From now on use CopyTabletData to fill lpOutput. memcpy will break
807 LPWTI_CURSORS_INFO tgtcursor
;
808 TRACE("(%u, %u, %p)\n", wCategory
, nIndex
, lpOutput
);
813 /* return largest necessary buffer */
814 TRACE("%i cursors\n",gNumCursors
);
817 FIXME("Return proper size\n");
826 strcpy(lpOutput
,"Wine Wintab 1.1");
829 case IFC_SPECVERSION
:
830 version
= (0x01) | (0x01 << 8);
831 rc
= CopyTabletData(lpOutput
, &version
,sizeof(WORD
));
833 case IFC_IMPLVERSION
:
834 version
= (0x00) | (0x01 << 8);
835 rc
= CopyTabletData(lpOutput
, &version
,sizeof(WORD
));
838 FIXME("WTI_INTERFACE unhandled index %i\n",nIndex
);
848 rc
= CopyTabletData(lpOutput
, &gSysContext
,
849 sizeof(LOGCONTEXTA
));
852 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcName
,
853 strlen(gSysContext
.lcName
)+1);
856 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcOptions
,
860 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcStatus
,
864 rc
= CopyTabletData (lpOutput
, &gSysContext
.lcLocks
,
868 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcMsgBase
,
872 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcDevice
,
876 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcPktRate
,
880 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcPktMode
,
884 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcMoveMask
,
888 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcBtnDnMask
,
892 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcBtnUpMask
,
896 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcInOrgX
,
900 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcInOrgY
,
904 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcInOrgZ
,
908 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcInExtX
,
912 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcInExtY
,
916 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcInExtZ
,
920 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcOutOrgX
,
924 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcOutOrgY
,
928 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcOutOrgZ
,
932 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcOutExtX
,
936 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcOutExtY
,
940 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcOutExtZ
,
944 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcSensX
,
948 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcSensY
,
952 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcSensZ
,
956 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcSysMode
,
960 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcSysOrgX
,
964 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcSysOrgY
,
968 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcSysExtX
,
972 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcSysExtY
,
976 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcSysSensX
,
980 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcSysSensY
,
984 FIXME("WTI_DEFSYSCTX unhandled index %i\n",nIndex
);
999 tgtcursor
= &gSysCursor
[wCategory
- WTI_CURSORS
];
1003 rc
= CopyTabletData(lpOutput
, &tgtcursor
->NAME
,
1004 strlen(tgtcursor
->NAME
)+1);
1007 rc
= CopyTabletData(lpOutput
,&tgtcursor
->ACTIVE
,
1011 rc
= CopyTabletData(lpOutput
,&tgtcursor
->PKTDATA
,
1015 rc
= CopyTabletData(lpOutput
,&tgtcursor
->BUTTONS
,
1018 case CSR_BUTTONBITS
:
1019 rc
= CopyTabletData(lpOutput
,&tgtcursor
->BUTTONBITS
,
1023 FIXME("Button Names not returned correctly\n");
1024 rc
= CopyTabletData(lpOutput
,&tgtcursor
->BTNNAMES
,
1025 strlen(tgtcursor
->BTNNAMES
)+1);
1028 rc
= CopyTabletData(lpOutput
,&tgtcursor
->BUTTONMAP
,
1032 rc
= CopyTabletData(lpOutput
,&tgtcursor
->SYSBTNMAP
,
1035 case CSR_NPBTNMARKS
:
1036 rc
= CopyTabletData(lpOutput
,&tgtcursor
->NPBTNMARKS
,
1040 rc
= CopyTabletData(lpOutput
,&tgtcursor
->NPBUTTON
,
1043 case CSR_NPRESPONSE
:
1044 FIXME("Not returning CSR_NPRESPONSE correctly\n");
1048 rc
= CopyTabletData(lpOutput
,&tgtcursor
->TPBUTTON
,
1051 case CSR_TPBTNMARKS
:
1052 rc
= CopyTabletData(lpOutput
,&tgtcursor
->TPBTNMARKS
,
1055 case CSR_TPRESPONSE
:
1056 FIXME("Not returning CSR_TPRESPONSE correctly\n");
1062 id
= tgtcursor
->PHYSID
;
1063 id
+= (wCategory
- WTI_CURSORS
);
1064 rc
= CopyTabletData(lpOutput
,&id
,sizeof(DWORD
));
1068 rc
= CopyTabletData(lpOutput
,&tgtcursor
->MODE
,sizeof(UINT
));
1070 case CSR_MINPKTDATA
:
1071 rc
= CopyTabletData(lpOutput
,&tgtcursor
->MINPKTDATA
,
1074 case CSR_MINBUTTONS
:
1075 rc
= CopyTabletData(lpOutput
,&tgtcursor
->MINBUTTONS
,
1078 case CSR_CAPABILITIES
:
1079 rc
= CopyTabletData(lpOutput
,&tgtcursor
->CAPABILITIES
,
1083 rc
= CopyTabletData(lpOutput
,&tgtcursor
->TYPE
,
1087 FIXME("WTI_CURSORS unhandled index %i\n",nIndex
);
1095 rc
= CopyTabletData(lpOutput
,gSysDevice
.NAME
,
1096 strlen(gSysDevice
.NAME
)+1);
1099 rc
= CopyTabletData(lpOutput
,&gSysDevice
.HARDWARE
,
1103 rc
= CopyTabletData(lpOutput
,&gSysDevice
.NCSRTYPES
,
1107 rc
= CopyTabletData(lpOutput
,&gSysDevice
.FIRSTCSR
,
1111 rc
= CopyTabletData(lpOutput
,&gSysDevice
.PKTRATE
,
1115 rc
= CopyTabletData(lpOutput
,&gSysDevice
.PKTDATA
,
1119 rc
= CopyTabletData(lpOutput
,&gSysDevice
.PKTMODE
,
1123 rc
= CopyTabletData(lpOutput
,&gSysDevice
.CSRDATA
,
1127 rc
= CopyTabletData(lpOutput
,&gSysDevice
.XMARGIN
,
1131 rc
= CopyTabletData(lpOutput
,&gSysDevice
.YMARGIN
,
1135 rc
= 0; /* unsupported */
1137 rc = CopyTabletData(lpOutput,&gSysDevice.ZMARGIN,
1142 rc
= CopyTabletData(lpOutput
,&gSysDevice
.X
,
1146 rc
= CopyTabletData(lpOutput
,&gSysDevice
.Y
,
1150 rc
= 0; /* unsupported */
1152 rc = CopyTabletData(lpOutput,&gSysDevice.Z,
1157 rc
= CopyTabletData(lpOutput
,&gSysDevice
.NPRESSURE
,
1161 rc
= 0; /* unsupported */
1163 rc = CopyTabletData(lpOutput,&gSysDevice.TPRESSURE,
1167 case DVC_ORIENTATION
:
1168 rc
= CopyTabletData(lpOutput
,&gSysDevice
.ORIENTATION
,
1172 rc
= 0; /* unsupported */
1174 rc = CopyTabletData(lpOutput,&gSysDevice.ROTATION,
1179 rc
= CopyTabletData(lpOutput
,gSysDevice
.PNPID
,
1180 strlen(gSysDevice
.PNPID
)+1);
1183 FIXME("WTI_DEVICES unhandled index %i\n",nIndex
);
1188 FIXME("Unhandled Category %i\n",wCategory
);
1193 #else /* HAVE_X11_EXTENSIONS_XINPUT_H */
1195 int X11DRV_ProcessTabletEvent(HWND hwnd
, XEvent
*event
)
1200 /***********************************************************************
1201 * AttachEventQueueToTablet (X11DRV.@)
1203 int X11DRV_AttachEventQueueToTablet(HWND hOwner
)
1208 /***********************************************************************
1209 * GetCurrentPacket (X11DRV.@)
1211 int X11DRV_GetCurrentPacket(LPWTPACKET
*packet
)
1216 /***********************************************************************
1217 * LoadTabletInfo (X11DRV.@)
1219 void X11DRV_LoadTabletInfo(HWND hwnddefault
)
1223 /***********************************************************************
1224 * WTInfoA (X11DRV.@)
1226 UINT
X11DRV_WTInfoA(UINT wCategory
, UINT nIndex
, LPVOID lpOutput
)
1231 #endif /* HAVE_X11_EXTENSIONS_XINPUT_H */