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
);
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
;
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 #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(XFreeDeviceList
)
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(XFreeDeviceList
)
268 LOAD_FUNCPTR(XOpenDevice
)
269 LOAD_FUNCPTR(XGetDeviceButtonMapping
)
270 LOAD_FUNCPTR(XCloseDevice
)
271 LOAD_FUNCPTR(XSelectExtensionEvent
)
272 LOAD_FUNCPTR(XQueryDeviceState
)
273 LOAD_FUNCPTR(XFreeDeviceState
)
281 static int Tablet_ErrorHandler(Display
*dpy
, XErrorEvent
*event
, void* arg
)
286 void X11DRV_LoadTabletInfo(HWND hwnddefault
)
288 struct x11drv_thread_data
*data
= x11drv_thread_data();
292 XDeviceInfo
*devices
;
293 XDeviceInfo
*target
= NULL
;
294 BOOL axis_read_complete
= FALSE
;
297 XButtonInfoPtr Button
;
298 XValuatorInfoPtr Val
;
303 if (!X11DRV_XInput_Init())
305 ERR("Unable to initialized the XInput library.\n");
309 hwndTabletDefault
= hwnddefault
;
311 /* Do base initializaion */
312 strcpy(gSysContext
.lcName
, "Wine Tablet Context");
313 strcpy(gSysDevice
.NAME
,"Wine Tablet Device");
315 gSysContext
.lcOptions
= CXO_SYSTEM
;
316 gSysContext
.lcLocks
= CXL_INSIZE
| CXL_INASPECT
| CXL_MARGIN
|
317 CXL_SENSITIVITY
| CXL_SYSOUT
;
319 gSysContext
.lcMsgBase
= WT_DEFBASE
;
320 gSysContext
.lcDevice
= 0;
321 gSysContext
.lcPktData
=
322 PK_CONTEXT
| PK_STATUS
| PK_SERIAL_NUMBER
| PK_TIME
| PK_CURSOR
|
323 PK_BUTTONS
| PK_X
| PK_Y
| PK_NORMAL_PRESSURE
| PK_ORIENTATION
;
324 gSysContext
.lcMoveMask
=
325 PK_BUTTONS
| PK_X
| PK_Y
| PK_NORMAL_PRESSURE
| PK_ORIENTATION
;
326 gSysContext
.lcStatus
= CXS_ONTOP
;
327 gSysContext
.lcPktRate
= 100;
328 gSysContext
.lcBtnDnMask
= 0xffffffff;
329 gSysContext
.lcBtnUpMask
= 0xffffffff;
330 gSysContext
.lcSensX
= 65536;
331 gSysContext
.lcSensY
= 65536;
332 gSysContext
.lcSensX
= 65536;
333 gSysContext
.lcSensZ
= 65536;
334 gSysContext
.lcSysSensX
= 65536;
335 gSysContext
.lcSysSensY
= 65536;
337 /* Device Defaults */
338 gSysDevice
.HARDWARE
= HWC_HARDPROX
|HWC_PHYSID_CURSORS
;
339 gSysDevice
.FIRSTCSR
= 0;
340 gSysDevice
.PKTRATE
= 100;
342 PK_CONTEXT
| PK_STATUS
| PK_SERIAL_NUMBER
| PK_TIME
| PK_CURSOR
|
343 PK_BUTTONS
| PK_X
| PK_Y
| PK_NORMAL_PRESSURE
| PK_ORIENTATION
;
344 strcpy(gSysDevice
.PNPID
,"non-pluginplay");
349 devices
= pXListInputDevices(data
->display
, &num_devices
);
352 WARN("XInput Extenstions reported as not avalable\n");
356 for (loop
=0; loop
< num_devices
; loop
++)
360 TRACE("Trying device %i(%s)\n",loop
,devices
[loop
].name
);
361 if (devices
[loop
].use
== IsXExtensionDevice
)
363 LPWTI_CURSORS_INFO cursor
;
365 TRACE("Is Extension Device\n");
367 target
= &devices
[loop
];
368 cursor
= &gSysCursor
[cursor_target
];
370 opendevice
= pXOpenDevice(data
->display
,target
->id
);
373 unsigned char map
[32];
377 X11DRV_expect_error(data
->display
,Tablet_ErrorHandler
,NULL
);
378 pXGetDeviceButtonMapping(data
->display
, opendevice
, map
, 32);
379 if (X11DRV_check_error())
381 TRACE("No buttons, Non Tablet Device\n");
382 pXCloseDevice(data
->display
, opendevice
);
387 for (i
=0; i
< cursor
->BUTTONS
; i
++,shft
++)
389 cursor
->BUTTONMAP
[i
] = map
[i
];
390 cursor
->SYSBTNMAP
[i
] = (1<<shft
);
392 pXCloseDevice(data
->display
, opendevice
);
396 WARN("Unable to open device %s\n",target
->name
);
401 strcpy(cursor
->NAME
,target
->name
);
404 cursor
->PKTDATA
= PK_TIME
| PK_CURSOR
| PK_BUTTONS
| PK_X
| PK_Y
|
405 PK_NORMAL_PRESSURE
| PK_TANGENT_PRESSURE
|
408 cursor
->PHYSID
= cursor_target
;
409 cursor
->NPBUTTON
= 1;
410 cursor
->NPBTNMARKS
[0] = 0 ;
411 cursor
->NPBTNMARKS
[1] = 1 ;
412 cursor
->CAPABILITIES
= CRC_MULTIMODE
;
413 if (strcasecmp(cursor
->NAME
,"stylus")==0)
414 cursor
->TYPE
= 0x4825;
415 if (strcasecmp(cursor
->NAME
,"eraser")==0)
416 cursor
->TYPE
= 0xc85a;
419 any
= (XAnyClassPtr
) (target
->inputclassinfo
);
421 for (class_loop
= 0; class_loop
< target
->num_classes
; class_loop
++)
426 if (!axis_read_complete
)
428 Val
= (XValuatorInfoPtr
) any
;
429 Axis
= (XAxisInfoPtr
) ((char *) Val
+ sizeof
432 if (Val
->num_axes
>=1)
435 gSysDevice
.X
.axMin
= Axis
->min_value
;
436 gSysDevice
.X
.axMax
= Axis
->max_value
;
437 gSysDevice
.X
.axUnits
= TU_INCHES
;
438 gSysDevice
.X
.axResolution
= Axis
->resolution
;
439 gSysContext
.lcInOrgX
= Axis
->min_value
;
440 gSysContext
.lcSysOrgX
= Axis
->min_value
;
441 gSysContext
.lcInExtX
= Axis
->max_value
;
442 gSysContext
.lcSysExtX
= Axis
->max_value
;
445 if (Val
->num_axes
>=2)
448 gSysDevice
.Y
.axMin
= Axis
->min_value
;
449 gSysDevice
.Y
.axMax
= Axis
->max_value
;
450 gSysDevice
.Y
.axUnits
= TU_INCHES
;
451 gSysDevice
.Y
.axResolution
= Axis
->resolution
;
452 gSysContext
.lcInOrgY
= Axis
->min_value
;
453 gSysContext
.lcSysOrgY
= Axis
->min_value
;
454 gSysContext
.lcInExtY
= Axis
->max_value
;
455 gSysContext
.lcSysExtY
= Axis
->max_value
;
458 if (Val
->num_axes
>=3)
460 /* Axis 3 is Normal Pressure */
461 gSysDevice
.NPRESSURE
.axMin
= Axis
->min_value
;
462 gSysDevice
.NPRESSURE
.axMax
= Axis
->max_value
;
463 gSysDevice
.NPRESSURE
.axUnits
= TU_INCHES
;
464 gSysDevice
.NPRESSURE
.axResolution
=
468 if (Val
->num_axes
>= 5)
470 /* Axis 4 and 5 are X and Y tilt */
471 XAxisInfoPtr XAxis
= Axis
;
473 if (max (abs(Axis
->max_value
),
474 abs(XAxis
->max_value
)))
476 gSysDevice
.ORIENTATION
[0].axMin
= 0;
477 gSysDevice
.ORIENTATION
[0].axMax
= 3600;
478 gSysDevice
.ORIENTATION
[0].axUnits
= TU_CIRCLE
;
479 gSysDevice
.ORIENTATION
[0].axResolution
481 gSysDevice
.ORIENTATION
[1].axMin
= -1000;
482 gSysDevice
.ORIENTATION
[1].axMax
= 1000;
483 gSysDevice
.ORIENTATION
[1].axUnits
= TU_CIRCLE
;
484 gSysDevice
.ORIENTATION
[1].axResolution
489 axis_read_complete
= TRUE
;
494 CHAR
*ptr
= cursor
->BTNNAMES
;
497 Button
= (XButtonInfoPtr
) any
;
498 cursor
->BUTTONS
= Button
->num_buttons
;
499 for (i
= 0; i
< cursor
->BUTTONS
; i
++)
501 strcpy(ptr
,cursor
->NAME
);
507 any
= (XAnyClassPtr
) ((char*) any
+ any
->length
);
511 pXFreeDeviceList(devices
);
513 gSysDevice
.NCSRTYPES
= cursor_target
+1;
514 gNumCursors
= cursor_target
+1;
517 static int figure_deg(int x
, int y
)
523 rc
= (int) 10 * (atan( (FLOAT
)abs(y
) / (FLOAT
)abs(x
)) / (3.1415 / 180));
550 static int get_button_state(int deviceid
)
552 return button_state
[deviceid
];
555 static void set_button_state(XID deviceid
)
557 struct x11drv_thread_data
*data
= x11drv_thread_data();
565 device
= pXOpenDevice(data
->display
,deviceid
);
566 state
= pXQueryDeviceState(data
->display
,device
);
571 for (loop
= 0; loop
< state
->num_classes
; loop
++)
573 if (class->class == ButtonClass
)
576 XButtonState
*button_state
= (XButtonState
*)class;
577 for (loop2
= 1; loop2
<= button_state
->num_buttons
; loop2
++)
579 if (button_state
->buttons
[loop2
/ 8] & (1 << (loop2
% 8)))
581 rc
|= (1<<(loop2
-1));
585 class = (XInputClass
*) ((char *) class + class->length
);
588 pXFreeDeviceState(state
);
590 button_state
[deviceid
] = rc
;
593 static void motion_event( HWND hwnd
, XEvent
*event
)
595 XDeviceMotionEvent
*motion
= (XDeviceMotionEvent
*)event
;
596 LPWTI_CURSORS_INFO cursor
= &gSysCursor
[motion
->deviceid
];
598 memset(&gMsgPacket
,0,sizeof(WTPACKET
));
600 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
= figure_deg(motion
->axis_data
[3],motion
->axis_data
[4]);
610 gMsgPacket
.pkOrientation
.orAltitude
= ((1000 - 15 * max
611 (abs(motion
->axis_data
[3]),
612 abs(motion
->axis_data
[4])))
613 * (gMsgPacket
.pkStatus
& TPS_INVERT
?-1:1));
614 gMsgPacket
.pkNormalPressure
= motion
->axis_data
[2];
615 gMsgPacket
.pkButtons
= get_button_state(motion
->deviceid
);
616 SendMessageW(hwndTabletDefault
,WT_PACKET
,0,(LPARAM
)hwnd
);
619 static void button_event( HWND hwnd
, XEvent
*event
)
621 XDeviceButtonEvent
*button
= (XDeviceButtonEvent
*) event
;
622 LPWTI_CURSORS_INFO cursor
= &gSysCursor
[button
->deviceid
];
624 memset(&gMsgPacket
,0,sizeof(WTPACKET
));
626 TRACE("Received tablet button %s event\n", (event
->type
== button_press_type
)?"press":"release");
628 /* Set cursor to inverted if cursor is the eraser */
629 gMsgPacket
.pkStatus
= (cursor
->TYPE
== 0xc85a ?TPS_INVERT
:0);
630 set_button_state(button
->deviceid
);
631 gMsgPacket
.pkTime
= EVENT_x11_time_to_win32_time(button
->time
);
632 gMsgPacket
.pkSerialNumber
= gSerial
++;
633 gMsgPacket
.pkCursor
= button
->deviceid
;
634 gMsgPacket
.pkX
= button
->axis_data
[0];
635 gMsgPacket
.pkY
= button
->axis_data
[1];
636 gMsgPacket
.pkOrientation
.orAzimuth
= figure_deg(button
->axis_data
[3],button
->axis_data
[4]);
637 gMsgPacket
.pkOrientation
.orAltitude
= ((1000 - 15 * max(abs(button
->axis_data
[3]),
638 abs(button
->axis_data
[4])))
639 * (gMsgPacket
.pkStatus
& TPS_INVERT
?-1:1));
640 gMsgPacket
.pkNormalPressure
= button
->axis_data
[2];
641 gMsgPacket
.pkButtons
= get_button_state(button
->deviceid
);
642 SendMessageW(hwndTabletDefault
,WT_PACKET
,0,(LPARAM
)hwnd
);
645 static void key_event( HWND hwnd
, XEvent
*event
)
647 if (event
->type
== key_press_type
)
648 FIXME("Received tablet key press event\n");
650 FIXME("Received tablet key release event\n");
653 static void proximity_event( HWND hwnd
, XEvent
*event
)
655 XProximityNotifyEvent
*proximity
= (XProximityNotifyEvent
*) event
;
656 LPWTI_CURSORS_INFO cursor
= &gSysCursor
[proximity
->deviceid
];
658 memset(&gMsgPacket
,0,sizeof(WTPACKET
));
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
= EVENT_x11_time_to_win32_time(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
= figure_deg(proximity
->axis_data
[3],proximity
->axis_data
[4]);
670 gMsgPacket
.pkOrientation
.orAltitude
= ((1000 - 15 * max(abs(proximity
->axis_data
[3]),
671 abs(proximity
->axis_data
[4])))
672 * (gMsgPacket
.pkStatus
& TPS_INVERT
?-1:1));
673 gMsgPacket
.pkNormalPressure
= proximity
->axis_data
[2];
674 gMsgPacket
.pkButtons
= get_button_state(proximity
->deviceid
);
676 SendMessageW(hwndTabletDefault
, WT_PROXIMITY
, (event
->type
== proximity_in_type
), (LPARAM
)hwnd
);
679 int X11DRV_AttachEventQueueToTablet(HWND hOwner
)
681 struct x11drv_thread_data
*data
= x11drv_thread_data();
685 XDeviceInfo
*devices
;
686 XDeviceInfo
*target
= NULL
;
688 XEventClass event_list
[7];
689 Window win
= X11DRV_get_whole_window( hOwner
);
693 TRACE("Creating context for window %p (%lx) %i cursors\n", hOwner
, win
, gNumCursors
);
696 devices
= pXListInputDevices(data
->display
, &num_devices
);
698 X11DRV_expect_error(data
->display
,Tablet_ErrorHandler
,NULL
);
699 for (cur_loop
=0; cur_loop
< gNumCursors
; cur_loop
++)
703 for (loop
=0; loop
< num_devices
; loop
++)
704 if (strcmp(devices
[loop
].name
,gSysCursor
[cur_loop
].NAME
)==0)
705 target
= &devices
[loop
];
707 TRACE("Opening cursor %i id %i\n",cur_loop
,(INT
)target
->id
);
709 the_device
= pXOpenDevice(data
->display
, target
->id
);
713 WARN("Unable to Open device\n");
717 if (the_device
->num_classes
> 0)
719 DeviceKeyPress(the_device
, key_press_type
, event_list
[event_number
]);
720 if (event_list
[event_number
]) event_number
++;
721 DeviceKeyRelease(the_device
, key_release_type
, event_list
[event_number
]);
722 if (event_list
[event_number
]) event_number
++;
723 DeviceButtonPress(the_device
, button_press_type
, event_list
[event_number
]);
724 if (event_list
[event_number
]) event_number
++;
725 DeviceButtonRelease(the_device
, button_release_type
, event_list
[event_number
]);
726 if (event_list
[event_number
]) event_number
++;
727 DeviceMotionNotify(the_device
, motion_type
, event_list
[event_number
]);
728 if (event_list
[event_number
]) event_number
++;
729 ProximityIn(the_device
, proximity_in_type
, event_list
[event_number
]);
730 if (event_list
[event_number
]) event_number
++;
731 ProximityOut(the_device
, proximity_out_type
, event_list
[event_number
]);
732 if (event_list
[event_number
]) event_number
++;
734 if (key_press_type
) X11DRV_register_event_handler( key_press_type
, key_event
);
735 if (key_release_type
) X11DRV_register_event_handler( key_release_type
, key_event
);
736 if (button_press_type
) X11DRV_register_event_handler( button_press_type
, button_event
);
737 if (button_release_type
) X11DRV_register_event_handler( button_release_type
, button_event
);
738 if (motion_type
) X11DRV_register_event_handler( motion_type
, motion_event
);
739 if (proximity_in_type
) X11DRV_register_event_handler( proximity_in_type
, proximity_event
);
740 if (proximity_out_type
) X11DRV_register_event_handler( proximity_out_type
, proximity_event
);
742 pXSelectExtensionEvent(data
->display
, win
, event_list
, event_number
);
745 XSync(data
->display
, False
);
746 X11DRV_check_error();
748 if (NULL
!= devices
) pXFreeDeviceList(devices
);
753 int X11DRV_GetCurrentPacket(LPWTPACKET
*packet
)
755 memcpy(packet
,&gMsgPacket
,sizeof(WTPACKET
));
760 int static inline CopyTabletData(LPVOID target
, LPVOID src
, INT size
)
763 * It is valid to call CopyTabletData with NULL.
764 * This handles the WTInfo() case where lpOutput is null.
767 memcpy(target
,src
,size
);
771 /***********************************************************************
772 * X11DRV_WTInfoA (X11DRV.@)
774 UINT
X11DRV_WTInfoA(UINT wCategory
, UINT nIndex
, LPVOID lpOutput
)
777 * It is valid to call WTInfoA with lpOutput == NULL, as per standard.
778 * lpOutput == NULL signifies the user only wishes
779 * to find the size of the data.
781 * From now on use CopyTabletData to fill lpOutput. memcpy will break
785 LPWTI_CURSORS_INFO tgtcursor
;
786 TRACE("(%u, %u, %p)\n", wCategory
, nIndex
, lpOutput
);
791 /* return largest necessary buffer */
792 TRACE("%i cursors\n",gNumCursors
);
795 FIXME("Return proper size\n");
804 strcpy(lpOutput
,"Wine Wintab 1.1");
807 case IFC_SPECVERSION
:
808 version
= (0x01) | (0x01 << 8);
809 rc
= CopyTabletData(lpOutput
, &version
,sizeof(WORD
));
811 case IFC_IMPLVERSION
:
812 version
= (0x00) | (0x01 << 8);
813 rc
= CopyTabletData(lpOutput
, &version
,sizeof(WORD
));
816 FIXME("WTI_INTERFACE unhandled index %i\n",nIndex
);
826 rc
= CopyTabletData(lpOutput
, &gSysContext
,
827 sizeof(LOGCONTEXTA
));
830 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcName
,
831 strlen(gSysContext
.lcName
)+1);
834 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcOptions
,
838 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcStatus
,
842 rc
= CopyTabletData (lpOutput
, &gSysContext
.lcLocks
,
846 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcMsgBase
,
850 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcDevice
,
854 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcPktRate
,
858 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcPktMode
,
862 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcMoveMask
,
866 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcBtnDnMask
,
870 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcBtnUpMask
,
874 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcInOrgX
,
878 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcInOrgY
,
882 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcInOrgZ
,
886 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcInExtX
,
890 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcInExtY
,
894 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcInExtZ
,
898 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcOutOrgX
,
902 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcOutOrgY
,
906 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcOutOrgZ
,
910 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcOutExtX
,
914 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcOutExtY
,
918 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcOutExtZ
,
922 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcSensX
,
926 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcSensY
,
930 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcSensZ
,
934 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcSysMode
,
938 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcSysOrgX
,
942 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcSysOrgY
,
946 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcSysExtX
,
950 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcSysExtY
,
954 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcSysSensX
,
958 rc
= CopyTabletData(lpOutput
, &gSysContext
.lcSysSensY
,
962 FIXME("WTI_DEFSYSCTX unhandled index %i\n",nIndex
);
977 tgtcursor
= &gSysCursor
[wCategory
- WTI_CURSORS
];
981 rc
= CopyTabletData(lpOutput
, &tgtcursor
->NAME
,
982 strlen(tgtcursor
->NAME
)+1);
985 rc
= CopyTabletData(lpOutput
,&tgtcursor
->ACTIVE
,
989 rc
= CopyTabletData(lpOutput
,&tgtcursor
->PKTDATA
,
993 rc
= CopyTabletData(lpOutput
,&tgtcursor
->BUTTONS
,
997 rc
= CopyTabletData(lpOutput
,&tgtcursor
->BUTTONBITS
,
1001 FIXME("Button Names not returned correctly\n");
1002 rc
= CopyTabletData(lpOutput
,&tgtcursor
->BTNNAMES
,
1003 strlen(tgtcursor
->BTNNAMES
)+1);
1006 rc
= CopyTabletData(lpOutput
,&tgtcursor
->BUTTONMAP
,
1010 rc
= CopyTabletData(lpOutput
,&tgtcursor
->SYSBTNMAP
,
1013 case CSR_NPBTNMARKS
:
1014 rc
= CopyTabletData(lpOutput
,&tgtcursor
->NPBTNMARKS
,
1018 rc
= CopyTabletData(lpOutput
,&tgtcursor
->NPBUTTON
,
1021 case CSR_NPRESPONSE
:
1022 FIXME("Not returning CSR_NPRESPONSE correctly\n");
1026 rc
= CopyTabletData(lpOutput
,&tgtcursor
->TPBUTTON
,
1029 case CSR_TPBTNMARKS
:
1030 rc
= CopyTabletData(lpOutput
,&tgtcursor
->TPBTNMARKS
,
1033 case CSR_TPRESPONSE
:
1034 FIXME("Not returning CSR_TPRESPONSE correctly\n");
1040 id
= tgtcursor
->PHYSID
;
1041 id
+= (wCategory
- WTI_CURSORS
);
1042 rc
= CopyTabletData(lpOutput
,&id
,sizeof(DWORD
));
1046 rc
= CopyTabletData(lpOutput
,&tgtcursor
->MODE
,sizeof(UINT
));
1048 case CSR_MINPKTDATA
:
1049 rc
= CopyTabletData(lpOutput
,&tgtcursor
->MINPKTDATA
,
1052 case CSR_MINBUTTONS
:
1053 rc
= CopyTabletData(lpOutput
,&tgtcursor
->MINBUTTONS
,
1056 case CSR_CAPABILITIES
:
1057 rc
= CopyTabletData(lpOutput
,&tgtcursor
->CAPABILITIES
,
1061 rc
= CopyTabletData(lpOutput
,&tgtcursor
->TYPE
,
1065 FIXME("WTI_CURSORS unhandled index %i\n",nIndex
);
1073 rc
= CopyTabletData(lpOutput
,gSysDevice
.NAME
,
1074 strlen(gSysDevice
.NAME
)+1);
1077 rc
= CopyTabletData(lpOutput
,&gSysDevice
.HARDWARE
,
1081 rc
= CopyTabletData(lpOutput
,&gSysDevice
.NCSRTYPES
,
1085 rc
= CopyTabletData(lpOutput
,&gSysDevice
.FIRSTCSR
,
1089 rc
= CopyTabletData(lpOutput
,&gSysDevice
.PKTRATE
,
1093 rc
= CopyTabletData(lpOutput
,&gSysDevice
.PKTDATA
,
1097 rc
= CopyTabletData(lpOutput
,&gSysDevice
.PKTMODE
,
1101 rc
= CopyTabletData(lpOutput
,&gSysDevice
.CSRDATA
,
1105 rc
= CopyTabletData(lpOutput
,&gSysDevice
.XMARGIN
,
1109 rc
= CopyTabletData(lpOutput
,&gSysDevice
.YMARGIN
,
1113 rc
= 0; /* unsupported */
1115 rc = CopyTabletData(lpOutput,&gSysDevice.ZMARGIN,
1120 rc
= CopyTabletData(lpOutput
,&gSysDevice
.X
,
1124 rc
= CopyTabletData(lpOutput
,&gSysDevice
.Y
,
1128 rc
= 0; /* unsupported */
1130 rc = CopyTabletData(lpOutput,&gSysDevice.Z,
1135 rc
= CopyTabletData(lpOutput
,&gSysDevice
.NPRESSURE
,
1139 rc
= 0; /* unsupported */
1141 rc = CopyTabletData(lpOutput,&gSysDevice.TPRESSURE,
1145 case DVC_ORIENTATION
:
1146 rc
= CopyTabletData(lpOutput
,&gSysDevice
.ORIENTATION
,
1150 rc
= 0; /* unsupported */
1152 rc = CopyTabletData(lpOutput,&gSysDevice.ROTATION,
1157 rc
= CopyTabletData(lpOutput
,gSysDevice
.PNPID
,
1158 strlen(gSysDevice
.PNPID
)+1);
1161 FIXME("WTI_DEVICES unhandled index %i\n",nIndex
);
1166 FIXME("Unhandled Category %i\n",wCategory
);
1171 #else /* HAVE_X11_EXTENSIONS_XINPUT_H */
1173 /***********************************************************************
1174 * AttachEventQueueToTablet (X11DRV.@)
1176 int X11DRV_AttachEventQueueToTablet(HWND hOwner
)
1181 /***********************************************************************
1182 * GetCurrentPacket (X11DRV.@)
1184 int X11DRV_GetCurrentPacket(LPWTPACKET
*packet
)
1189 /***********************************************************************
1190 * LoadTabletInfo (X11DRV.@)
1192 void X11DRV_LoadTabletInfo(HWND hwnddefault
)
1196 /***********************************************************************
1197 * WTInfoA (X11DRV.@)
1199 UINT
X11DRV_WTInfoA(UINT wCategory
, UINT nIndex
, LPVOID lpOutput
)
1204 #endif /* HAVE_X11_EXTENSIONS_XINPUT_H */