eventconvert.c revision 1b5d61b8
1/*
2 * Copyright © 2009 Red Hat, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 *
23 */
24
25/**
26 * @file eventconvert.c
27 * This file contains event conversion routines from InternalEvent to the
28 * matching protocol events.
29 */
30
31#ifdef HAVE_DIX_CONFIG_H
32#include <dix-config.h>
33#endif
34
35#include <stdint.h>
36#include <X11/X.h>
37#include <X11/extensions/XIproto.h>
38#include <X11/extensions/XI2proto.h>
39#include <X11/extensions/XI.h>
40#include <X11/extensions/XI2.h>
41
42#include "dix.h"
43#include "inputstr.h"
44#include "misc.h"
45#include "eventstr.h"
46#include "exevents.h"
47#include "exglobals.h"
48#include "eventconvert.h"
49#include "inpututils.h"
50#include "xiquerydevice.h"
51#include "xkbsrv.h"
52#include "inpututils.h"
53
54static int countValuators(DeviceEvent *ev, int *first);
55static int getValuatorEvents(DeviceEvent *ev, deviceValuator * xv);
56static int eventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count);
57static int eventToDeviceChanged(DeviceChangedEvent *ev, xEvent **dcce);
58static int eventToDeviceEvent(DeviceEvent *ev, xEvent **xi);
59static int eventToRawEvent(RawDeviceEvent *ev, xEvent **xi);
60static int eventToBarrierEvent(BarrierEvent *ev, xEvent **xi);
61static int eventToTouchOwnershipEvent(TouchOwnershipEvent *ev, xEvent **xi);
62
63/* Do not use, read comments below */
64BOOL EventIsKeyRepeat(xEvent *event);
65
66/**
67 * Hack to allow detectable autorepeat for core and XI1 events.
68 * The sequence number is unused until we send to the client and can be
69 * misused to store data. More or less, anyway.
70 *
71 * Do not use this. It may change any time without warning, eat your babies
72 * and piss on your cat.
73 */
74static void
75EventSetKeyRepeatFlag(xEvent *event, BOOL on)
76{
77    event->u.u.sequenceNumber = on;
78}
79
80/**
81 * Check if the event was marked as a repeat event before.
82 * NOTE: This is a nasty hack and should NOT be used by anyone else but
83 * TryClientEvents.
84 */
85BOOL
86EventIsKeyRepeat(xEvent *event)
87{
88    return ! !event->u.u.sequenceNumber;
89}
90
91/**
92 * Convert the given event to the respective core event.
93 *
94 * Return values:
95 * Success ... core contains the matching core event.
96 * BadValue .. One or more values in the internal event are invalid.
97 * BadMatch .. The event has no core equivalent.
98 *
99 * @param[in] event The event to convert into a core event.
100 * @param[in] core The memory location to store the core event at.
101 * @return Success or the matching error code.
102 */
103int
104EventToCore(InternalEvent *event, xEvent **core_out, int *count_out)
105{
106    xEvent *core = NULL;
107    int count = 0;
108    int ret = BadImplementation;
109
110    switch (event->any.type) {
111    case ET_Motion:
112    {
113        DeviceEvent *e = &event->device_event;
114
115        /* Don't create core motion event if neither x nor y are
116         * present */
117        if (!BitIsOn(e->valuators.mask, 0) && !BitIsOn(e->valuators.mask, 1)) {
118            ret = BadMatch;
119            goto out;
120        }
121    }
122        /* fallthrough */
123    case ET_ButtonPress:
124    case ET_ButtonRelease:
125    case ET_KeyPress:
126    case ET_KeyRelease:
127    {
128        DeviceEvent *e = &event->device_event;
129
130        if (e->detail.key > 0xFF) {
131            ret = BadMatch;
132            goto out;
133        }
134
135        core = calloc(1, sizeof(*core));
136        if (!core)
137            return BadAlloc;
138        count = 1;
139        core->u.u.type = e->type - ET_KeyPress + KeyPress;
140        core->u.u.detail = e->detail.key & 0xFF;
141        core->u.keyButtonPointer.time = e->time;
142        core->u.keyButtonPointer.rootX = e->root_x;
143        core->u.keyButtonPointer.rootY = e->root_y;
144        core->u.keyButtonPointer.state = e->corestate;
145        core->u.keyButtonPointer.root = e->root;
146        EventSetKeyRepeatFlag(core, (e->type == ET_KeyPress && e->key_repeat));
147        ret = Success;
148    }
149        break;
150    case ET_ProximityIn:
151    case ET_ProximityOut:
152    case ET_RawKeyPress:
153    case ET_RawKeyRelease:
154    case ET_RawButtonPress:
155    case ET_RawButtonRelease:
156    case ET_RawMotion:
157    case ET_RawTouchBegin:
158    case ET_RawTouchUpdate:
159    case ET_RawTouchEnd:
160    case ET_TouchBegin:
161    case ET_TouchUpdate:
162    case ET_TouchEnd:
163    case ET_TouchOwnership:
164    case ET_BarrierHit:
165    case ET_BarrierLeave:
166        ret = BadMatch;
167        break;
168    default:
169        /* XXX: */
170        ErrorF("[dix] EventToCore: Not implemented yet \n");
171        ret = BadImplementation;
172    }
173
174 out:
175    *core_out = core;
176    *count_out = count;
177    return ret;
178}
179
180/**
181 * Convert the given event to the respective XI 1.x event and store it in
182 * xi. xi is allocated on demand and must be freed by the caller.
183 * count returns the number of events in xi. If count is 1, and the type of
184 * xi is GenericEvent, then xi may be larger than 32 bytes.
185 *
186 * Return values:
187 * Success ... core contains the matching core event.
188 * BadValue .. One or more values in the internal event are invalid.
189 * BadMatch .. The event has no XI equivalent.
190 *
191 * @param[in] ev The event to convert into an XI 1 event.
192 * @param[out] xi Future memory location for the XI event.
193 * @param[out] count Number of elements in xi.
194 *
195 * @return Success or the error code.
196 */
197int
198EventToXI(InternalEvent *ev, xEvent **xi, int *count)
199{
200    switch (ev->any.type) {
201    case ET_Motion:
202    case ET_ButtonPress:
203    case ET_ButtonRelease:
204    case ET_KeyPress:
205    case ET_KeyRelease:
206    case ET_ProximityIn:
207    case ET_ProximityOut:
208        return eventToKeyButtonPointer(&ev->device_event, xi, count);
209    case ET_DeviceChanged:
210    case ET_RawKeyPress:
211    case ET_RawKeyRelease:
212    case ET_RawButtonPress:
213    case ET_RawButtonRelease:
214    case ET_RawMotion:
215    case ET_RawTouchBegin:
216    case ET_RawTouchUpdate:
217    case ET_RawTouchEnd:
218    case ET_TouchBegin:
219    case ET_TouchUpdate:
220    case ET_TouchEnd:
221    case ET_TouchOwnership:
222    case ET_BarrierHit:
223    case ET_BarrierLeave:
224        *count = 0;
225        *xi = NULL;
226        return BadMatch;
227    default:
228        break;
229    }
230
231    ErrorF("[dix] EventToXI: Not implemented for %d \n", ev->any.type);
232    return BadImplementation;
233}
234
235/**
236 * Convert the given event to the respective XI 2.x event and store it in xi.
237 * xi is allocated on demand and must be freed by the caller.
238 *
239 * Return values:
240 * Success ... core contains the matching core event.
241 * BadValue .. One or more values in the internal event are invalid.
242 * BadMatch .. The event has no XI2 equivalent.
243 *
244 * @param[in] ev The event to convert into an XI2 event
245 * @param[out] xi Future memory location for the XI2 event.
246 *
247 * @return Success or the error code.
248 */
249int
250EventToXI2(InternalEvent *ev, xEvent **xi)
251{
252    switch (ev->any.type) {
253        /* Enter/FocusIn are for grabs. We don't need an actual event, since
254         * the real events delivered are triggered elsewhere */
255    case ET_Enter:
256    case ET_FocusIn:
257        *xi = NULL;
258        return Success;
259    case ET_Motion:
260    case ET_ButtonPress:
261    case ET_ButtonRelease:
262    case ET_KeyPress:
263    case ET_KeyRelease:
264    case ET_TouchBegin:
265    case ET_TouchUpdate:
266    case ET_TouchEnd:
267        return eventToDeviceEvent(&ev->device_event, xi);
268    case ET_TouchOwnership:
269        return eventToTouchOwnershipEvent(&ev->touch_ownership_event, xi);
270    case ET_ProximityIn:
271    case ET_ProximityOut:
272        *xi = NULL;
273        return BadMatch;
274    case ET_DeviceChanged:
275        return eventToDeviceChanged(&ev->changed_event, xi);
276    case ET_RawKeyPress:
277    case ET_RawKeyRelease:
278    case ET_RawButtonPress:
279    case ET_RawButtonRelease:
280    case ET_RawMotion:
281    case ET_RawTouchBegin:
282    case ET_RawTouchUpdate:
283    case ET_RawTouchEnd:
284        return eventToRawEvent(&ev->raw_event, xi);
285    case ET_BarrierHit:
286    case ET_BarrierLeave:
287        return eventToBarrierEvent(&ev->barrier_event, xi);
288    default:
289        break;
290    }
291
292    ErrorF("[dix] EventToXI2: Not implemented for %d \n", ev->any.type);
293    return BadImplementation;
294}
295
296static int
297eventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count)
298{
299    int num_events;
300    int first;                  /* dummy */
301    deviceKeyButtonPointer *kbp;
302
303    /* Sorry, XI 1.x protocol restrictions. */
304    if (ev->detail.button > 0xFF || ev->deviceid >= 0x80) {
305        *count = 0;
306        return Success;
307    }
308
309    num_events = (countValuators(ev, &first) + 5) / 6;  /* valuator ev */
310    if (num_events <= 0) {
311        switch (ev->type) {
312        case ET_KeyPress:
313        case ET_KeyRelease:
314        case ET_ButtonPress:
315        case ET_ButtonRelease:
316            /* no axes is ok */
317            break;
318        case ET_Motion:
319        case ET_ProximityIn:
320        case ET_ProximityOut:
321            *count = 0;
322            return BadMatch;
323        default:
324            *count = 0;
325            return BadImplementation;
326        }
327    }
328
329    num_events++;               /* the actual event event */
330
331    *xi = calloc(num_events, sizeof(xEvent));
332    if (!(*xi)) {
333        return BadAlloc;
334    }
335
336    kbp = (deviceKeyButtonPointer *) (*xi);
337    kbp->detail = ev->detail.button;
338    kbp->time = ev->time;
339    kbp->root = ev->root;
340    kbp->root_x = ev->root_x;
341    kbp->root_y = ev->root_y;
342    kbp->deviceid = ev->deviceid;
343    kbp->state = ev->corestate;
344    EventSetKeyRepeatFlag((xEvent *) kbp,
345                          (ev->type == ET_KeyPress && ev->key_repeat));
346
347    if (num_events > 1)
348        kbp->deviceid |= MORE_EVENTS;
349
350    switch (ev->type) {
351    case ET_Motion:
352        kbp->type = DeviceMotionNotify;
353        break;
354    case ET_ButtonPress:
355        kbp->type = DeviceButtonPress;
356        break;
357    case ET_ButtonRelease:
358        kbp->type = DeviceButtonRelease;
359        break;
360    case ET_KeyPress:
361        kbp->type = DeviceKeyPress;
362        break;
363    case ET_KeyRelease:
364        kbp->type = DeviceKeyRelease;
365        break;
366    case ET_ProximityIn:
367        kbp->type = ProximityIn;
368        break;
369    case ET_ProximityOut:
370        kbp->type = ProximityOut;
371        break;
372    default:
373        break;
374    }
375
376    if (num_events > 1) {
377        getValuatorEvents(ev, (deviceValuator *) (kbp + 1));
378    }
379
380    *count = num_events;
381    return Success;
382}
383
384/**
385 * Set first to the first valuator in the event ev and return the number of
386 * valuators from first to the last set valuator.
387 */
388static int
389countValuators(DeviceEvent *ev, int *first)
390{
391    int first_valuator = -1, last_valuator = -1, num_valuators = 0;
392    int i;
393
394    for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++) {
395        if (BitIsOn(ev->valuators.mask, i)) {
396            if (first_valuator == -1)
397                first_valuator = i;
398            last_valuator = i;
399        }
400    }
401
402    if (first_valuator != -1) {
403        num_valuators = last_valuator - first_valuator + 1;
404        *first = first_valuator;
405    }
406
407    return num_valuators;
408}
409
410static int
411getValuatorEvents(DeviceEvent *ev, deviceValuator * xv)
412{
413    int i;
414    int state = 0;
415    int first_valuator, num_valuators;
416
417    num_valuators = countValuators(ev, &first_valuator);
418    if (num_valuators > 0) {
419        DeviceIntPtr dev = NULL;
420
421        dixLookupDevice(&dev, ev->deviceid, serverClient, DixUseAccess);
422        /* State needs to be assembled BEFORE the device is updated. */
423        state = (dev &&
424                 dev->key) ? XkbStateFieldFromRec(&dev->key->xkbInfo->
425                                                  state) : 0;
426        state |= (dev && dev->button) ? (dev->button->state) : 0;
427    }
428
429    for (i = 0; i < num_valuators; i += 6, xv++) {
430        INT32 *valuators = &xv->valuator0;      // Treat all 6 vals as an array
431        int j;
432
433        xv->type = DeviceValuator;
434        xv->first_valuator = first_valuator + i;
435        xv->num_valuators = ((num_valuators - i) > 6) ? 6 : (num_valuators - i);
436        xv->deviceid = ev->deviceid;
437        xv->device_state = state;
438
439        /* Unset valuators in masked valuator events have the proper data values
440         * in the case of an absolute axis in between two set valuators. */
441        for (j = 0; j < xv->num_valuators; j++)
442            valuators[j] = ev->valuators.data[xv->first_valuator + j];
443
444        if (i + 6 < num_valuators)
445            xv->deviceid |= MORE_EVENTS;
446    }
447
448    return (num_valuators + 5) / 6;
449}
450
451static int
452appendKeyInfo(DeviceChangedEvent *dce, xXIKeyInfo * info)
453{
454    uint32_t *kc;
455    int i;
456
457    info->type = XIKeyClass;
458    info->num_keycodes = dce->keys.max_keycode - dce->keys.min_keycode + 1;
459    info->length = sizeof(xXIKeyInfo) / 4 + info->num_keycodes;
460    info->sourceid = dce->sourceid;
461
462    kc = (uint32_t *) &info[1];
463    for (i = 0; i < info->num_keycodes; i++)
464        *kc++ = i + dce->keys.min_keycode;
465
466    return info->length * 4;
467}
468
469static int
470appendButtonInfo(DeviceChangedEvent *dce, xXIButtonInfo * info)
471{
472    unsigned char *bits;
473    int mask_len;
474
475    mask_len = bytes_to_int32(bits_to_bytes(dce->buttons.num_buttons));
476
477    info->type = XIButtonClass;
478    info->num_buttons = dce->buttons.num_buttons;
479    info->length = bytes_to_int32(sizeof(xXIButtonInfo)) +
480        info->num_buttons + mask_len;
481    info->sourceid = dce->sourceid;
482
483    bits = (unsigned char *) &info[1];
484    memset(bits, 0, mask_len * 4);
485    /* FIXME: is_down? */
486
487    bits += mask_len * 4;
488    memcpy(bits, dce->buttons.names, dce->buttons.num_buttons * sizeof(Atom));
489
490    return info->length * 4;
491}
492
493static int
494appendValuatorInfo(DeviceChangedEvent *dce, xXIValuatorInfo * info,
495                   int axisnumber)
496{
497    info->type = XIValuatorClass;
498    info->length = sizeof(xXIValuatorInfo) / 4;
499    info->label = dce->valuators[axisnumber].name;
500    info->min.integral = dce->valuators[axisnumber].min;
501    info->min.frac = 0;
502    info->max.integral = dce->valuators[axisnumber].max;
503    info->max.frac = 0;
504    info->value = double_to_fp3232(dce->valuators[axisnumber].value);
505    info->resolution = dce->valuators[axisnumber].resolution;
506    info->number = axisnumber;
507    info->mode = dce->valuators[axisnumber].mode;
508    info->sourceid = dce->sourceid;
509
510    return info->length * 4;
511}
512
513static int
514appendScrollInfo(DeviceChangedEvent *dce, xXIScrollInfo * info, int axisnumber)
515{
516    if (dce->valuators[axisnumber].scroll.type == SCROLL_TYPE_NONE)
517        return 0;
518
519    info->type = XIScrollClass;
520    info->length = sizeof(xXIScrollInfo) / 4;
521    info->number = axisnumber;
522    switch (dce->valuators[axisnumber].scroll.type) {
523    case SCROLL_TYPE_VERTICAL:
524        info->scroll_type = XIScrollTypeVertical;
525        break;
526    case SCROLL_TYPE_HORIZONTAL:
527        info->scroll_type = XIScrollTypeHorizontal;
528        break;
529    default:
530        ErrorF("[Xi] Unknown scroll type %d. This is a bug.\n",
531               dce->valuators[axisnumber].scroll.type);
532        break;
533    }
534    info->increment =
535        double_to_fp3232(dce->valuators[axisnumber].scroll.increment);
536    info->sourceid = dce->sourceid;
537
538    info->flags = 0;
539
540    if (dce->valuators[axisnumber].scroll.flags & SCROLL_FLAG_DONT_EMULATE)
541        info->flags |= XIScrollFlagNoEmulation;
542    if (dce->valuators[axisnumber].scroll.flags & SCROLL_FLAG_PREFERRED)
543        info->flags |= XIScrollFlagPreferred;
544
545    return info->length * 4;
546}
547
548static int
549eventToDeviceChanged(DeviceChangedEvent *dce, xEvent **xi)
550{
551    xXIDeviceChangedEvent *dcce;
552    int len = sizeof(xXIDeviceChangedEvent);
553    int nkeys;
554    char *ptr;
555
556    if (dce->buttons.num_buttons) {
557        len += sizeof(xXIButtonInfo);
558        len += dce->buttons.num_buttons * sizeof(Atom); /* button names */
559        len += pad_to_int32(bits_to_bytes(dce->buttons.num_buttons));
560    }
561    if (dce->num_valuators) {
562        int i;
563
564        len += sizeof(xXIValuatorInfo) * dce->num_valuators;
565
566        for (i = 0; i < dce->num_valuators; i++)
567            if (dce->valuators[i].scroll.type != SCROLL_TYPE_NONE)
568                len += sizeof(xXIScrollInfo);
569    }
570
571    nkeys = (dce->keys.max_keycode > 0) ?
572        dce->keys.max_keycode - dce->keys.min_keycode + 1 : 0;
573    if (nkeys > 0) {
574        len += sizeof(xXIKeyInfo);
575        len += sizeof(CARD32) * nkeys;  /* keycodes */
576    }
577
578    dcce = calloc(1, len);
579    if (!dcce) {
580        ErrorF("[Xi] BadAlloc in SendDeviceChangedEvent.\n");
581        return BadAlloc;
582    }
583
584    dcce->type = GenericEvent;
585    dcce->extension = IReqCode;
586    dcce->evtype = XI_DeviceChanged;
587    dcce->time = dce->time;
588    dcce->deviceid = dce->deviceid;
589    dcce->sourceid = dce->sourceid;
590    dcce->reason =
591        (dce->flags & DEVCHANGE_DEVICE_CHANGE) ? XIDeviceChange : XISlaveSwitch;
592    dcce->num_classes = 0;
593    dcce->length = bytes_to_int32(len - sizeof(xEvent));
594
595    ptr = (char *) &dcce[1];
596    if (dce->buttons.num_buttons) {
597        dcce->num_classes++;
598        ptr += appendButtonInfo(dce, (xXIButtonInfo *) ptr);
599    }
600
601    if (nkeys) {
602        dcce->num_classes++;
603        ptr += appendKeyInfo(dce, (xXIKeyInfo *) ptr);
604    }
605
606    if (dce->num_valuators) {
607        int i;
608
609        dcce->num_classes += dce->num_valuators;
610        for (i = 0; i < dce->num_valuators; i++)
611            ptr += appendValuatorInfo(dce, (xXIValuatorInfo *) ptr, i);
612
613        for (i = 0; i < dce->num_valuators; i++) {
614            if (dce->valuators[i].scroll.type != SCROLL_TYPE_NONE) {
615                dcce->num_classes++;
616                ptr += appendScrollInfo(dce, (xXIScrollInfo *) ptr, i);
617            }
618        }
619    }
620
621    *xi = (xEvent *) dcce;
622
623    return Success;
624}
625
626static int
627count_bits(unsigned char *ptr, int len)
628{
629    int bits = 0;
630    unsigned int i;
631    unsigned char x;
632
633    for (i = 0; i < len; i++) {
634        x = ptr[i];
635        while (x > 0) {
636            bits += (x & 0x1);
637            x >>= 1;
638        }
639    }
640    return bits;
641}
642
643static int
644eventToDeviceEvent(DeviceEvent *ev, xEvent **xi)
645{
646    int len = sizeof(xXIDeviceEvent);
647    xXIDeviceEvent *xde;
648    int i, btlen, vallen;
649    char *ptr;
650    FP3232 *axisval;
651
652    /* FIXME: this should just send the buttons we have, not MAX_BUTTONs. Same
653     * with MAX_VALUATORS below */
654    /* btlen is in 4 byte units */
655    btlen = bytes_to_int32(bits_to_bytes(MAX_BUTTONS));
656    len += btlen * 4;           /* buttonmask len */
657
658    vallen = count_bits(ev->valuators.mask, ARRAY_SIZE(ev->valuators.mask));
659    len += vallen * 2 * sizeof(uint32_t);       /* axisvalues */
660    vallen = bytes_to_int32(bits_to_bytes(MAX_VALUATORS));
661    len += vallen * 4;          /* valuators mask */
662
663    *xi = calloc(1, len);
664    xde = (xXIDeviceEvent *) * xi;
665    xde->type = GenericEvent;
666    xde->extension = IReqCode;
667    xde->evtype = GetXI2Type(ev->type);
668    xde->time = ev->time;
669    xde->length = bytes_to_int32(len - sizeof(xEvent));
670    if (IsTouchEvent((InternalEvent *) ev))
671        xde->detail = ev->touchid;
672    else
673        xde->detail = ev->detail.button;
674
675    xde->root = ev->root;
676    xde->buttons_len = btlen;
677    xde->valuators_len = vallen;
678    xde->deviceid = ev->deviceid;
679    xde->sourceid = ev->sourceid;
680    xde->root_x = double_to_fp1616(ev->root_x + ev->root_x_frac);
681    xde->root_y = double_to_fp1616(ev->root_y + ev->root_y_frac);
682
683    if (IsTouchEvent((InternalEvent *)ev)) {
684        if (ev->type == ET_TouchUpdate)
685            xde->flags |= (ev->flags & TOUCH_PENDING_END) ? XITouchPendingEnd : 0;
686
687        if (ev->flags & TOUCH_POINTER_EMULATED)
688            xde->flags |= XITouchEmulatingPointer;
689    } else {
690        xde->flags = ev->flags;
691
692        if (ev->key_repeat)
693            xde->flags |= XIKeyRepeat;
694    }
695
696    xde->mods.base_mods = ev->mods.base;
697    xde->mods.latched_mods = ev->mods.latched;
698    xde->mods.locked_mods = ev->mods.locked;
699    xde->mods.effective_mods = ev->mods.effective;
700
701    xde->group.base_group = ev->group.base;
702    xde->group.latched_group = ev->group.latched;
703    xde->group.locked_group = ev->group.locked;
704    xde->group.effective_group = ev->group.effective;
705
706    ptr = (char *) &xde[1];
707    for (i = 0; i < sizeof(ev->buttons) * 8; i++) {
708        if (BitIsOn(ev->buttons, i))
709            SetBit(ptr, i);
710    }
711
712    ptr += xde->buttons_len * 4;
713    axisval = (FP3232 *) (ptr + xde->valuators_len * 4);
714    for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++) {
715        if (BitIsOn(ev->valuators.mask, i)) {
716            SetBit(ptr, i);
717            *axisval = double_to_fp3232(ev->valuators.data[i]);
718            axisval++;
719        }
720    }
721
722    return Success;
723}
724
725static int
726eventToTouchOwnershipEvent(TouchOwnershipEvent *ev, xEvent **xi)
727{
728    int len = sizeof(xXITouchOwnershipEvent);
729    xXITouchOwnershipEvent *xtoe;
730
731    *xi = calloc(1, len);
732    xtoe = (xXITouchOwnershipEvent *) * xi;
733    xtoe->type = GenericEvent;
734    xtoe->extension = IReqCode;
735    xtoe->length = bytes_to_int32(len - sizeof(xEvent));
736    xtoe->evtype = GetXI2Type(ev->type);
737    xtoe->deviceid = ev->deviceid;
738    xtoe->time = ev->time;
739    xtoe->sourceid = ev->sourceid;
740    xtoe->touchid = ev->touchid;
741    xtoe->flags = 0;            /* we don't have wire flags for ownership yet */
742
743    return Success;
744}
745
746static int
747eventToRawEvent(RawDeviceEvent *ev, xEvent **xi)
748{
749    xXIRawEvent *raw;
750    int vallen, nvals;
751    int i, len = sizeof(xXIRawEvent);
752    char *ptr;
753    FP3232 *axisval, *axisval_raw;
754
755    nvals = count_bits(ev->valuators.mask, sizeof(ev->valuators.mask));
756    len += nvals * sizeof(FP3232) * 2;  /* 8 byte per valuator, once
757                                           raw, once processed */
758    vallen = bytes_to_int32(bits_to_bytes(MAX_VALUATORS));
759    len += vallen * 4;          /* valuators mask */
760
761    *xi = calloc(1, len);
762    raw = (xXIRawEvent *) * xi;
763    raw->type = GenericEvent;
764    raw->extension = IReqCode;
765    raw->evtype = GetXI2Type(ev->type);
766    raw->time = ev->time;
767    raw->length = bytes_to_int32(len - sizeof(xEvent));
768    raw->detail = ev->detail.button;
769    raw->deviceid = ev->deviceid;
770    raw->sourceid = ev->sourceid;
771    raw->valuators_len = vallen;
772    raw->flags = ev->flags;
773
774    ptr = (char *) &raw[1];
775    axisval = (FP3232 *) (ptr + raw->valuators_len * 4);
776    axisval_raw = axisval + nvals;
777    for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++) {
778        if (BitIsOn(ev->valuators.mask, i)) {
779            SetBit(ptr, i);
780            *axisval = double_to_fp3232(ev->valuators.data[i]);
781            *axisval_raw = double_to_fp3232(ev->valuators.data_raw[i]);
782            axisval++;
783            axisval_raw++;
784        }
785    }
786
787    return Success;
788}
789
790static int
791eventToBarrierEvent(BarrierEvent *ev, xEvent **xi)
792{
793    xXIBarrierEvent *barrier;
794    int len = sizeof(xXIBarrierEvent);
795
796    *xi = calloc(1, len);
797    barrier = (xXIBarrierEvent*) *xi;
798    barrier->type = GenericEvent;
799    barrier->extension = IReqCode;
800    barrier->evtype = GetXI2Type(ev->type);
801    barrier->length = bytes_to_int32(len - sizeof(xEvent));
802    barrier->deviceid = ev->deviceid;
803    barrier->sourceid = ev->sourceid;
804    barrier->time = ev->time;
805    barrier->event = ev->window;
806    barrier->root = ev->root;
807    barrier->dx = double_to_fp3232(ev->dx);
808    barrier->dy = double_to_fp3232(ev->dy);
809    barrier->dtime = ev->dt;
810    barrier->flags = ev->flags;
811    barrier->eventid = ev->event_id;
812    barrier->barrier = ev->barrierid;
813    barrier->root_x = double_to_fp1616(ev->root_x);
814    barrier->root_y = double_to_fp1616(ev->root_y);
815
816    return Success;
817}
818
819/**
820 * Return the corresponding core type for the given event or 0 if no core
821 * equivalent exists.
822 */
823int
824GetCoreType(enum EventType type)
825{
826    int coretype = 0;
827
828    switch (type) {
829    case ET_Motion:
830        coretype = MotionNotify;
831        break;
832    case ET_ButtonPress:
833        coretype = ButtonPress;
834        break;
835    case ET_ButtonRelease:
836        coretype = ButtonRelease;
837        break;
838    case ET_KeyPress:
839        coretype = KeyPress;
840        break;
841    case ET_KeyRelease:
842        coretype = KeyRelease;
843        break;
844    default:
845        break;
846    }
847    return coretype;
848}
849
850/**
851 * Return the corresponding XI 1.x type for the given event or 0 if no
852 * equivalent exists.
853 */
854int
855GetXIType(enum EventType type)
856{
857    int xitype = 0;
858
859    switch (type) {
860    case ET_Motion:
861        xitype = DeviceMotionNotify;
862        break;
863    case ET_ButtonPress:
864        xitype = DeviceButtonPress;
865        break;
866    case ET_ButtonRelease:
867        xitype = DeviceButtonRelease;
868        break;
869    case ET_KeyPress:
870        xitype = DeviceKeyPress;
871        break;
872    case ET_KeyRelease:
873        xitype = DeviceKeyRelease;
874        break;
875    case ET_ProximityIn:
876        xitype = ProximityIn;
877        break;
878    case ET_ProximityOut:
879        xitype = ProximityOut;
880        break;
881    default:
882        break;
883    }
884    return xitype;
885}
886
887/**
888 * Return the corresponding XI 2.x type for the given event or 0 if no
889 * equivalent exists.
890 */
891int
892GetXI2Type(enum EventType type)
893{
894    int xi2type = 0;
895
896    switch (type) {
897    case ET_Motion:
898        xi2type = XI_Motion;
899        break;
900    case ET_ButtonPress:
901        xi2type = XI_ButtonPress;
902        break;
903    case ET_ButtonRelease:
904        xi2type = XI_ButtonRelease;
905        break;
906    case ET_KeyPress:
907        xi2type = XI_KeyPress;
908        break;
909    case ET_KeyRelease:
910        xi2type = XI_KeyRelease;
911        break;
912    case ET_Enter:
913        xi2type = XI_Enter;
914        break;
915    case ET_Leave:
916        xi2type = XI_Leave;
917        break;
918    case ET_Hierarchy:
919        xi2type = XI_HierarchyChanged;
920        break;
921    case ET_DeviceChanged:
922        xi2type = XI_DeviceChanged;
923        break;
924    case ET_RawKeyPress:
925        xi2type = XI_RawKeyPress;
926        break;
927    case ET_RawKeyRelease:
928        xi2type = XI_RawKeyRelease;
929        break;
930    case ET_RawButtonPress:
931        xi2type = XI_RawButtonPress;
932        break;
933    case ET_RawButtonRelease:
934        xi2type = XI_RawButtonRelease;
935        break;
936    case ET_RawMotion:
937        xi2type = XI_RawMotion;
938        break;
939    case ET_RawTouchBegin:
940        xi2type = XI_RawTouchBegin;
941        break;
942    case ET_RawTouchUpdate:
943        xi2type = XI_RawTouchUpdate;
944        break;
945    case ET_RawTouchEnd:
946        xi2type = XI_RawTouchEnd;
947        break;
948    case ET_FocusIn:
949        xi2type = XI_FocusIn;
950        break;
951    case ET_FocusOut:
952        xi2type = XI_FocusOut;
953        break;
954    case ET_TouchBegin:
955        xi2type = XI_TouchBegin;
956        break;
957    case ET_TouchEnd:
958        xi2type = XI_TouchEnd;
959        break;
960    case ET_TouchUpdate:
961        xi2type = XI_TouchUpdate;
962        break;
963    case ET_TouchOwnership:
964        xi2type = XI_TouchOwnership;
965        break;
966    case ET_BarrierHit:
967        xi2type = XI_BarrierHit;
968        break;
969    case ET_BarrierLeave:
970        xi2type = XI_BarrierLeave;
971        break;
972    default:
973        break;
974    }
975    return xi2type;
976}
977