Bug Summary

File:XExtInt.c
Location:line 808, column 25
Description:Value stored to 'data' is never read

Annotated Source Code

1/************************************************************
2
3Copyright 1989, 1998 The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21Except as contained in this notice, the name of The Open Group shall not be
22used in advertising or otherwise to promote the sale, use or other dealings
23in this Software without prior written authorization from The Open Group.
24
25Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
26
27 All Rights Reserved
28
29Permission to use, copy, modify, and distribute this software and its
30documentation for any purpose and without fee is hereby granted,
31provided that the above copyright notice appear in all copies and that
32both that copyright notice and this permission notice appear in
33supporting documentation, and that the name of Hewlett-Packard not be
34used in advertising or publicity pertaining to distribution of the
35software without specific, written prior permission.
36
37HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
38ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
39HEWLETT-PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
40ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
41WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
42ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
43SOFTWARE.
44
45********************************************************/
46
47/***********************************************************************
48 *
49 * Input Extension library internal functions.
50 *
51 */
52
53#if HAVE_CONFIG_H1
54#include <config.h>
55#endif
56
57#include <stdio.h>
58#include <stdint.h>
59#include <X11/extensions/XI.h>
60#include <X11/extensions/XI2.h>
61#include <X11/extensions/XIproto.h>
62#include <X11/extensions/XI2proto.h>
63#include <X11/Xlibint.h>
64#include <X11/extensions/XInput.h>
65#include <X11/extensions/XInput2.h>
66#include <X11/extensions/extutil.h>
67#include <X11/extensions/geproto.h>
68#include <X11/extensions/ge.h>
69#include <X11/extensions/Xge.h>
70#include "XIint.h"
71
72#define ENQUEUE_EVENT1 True1
73#define DONT_ENQUEUE0 False0
74#define FP1616toDBL(x)((x) * 1.0 / (1 << 16)) ((x) * 1.0 / (1 << 16))
75
76extern void _xibaddevice(
77 Display * /* dpy */,
78 int * /* error */
79);
80
81extern void _xibadclass(
82 Display * /* dpy */,
83 int * /* error */
84);
85
86extern void _xibadevent(
87 Display * /* dpy */,
88 int * /* error */
89);
90
91extern void _xibadmode(
92 Display * /* dpy */,
93 int * /* error */
94);
95
96extern void _xidevicebusy(
97 Display * /* dpy */,
98 int * /* error */
99);
100
101extern int _XiGetDevicePresenceNotifyEvent(
102 Display * /* dpy */
103);
104
105int copy_classes(XIDeviceInfo *to, xXIAnyInfo* from, int *nclasses);
106int size_classes(xXIAnyInfo* from, int nclasses);
107
108static XExtensionInfo *xinput_info;
109static /* const */ char *xinput_extension_name = INAME"XInputExtension";
110
111static int XInputClose(
112 Display * /* dpy */,
113 XExtCodes * /* codes */
114);
115
116static char *XInputError(
117 Display * /* dpy */,
118 int /* code */,
119 XExtCodes * /* codes */,
120 char * /* buf */,
121 int /* n */
122);
123
124static Boolint XInputWireToEvent(
125 Display * /* dpy */,
126 XEvent * /* re */,
127 xEvent * /* event */
128);
129static Boolint XInputWireToCookie(
130 Display* /* display */,
131 XGenericEventCookie* /* re */,
132 xEvent* /* event */
133);
134
135static Boolint XInputCopyCookie(
136 Display* /* display */,
137 XGenericEventCookie* /* in */,
138 XGenericEventCookie* /* out */
139);
140
141static int
142wireToDeviceEvent(xXIDeviceEvent *in, XGenericEventCookie* out);
143static int
144wireToDeviceChangedEvent(xXIDeviceChangedEvent *in, XGenericEventCookie *cookie);
145static int
146wireToHierarchyChangedEvent(xXIHierarchyEvent *in, XGenericEventCookie *cookie);
147static int
148wireToRawEvent(XExtDisplayInfo *info, xXIRawEvent *in, XGenericEventCookie *cookie);
149static int
150wireToEnterLeave(xXIEnterEvent *in, XGenericEventCookie *cookie);
151static int
152wireToPropertyEvent(xXIPropertyEvent *in, XGenericEventCookie *cookie);
153static int
154wireToTouchOwnershipEvent(xXITouchOwnershipEvent *in,
155 XGenericEventCookie *cookie);
156
157static /* const */ XEvent emptyevent;
158
159typedef Statusint (*core_event_to_wire)(Display*, XEvent*, xEvent*);
160
161static /* const */ XExtensionHooks xinput_extension_hooks = {
162 NULL((void*)0), /* create_gc */
163 NULL((void*)0), /* copy_gc */
164 NULL((void*)0), /* flush_gc */
165 NULL((void*)0), /* free_gc */
166 NULL((void*)0), /* create_font */
167 NULL((void*)0), /* free_font */
168 XInputClose, /* close_display */
169 XInputWireToEvent, /* wire_to_event */
170 (core_event_to_wire)_XiEventToWire, /* event_to_wire */
171 NULL((void*)0), /* error */
172 XInputError, /* error_string */
173};
174
175static char *XInputErrorList[] = {
176 "BadDevice, invalid or uninitialized input device", /* BadDevice */
177 "BadEvent, invalid event type", /* BadEvent */
178 "BadMode, invalid mode parameter", /* BadMode */
179 "DeviceBusy, device is busy", /* DeviceBusy */
180 "BadClass, invalid event class", /* BadClass */
181};
182
183/* Get the version supported by the server to know which number of
184* events are support. Otherwise, a wrong number of events may smash
185* the Xlib-internal event processing vector.
186*
187* Since the extension hasn't been initialized yet, we need to
188* manually get the opcode, then the version.
189*/
190static int
191_XiFindEventsSupported(Display *dpy)
192{
193 XExtCodes codes;
194 XExtensionVersion *extversion = NULL((void*)0);
195 int nevents = 0;
196
197 if (!XQueryExtension(dpy, INAME"XInputExtension", &codes.major_opcode,
198 &codes.first_event, &codes.first_error))
199 goto out;
200
201 LockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->lock_display
)(dpy)
;
202 extversion = _XiGetExtensionVersionRequest(dpy, INAME"XInputExtension", codes.major_opcode);
203 UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display
)(dpy)
;
204 SyncHandle()if (dpy->synchandler) (*dpy->synchandler)(dpy);
205
206 if (!extversion || !extversion->present)
207 goto out;
208
209 if (extversion->major_version >= 2)
210 nevents = IEVENTS17; /* number is fixed, XI2 adds GenericEvents only */
211 else if (extversion->major_version <= 0)
212 {
213 printf("XInput_find_display: invalid extension version %d.%d\n",
214 extversion->major_version, extversion->minor_version);
215 goto out;
216 }
217 else
218 {
219 switch(extversion->minor_version)
220 {
221 case XI_Add_DeviceProperties_Minor5:
222 nevents = XI_DevicePropertyNotify16 + 1;
223 break;
224 case XI_Add_DevicePresenceNotify_Minor4:
225 nevents = XI_DevicePresenceNotify15 + 1;
226 break;
227 default:
228 nevents = XI_DeviceButtonstateNotify14 + 1;
229 break;
230 }
231 }
232
233out:
234 if (extversion)
235 XFree(extversion);
236 return nevents;
237}
238
239
240_X_HIDDEN__attribute__((visibility("hidden")))
241XExtDisplayInfo *XInput_find_display (Display *dpy)
242{
243 XExtDisplayInfo *dpyinfo;
244 if (!xinput_info) { if (!(xinput_info = XextCreateExtension())) return NULL((void*)0); }
245 if (!(dpyinfo = XextFindDisplay (xinput_info, dpy)))
246 {
247 int nevents = _XiFindEventsSupported(dpy);
248
249 dpyinfo = XextAddDisplay (xinput_info, dpy,
250 xinput_extension_name,
251 &xinput_extension_hooks,
252 nevents, NULL((void*)0));
253 if (dpyinfo->codes) /* NULL if XI doesn't exist on the server */
254 {
255 XESetWireToEventCookie(dpy, dpyinfo->codes->major_opcode, XInputWireToCookie);
256 XESetCopyEventCookie(dpy, dpyinfo->codes->major_opcode, XInputCopyCookie);
257 }
258 }
259 return dpyinfo;
260}
261
262static XEXT_GENERATE_ERROR_STRING(XInputError, xinput_extension_name,char *XInputError (Display *dpy, int code, XExtCodes *codes, char
*buf, int n) { code -= codes->first_error; if (code >=
0 && code < 5) { char tmp[256]; sprintf (tmp, "%s.%d"
, xinput_extension_name, code); XGetErrorDatabaseText (dpy, "XProtoError"
, tmp, XInputErrorList[code], buf, n); return buf; } return (
char *)0; }
263 IERRORS, XInputErrorList)char *XInputError (Display *dpy, int code, XExtCodes *codes, char
*buf, int n) { code -= codes->first_error; if (code >=
0 && code < 5) { char tmp[256]; sprintf (tmp, "%s.%d"
, xinput_extension_name, code); XGetErrorDatabaseText (dpy, "XProtoError"
, tmp, XInputErrorList[code], buf, n); return buf; } return (
char *)0; }
264/*******************************************************************
265*
266* Input extension versions.
267*
268*/
269static XExtensionVersion versions[] = { {XI_Absent0, 0, 0},
270{XI_Present1, XI_Initial_Release_Major1, XI_Initial_Release_Minor0},
271{XI_Present1, XI_Add_XDeviceBell_Major1, XI_Add_XDeviceBell_Minor1},
272{XI_Present1, XI_Add_XSetDeviceValuators_Major1,
273 XI_Add_XSetDeviceValuators_Minor2},
274{XI_Present1, XI_Add_XChangeDeviceControl_Major1,
275 XI_Add_XChangeDeviceControl_Minor3},
276{XI_Present1, XI_Add_DevicePresenceNotify_Major1,
277 XI_Add_DevicePresenceNotify_Minor4},
278{XI_Present1, XI_Add_DeviceProperties_Major1,
279 XI_Add_DeviceProperties_Minor5},
280{XI_Present1, 2, 0},
281{XI_Present1, 2, 1},
282{XI_Present1, 2, 2}
283};
284
285/***********************************************************************
286 *
287 * Return errors reported by this extension.
288 *
289 */
290
291void
292_xibaddevice(
293 Display *dpy,
294 int *error)
295{
296 XExtDisplayInfo *info = XInput_find_display(dpy);
297
298 *error = info->codes->first_error + XI_BadDevice0;
299}
300
301void
302_xibadclass(
303 Display *dpy,
304 int *error)
305{
306 XExtDisplayInfo *info = XInput_find_display(dpy);
307
308 *error = info->codes->first_error + XI_BadClass4;
309}
310
311void
312_xibadevent(
313 Display *dpy,
314 int *error)
315{
316 XExtDisplayInfo *info = XInput_find_display(dpy);
317
318 *error = info->codes->first_error + XI_BadEvent1;
319}
320
321void
322_xibadmode(
323 Display *dpy,
324 int *error)
325{
326 XExtDisplayInfo *info = XInput_find_display(dpy);
327
328 *error = info->codes->first_error + XI_BadMode2;
329}
330
331void
332_xidevicebusy(
333 Display *dpy,
334 int *error)
335{
336 XExtDisplayInfo *info = XInput_find_display(dpy);
337
338 *error = info->codes->first_error + XI_DeviceBusy3;
339}
340
341static int XInputCheckExtension(Display *dpy, XExtDisplayInfo *info)
342{
343 XextCheckExtension (dpy, info, xinput_extension_name, 0)if (!((info) && ((info)->codes))) { XMissingExtension
(dpy, xinput_extension_name); return 0; }
;
344 return 1;
345}
346
347/*****************************************************************
348 * Compare version numbers between info and the built-in version table.
349 * Returns
350 * -1 if info's version is less than version_index's version,
351 * 0 if equal (or DontCheck),
352 * 1 if info's version is greater than version_index's version.
353 * Returns -2 on initialization errors which shouldn't happen if you call it
354 * correctly.
355 */
356_X_HIDDEN__attribute__((visibility("hidden"))) int
357_XiCheckVersion(XExtDisplayInfo *info,
358 int version_index)
359{
360 XExtensionVersion *ext;
361
362 if (versions[version_index].major_version == Dont_Check0)
363 return 0;
364
365 if (!info->data)
366 return -2;
367
368 ext = ((XInputData *) info->data)->vers;
369 if (!ext)
370 return -2;
371
372 if (ext->major_version == versions[version_index].major_version &&
373 ext->minor_version == versions[version_index].minor_version)
374 return 0;
375
376 if (ext->major_version < versions[version_index].major_version ||
377 (ext->major_version == versions[version_index].major_version &&
378 ext->minor_version < versions[version_index].minor_version))
379 return -1;
380 else
381 return 1;
382}
383
384/***********************************************************************
385 *
386 * Check to see if the input extension is installed in the server.
387 * Also check to see if the version is >= the requested version.
388 *
389 */
390
391_X_HIDDEN__attribute__((visibility("hidden"))) int
392_XiCheckExtInit(
393 register Display *dpy,
394 register int version_index,
395 XExtDisplayInfo *info)
396{
397 if (!XInputCheckExtension(dpy, info)) {
398 UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display
)(dpy)
;
399 return (-1);
400 }
401
402 if (info->data == NULL((void*)0)) {
403 info->data = (XPointer) Xmalloc(sizeof(XInputData))malloc(((sizeof(XInputData)) == 0 ? 1 : (sizeof(XInputData)))
)
;
404 if (!info->data) {
405 UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display
)(dpy)
;
406 return (-1);
407 }
408 ((XInputData *) info->data)->vers =
409 _XiGetExtensionVersion(dpy, "XInputExtension", info);
410 }
411
412 if (_XiCheckVersion(info, version_index) < 0) {
413 UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display
)(dpy)
;
414 return -1;
415 }
416
417 return (0);
418}
419
420/***********************************************************************
421 *
422 * Close display routine.
423 *
424 */
425
426static int
427XInputClose(
428 Display *dpy,
429 XExtCodes *codes)
430{
431 XExtDisplayInfo *info = XInput_find_display(dpy);
432
433 if (info->data != NULL((void*)0)) {
434 XFree((char *)((XInputData *) info->data)->vers);
435 XFree((char *)info->data);
436 }
437
438 if (!XextRemoveDisplay(xinput_info, dpy))
439 return 0;
440
441 if (xinput_info->ndisplays == 0) {
442 XextDestroyExtension(xinput_info);
443 xinput_info = NULL((void*)0);
444 }
445
446 return 1;
447}
448
449static int
450Ones(Mask mask)
451{
452 register Mask y;
453
454 y = (mask >> 1) & 033333333333;
455 y = mask - y - ((y >> 1) & 033333333333);
456 return (((y + (y >> 3)) & 030707070707) % 077);
457}
458
459static int count_bits(unsigned char* ptr, int len)
460{
461 int bits = 0;
462 unsigned int i;
463 unsigned char x;
464
465 for (i = 0; i < len; i++)
466 {
467 x = ptr[i];
468 while(x > 0)
469 {
470 bits += (x & 0x1);
471 x >>= 1;
472 }
473 }
474 return bits;
475}
476
477int
478_XiGetDevicePresenceNotifyEvent(Display * dpy)
479{
480 XExtDisplayInfo *info = XInput_find_display(dpy);
481
482 return info->codes->first_event + XI_DevicePresenceNotify15;
483}
484
485/***********************************************************************
486 *
487 * Handle Input extension events.
488 * Reformat a wire event into an XEvent structure of the right type.
489 *
490 */
491
492static Boolint
493XInputWireToEvent(
494 Display *dpy,
495 XEvent *re,
496 xEvent *event)
497{
498 unsigned int type, reltype;
499 unsigned int i, j;
500 XExtDisplayInfo *info = XInput_find_display(dpy);
501 XEvent *save = (XEvent *) info->data;
502
503 type = event->u.u.type & 0x7f;
504 reltype = (type - info->codes->first_event);
505
506 if (type == GenericEvent35 ||
507 (reltype != XI_DeviceValuator0 &&
508 reltype != XI_DeviceKeystateNotify13 &&
509 reltype != XI_DeviceButtonstateNotify14)) {
510 *save = emptyevent;
511 save->type = type;
512 ((XAnyEvent *) save)->serial = _XSetLastRequestRead(dpy,
513 (xGenericReply *)
514 event);
515 ((XAnyEvent *) save)->send_event = ((event->u.u.type & 0x80) != 0);
516 ((XAnyEvent *) save)->display = dpy;
517 }
518
519 /* Process traditional events */
520 if (type != GenericEvent35)
521 {
522 switch (reltype) {
523 case XI_DeviceMotionNotify5:
524 {
525 register XDeviceMotionEvent *ev = (XDeviceMotionEvent *) save;
526 deviceKeyButtonPointer *ev2 = (deviceKeyButtonPointer *) event;
527
528 ev->root = ev2->root;
529 ev->window = ev2->event;
530 ev->subwindow = ev2->child;
531 ev->time = ev2->time;
532 ev->x_root = ev2->root_x;
533 ev->y_root = ev2->root_y;
534 ev->x = ev2->event_x;
535 ev->y = ev2->event_y;
536 ev->state = ev2->state;
537 ev->same_screen = ev2->same_screen;
538 ev->is_hint = ev2->detail;
539 ev->deviceid = ev2->deviceid & DEVICE_BITS0x7F;
540 return (DONT_ENQUEUE0);
541 }
542 break;
543 case XI_DeviceKeyPress1:
544 case XI_DeviceKeyRelease2:
545 {
546 register XDeviceKeyEvent *ev = (XDeviceKeyEvent *) save;
547 deviceKeyButtonPointer *ev2 = (deviceKeyButtonPointer *) event;
548
549 ev->root = ev2->root;
550 ev->window = ev2->event;
551 ev->subwindow = ev2->child;
552 ev->time = ev2->time;
553 ev->x_root = ev2->root_x;
554 ev->y_root = ev2->root_y;
555 ev->x = ev2->event_x;
556 ev->y = ev2->event_y;
557 ev->state = ev2->state;
558 ev->same_screen = ev2->same_screen;
559 ev->keycode = ev2->detail;
560 ev->deviceid = ev2->deviceid & DEVICE_BITS0x7F;
561 if (ev2->deviceid & MORE_EVENTS0x80)
562 return (DONT_ENQUEUE0);
563 else {
564 *re = *save;
565 return (ENQUEUE_EVENT1);
566 }
567 }
568 break;
569 case XI_DeviceButtonPress3:
570 case XI_DeviceButtonRelease4:
571 {
572 register XDeviceButtonEvent *ev = (XDeviceButtonEvent *) save;
573 deviceKeyButtonPointer *ev2 = (deviceKeyButtonPointer *) event;
574
575 ev->root = ev2->root;
576 ev->window = ev2->event;
577 ev->subwindow = ev2->child;
578 ev->time = ev2->time;
579 ev->x_root = ev2->root_x;
580 ev->y_root = ev2->root_y;
581 ev->x = ev2->event_x;
582 ev->y = ev2->event_y;
583 ev->state = ev2->state;
584 ev->same_screen = ev2->same_screen;
585 ev->button = ev2->detail;
586 ev->deviceid = ev2->deviceid & DEVICE_BITS0x7F;
587 if (ev2->deviceid & MORE_EVENTS0x80)
588 return (DONT_ENQUEUE0);
589 else {
590 *re = *save;
591 return (ENQUEUE_EVENT1);
592 }
593 }
594 break;
595 case XI_ProximityIn8:
596 case XI_ProximityOut9:
597 {
598 register XProximityNotifyEvent *ev = (XProximityNotifyEvent *) save;
599 deviceKeyButtonPointer *ev2 = (deviceKeyButtonPointer *) event;
600
601 ev->root = ev2->root;
602 ev->window = ev2->event;
603 ev->subwindow = ev2->child;
604 ev->time = ev2->time;
605 ev->x_root = ev2->root_x;
606 ev->y_root = ev2->root_y;
607 ev->x = ev2->event_x;
608 ev->y = ev2->event_y;
609 ev->state = ev2->state;
610 ev->same_screen = ev2->same_screen;
611 ev->deviceid = ev2->deviceid & DEVICE_BITS0x7F;
612 if (ev2->deviceid & MORE_EVENTS0x80)
613 return (DONT_ENQUEUE0);
614 else {
615 *re = *save;
616 return (ENQUEUE_EVENT1);
617 }
618 }
619 break;
620 case XI_DeviceValuator0:
621 {
622 deviceValuator *xev = (deviceValuator *) event;
623 int save_type = save->type - info->codes->first_event;
624
625 if (save_type == XI_DeviceKeyPress1 || save_type == XI_DeviceKeyRelease2) {
626 XDeviceKeyEvent *kev = (XDeviceKeyEvent *) save;
627
628 kev->device_state = xev->device_state;
629 kev->axes_count = xev->num_valuators;
630 kev->first_axis = xev->first_valuator;
631 i = xev->num_valuators;
632 if (i > 6)
633 i = 6;
634 switch (i) {
635 case 6:
636 kev->axis_data[5] = xev->valuator5;
637 case 5:
638 kev->axis_data[4] = xev->valuator4;
639 case 4:
640 kev->axis_data[3] = xev->valuator3;
641 case 3:
642 kev->axis_data[2] = xev->valuator2;
643 case 2:
644 kev->axis_data[1] = xev->valuator1;
645 case 1:
646 kev->axis_data[0] = xev->valuator0;
647 }
648 } else if (save_type == XI_DeviceButtonPress3 ||
649 save_type == XI_DeviceButtonRelease4) {
650 XDeviceButtonEvent *bev = (XDeviceButtonEvent *) save;
651
652 bev->device_state = xev->device_state;
653 bev->axes_count = xev->num_valuators;
654 bev->first_axis = xev->first_valuator;
655 i = xev->num_valuators;
656 if (i > 6)
657 i = 6;
658 switch (i) {
659 case 6:
660 bev->axis_data[5] = xev->valuator5;
661 case 5:
662 bev->axis_data[4] = xev->valuator4;
663 case 4:
664 bev->axis_data[3] = xev->valuator3;
665 case 3:
666 bev->axis_data[2] = xev->valuator2;
667 case 2:
668 bev->axis_data[1] = xev->valuator1;
669 case 1:
670 bev->axis_data[0] = xev->valuator0;
671 }
672 } else if (save_type == XI_DeviceMotionNotify5) {
673 XDeviceMotionEvent *mev = (XDeviceMotionEvent *) save;
674
675 mev->device_state = xev->device_state;
676 mev->axes_count = xev->num_valuators;
677 mev->first_axis = xev->first_valuator;
678 i = xev->num_valuators;
679 if (i > 6)
680 i = 6;
681 switch (i) {
682 case 6:
683 mev->axis_data[5] = xev->valuator5;
684 case 5:
685 mev->axis_data[4] = xev->valuator4;
686 case 4:
687 mev->axis_data[3] = xev->valuator3;
688 case 3:
689 mev->axis_data[2] = xev->valuator2;
690 case 2:
691 mev->axis_data[1] = xev->valuator1;
692 case 1:
693 mev->axis_data[0] = xev->valuator0;
694 }
695 } else if (save_type == XI_ProximityIn8 || save_type == XI_ProximityOut9) {
696 XProximityNotifyEvent *pev = (XProximityNotifyEvent *) save;
697
698 pev->device_state = xev->device_state;
699 pev->axes_count = xev->num_valuators;
700 pev->first_axis = xev->first_valuator;
701 i = xev->num_valuators;
702 if (i > 6)
703 i = 6;
704 switch (i) {
705 case 6:
706 pev->axis_data[5] = xev->valuator5;
707 case 5:
708 pev->axis_data[4] = xev->valuator4;
709 case 4:
710 pev->axis_data[3] = xev->valuator3;
711 case 3:
712 pev->axis_data[2] = xev->valuator2;
713 case 2:
714 pev->axis_data[1] = xev->valuator1;
715 case 1:
716 pev->axis_data[0] = xev->valuator0;
717 }
718 } else if (save_type == XI_DeviceStateNotify10) {
719 XDeviceStateNotifyEvent *sev = (XDeviceStateNotifyEvent *) save;
720 XInputClass *any = (XInputClass *) & sev->data[0];
721 XValuatorStatus *v;
722
723 for (i = 0; i < sev->num_classes; i++)
724 if (any->class != ValuatorClass2)
725 any = (XInputClass *) ((char *)any + any->length);
726 v = (XValuatorStatus *) any;
727 i = v->num_valuators;
728 j = xev->num_valuators;
729 if (j > 3)
730 j = 3;
731 switch (j) {
732 case 3:
733 v->valuators[i + 2] = xev->valuator2;
734 case 2:
735 v->valuators[i + 1] = xev->valuator1;
736 case 1:
737 v->valuators[i + 0] = xev->valuator0;
738 }
739 v->num_valuators += j;
740
741 }
742 *re = *save;
743 return (ENQUEUE_EVENT1);
744 }
745 break;
746 case XI_DeviceFocusIn6:
747 case XI_DeviceFocusOut7:
748 {
749 register XDeviceFocusChangeEvent *ev = (XDeviceFocusChangeEvent *) re;
750 deviceFocus *fev = (deviceFocus *) event;
751
752 *ev = *((XDeviceFocusChangeEvent *) save);
753 ev->window = fev->window;
754 ev->time = fev->time;
755 ev->mode = fev->mode;
756 ev->detail = fev->detail;
757 ev->deviceid = fev->deviceid & DEVICE_BITS0x7F;
758 return (ENQUEUE_EVENT1);
759 }
760 break;
761 case XI_DeviceStateNotify10:
762 {
763 XDeviceStateNotifyEvent *stev = (XDeviceStateNotifyEvent *) save;
764 deviceStateNotify *sev = (deviceStateNotify *) event;
765 char *data;
766
767 stev->window = None0L;
768 stev->deviceid = sev->deviceid & DEVICE_BITS0x7F;
769 stev->time = sev->time;
770 stev->num_classes = Ones((Mask) sev->classes_reported & InputClassBits0x3F);
771 data = (char *)&stev->data[0];
772 if (sev->classes_reported & (1 << KeyClass0)) {
773 register XKeyStatus *kstev = (XKeyStatus *) data;
774
775 kstev->class = KeyClass0;
776 kstev->length = sizeof(XKeyStatus);
777 kstev->num_keys = sev->num_keys;
778 memcpy((char *)&kstev->keys[0], (char *)&sev->keys[0], 4);
779 data += sizeof(XKeyStatus);
780 }
781 if (sev->classes_reported & (1 << ButtonClass1)) {
782 register XButtonStatus *bev = (XButtonStatus *) data;
783
784 bev->class = ButtonClass1;
785 bev->length = sizeof(XButtonStatus);
786 bev->num_buttons = sev->num_buttons;
787 memcpy((char *)bev->buttons, (char *)sev->buttons, 4);
788 data += sizeof(XButtonStatus);
789 }
790 if (sev->classes_reported & (1 << ValuatorClass2)) {
791 register XValuatorStatus *vev = (XValuatorStatus *) data;
792
793 vev->class = ValuatorClass2;
794 vev->length = sizeof(XValuatorStatus);
795 vev->num_valuators = sev->num_valuators;
796 vev->mode = sev->classes_reported >> ModeBitsShift6;
797 j = sev->num_valuators;
798 if (j > 3)
799 j = 3;
800 switch (j) {
801 case 3:
802 vev->valuators[2] = sev->valuator2;
803 case 2:
804 vev->valuators[1] = sev->valuator1;
805 case 1:
806 vev->valuators[0] = sev->valuator0;
807 }
808 data += sizeof(XValuatorStatus);
Value stored to 'data' is never read
809 }
810 if (sev->deviceid & MORE_EVENTS0x80)
811 return (DONT_ENQUEUE0);
812 else {
813 *re = *save;
814 return (ENQUEUE_EVENT1);
815 }
816 }
817 break;
818 case XI_DeviceKeystateNotify13:
819 {
820 int i;
821 XInputClass *anyclass;
822 register XKeyStatus *kv;
823 deviceKeyStateNotify *ksev = (deviceKeyStateNotify *) event;
824 XDeviceStateNotifyEvent *kstev = (XDeviceStateNotifyEvent *) save;
825
826 anyclass = (XInputClass *) & kstev->data[0];
827 for (i = 0; i < kstev->num_classes; i++)
828 if (anyclass->class == KeyClass0)
829 break;
830 else
831 anyclass = (XInputClass *) ((char *)anyclass +
832 anyclass->length);
833
834 kv = (XKeyStatus *) anyclass;
835 kv->num_keys = 256;
836 memcpy((char *)&kv->keys[4], (char *)ksev->keys, 28);
837 if (ksev->deviceid & MORE_EVENTS0x80)
838 return (DONT_ENQUEUE0);
839 else {
840 *re = *save;
841 return (ENQUEUE_EVENT1);
842 }
843 }
844 break;
845 case XI_DeviceButtonstateNotify14:
846 {
847 int i;
848 XInputClass *anyclass;
849 register XButtonStatus *bv;
850 deviceButtonStateNotify *bsev = (deviceButtonStateNotify *) event;
851 XDeviceStateNotifyEvent *bstev = (XDeviceStateNotifyEvent *) save;
852
853 anyclass = (XInputClass *) & bstev->data[0];
854 for (i = 0; i < bstev->num_classes; i++)
855 if (anyclass->class == ButtonClass1)
856 break;
857 else
858 anyclass = (XInputClass *) ((char *)anyclass +
859 anyclass->length);
860
861 bv = (XButtonStatus *) anyclass;
862 bv->num_buttons = 256;
863 memcpy((char *)&bv->buttons[4], (char *)bsev->buttons, 28);
864 if (bsev->deviceid & MORE_EVENTS0x80)
865 return (DONT_ENQUEUE0);
866 else {
867 *re = *save;
868 return (ENQUEUE_EVENT1);
869 }
870 }
871 break;
872 case XI_DeviceMappingNotify11:
873 {
874 register XDeviceMappingEvent *ev = (XDeviceMappingEvent *) re;
875 deviceMappingNotify *ev2 = (deviceMappingNotify *) event;
876
877 *ev = *((XDeviceMappingEvent *) save);
878 ev->window = 0;
879 ev->first_keycode = ev2->firstKeyCode;
880 ev->request = ev2->request;
881 ev->count = ev2->count;
882 ev->time = ev2->time;
883 ev->deviceid = ev2->deviceid & DEVICE_BITS0x7F;
884 return (ENQUEUE_EVENT1);
885 }
886 break;
887 case XI_ChangeDeviceNotify12:
888 {
889 register XChangeDeviceNotifyEvent *ev = (XChangeDeviceNotifyEvent *) re;
890 changeDeviceNotify *ev2 = (changeDeviceNotify *) event;
891
892 *ev = *((XChangeDeviceNotifyEvent *) save);
893 ev->window = 0;
894 ev->request = ev2->request;
895 ev->time = ev2->time;
896 ev->deviceid = ev2->deviceid & DEVICE_BITS0x7F;
897 return (ENQUEUE_EVENT1);
898 }
899 break;
900
901 case XI_DevicePresenceNotify15:
902 {
903 XDevicePresenceNotifyEvent *ev = (XDevicePresenceNotifyEvent *) re;
904 devicePresenceNotify *ev2 = (devicePresenceNotify *) event;
905
906 *ev = *(XDevicePresenceNotifyEvent *) save;
907 ev->window = 0;
908 ev->time = ev2->time;
909 ev->devchange = ev2->devchange;
910 ev->deviceid = ev2->deviceid;
911 ev->control = ev2->control;
912 return (ENQUEUE_EVENT1);
913 }
914 break;
915 case XI_DevicePropertyNotify16:
916 {
917 XDevicePropertyNotifyEvent* ev = (XDevicePropertyNotifyEvent*)re;
918 devicePropertyNotify *ev2 = (devicePropertyNotify*)event;
919
920 *ev = *(XDevicePropertyNotifyEvent*)save;
921 ev->time = ev2->time;
922 ev->deviceid = ev2->deviceid;
923 ev->atom = ev2->atom;
924 ev->state = ev2->state;
925 return ENQUEUE_EVENT1;
926 }
927 break;
928 default:
929 printf("XInputWireToEvent: UNKNOWN WIRE EVENT! type=%d\n", type);
930 break;
931 }
932 }
933 return (DONT_ENQUEUE0);
934}
935
936static void xge_copy_to_cookie(xGenericEvent* ev,
937 XGenericEventCookie *cookie)
938{
939 cookie->type = ev->type;
940 cookie->evtype = ev->evtype;
941 cookie->extension = ev->extension;
942}
943
944static Boolint
945XInputWireToCookie(
946 Display *dpy,
947 XGenericEventCookie *cookie,
948 xEvent *event)
949{
950 XExtDisplayInfo *info = XInput_find_display(dpy);
951 XEvent *save = (XEvent *) info->data;
952 xGenericEvent* ge = (xGenericEvent*)event;
953
954 if (ge->extension != info->codes->major_opcode)
955 {
956 printf("XInputWireToCookie: wrong extension opcode %d\n",
957 ge->extension);
958 return DONT_ENQUEUE0;
959 }
960
961 *save = emptyevent;
962 save->type = event->u.u.type;
963 ((XAnyEvent*)save)->serial = _XSetLastRequestRead(dpy, (xGenericReply *) event);
964 ((XAnyEvent*)save)->send_event = ((event->u.u.type & 0x80) != 0);
965 ((XAnyEvent*)save)->display = dpy;
966
967 xge_copy_to_cookie((xGenericEvent*)event, (XGenericEventCookie*)save);
968 switch(ge->evtype)
969 {
970 case XI_Motion6:
971 case XI_ButtonPress4:
972 case XI_ButtonRelease5:
973 case XI_KeyPress2:
974 case XI_KeyRelease3:
975 case XI_TouchBegin18:
976 case XI_TouchUpdate19:
977 case XI_TouchEnd20:
978 *cookie = *(XGenericEventCookie*)save;
979 if (!wireToDeviceEvent((xXIDeviceEvent*)event, cookie))
980 {
981 printf("XInputWireToCookie: CONVERSION FAILURE! evtype=%d\n",
982 ge->evtype);
983 break;
984 }
985 return ENQUEUE_EVENT1;
986 case XI_DeviceChanged1:
987 *cookie = *(XGenericEventCookie*)save;
988 if (!wireToDeviceChangedEvent((xXIDeviceChangedEvent*)event, cookie))
989 {
990 printf("XInputWireToCookie: CONVERSION FAILURE! evtype=%d\n",
991 ge->evtype);
992 break;
993 }
994 return ENQUEUE_EVENT1;
995 case XI_HierarchyChanged11:
996 *cookie = *(XGenericEventCookie*)save;
997 if (!wireToHierarchyChangedEvent((xXIHierarchyEvent*)event, cookie))
998 {
999 printf("XInputWireToCookie: CONVERSION FAILURE! evtype=%d\n",
1000 ge->evtype);
1001 break;
1002 }
1003 return ENQUEUE_EVENT1;
1004 case XI_TouchOwnership21:
1005 *cookie = *(XGenericEventCookie*)save;
1006 if (!wireToTouchOwnershipEvent((xXITouchOwnershipEvent*)event,
1007 cookie))
1008 {
1009 printf("XInputWireToCookie: CONVERSION FAILURE! evtype=%d\n",
1010 ge->evtype);
1011 break;
1012 }
1013 return ENQUEUE_EVENT1;
1014
1015 case XI_RawKeyPress13:
1016 case XI_RawKeyRelease14:
1017 case XI_RawButtonPress15:
1018 case XI_RawButtonRelease16:
1019 case XI_RawMotion17:
1020 case XI_RawTouchBegin22:
1021 case XI_RawTouchUpdate23:
1022 case XI_RawTouchEnd24:
1023 *cookie = *(XGenericEventCookie*)save;
1024 if (!wireToRawEvent(info, (xXIRawEvent*)event, cookie))
1025 {
1026 printf("XInputWireToCookie: CONVERSION FAILURE! evtype=%d\n",
1027 ge->evtype);
1028 break;
1029 }
1030 return ENQUEUE_EVENT1;
1031 case XI_Enter7:
1032 case XI_Leave8:
1033 case XI_FocusIn9:
1034 case XI_FocusOut10:
1035 *cookie = *(XGenericEventCookie*)save;
1036 if (!wireToEnterLeave((xXIEnterEvent*)event, cookie))
1037 {
1038 printf("XInputWireToCookie: CONVERSION FAILURE! evtype=%d\n",
1039 ge->evtype);
1040 break;
1041 }
1042 return ENQUEUE_EVENT1;
1043 case XI_PropertyEvent12:
1044 *cookie = *(XGenericEventCookie*)save;
1045 if (!wireToPropertyEvent((xXIPropertyEvent*)event, cookie))
1046 {
1047 printf("XInputWireToCookie: CONVERSION FAILURE! evtype=%d\n",
1048 ge->evtype);
1049 break;
1050 }
1051 return ENQUEUE_EVENT1;
1052 default:
1053 printf("XInputWireToCookie: Unknown generic event. type %d\n", ge->evtype);
1054
1055 }
1056 return DONT_ENQUEUE0;
1057}
1058
1059/**
1060 * Calculate length in bytes needed for the device event with the given
1061 * button mask length, valuator mask length + valuator mask. All parameters
1062 * in bytes.
1063 */
1064static inline int
1065sizeDeviceEvent(int buttons_len, int valuators_len,
1066 unsigned char *valuators_mask)
1067{
1068 int len;
1069
1070 len = sizeof(XIDeviceEvent);
1071 len += sizeof(XIButtonState) + buttons_len;
1072 len += sizeof(XIValuatorState) + valuators_len;
1073 len += count_bits(valuators_mask, valuators_len) * sizeof(double);
1074 len += sizeof(XIModifierState) + sizeof(XIGroupState);
1075
1076 return len;
1077}
1078
1079/* Return the size with added padding so next element would be
1080 double-aligned unless the architecture is known to allow unaligned
1081 data accesses. Not doing this can cause a bus error on
1082 MIPS N32. */
1083static int
1084pad_to_double(int size)
1085{
1086#if !defined(__i386__) && !defined(__sh__)
1087 if (size % sizeof(double) != 0)
1088 size += sizeof(double) - size % sizeof(double);
1089#endif
1090 return size;
1091}
1092
1093/**
1094 * Set structure and atoms to size in bytes of XIButtonClassInfo, its
1095 * button state mask and labels array.
1096 */
1097static void
1098sizeXIButtonClassType(int num_buttons, int* structure, int* state, int* atoms)
1099{
1100 int size;
1101 int labels;
1102
1103 *structure = pad_to_double(sizeof(XIButtonClassInfo));
1104 size = ((((num_buttons + 7)/8) + 3)/4);
1105
1106 /* Force mask alignment with longs to avoid unaligned
1107 * access when accessing the atoms. */
1108 *state = pad_to_double(size * 4);
1109 labels = num_buttons * sizeof(Atom);
1110
1111 /* Force mask alignment with longs to avoid
1112 * unaligned access when accessing the atoms. */
1113 labels += ((((num_buttons + 7)/8) + 3)/4) * sizeof(Atom);
1114 *atoms = pad_to_double(labels);
1115}
1116
1117/**
1118 * Set structure and keycodes to size in bytes of XIKeyClassInfo and
1119 * its keycodes array.
1120 */
1121static void
1122sizeXIKeyClassType(int num_keycodes, int* structure, int* keycodes)
1123{
1124 *structure = pad_to_double(sizeof(XIKeyClassInfo));
1125 *keycodes = pad_to_double(num_keycodes * sizeof(int));
1126}
1127
1128/**
1129 * Return the size in bytes required to store the matching class type
1130 * num_elements is num_buttons for XIButtonClass or num_keycodes for
1131 * XIKeyClass.
1132 *
1133 * Also used from copy_classes in XIQueryDevice.c
1134 */
1135static int
1136sizeDeviceClassType(int type, int num_elements)
1137{
1138 int l = 0;
1139 int extra1 = 0;
1140 int extra2 = 0;
1141 switch(type)
1142 {
1143 case XIButtonClass1:
1144 sizeXIButtonClassType(num_elements, &l, &extra1, &extra2);
1145 l += extra1 + extra2;
1146 break;
1147 case XIKeyClass0:
1148 sizeXIKeyClassType(num_elements, &l, &extra1);
1149 l += extra1;
1150 break;
1151 case XIValuatorClass2:
1152 l = pad_to_double(sizeof(XIValuatorClassInfo));
1153 break;
1154 case XIScrollClass3:
1155 l = pad_to_double(sizeof(XIScrollClassInfo));
1156 break;
1157 case XITouchClass8:
1158 l = pad_to_double(sizeof(XITouchClassInfo));
1159 break;
1160 default:
1161 printf("sizeDeviceClassType: unknown type %d\n", type);
1162 break;
1163 }
1164 return l;
1165}
1166
1167static Boolint
1168copyHierarchyEvent(XGenericEventCookie *cookie_in,
1169 XGenericEventCookie *cookie_out)
1170{
1171 XIHierarchyEvent *in, *out;
1172 void *ptr;
1173
1174 in = cookie_in->data;
1175
1176 ptr = cookie_out->data = malloc(sizeof(XIHierarchyEvent) +
1177 in->num_info * sizeof(XIHierarchyInfo));
1178 if (!ptr)
1179 return False0;
1180
1181 out = next_block(&ptr, sizeof(XIHierarchyEvent));
1182 *out = *in;
1183 out->info = next_block(&ptr, in->num_info * sizeof(XIHierarchyInfo));
1184 memcpy(out->info, in->info, in->num_info * sizeof(XIHierarchyInfo));
1185
1186 return True1;
1187}
1188
1189static Boolint
1190copyDeviceChangedEvent(XGenericEventCookie *in_cookie,
1191 XGenericEventCookie *out_cookie)
1192{
1193 int len, i;
1194 XIDeviceChangedEvent *in, *out;
1195 XIAnyClassInfo *any;
1196 void *ptr;
1197
1198 in = in_cookie->data;
1199
1200 len = sizeof(XIDeviceChangedEvent);
1201 len += in->num_classes * sizeof(XIAnyClassInfo*);
1202
1203 for (i = 0; i < in->num_classes; i++)
1204 {
1205 any = in->classes[i];
1206 switch(any->type)
1207 {
1208 case XIButtonClass1:
1209 len += sizeDeviceClassType(XIButtonClass1,
1210 ((XIButtonClassInfo*)any)->num_buttons);
1211 break;
1212 case XIKeyClass0:
1213 len += sizeDeviceClassType(XIKeyClass0,
1214 ((XIKeyClassInfo*)any)->num_keycodes);
1215 break;
1216 case XIValuatorClass2:
1217 len += sizeDeviceClassType(XIValuatorClass2, 0);
1218 break;
1219 case XIScrollClass3:
1220 len += sizeDeviceClassType(XIScrollClass3, 0);
1221 break;
1222 default:
1223 printf("copyDeviceChangedEvent: unknown type %d\n",
1224 any->type);
1225 break;
1226 }
1227
1228 }
1229
1230 ptr = out_cookie->data = malloc(len);
1231 if (!ptr)
1232 return False0;
1233 out = next_block(&ptr, sizeof(XIDeviceChangedEvent));
1234 *out = *in;
1235
1236 out->classes = next_block(&ptr,
1237 out->num_classes * sizeof(XIAnyClassInfo*));
1238
1239 for (i = 0; i < in->num_classes; i++)
1240 {
1241 any = in->classes[i];
1242
1243 switch(any->type)
1244 {
1245 case XIButtonClass1:
1246 {
1247 int struct_size;
1248 int state_size;
1249 int labels_size;
1250 XIButtonClassInfo *bin, *bout;
1251 bin = (XIButtonClassInfo*)any;
1252 sizeXIButtonClassType(bin->num_buttons, &struct_size,
1253 &state_size, &labels_size);
1254 bout = next_block(&ptr, struct_size);
1255
1256 *bout = *bin;
1257 bout->state.mask = next_block(&ptr, state_size);
1258 memcpy(bout->state.mask, bin->state.mask,
1259 bout->state.mask_len);
1260
1261 bout->labels = next_block(&ptr, labels_size);
1262 memcpy(bout->labels, bin->labels, bout->num_buttons * sizeof(Atom));
1263 out->classes[i] = (XIAnyClassInfo*)bout;
1264 break;
1265 }
1266 case XIKeyClass0:
1267 {
1268 XIKeyClassInfo *kin, *kout;
1269 int struct_size;
1270 int keycodes_size;
1271 kin = (XIKeyClassInfo*)any;
1272 sizeXIKeyClassType(kin->num_keycodes, &struct_size,
1273 &keycodes_size);
1274
1275 kout = next_block(&ptr, struct_size);
1276 *kout = *kin;
1277 kout->keycodes = next_block(&ptr, keycodes_size);
1278 memcpy(kout->keycodes, kin->keycodes, kout->num_keycodes * sizeof(int));
1279 out->classes[i] = (XIAnyClassInfo*)kout;
1280 break;
1281 }
1282 case XIValuatorClass2:
1283 {
1284 XIValuatorClassInfo *vin, *vout;
1285 vin = (XIValuatorClassInfo*)any;
1286 vout = next_block(&ptr,
1287 sizeDeviceClassType(XIValuatorClass2, 0));
1288 *vout = *vin;
1289 out->classes[i] = (XIAnyClassInfo*)vout;
1290 break;
1291 }
1292 case XIScrollClass3:
1293 {
1294 XIScrollClassInfo *sin, *sout;
1295 sin = (XIScrollClassInfo*)any;
1296 sout = next_block(&ptr,
1297 sizeDeviceClassType(XIScrollClass3, 0));
1298 *sout = *sin;
1299 out->classes[i] = (XIAnyClassInfo*)sout;
1300 break;
1301 }
1302 }
1303 }
1304
1305 return True1;
1306}
1307
1308static Boolint
1309copyDeviceEvent(XGenericEventCookie *cookie_in,
1310 XGenericEventCookie *cookie_out)
1311{
1312 int len;
1313 XIDeviceEvent *in, *out;
1314 int bits; /* valuator bits */
1315 void *ptr;
1316
1317 in = cookie_in->data;
1318 bits = count_bits(in->valuators.mask, in->valuators.mask_len);
1319
1320 len = sizeDeviceEvent(in->buttons.mask_len, in->valuators.mask_len,
1321 in->valuators.mask);
1322
1323 ptr = cookie_out->data = malloc(len);
1324 if (!ptr)
1325 return False0;
1326
1327 out = next_block(&ptr, sizeof(XIDeviceEvent));
1328 *out = *in;
1329
1330 out->buttons.mask = next_block(&ptr, in->buttons.mask_len);
1331 memcpy(out->buttons.mask, in->buttons.mask,
1332 out->buttons.mask_len);
1333 out->valuators.mask = next_block(&ptr, in->valuators.mask_len);
1334 memcpy(out->valuators.mask, in->valuators.mask,
1335 out->valuators.mask_len);
1336 out->valuators.values = next_block(&ptr, bits * sizeof(double));
1337 memcpy(out->valuators.values, in->valuators.values,
1338 bits * sizeof(double));
1339
1340 return True1;
1341}
1342
1343static Boolint
1344copyEnterEvent(XGenericEventCookie *cookie_in,
1345 XGenericEventCookie *cookie_out)
1346{
1347 int len;
1348 XIEnterEvent *in, *out;
1349 void *ptr;
1350
1351 in = cookie_in->data;
1352
1353 len = sizeof(XIEnterEvent) + in->buttons.mask_len;
1354
1355 ptr = cookie_out->data = malloc(len);
1356 if (!ptr)
1357 return False0;
1358
1359 out = next_block(&ptr, sizeof(XIEnterEvent));
1360 *out = *in;
1361
1362 out->buttons.mask = next_block(&ptr, in->buttons.mask_len);
1363 memcpy(out->buttons.mask, in->buttons.mask, out->buttons.mask_len);
1364
1365 return True1;
1366}
1367
1368static Boolint
1369copyPropertyEvent(XGenericEventCookie *cookie_in,
1370 XGenericEventCookie *cookie_out)
1371{
1372 XIPropertyEvent *in, *out;
1373
1374 in = cookie_in->data;
1375
1376 out = cookie_out->data = malloc(sizeof(XIPropertyEvent));
1377 if (!out)
1378 return False0;
1379
1380 *out = *in;
1381 return True1;
1382}
1383
1384static Boolint
1385copyTouchOwnershipEvent(XGenericEventCookie *cookie_in,
1386 XGenericEventCookie *cookie_out)
1387{
1388 XITouchOwnershipEvent *in, *out;
1389
1390 in = cookie_in->data;
1391
1392 out = cookie_out->data = malloc(sizeof(XITouchOwnershipEvent));
1393 if (!out)
1394 return False0;
1395
1396 *out = *in;
1397 return True1;
1398}
1399
1400static Boolint
1401copyRawEvent(XGenericEventCookie *cookie_in,
1402 XGenericEventCookie *cookie_out)
1403{
1404 XIRawEvent *in, *out;
1405 void *ptr;
1406 int len;
1407 int bits;
1408
1409 in = cookie_in->data;
1410
1411 bits = count_bits(in->valuators.mask, in->valuators.mask_len);
1412 len = sizeof(XIRawEvent) + in->valuators.mask_len;
1413 len += bits * sizeof(double) * 2;
1414
1415 ptr = cookie_out->data = malloc(len);
1416 if (!ptr)
1417 return False0;
1418
1419 out = next_block(&ptr, sizeof(XIRawEvent));
1420 *out = *in;
1421 out->valuators.mask = next_block(&ptr, out->valuators.mask_len);
1422 memcpy(out->valuators.mask, in->valuators.mask, out->valuators.mask_len);
1423
1424 out->valuators.values = next_block(&ptr, bits * sizeof(double));
1425 memcpy(out->valuators.values, in->valuators.values, bits * sizeof(double));
1426
1427 out->raw_values = next_block(&ptr, bits * sizeof(double));
1428 memcpy(out->raw_values, in->raw_values, bits * sizeof(double));
1429
1430 return True1;
1431}
1432
1433
1434
1435static Boolint
1436XInputCopyCookie(Display *dpy, XGenericEventCookie *in, XGenericEventCookie *out)
1437{
1438 int ret = True1;
1439
1440 XExtDisplayInfo *info = XInput_find_display(dpy);
1441
1442 if (in->extension != info->codes->major_opcode)
1443 {
1444 printf("XInputCopyCookie: wrong extension opcode %d\n",
1445 in->extension);
1446 return False0;
1447 }
1448
1449 *out = *in;
1450 out->data = NULL((void*)0);
1451 out->cookie = 0;
1452
1453 switch(in->evtype) {
1454 case XI_Motion6:
1455 case XI_ButtonPress4:
1456 case XI_ButtonRelease5:
1457 case XI_KeyPress2:
1458 case XI_KeyRelease3:
1459 case XI_TouchBegin18:
1460 case XI_TouchUpdate19:
1461 case XI_TouchEnd20:
1462 ret = copyDeviceEvent(in, out);
1463 break;
1464 case XI_DeviceChanged1:
1465 ret = copyDeviceChangedEvent(in, out);
1466 break;
1467 case XI_HierarchyChanged11:
1468 ret = copyHierarchyEvent(in, out);
1469 break;
1470 case XI_Enter7:
1471 case XI_Leave8:
1472 case XI_FocusIn9:
1473 case XI_FocusOut10:
1474 ret = copyEnterEvent(in, out);
1475 break;
1476 case XI_PropertyEvent12:
1477 ret = copyPropertyEvent(in, out);
1478 break;
1479 case XI_TouchOwnership21:
1480 ret = copyTouchOwnershipEvent(in, out);
1481 break;
1482 case XI_RawKeyPress13:
1483 case XI_RawKeyRelease14:
1484 case XI_RawButtonPress15:
1485 case XI_RawButtonRelease16:
1486 case XI_RawMotion17:
1487 ret = copyRawEvent(in, out);
1488 break;
1489 default:
1490 printf("XInputCopyCookie: unknown evtype %d\n", in->evtype);
1491 ret = False0;
1492 }
1493
1494 if (!ret)
1495 printf("XInputCopyCookie: Failed to copy evtype %d", in->evtype);
1496 return ret;
1497}
1498
1499static int
1500wireToDeviceEvent(xXIDeviceEvent *in, XGenericEventCookie* cookie)
1501{
1502 int len, i;
1503 unsigned char *ptr;
1504 void *ptr_lib;
1505 FP3232 *values;
1506 XIDeviceEvent *out;
1507
1508 ptr = (unsigned char*)&in[1] + in->buttons_len * 4;
1509
1510 len = sizeDeviceEvent(in->buttons_len * 4, in->valuators_len * 4, ptr);
1511
1512 cookie->data = ptr_lib = malloc(len);
1513
1514 out = next_block(&ptr_lib, sizeof(XIDeviceEvent));
1515 out->display = cookie->display;
1516 out->type = in->type;
1517 out->extension = in->extension;
1518 out->evtype = in->evtype;
1519 out->send_event = ((in->type & 0x80) != 0);
1520 out->time = in->time;
1521 out->deviceid = in->deviceid;
1522 out->sourceid = in->sourceid;
1523 out->detail = in->detail;
1524 out->root = in->root;
1525 out->event = in->event;
1526 out->child = in->child;
1527 out->root_x = FP1616toDBL(in->root_x)((in->root_x) * 1.0 / (1 << 16));
1528 out->root_y = FP1616toDBL(in->root_y)((in->root_y) * 1.0 / (1 << 16));
1529 out->event_x = FP1616toDBL(in->event_x)((in->event_x) * 1.0 / (1 << 16));
1530 out->event_y = FP1616toDBL(in->event_y)((in->event_y) * 1.0 / (1 << 16));
1531 out->flags = in->flags;
1532 out->mods.base = in->mods.base_mods;
1533 out->mods.locked = in->mods.locked_mods;
1534 out->mods.latched = in->mods.latched_mods;
1535 out->mods.effective = in->mods.effective_mods;
1536 out->group.base = in->group.base_group;
1537 out->group.locked = in->group.locked_group;
1538 out->group.latched = in->group.latched_group;
1539 out->group.effective = in->group.effective_group;
1540 out->buttons.mask_len = in->buttons_len * 4;
1541 out->valuators.mask_len = in->valuators_len * 4;
1542
1543 out->buttons.mask = next_block(&ptr_lib, out->buttons.mask_len);
1544
1545 /* buttons */
1546 ptr = (unsigned char*)&in[1];
1547 memcpy(out->buttons.mask, ptr, out->buttons.mask_len);
1548 ptr += in->buttons_len * 4;
1549
1550 /* valuators */
1551 out->valuators.mask = next_block(&ptr_lib, out->valuators.mask_len);
1552 memcpy(out->valuators.mask, ptr, out->valuators.mask_len);
1553 ptr += in->valuators_len * 4;
1554
1555 len = count_bits(out->valuators.mask, out->valuators.mask_len);
1556 out->valuators.values = next_block(&ptr_lib, len * sizeof(double));
1557
1558 values = (FP3232*)ptr;
1559 for (i = 0; i < len; i++, values++)
1560 {
1561 out->valuators.values[i] = values->integral;
1562 out->valuators.values[i] += ((double)values->frac / (1 << 16) / (1 << 16));
1563 }
1564
1565
1566 return 1;
1567}
1568
1569_X_HIDDEN__attribute__((visibility("hidden"))) int
1570size_classes(xXIAnyInfo* from, int nclasses)
1571{
1572 int len, i;
1573 xXIAnyInfo *any_wire;
1574 char *ptr_wire;
1575
1576 /* len for to->classes */
1577 len = pad_to_double(nclasses * sizeof(XIAnyClassInfo*));
1578 ptr_wire = (char*)from;
1579 for (i = 0; i < nclasses; i++)
1580 {
1581 int l = 0;
1582 any_wire = (xXIAnyInfo*)ptr_wire;
1583 switch(any_wire->type)
1584 {
1585 case XIButtonClass1:
1586 l = sizeDeviceClassType(XIButtonClass1,
1587 ((xXIButtonInfo*)any_wire)->num_buttons);
1588 break;
1589 case XIKeyClass0:
1590 l = sizeDeviceClassType(XIKeyClass0,
1591 ((xXIKeyInfo*)any_wire)->num_keycodes);
1592 break;
1593 case XIValuatorClass2:
1594 l = sizeDeviceClassType(XIValuatorClass2, 0);
1595 break;
1596 case XIScrollClass3:
1597 l = sizeDeviceClassType(XIScrollClass3, 0);
1598 break;
1599 case XITouchClass8:
1600 l = sizeDeviceClassType(XITouchClass8, 0);
1601 break;
1602 }
1603
1604 len += l;
1605 ptr_wire += any_wire->length * 4;
1606 }
1607
1608 return len;
1609}
1610
1611/* Copy classes from any into to->classes and return the number of bytes
1612 * copied. Memory layout of to->classes is
1613 * [clsptr][clsptr][clsptr][classinfo][classinfo]...
1614 * |________|___________^
1615 * |______________________^
1616 */
1617_X_HIDDEN__attribute__((visibility("hidden"))) int
1618copy_classes(XIDeviceInfo* to, xXIAnyInfo* from, int *nclasses)
1619{
1620 XIAnyClassInfo *any_lib;
1621 xXIAnyInfo *any_wire;
1622 void *ptr_lib;
1623 char *ptr_wire;
1624 int i, len;
1625 int cls_idx = 0;
1626
1627 if (!to->classes)
1628 return -1;
1629
1630 ptr_wire = (char*)from;
1631 ptr_lib = to->classes;
1632 to->classes = next_block(&ptr_lib,
1633 pad_to_double((*nclasses) * sizeof(XIAnyClassInfo*)));
1634 memset(to->classes, 0, (*nclasses) * sizeof(XIAnyClassInfo*));
1635 len = 0; /* count wire length */
1636
1637 for (i = 0; i < *nclasses; i++)
1638 {
1639 any_lib = (XIAnyClassInfo*)ptr_lib;
1640 any_wire = (xXIAnyInfo*)ptr_wire;
1641
1642 switch(any_wire->type)
1643 {
1644 case XIButtonClass1:
1645 {
1646 XIButtonClassInfo *cls_lib;
1647 xXIButtonInfo *cls_wire;
1648 uint32_t *atoms;
1649 int j;
1650 int struct_size;
1651 int state_size;
1652 int labels_size;
1653 int wire_mask_size;
1654
1655 cls_wire = (xXIButtonInfo*)any_wire;
1656 sizeXIButtonClassType(cls_wire->num_buttons,
1657 &struct_size, &state_size,
1658 &labels_size);
1659 cls_lib = next_block(&ptr_lib, struct_size);
1660 wire_mask_size = ((cls_wire->num_buttons + 7)/8 + 3)/4 * 4;
1661
1662 cls_lib->type = cls_wire->type;
1663 cls_lib->sourceid = cls_wire->sourceid;
1664 cls_lib->num_buttons = cls_wire->num_buttons;
1665 cls_lib->state.mask_len = state_size;
1666 cls_lib->state.mask = next_block(&ptr_lib, state_size);
1667 memcpy(cls_lib->state.mask, &cls_wire[1],
1668 wire_mask_size);
1669 if (state_size != wire_mask_size)
1670 memset(&cls_lib->state.mask[wire_mask_size], 0,
1671 state_size - wire_mask_size);
1672
1673 cls_lib->labels = next_block(&ptr_lib, labels_size);
1674
1675 atoms =(uint32_t*)((char*)&cls_wire[1] + wire_mask_size);
1676 for (j = 0; j < cls_lib->num_buttons; j++)
1677 cls_lib->labels[j] = *atoms++;
1678
1679 to->classes[cls_idx++] = any_lib;
1680 break;
1681 }
1682 case XIKeyClass0:
1683 {
1684 XIKeyClassInfo *cls_lib;
1685 xXIKeyInfo *cls_wire;
1686 int struct_size;
1687 int keycodes_size;
1688
1689 cls_wire = (xXIKeyInfo*)any_wire;
1690 sizeXIKeyClassType(cls_wire->num_keycodes,
1691 &struct_size, &keycodes_size);
1692 cls_lib = next_block(&ptr_lib, struct_size);
1693
1694 cls_lib->type = cls_wire->type;
1695 cls_lib->sourceid = cls_wire->sourceid;
1696 cls_lib->num_keycodes = cls_wire->num_keycodes;
1697 cls_lib->keycodes = next_block(&ptr_lib, keycodes_size);
1698 memcpy(cls_lib->keycodes, &cls_wire[1],
1699 cls_lib->num_keycodes);
1700
1701 to->classes[cls_idx++] = any_lib;
1702 break;
1703 }
1704 case XIValuatorClass2:
1705 {
1706 XIValuatorClassInfo *cls_lib;
1707 xXIValuatorInfo *cls_wire;
1708
1709 cls_lib =
1710 next_block(&ptr_lib,
1711 sizeDeviceClassType(XIValuatorClass2, 0));
1712 cls_wire = (xXIValuatorInfo*)any_wire;
1713
1714 cls_lib->type = cls_wire->type;
1715 cls_lib->sourceid = cls_wire->sourceid;
1716 cls_lib->number = cls_wire->number;
1717 cls_lib->label = cls_wire->label;
1718 cls_lib->resolution = cls_wire->resolution;
1719 cls_lib->min = cls_wire->min.integral;
1720 cls_lib->max = cls_wire->max.integral;
1721 cls_lib->value = cls_wire->value.integral;
1722 /* FIXME: fractional parts */
1723 cls_lib->mode = cls_wire->mode;
1724
1725 to->classes[cls_idx++] = any_lib;
1726 }
1727 break;
1728 case XIScrollClass3:
1729 {
1730 XIScrollClassInfo *cls_lib;
1731 xXIScrollInfo *cls_wire;
1732
1733 cls_lib =
1734 next_block(&ptr_lib,
1735 sizeDeviceClassType(XIScrollClass3, 0));
1736 cls_wire = (xXIScrollInfo*)any_wire;
1737
1738 cls_lib->type = cls_wire->type;
1739 cls_lib->sourceid = cls_wire->sourceid;
1740 cls_lib->number = cls_wire->number;
1741 cls_lib->scroll_type= cls_wire->scroll_type;
1742 cls_lib->flags = cls_wire->flags;
1743 cls_lib->increment = cls_wire->increment.integral;
1744 cls_lib->increment += (unsigned int)cls_wire->increment.frac/(double)(1ULL << 32);
1745
1746 to->classes[cls_idx++] = any_lib;
1747 }
1748 break;
1749 case XITouchClass8:
1750 {
1751 XITouchClassInfo *cls_lib;
1752 xXITouchInfo *cls_wire;
1753
1754 cls_wire = (xXITouchInfo*)any_wire;
1755 cls_lib = next_block(&ptr_lib, sizeof(XITouchClassInfo));
1756
1757 cls_lib->type = cls_wire->type;
1758 cls_lib->sourceid = cls_wire->sourceid;
1759 cls_lib->mode = cls_wire->mode;
1760 cls_lib->num_touches = cls_wire->num_touches;
1761
1762 to->classes[cls_idx++] = any_lib;
1763 }
1764 break;
1765 }
1766 len += any_wire->length * 4;
1767 ptr_wire += any_wire->length * 4;
1768 }
1769
1770 /* we may have skipped unknown classes, reset nclasses */
1771 *nclasses = cls_idx;
1772 return len;
1773}
1774
1775
1776static int
1777wireToDeviceChangedEvent(xXIDeviceChangedEvent *in, XGenericEventCookie *cookie)
1778{
1779 XIDeviceChangedEvent *out;
1780 XIDeviceInfo info;
1781 int len;
1782 int nclasses = in->num_classes;
1783
1784 len = size_classes((xXIAnyInfo*)&in[1], in->num_classes);
1785
1786 cookie->data = out = malloc(sizeof(XIDeviceChangedEvent) + len);
1787
1788 out->type = in->type;
1789 out->display = cookie->display;
1790 out->extension = in->extension;
1791 out->evtype = in->evtype;
1792 out->send_event = ((in->type & 0x80) != 0);
1793 out->time = in->time;
1794 out->deviceid = in->deviceid;
1795 out->sourceid = in->sourceid;
1796 out->reason = in->reason;
1797
1798 out->classes = (XIAnyClassInfo**)&out[1];
1799
1800 info.classes = out->classes;
1801
1802 copy_classes(&info, (xXIAnyInfo*)&in[1], &nclasses);
1803 out->num_classes = nclasses;
1804
1805 return 1;
1806}
1807
1808static int
1809wireToHierarchyChangedEvent(xXIHierarchyEvent *in, XGenericEventCookie *cookie)
1810{
1811 int i;
1812 XIHierarchyInfo *info_out;
1813 xXIHierarchyInfo *info_in;
1814 XIHierarchyEvent *out;
1815
1816 cookie->data = out = malloc(sizeof(XIHierarchyEvent) + in->num_info * sizeof(XIHierarchyInfo));;
1817
1818 out->info = (XIHierarchyInfo*)&out[1];
1819 out->display = cookie->display;
1820 out->type = in->type;
1821 out->extension = in->extension;
1822 out->evtype = in->evtype;
1823 out->send_event = ((in->type & 0x80) != 0);
1824 out->time = in->time;
1825 out->flags = in->flags;
1826 out->num_info = in->num_info;
1827
1828 info_out = out->info;
1829 info_in = (xXIHierarchyInfo*)&in[1];
1830
1831 for (i = 0; i < out->num_info; i++, info_out++, info_in++)
1832 {
1833 info_out->deviceid = info_in->deviceid;
1834 info_out->attachment = info_in->attachment;
1835 info_out->use = info_in->use;
1836 info_out->enabled = info_in->enabled;
1837 info_out->flags = info_in->flags;
1838 }
1839
1840 return 1;
1841}
1842
1843static int
1844wireToRawEvent(XExtDisplayInfo *info, xXIRawEvent *in, XGenericEventCookie *cookie)
1845{
1846 int len, i, bits;
1847 FP3232 *values;
1848 XIRawEvent *out;
1849 void *ptr;
1850
1851 len = sizeof(XIRawEvent) + in->valuators_len * 4;
1852 bits = count_bits((unsigned char*)&in[1], in->valuators_len * 4);
1853 len += bits * sizeof(double) * 2; /* raw + normal */
1854
1855 cookie->data = ptr = calloc(1, len);
1856 if (!ptr)
1857 return 0;
1858
1859 out = next_block(&ptr, sizeof(XIRawEvent));
1860 out->type = in->type;
1861 out->display = cookie->display;
1862 out->extension = in->extension;
1863 out->evtype = in->evtype;
1864 out->send_event = ((in->type & 0x80) != 0);
1865 out->time = in->time;
1866 out->detail = in->detail;
1867 out->deviceid = in->deviceid;
1868 out->flags = in->flags;
1869
1870 /* https://bugs.freedesktop.org/show_bug.cgi?id=34240 */
1871 if (_XiCheckVersion(info, XInput_2_29) >= 0)
1872 out->sourceid = in->sourceid;
1873 else
1874 out->sourceid = 0;
1875
1876 out->valuators.mask_len = in->valuators_len * 4;
1877 out->valuators.mask = next_block(&ptr, out->valuators.mask_len);
1878 memcpy(out->valuators.mask, &in[1], out->valuators.mask_len);
1879
1880 out->valuators.values = next_block(&ptr, bits * sizeof(double));
1881 out->raw_values = next_block(&ptr, bits * sizeof(double));
1882
1883 values = (FP3232*)(((char*)&in[1]) + in->valuators_len * 4);
1884 for (i = 0; i < bits; i++)
1885 {
1886 out->valuators.values[i] = values->integral;
1887 out->valuators.values[i] += ((double)values->frac / (1 << 16) / (1 << 16));
1888 out->raw_values[i] = (values + bits)->integral;
1889 out->raw_values[i] += ((double)(values + bits)->frac / (1 << 16) / (1 << 16));
1890 values++;
1891 }
1892
1893 return 1;
1894}
1895
1896/* Memory layout of XIEnterEvents:
1897 [event][modifiers][group][button]
1898 */
1899static int
1900wireToEnterLeave(xXIEnterEvent *in, XGenericEventCookie *cookie)
1901{
1902 int len;
1903 XIEnterEvent *out;
1904
1905 len = sizeof(XIEnterEvent) + in->buttons_len * 4;
1906
1907 cookie->data = out = malloc(len);
1908 out->buttons.mask = (unsigned char*)&out[1];
1909
1910 out->type = in->type;
1911 out->display = cookie->display;
1912 out->extension = in->extension;
1913 out->evtype = in->evtype;
1914 out->send_event = ((in->type & 0x80) != 0);
1915 out->time = in->time;
1916 out->detail = in->detail;
1917 out->deviceid = in->deviceid;
1918 out->root = in->root;
1919 out->event = in->event;
1920 out->child = in->child;
1921 out->sourceid = in->sourceid;
1922 out->root_x = FP1616toDBL(in->root_x)((in->root_x) * 1.0 / (1 << 16));
1923 out->root_y = FP1616toDBL(in->root_y)((in->root_y) * 1.0 / (1 << 16));
1924 out->event_x = FP1616toDBL(in->event_x)((in->event_x) * 1.0 / (1 << 16));
1925 out->event_y = FP1616toDBL(in->event_y)((in->event_y) * 1.0 / (1 << 16));
1926 out->mode = in->mode;
1927 out->focus = in->focus;
1928 out->same_screen = in->same_screen;
1929
1930 out->mods.base = in->mods.base_mods;
1931 out->mods.locked = in->mods.locked_mods;
1932 out->mods.latched = in->mods.latched_mods;
1933 out->mods.effective = in->mods.effective_mods;
1934 out->group.base = in->group.base_group;
1935 out->group.locked = in->group.locked_group;
1936 out->group.latched = in->group.latched_group;
1937 out->group.effective = in->group.effective_group;
1938
1939 out->buttons.mask_len = in->buttons_len * 4;
1940 memcpy(out->buttons.mask, &in[1], out->buttons.mask_len);
1941
1942 return 1;
1943}
1944
1945static int
1946wireToPropertyEvent(xXIPropertyEvent *in, XGenericEventCookie *cookie)
1947{
1948 XIPropertyEvent *out = malloc(sizeof(XIPropertyEvent));
1949
1950 cookie->data = out;
1951
1952 out->type = in->type;
1953 out->extension = in->extension;
1954 out->evtype = in->evtype;
1955 out->send_event = ((in->type & 0x80) != 0);
1956 out->time = in->time;
1957 out->property = in->property;
1958 out->what = in->what;
1959 out->deviceid = in->deviceid;
1960
1961 return 1;
1962}
1963
1964static int
1965wireToTouchOwnershipEvent(xXITouchOwnershipEvent *in,
1966 XGenericEventCookie *cookie)
1967{
1968 XITouchOwnershipEvent *out = malloc(sizeof(XITouchOwnershipEvent));
1969
1970 cookie->data = out;
1971
1972 out->type = in->type;
1973 out->display = cookie->display;
1974 out->extension = in->extension;
1975 out->evtype = in->evtype;
1976 out->send_event = ((in->type & 0x80) != 0);
1977 out->time = in->time;
1978 out->deviceid = in->deviceid;
1979 out->sourceid = in->sourceid;
1980 out->touchid = in->touchid;
1981 out->root = in->root;
1982 out->event = in->event;
1983 out->child = in->child;
1984 out->flags = in->flags;
1985
1986 return 1;
1987}