eventconvert.c revision 1b5d61b8
16747b715Smrg/*
26747b715Smrg * Copyright © 2009 Red Hat, Inc.
36747b715Smrg *
46747b715Smrg * Permission is hereby granted, free of charge, to any person obtaining a
56747b715Smrg * copy of this software and associated documentation files (the "Software"),
66747b715Smrg * to deal in the Software without restriction, including without limitation
76747b715Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
86747b715Smrg * and/or sell copies of the Software, and to permit persons to whom the
96747b715Smrg * Software is furnished to do so, subject to the following conditions:
106747b715Smrg *
116747b715Smrg * The above copyright notice and this permission notice (including the next
126747b715Smrg * paragraph) shall be included in all copies or substantial portions of the
136747b715Smrg * Software.
146747b715Smrg *
156747b715Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
166747b715Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
176747b715Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
186747b715Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
196747b715Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
206747b715Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
216747b715Smrg * DEALINGS IN THE SOFTWARE.
226747b715Smrg *
236747b715Smrg */
246747b715Smrg
256747b715Smrg/**
266747b715Smrg * @file eventconvert.c
276747b715Smrg * This file contains event conversion routines from InternalEvent to the
286747b715Smrg * matching protocol events.
296747b715Smrg */
306747b715Smrg
316747b715Smrg#ifdef HAVE_DIX_CONFIG_H
326747b715Smrg#include <dix-config.h>
336747b715Smrg#endif
346747b715Smrg
356747b715Smrg#include <stdint.h>
366747b715Smrg#include <X11/X.h>
376747b715Smrg#include <X11/extensions/XIproto.h>
386747b715Smrg#include <X11/extensions/XI2proto.h>
396747b715Smrg#include <X11/extensions/XI.h>
406747b715Smrg#include <X11/extensions/XI2.h>
416747b715Smrg
426747b715Smrg#include "dix.h"
436747b715Smrg#include "inputstr.h"
446747b715Smrg#include "misc.h"
456747b715Smrg#include "eventstr.h"
4635c4bbdfSmrg#include "exevents.h"
476747b715Smrg#include "exglobals.h"
486747b715Smrg#include "eventconvert.h"
4935c4bbdfSmrg#include "inpututils.h"
506747b715Smrg#include "xiquerydevice.h"
516747b715Smrg#include "xkbsrv.h"
5235c4bbdfSmrg#include "inpututils.h"
536747b715Smrg
546747b715Smrgstatic int countValuators(DeviceEvent *ev, int *first);
5535c4bbdfSmrgstatic int getValuatorEvents(DeviceEvent *ev, deviceValuator * xv);
566747b715Smrgstatic int eventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count);
576747b715Smrgstatic int eventToDeviceChanged(DeviceChangedEvent *ev, xEvent **dcce);
586747b715Smrgstatic int eventToDeviceEvent(DeviceEvent *ev, xEvent **xi);
596747b715Smrgstatic int eventToRawEvent(RawDeviceEvent *ev, xEvent **xi);
6035c4bbdfSmrgstatic int eventToBarrierEvent(BarrierEvent *ev, xEvent **xi);
6135c4bbdfSmrgstatic int eventToTouchOwnershipEvent(TouchOwnershipEvent *ev, xEvent **xi);
626747b715Smrg
636747b715Smrg/* Do not use, read comments below */
646747b715SmrgBOOL EventIsKeyRepeat(xEvent *event);
656747b715Smrg
666747b715Smrg/**
676747b715Smrg * Hack to allow detectable autorepeat for core and XI1 events.
686747b715Smrg * The sequence number is unused until we send to the client and can be
696747b715Smrg * misused to store data. More or less, anyway.
706747b715Smrg *
716747b715Smrg * Do not use this. It may change any time without warning, eat your babies
726747b715Smrg * and piss on your cat.
736747b715Smrg */
746747b715Smrgstatic void
756747b715SmrgEventSetKeyRepeatFlag(xEvent *event, BOOL on)
766747b715Smrg{
776747b715Smrg    event->u.u.sequenceNumber = on;
786747b715Smrg}
796747b715Smrg
806747b715Smrg/**
816747b715Smrg * Check if the event was marked as a repeat event before.
826747b715Smrg * NOTE: This is a nasty hack and should NOT be used by anyone else but
836747b715Smrg * TryClientEvents.
846747b715Smrg */
856747b715SmrgBOOL
866747b715SmrgEventIsKeyRepeat(xEvent *event)
876747b715Smrg{
8835c4bbdfSmrg    return ! !event->u.u.sequenceNumber;
896747b715Smrg}
906747b715Smrg
916747b715Smrg/**
926747b715Smrg * Convert the given event to the respective core event.
936747b715Smrg *
946747b715Smrg * Return values:
956747b715Smrg * Success ... core contains the matching core event.
966747b715Smrg * BadValue .. One or more values in the internal event are invalid.
976747b715Smrg * BadMatch .. The event has no core equivalent.
986747b715Smrg *
996747b715Smrg * @param[in] event The event to convert into a core event.
1006747b715Smrg * @param[in] core The memory location to store the core event at.
1016747b715Smrg * @return Success or the matching error code.
1026747b715Smrg */
1036747b715Smrgint
10435c4bbdfSmrgEventToCore(InternalEvent *event, xEvent **core_out, int *count_out)
1056747b715Smrg{
10635c4bbdfSmrg    xEvent *core = NULL;
10735c4bbdfSmrg    int count = 0;
10835c4bbdfSmrg    int ret = BadImplementation;
10935c4bbdfSmrg
11035c4bbdfSmrg    switch (event->any.type) {
11135c4bbdfSmrg    case ET_Motion:
1126747b715Smrg    {
11335c4bbdfSmrg        DeviceEvent *e = &event->device_event;
11435c4bbdfSmrg
11535c4bbdfSmrg        /* Don't create core motion event if neither x nor y are
11635c4bbdfSmrg         * present */
11735c4bbdfSmrg        if (!BitIsOn(e->valuators.mask, 0) && !BitIsOn(e->valuators.mask, 1)) {
11835c4bbdfSmrg            ret = BadMatch;
11935c4bbdfSmrg            goto out;
12035c4bbdfSmrg        }
1216747b715Smrg    }
12235c4bbdfSmrg        /* fallthrough */
12335c4bbdfSmrg    case ET_ButtonPress:
12435c4bbdfSmrg    case ET_ButtonRelease:
12535c4bbdfSmrg    case ET_KeyPress:
12635c4bbdfSmrg    case ET_KeyRelease:
12735c4bbdfSmrg    {
12835c4bbdfSmrg        DeviceEvent *e = &event->device_event;
12935c4bbdfSmrg
13035c4bbdfSmrg        if (e->detail.key > 0xFF) {
13135c4bbdfSmrg            ret = BadMatch;
13235c4bbdfSmrg            goto out;
13335c4bbdfSmrg        }
13435c4bbdfSmrg
13535c4bbdfSmrg        core = calloc(1, sizeof(*core));
13635c4bbdfSmrg        if (!core)
13735c4bbdfSmrg            return BadAlloc;
13835c4bbdfSmrg        count = 1;
13935c4bbdfSmrg        core->u.u.type = e->type - ET_KeyPress + KeyPress;
14035c4bbdfSmrg        core->u.u.detail = e->detail.key & 0xFF;
14135c4bbdfSmrg        core->u.keyButtonPointer.time = e->time;
14235c4bbdfSmrg        core->u.keyButtonPointer.rootX = e->root_x;
14335c4bbdfSmrg        core->u.keyButtonPointer.rootY = e->root_y;
14435c4bbdfSmrg        core->u.keyButtonPointer.state = e->corestate;
14535c4bbdfSmrg        core->u.keyButtonPointer.root = e->root;
14635c4bbdfSmrg        EventSetKeyRepeatFlag(core, (e->type == ET_KeyPress && e->key_repeat));
14735c4bbdfSmrg        ret = Success;
14835c4bbdfSmrg    }
14935c4bbdfSmrg        break;
15035c4bbdfSmrg    case ET_ProximityIn:
15135c4bbdfSmrg    case ET_ProximityOut:
15235c4bbdfSmrg    case ET_RawKeyPress:
15335c4bbdfSmrg    case ET_RawKeyRelease:
15435c4bbdfSmrg    case ET_RawButtonPress:
15535c4bbdfSmrg    case ET_RawButtonRelease:
15635c4bbdfSmrg    case ET_RawMotion:
15735c4bbdfSmrg    case ET_RawTouchBegin:
15835c4bbdfSmrg    case ET_RawTouchUpdate:
15935c4bbdfSmrg    case ET_RawTouchEnd:
16035c4bbdfSmrg    case ET_TouchBegin:
16135c4bbdfSmrg    case ET_TouchUpdate:
16235c4bbdfSmrg    case ET_TouchEnd:
16335c4bbdfSmrg    case ET_TouchOwnership:
16435c4bbdfSmrg    case ET_BarrierHit:
16535c4bbdfSmrg    case ET_BarrierLeave:
16635c4bbdfSmrg        ret = BadMatch;
16735c4bbdfSmrg        break;
16835c4bbdfSmrg    default:
16935c4bbdfSmrg        /* XXX: */
17035c4bbdfSmrg        ErrorF("[dix] EventToCore: Not implemented yet \n");
17135c4bbdfSmrg        ret = BadImplementation;
17235c4bbdfSmrg    }
17335c4bbdfSmrg
17435c4bbdfSmrg out:
17535c4bbdfSmrg    *core_out = core;
17635c4bbdfSmrg    *count_out = count;
17735c4bbdfSmrg    return ret;
1786747b715Smrg}
1796747b715Smrg
1806747b715Smrg/**
1816747b715Smrg * Convert the given event to the respective XI 1.x event and store it in
1826747b715Smrg * xi. xi is allocated on demand and must be freed by the caller.
1836747b715Smrg * count returns the number of events in xi. If count is 1, and the type of
1846747b715Smrg * xi is GenericEvent, then xi may be larger than 32 bytes.
1856747b715Smrg *
1866747b715Smrg * Return values:
1876747b715Smrg * Success ... core contains the matching core event.
1886747b715Smrg * BadValue .. One or more values in the internal event are invalid.
1896747b715Smrg * BadMatch .. The event has no XI equivalent.
1906747b715Smrg *
1916747b715Smrg * @param[in] ev The event to convert into an XI 1 event.
1926747b715Smrg * @param[out] xi Future memory location for the XI event.
1936747b715Smrg * @param[out] count Number of elements in xi.
1946747b715Smrg *
1956747b715Smrg * @return Success or the error code.
1966747b715Smrg */
1976747b715Smrgint
1986747b715SmrgEventToXI(InternalEvent *ev, xEvent **xi, int *count)
1996747b715Smrg{
20035c4bbdfSmrg    switch (ev->any.type) {
20135c4bbdfSmrg    case ET_Motion:
20235c4bbdfSmrg    case ET_ButtonPress:
20335c4bbdfSmrg    case ET_ButtonRelease:
20435c4bbdfSmrg    case ET_KeyPress:
20535c4bbdfSmrg    case ET_KeyRelease:
20635c4bbdfSmrg    case ET_ProximityIn:
20735c4bbdfSmrg    case ET_ProximityOut:
20835c4bbdfSmrg        return eventToKeyButtonPointer(&ev->device_event, xi, count);
20935c4bbdfSmrg    case ET_DeviceChanged:
21035c4bbdfSmrg    case ET_RawKeyPress:
21135c4bbdfSmrg    case ET_RawKeyRelease:
21235c4bbdfSmrg    case ET_RawButtonPress:
21335c4bbdfSmrg    case ET_RawButtonRelease:
21435c4bbdfSmrg    case ET_RawMotion:
21535c4bbdfSmrg    case ET_RawTouchBegin:
21635c4bbdfSmrg    case ET_RawTouchUpdate:
21735c4bbdfSmrg    case ET_RawTouchEnd:
21835c4bbdfSmrg    case ET_TouchBegin:
21935c4bbdfSmrg    case ET_TouchUpdate:
22035c4bbdfSmrg    case ET_TouchEnd:
22135c4bbdfSmrg    case ET_TouchOwnership:
22235c4bbdfSmrg    case ET_BarrierHit:
22335c4bbdfSmrg    case ET_BarrierLeave:
22435c4bbdfSmrg        *count = 0;
22535c4bbdfSmrg        *xi = NULL;
22635c4bbdfSmrg        return BadMatch;
22735c4bbdfSmrg    default:
22835c4bbdfSmrg        break;
2296747b715Smrg    }
2306747b715Smrg
2316747b715Smrg    ErrorF("[dix] EventToXI: Not implemented for %d \n", ev->any.type);
2326747b715Smrg    return BadImplementation;
2336747b715Smrg}
2346747b715Smrg
2356747b715Smrg/**
2366747b715Smrg * Convert the given event to the respective XI 2.x event and store it in xi.
2376747b715Smrg * xi is allocated on demand and must be freed by the caller.
2386747b715Smrg *
2396747b715Smrg * Return values:
2406747b715Smrg * Success ... core contains the matching core event.
2416747b715Smrg * BadValue .. One or more values in the internal event are invalid.
2426747b715Smrg * BadMatch .. The event has no XI2 equivalent.
2436747b715Smrg *
2446747b715Smrg * @param[in] ev The event to convert into an XI2 event
2456747b715Smrg * @param[out] xi Future memory location for the XI2 event.
2466747b715Smrg *
2476747b715Smrg * @return Success or the error code.
2486747b715Smrg */
2496747b715Smrgint
2506747b715SmrgEventToXI2(InternalEvent *ev, xEvent **xi)
2516747b715Smrg{
25235c4bbdfSmrg    switch (ev->any.type) {
2536747b715Smrg        /* Enter/FocusIn are for grabs. We don't need an actual event, since
2546747b715Smrg         * the real events delivered are triggered elsewhere */
25535c4bbdfSmrg    case ET_Enter:
25635c4bbdfSmrg    case ET_FocusIn:
25735c4bbdfSmrg        *xi = NULL;
25835c4bbdfSmrg        return Success;
25935c4bbdfSmrg    case ET_Motion:
26035c4bbdfSmrg    case ET_ButtonPress:
26135c4bbdfSmrg    case ET_ButtonRelease:
26235c4bbdfSmrg    case ET_KeyPress:
26335c4bbdfSmrg    case ET_KeyRelease:
26435c4bbdfSmrg    case ET_TouchBegin:
26535c4bbdfSmrg    case ET_TouchUpdate:
26635c4bbdfSmrg    case ET_TouchEnd:
26735c4bbdfSmrg        return eventToDeviceEvent(&ev->device_event, xi);
26835c4bbdfSmrg    case ET_TouchOwnership:
26935c4bbdfSmrg        return eventToTouchOwnershipEvent(&ev->touch_ownership_event, xi);
27035c4bbdfSmrg    case ET_ProximityIn:
27135c4bbdfSmrg    case ET_ProximityOut:
27235c4bbdfSmrg        *xi = NULL;
27335c4bbdfSmrg        return BadMatch;
27435c4bbdfSmrg    case ET_DeviceChanged:
27535c4bbdfSmrg        return eventToDeviceChanged(&ev->changed_event, xi);
27635c4bbdfSmrg    case ET_RawKeyPress:
27735c4bbdfSmrg    case ET_RawKeyRelease:
27835c4bbdfSmrg    case ET_RawButtonPress:
27935c4bbdfSmrg    case ET_RawButtonRelease:
28035c4bbdfSmrg    case ET_RawMotion:
28135c4bbdfSmrg    case ET_RawTouchBegin:
28235c4bbdfSmrg    case ET_RawTouchUpdate:
28335c4bbdfSmrg    case ET_RawTouchEnd:
28435c4bbdfSmrg        return eventToRawEvent(&ev->raw_event, xi);
28535c4bbdfSmrg    case ET_BarrierHit:
28635c4bbdfSmrg    case ET_BarrierLeave:
28735c4bbdfSmrg        return eventToBarrierEvent(&ev->barrier_event, xi);
28835c4bbdfSmrg    default:
28935c4bbdfSmrg        break;
2906747b715Smrg    }
2916747b715Smrg
2926747b715Smrg    ErrorF("[dix] EventToXI2: Not implemented for %d \n", ev->any.type);
2936747b715Smrg    return BadImplementation;
2946747b715Smrg}
2956747b715Smrg
2966747b715Smrgstatic int
2976747b715SmrgeventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count)
2986747b715Smrg{
2996747b715Smrg    int num_events;
30035c4bbdfSmrg    int first;                  /* dummy */
3016747b715Smrg    deviceKeyButtonPointer *kbp;
3026747b715Smrg
3036747b715Smrg    /* Sorry, XI 1.x protocol restrictions. */
30435c4bbdfSmrg    if (ev->detail.button > 0xFF || ev->deviceid >= 0x80) {
3056747b715Smrg        *count = 0;
3066747b715Smrg        return Success;
3076747b715Smrg    }
3086747b715Smrg
30935c4bbdfSmrg    num_events = (countValuators(ev, &first) + 5) / 6;  /* valuator ev */
31035c4bbdfSmrg    if (num_events <= 0) {
31135c4bbdfSmrg        switch (ev->type) {
31235c4bbdfSmrg        case ET_KeyPress:
31335c4bbdfSmrg        case ET_KeyRelease:
31435c4bbdfSmrg        case ET_ButtonPress:
31535c4bbdfSmrg        case ET_ButtonRelease:
31635c4bbdfSmrg            /* no axes is ok */
31735c4bbdfSmrg            break;
31835c4bbdfSmrg        case ET_Motion:
31935c4bbdfSmrg        case ET_ProximityIn:
32035c4bbdfSmrg        case ET_ProximityOut:
32135c4bbdfSmrg            *count = 0;
32235c4bbdfSmrg            return BadMatch;
32335c4bbdfSmrg        default:
32435c4bbdfSmrg            *count = 0;
32535c4bbdfSmrg            return BadImplementation;
3269ace9065Smrg        }
3279ace9065Smrg    }
3289ace9065Smrg
32935c4bbdfSmrg    num_events++;               /* the actual event event */
3306747b715Smrg
3316747b715Smrg    *xi = calloc(num_events, sizeof(xEvent));
33235c4bbdfSmrg    if (!(*xi)) {
3336747b715Smrg        return BadAlloc;
3346747b715Smrg    }
3356747b715Smrg
33635c4bbdfSmrg    kbp = (deviceKeyButtonPointer *) (*xi);
33735c4bbdfSmrg    kbp->detail = ev->detail.button;
33835c4bbdfSmrg    kbp->time = ev->time;
33935c4bbdfSmrg    kbp->root = ev->root;
34035c4bbdfSmrg    kbp->root_x = ev->root_x;
34135c4bbdfSmrg    kbp->root_y = ev->root_y;
3426747b715Smrg    kbp->deviceid = ev->deviceid;
34335c4bbdfSmrg    kbp->state = ev->corestate;
34435c4bbdfSmrg    EventSetKeyRepeatFlag((xEvent *) kbp,
3456747b715Smrg                          (ev->type == ET_KeyPress && ev->key_repeat));
3466747b715Smrg
3476747b715Smrg    if (num_events > 1)
3486747b715Smrg        kbp->deviceid |= MORE_EVENTS;
3496747b715Smrg
35035c4bbdfSmrg    switch (ev->type) {
35135c4bbdfSmrg    case ET_Motion:
35235c4bbdfSmrg        kbp->type = DeviceMotionNotify;
35335c4bbdfSmrg        break;
35435c4bbdfSmrg    case ET_ButtonPress:
35535c4bbdfSmrg        kbp->type = DeviceButtonPress;
35635c4bbdfSmrg        break;
35735c4bbdfSmrg    case ET_ButtonRelease:
35835c4bbdfSmrg        kbp->type = DeviceButtonRelease;
35935c4bbdfSmrg        break;
36035c4bbdfSmrg    case ET_KeyPress:
36135c4bbdfSmrg        kbp->type = DeviceKeyPress;
36235c4bbdfSmrg        break;
36335c4bbdfSmrg    case ET_KeyRelease:
36435c4bbdfSmrg        kbp->type = DeviceKeyRelease;
36535c4bbdfSmrg        break;
36635c4bbdfSmrg    case ET_ProximityIn:
36735c4bbdfSmrg        kbp->type = ProximityIn;
36835c4bbdfSmrg        break;
36935c4bbdfSmrg    case ET_ProximityOut:
37035c4bbdfSmrg        kbp->type = ProximityOut;
37135c4bbdfSmrg        break;
37235c4bbdfSmrg    default:
37335c4bbdfSmrg        break;
3746747b715Smrg    }
3756747b715Smrg
37635c4bbdfSmrg    if (num_events > 1) {
37735c4bbdfSmrg        getValuatorEvents(ev, (deviceValuator *) (kbp + 1));
3786747b715Smrg    }
3796747b715Smrg
3806747b715Smrg    *count = num_events;
3816747b715Smrg    return Success;
3826747b715Smrg}
3836747b715Smrg
3846747b715Smrg/**
3856747b715Smrg * Set first to the first valuator in the event ev and return the number of
3866747b715Smrg * valuators from first to the last set valuator.
3876747b715Smrg */
3886747b715Smrgstatic int
3896747b715SmrgcountValuators(DeviceEvent *ev, int *first)
3906747b715Smrg{
3916747b715Smrg    int first_valuator = -1, last_valuator = -1, num_valuators = 0;
3926747b715Smrg    int i;
3936747b715Smrg
39435c4bbdfSmrg    for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++) {
39535c4bbdfSmrg        if (BitIsOn(ev->valuators.mask, i)) {
3966747b715Smrg            if (first_valuator == -1)
3976747b715Smrg                first_valuator = i;
3986747b715Smrg            last_valuator = i;
3996747b715Smrg        }
4006747b715Smrg    }
4016747b715Smrg
40235c4bbdfSmrg    if (first_valuator != -1) {
4036747b715Smrg        num_valuators = last_valuator - first_valuator + 1;
4046747b715Smrg        *first = first_valuator;
4056747b715Smrg    }
4066747b715Smrg
4076747b715Smrg    return num_valuators;
4086747b715Smrg}
4096747b715Smrg
4106747b715Smrgstatic int
41135c4bbdfSmrggetValuatorEvents(DeviceEvent *ev, deviceValuator * xv)
4126747b715Smrg{
4136747b715Smrg    int i;
4146747b715Smrg    int state = 0;
4156747b715Smrg    int first_valuator, num_valuators;
4166747b715Smrg
4176747b715Smrg    num_valuators = countValuators(ev, &first_valuator);
41835c4bbdfSmrg    if (num_valuators > 0) {
4196747b715Smrg        DeviceIntPtr dev = NULL;
42035c4bbdfSmrg
4216747b715Smrg        dixLookupDevice(&dev, ev->deviceid, serverClient, DixUseAccess);
4226747b715Smrg        /* State needs to be assembled BEFORE the device is updated. */
42335c4bbdfSmrg        state = (dev &&
42435c4bbdfSmrg                 dev->key) ? XkbStateFieldFromRec(&dev->key->xkbInfo->
42535c4bbdfSmrg                                                  state) : 0;
4266747b715Smrg        state |= (dev && dev->button) ? (dev->button->state) : 0;
4276747b715Smrg    }
4286747b715Smrg
4296747b715Smrg    for (i = 0; i < num_valuators; i += 6, xv++) {
43035c4bbdfSmrg        INT32 *valuators = &xv->valuator0;      // Treat all 6 vals as an array
4319ace9065Smrg        int j;
4329ace9065Smrg
4336747b715Smrg        xv->type = DeviceValuator;
4346747b715Smrg        xv->first_valuator = first_valuator + i;
4356747b715Smrg        xv->num_valuators = ((num_valuators - i) > 6) ? 6 : (num_valuators - i);
4366747b715Smrg        xv->deviceid = ev->deviceid;
4376747b715Smrg        xv->device_state = state;
4389ace9065Smrg
4399ace9065Smrg        /* Unset valuators in masked valuator events have the proper data values
4409ace9065Smrg         * in the case of an absolute axis in between two set valuators. */
4419ace9065Smrg        for (j = 0; j < xv->num_valuators; j++)
4429ace9065Smrg            valuators[j] = ev->valuators.data[xv->first_valuator + j];
4436747b715Smrg
4446747b715Smrg        if (i + 6 < num_valuators)
4456747b715Smrg            xv->deviceid |= MORE_EVENTS;
4466747b715Smrg    }
4476747b715Smrg
4486747b715Smrg    return (num_valuators + 5) / 6;
4496747b715Smrg}
4506747b715Smrg
4516747b715Smrgstatic int
45235c4bbdfSmrgappendKeyInfo(DeviceChangedEvent *dce, xXIKeyInfo * info)
4536747b715Smrg{
4546747b715Smrg    uint32_t *kc;
4556747b715Smrg    int i;
4566747b715Smrg
4576747b715Smrg    info->type = XIKeyClass;
4586747b715Smrg    info->num_keycodes = dce->keys.max_keycode - dce->keys.min_keycode + 1;
45935c4bbdfSmrg    info->length = sizeof(xXIKeyInfo) / 4 + info->num_keycodes;
4606747b715Smrg    info->sourceid = dce->sourceid;
4616747b715Smrg
46235c4bbdfSmrg    kc = (uint32_t *) &info[1];
4636747b715Smrg    for (i = 0; i < info->num_keycodes; i++)
4646747b715Smrg        *kc++ = i + dce->keys.min_keycode;
4656747b715Smrg
4666747b715Smrg    return info->length * 4;
4676747b715Smrg}
4686747b715Smrg
4696747b715Smrgstatic int
47035c4bbdfSmrgappendButtonInfo(DeviceChangedEvent *dce, xXIButtonInfo * info)
4716747b715Smrg{
4726747b715Smrg    unsigned char *bits;
4736747b715Smrg    int mask_len;
4746747b715Smrg
4756747b715Smrg    mask_len = bytes_to_int32(bits_to_bytes(dce->buttons.num_buttons));
4766747b715Smrg
4776747b715Smrg    info->type = XIButtonClass;
4786747b715Smrg    info->num_buttons = dce->buttons.num_buttons;
4796747b715Smrg    info->length = bytes_to_int32(sizeof(xXIButtonInfo)) +
48035c4bbdfSmrg        info->num_buttons + mask_len;
4816747b715Smrg    info->sourceid = dce->sourceid;
4826747b715Smrg
48335c4bbdfSmrg    bits = (unsigned char *) &info[1];
4846747b715Smrg    memset(bits, 0, mask_len * 4);
4856747b715Smrg    /* FIXME: is_down? */
4866747b715Smrg
4876747b715Smrg    bits += mask_len * 4;
4886747b715Smrg    memcpy(bits, dce->buttons.names, dce->buttons.num_buttons * sizeof(Atom));
4896747b715Smrg
4906747b715Smrg    return info->length * 4;
4916747b715Smrg}
4926747b715Smrg
4936747b715Smrgstatic int
49435c4bbdfSmrgappendValuatorInfo(DeviceChangedEvent *dce, xXIValuatorInfo * info,
49535c4bbdfSmrg                   int axisnumber)
4966747b715Smrg{
4976747b715Smrg    info->type = XIValuatorClass;
49835c4bbdfSmrg    info->length = sizeof(xXIValuatorInfo) / 4;
4996747b715Smrg    info->label = dce->valuators[axisnumber].name;
5006747b715Smrg    info->min.integral = dce->valuators[axisnumber].min;
5016747b715Smrg    info->min.frac = 0;
5026747b715Smrg    info->max.integral = dce->valuators[axisnumber].max;
5036747b715Smrg    info->max.frac = 0;
50435c4bbdfSmrg    info->value = double_to_fp3232(dce->valuators[axisnumber].value);
5056747b715Smrg    info->resolution = dce->valuators[axisnumber].resolution;
5066747b715Smrg    info->number = axisnumber;
5079ace9065Smrg    info->mode = dce->valuators[axisnumber].mode;
5086747b715Smrg    info->sourceid = dce->sourceid;
5096747b715Smrg
5106747b715Smrg    return info->length * 4;
5116747b715Smrg}
5126747b715Smrg
51335c4bbdfSmrgstatic int
51435c4bbdfSmrgappendScrollInfo(DeviceChangedEvent *dce, xXIScrollInfo * info, int axisnumber)
51535c4bbdfSmrg{
51635c4bbdfSmrg    if (dce->valuators[axisnumber].scroll.type == SCROLL_TYPE_NONE)
51735c4bbdfSmrg        return 0;
51835c4bbdfSmrg
51935c4bbdfSmrg    info->type = XIScrollClass;
52035c4bbdfSmrg    info->length = sizeof(xXIScrollInfo) / 4;
52135c4bbdfSmrg    info->number = axisnumber;
52235c4bbdfSmrg    switch (dce->valuators[axisnumber].scroll.type) {
52335c4bbdfSmrg    case SCROLL_TYPE_VERTICAL:
52435c4bbdfSmrg        info->scroll_type = XIScrollTypeVertical;
52535c4bbdfSmrg        break;
52635c4bbdfSmrg    case SCROLL_TYPE_HORIZONTAL:
52735c4bbdfSmrg        info->scroll_type = XIScrollTypeHorizontal;
52835c4bbdfSmrg        break;
52935c4bbdfSmrg    default:
53035c4bbdfSmrg        ErrorF("[Xi] Unknown scroll type %d. This is a bug.\n",
53135c4bbdfSmrg               dce->valuators[axisnumber].scroll.type);
53235c4bbdfSmrg        break;
53335c4bbdfSmrg    }
53435c4bbdfSmrg    info->increment =
53535c4bbdfSmrg        double_to_fp3232(dce->valuators[axisnumber].scroll.increment);
53635c4bbdfSmrg    info->sourceid = dce->sourceid;
53735c4bbdfSmrg
53835c4bbdfSmrg    info->flags = 0;
53935c4bbdfSmrg
54035c4bbdfSmrg    if (dce->valuators[axisnumber].scroll.flags & SCROLL_FLAG_DONT_EMULATE)
54135c4bbdfSmrg        info->flags |= XIScrollFlagNoEmulation;
54235c4bbdfSmrg    if (dce->valuators[axisnumber].scroll.flags & SCROLL_FLAG_PREFERRED)
54335c4bbdfSmrg        info->flags |= XIScrollFlagPreferred;
54435c4bbdfSmrg
54535c4bbdfSmrg    return info->length * 4;
54635c4bbdfSmrg}
54735c4bbdfSmrg
5486747b715Smrgstatic int
5496747b715SmrgeventToDeviceChanged(DeviceChangedEvent *dce, xEvent **xi)
5506747b715Smrg{
5516747b715Smrg    xXIDeviceChangedEvent *dcce;
5526747b715Smrg    int len = sizeof(xXIDeviceChangedEvent);
5536747b715Smrg    int nkeys;
5546747b715Smrg    char *ptr;
5556747b715Smrg
55635c4bbdfSmrg    if (dce->buttons.num_buttons) {
5576747b715Smrg        len += sizeof(xXIButtonInfo);
5586747b715Smrg        len += dce->buttons.num_buttons * sizeof(Atom); /* button names */
5596747b715Smrg        len += pad_to_int32(bits_to_bytes(dce->buttons.num_buttons));
5606747b715Smrg    }
56135c4bbdfSmrg    if (dce->num_valuators) {
56235c4bbdfSmrg        int i;
56335c4bbdfSmrg
5646747b715Smrg        len += sizeof(xXIValuatorInfo) * dce->num_valuators;
5656747b715Smrg
56635c4bbdfSmrg        for (i = 0; i < dce->num_valuators; i++)
56735c4bbdfSmrg            if (dce->valuators[i].scroll.type != SCROLL_TYPE_NONE)
56835c4bbdfSmrg                len += sizeof(xXIScrollInfo);
56935c4bbdfSmrg    }
57035c4bbdfSmrg
5716747b715Smrg    nkeys = (dce->keys.max_keycode > 0) ?
57235c4bbdfSmrg        dce->keys.max_keycode - dce->keys.min_keycode + 1 : 0;
57335c4bbdfSmrg    if (nkeys > 0) {
5746747b715Smrg        len += sizeof(xXIKeyInfo);
57535c4bbdfSmrg        len += sizeof(CARD32) * nkeys;  /* keycodes */
5766747b715Smrg    }
5776747b715Smrg
5786747b715Smrg    dcce = calloc(1, len);
57935c4bbdfSmrg    if (!dcce) {
5806747b715Smrg        ErrorF("[Xi] BadAlloc in SendDeviceChangedEvent.\n");
5816747b715Smrg        return BadAlloc;
5826747b715Smrg    }
5836747b715Smrg
58435c4bbdfSmrg    dcce->type = GenericEvent;
58535c4bbdfSmrg    dcce->extension = IReqCode;
58635c4bbdfSmrg    dcce->evtype = XI_DeviceChanged;
58735c4bbdfSmrg    dcce->time = dce->time;
58835c4bbdfSmrg    dcce->deviceid = dce->deviceid;
58935c4bbdfSmrg    dcce->sourceid = dce->sourceid;
59035c4bbdfSmrg    dcce->reason =
59135c4bbdfSmrg        (dce->flags & DEVCHANGE_DEVICE_CHANGE) ? XIDeviceChange : XISlaveSwitch;
59235c4bbdfSmrg    dcce->num_classes = 0;
5936747b715Smrg    dcce->length = bytes_to_int32(len - sizeof(xEvent));
5946747b715Smrg
59535c4bbdfSmrg    ptr = (char *) &dcce[1];
59635c4bbdfSmrg    if (dce->buttons.num_buttons) {
5976747b715Smrg        dcce->num_classes++;
59835c4bbdfSmrg        ptr += appendButtonInfo(dce, (xXIButtonInfo *) ptr);
5996747b715Smrg    }
6006747b715Smrg
60135c4bbdfSmrg    if (nkeys) {
6026747b715Smrg        dcce->num_classes++;
60335c4bbdfSmrg        ptr += appendKeyInfo(dce, (xXIKeyInfo *) ptr);
6046747b715Smrg    }
6056747b715Smrg
60635c4bbdfSmrg    if (dce->num_valuators) {
6076747b715Smrg        int i;
6086747b715Smrg
6096747b715Smrg        dcce->num_classes += dce->num_valuators;
6106747b715Smrg        for (i = 0; i < dce->num_valuators; i++)
61135c4bbdfSmrg            ptr += appendValuatorInfo(dce, (xXIValuatorInfo *) ptr, i);
61235c4bbdfSmrg
61335c4bbdfSmrg        for (i = 0; i < dce->num_valuators; i++) {
61435c4bbdfSmrg            if (dce->valuators[i].scroll.type != SCROLL_TYPE_NONE) {
61535c4bbdfSmrg                dcce->num_classes++;
61635c4bbdfSmrg                ptr += appendScrollInfo(dce, (xXIScrollInfo *) ptr, i);
61735c4bbdfSmrg            }
61835c4bbdfSmrg        }
6196747b715Smrg    }
6206747b715Smrg
62135c4bbdfSmrg    *xi = (xEvent *) dcce;
6226747b715Smrg
6236747b715Smrg    return Success;
6246747b715Smrg}
6256747b715Smrg
62635c4bbdfSmrgstatic int
62735c4bbdfSmrgcount_bits(unsigned char *ptr, int len)
6286747b715Smrg{
6296747b715Smrg    int bits = 0;
6306747b715Smrg    unsigned int i;
6316747b715Smrg    unsigned char x;
6326747b715Smrg
63335c4bbdfSmrg    for (i = 0; i < len; i++) {
6346747b715Smrg        x = ptr[i];
63535c4bbdfSmrg        while (x > 0) {
6366747b715Smrg            bits += (x & 0x1);
6376747b715Smrg            x >>= 1;
6386747b715Smrg        }
6396747b715Smrg    }
6406747b715Smrg    return bits;
6416747b715Smrg}
6426747b715Smrg
6436747b715Smrgstatic int
6446747b715SmrgeventToDeviceEvent(DeviceEvent *ev, xEvent **xi)
6456747b715Smrg{
6466747b715Smrg    int len = sizeof(xXIDeviceEvent);
6476747b715Smrg    xXIDeviceEvent *xde;
6486747b715Smrg    int i, btlen, vallen;
6496747b715Smrg    char *ptr;
6506747b715Smrg    FP3232 *axisval;
6516747b715Smrg
6526747b715Smrg    /* FIXME: this should just send the buttons we have, not MAX_BUTTONs. Same
6536747b715Smrg     * with MAX_VALUATORS below */
6546747b715Smrg    /* btlen is in 4 byte units */
6556747b715Smrg    btlen = bytes_to_int32(bits_to_bytes(MAX_BUTTONS));
65635c4bbdfSmrg    len += btlen * 4;           /* buttonmask len */
6576747b715Smrg
6581b5d61b8Smrg    vallen = count_bits(ev->valuators.mask, ARRAY_SIZE(ev->valuators.mask));
65935c4bbdfSmrg    len += vallen * 2 * sizeof(uint32_t);       /* axisvalues */
6606747b715Smrg    vallen = bytes_to_int32(bits_to_bytes(MAX_VALUATORS));
66135c4bbdfSmrg    len += vallen * 4;          /* valuators mask */
6626747b715Smrg
6636747b715Smrg    *xi = calloc(1, len);
66435c4bbdfSmrg    xde = (xXIDeviceEvent *) * xi;
66535c4bbdfSmrg    xde->type = GenericEvent;
66635c4bbdfSmrg    xde->extension = IReqCode;
66735c4bbdfSmrg    xde->evtype = GetXI2Type(ev->type);
66835c4bbdfSmrg    xde->time = ev->time;
66935c4bbdfSmrg    xde->length = bytes_to_int32(len - sizeof(xEvent));
67035c4bbdfSmrg    if (IsTouchEvent((InternalEvent *) ev))
67135c4bbdfSmrg        xde->detail = ev->touchid;
67235c4bbdfSmrg    else
67335c4bbdfSmrg        xde->detail = ev->detail.button;
67435c4bbdfSmrg
67535c4bbdfSmrg    xde->root = ev->root;
67635c4bbdfSmrg    xde->buttons_len = btlen;
67735c4bbdfSmrg    xde->valuators_len = vallen;
67835c4bbdfSmrg    xde->deviceid = ev->deviceid;
67935c4bbdfSmrg    xde->sourceid = ev->sourceid;
68035c4bbdfSmrg    xde->root_x = double_to_fp1616(ev->root_x + ev->root_x_frac);
68135c4bbdfSmrg    xde->root_y = double_to_fp1616(ev->root_y + ev->root_y_frac);
68235c4bbdfSmrg
68335c4bbdfSmrg    if (IsTouchEvent((InternalEvent *)ev)) {
68435c4bbdfSmrg        if (ev->type == ET_TouchUpdate)
68535c4bbdfSmrg            xde->flags |= (ev->flags & TOUCH_PENDING_END) ? XITouchPendingEnd : 0;
68635c4bbdfSmrg
68735c4bbdfSmrg        if (ev->flags & TOUCH_POINTER_EMULATED)
68835c4bbdfSmrg            xde->flags |= XITouchEmulatingPointer;
68935c4bbdfSmrg    } else {
69035c4bbdfSmrg        xde->flags = ev->flags;
69135c4bbdfSmrg
69235c4bbdfSmrg        if (ev->key_repeat)
69335c4bbdfSmrg            xde->flags |= XIKeyRepeat;
69435c4bbdfSmrg    }
69535c4bbdfSmrg
69635c4bbdfSmrg    xde->mods.base_mods = ev->mods.base;
69735c4bbdfSmrg    xde->mods.latched_mods = ev->mods.latched;
69835c4bbdfSmrg    xde->mods.locked_mods = ev->mods.locked;
69935c4bbdfSmrg    xde->mods.effective_mods = ev->mods.effective;
70035c4bbdfSmrg
70135c4bbdfSmrg    xde->group.base_group = ev->group.base;
70235c4bbdfSmrg    xde->group.latched_group = ev->group.latched;
70335c4bbdfSmrg    xde->group.locked_group = ev->group.locked;
70435c4bbdfSmrg    xde->group.effective_group = ev->group.effective;
70535c4bbdfSmrg
70635c4bbdfSmrg    ptr = (char *) &xde[1];
70735c4bbdfSmrg    for (i = 0; i < sizeof(ev->buttons) * 8; i++) {
7086747b715Smrg        if (BitIsOn(ev->buttons, i))
7096747b715Smrg            SetBit(ptr, i);
7106747b715Smrg    }
7116747b715Smrg
7126747b715Smrg    ptr += xde->buttons_len * 4;
71335c4bbdfSmrg    axisval = (FP3232 *) (ptr + xde->valuators_len * 4);
71435c4bbdfSmrg    for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++) {
71535c4bbdfSmrg        if (BitIsOn(ev->valuators.mask, i)) {
7166747b715Smrg            SetBit(ptr, i);
71735c4bbdfSmrg            *axisval = double_to_fp3232(ev->valuators.data[i]);
7186747b715Smrg            axisval++;
7196747b715Smrg        }
7206747b715Smrg    }
7216747b715Smrg
7226747b715Smrg    return Success;
7236747b715Smrg}
7246747b715Smrg
72535c4bbdfSmrgstatic int
72635c4bbdfSmrgeventToTouchOwnershipEvent(TouchOwnershipEvent *ev, xEvent **xi)
72735c4bbdfSmrg{
72835c4bbdfSmrg    int len = sizeof(xXITouchOwnershipEvent);
72935c4bbdfSmrg    xXITouchOwnershipEvent *xtoe;
73035c4bbdfSmrg
73135c4bbdfSmrg    *xi = calloc(1, len);
73235c4bbdfSmrg    xtoe = (xXITouchOwnershipEvent *) * xi;
73335c4bbdfSmrg    xtoe->type = GenericEvent;
73435c4bbdfSmrg    xtoe->extension = IReqCode;
73535c4bbdfSmrg    xtoe->length = bytes_to_int32(len - sizeof(xEvent));
73635c4bbdfSmrg    xtoe->evtype = GetXI2Type(ev->type);
73735c4bbdfSmrg    xtoe->deviceid = ev->deviceid;
73835c4bbdfSmrg    xtoe->time = ev->time;
73935c4bbdfSmrg    xtoe->sourceid = ev->sourceid;
74035c4bbdfSmrg    xtoe->touchid = ev->touchid;
74135c4bbdfSmrg    xtoe->flags = 0;            /* we don't have wire flags for ownership yet */
74235c4bbdfSmrg
74335c4bbdfSmrg    return Success;
74435c4bbdfSmrg}
74535c4bbdfSmrg
7466747b715Smrgstatic int
7476747b715SmrgeventToRawEvent(RawDeviceEvent *ev, xEvent **xi)
7486747b715Smrg{
74935c4bbdfSmrg    xXIRawEvent *raw;
7506747b715Smrg    int vallen, nvals;
7516747b715Smrg    int i, len = sizeof(xXIRawEvent);
7526747b715Smrg    char *ptr;
75335c4bbdfSmrg    FP3232 *axisval, *axisval_raw;
7546747b715Smrg
7556747b715Smrg    nvals = count_bits(ev->valuators.mask, sizeof(ev->valuators.mask));
75635c4bbdfSmrg    len += nvals * sizeof(FP3232) * 2;  /* 8 byte per valuator, once
75735c4bbdfSmrg                                           raw, once processed */
7586747b715Smrg    vallen = bytes_to_int32(bits_to_bytes(MAX_VALUATORS));
75935c4bbdfSmrg    len += vallen * 4;          /* valuators mask */
7606747b715Smrg
7616747b715Smrg    *xi = calloc(1, len);
76235c4bbdfSmrg    raw = (xXIRawEvent *) * xi;
76335c4bbdfSmrg    raw->type = GenericEvent;
76435c4bbdfSmrg    raw->extension = IReqCode;
76535c4bbdfSmrg    raw->evtype = GetXI2Type(ev->type);
76635c4bbdfSmrg    raw->time = ev->time;
76735c4bbdfSmrg    raw->length = bytes_to_int32(len - sizeof(xEvent));
76835c4bbdfSmrg    raw->detail = ev->detail.button;
76935c4bbdfSmrg    raw->deviceid = ev->deviceid;
77035c4bbdfSmrg    raw->sourceid = ev->sourceid;
77135c4bbdfSmrg    raw->valuators_len = vallen;
77235c4bbdfSmrg    raw->flags = ev->flags;
77335c4bbdfSmrg
77435c4bbdfSmrg    ptr = (char *) &raw[1];
77535c4bbdfSmrg    axisval = (FP3232 *) (ptr + raw->valuators_len * 4);
77635c4bbdfSmrg    axisval_raw = axisval + nvals;
77735c4bbdfSmrg    for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++) {
77835c4bbdfSmrg        if (BitIsOn(ev->valuators.mask, i)) {
7796747b715Smrg            SetBit(ptr, i);
78035c4bbdfSmrg            *axisval = double_to_fp3232(ev->valuators.data[i]);
78135c4bbdfSmrg            *axisval_raw = double_to_fp3232(ev->valuators.data_raw[i]);
7826747b715Smrg            axisval++;
78335c4bbdfSmrg            axisval_raw++;
7846747b715Smrg        }
7856747b715Smrg    }
7866747b715Smrg
7876747b715Smrg    return Success;
7886747b715Smrg}
7896747b715Smrg
79035c4bbdfSmrgstatic int
79135c4bbdfSmrgeventToBarrierEvent(BarrierEvent *ev, xEvent **xi)
79235c4bbdfSmrg{
79335c4bbdfSmrg    xXIBarrierEvent *barrier;
79435c4bbdfSmrg    int len = sizeof(xXIBarrierEvent);
79535c4bbdfSmrg
79635c4bbdfSmrg    *xi = calloc(1, len);
79735c4bbdfSmrg    barrier = (xXIBarrierEvent*) *xi;
79835c4bbdfSmrg    barrier->type = GenericEvent;
79935c4bbdfSmrg    barrier->extension = IReqCode;
80035c4bbdfSmrg    barrier->evtype = GetXI2Type(ev->type);
80135c4bbdfSmrg    barrier->length = bytes_to_int32(len - sizeof(xEvent));
80235c4bbdfSmrg    barrier->deviceid = ev->deviceid;
80335c4bbdfSmrg    barrier->sourceid = ev->sourceid;
80435c4bbdfSmrg    barrier->time = ev->time;
80535c4bbdfSmrg    barrier->event = ev->window;
80635c4bbdfSmrg    barrier->root = ev->root;
80735c4bbdfSmrg    barrier->dx = double_to_fp3232(ev->dx);
80835c4bbdfSmrg    barrier->dy = double_to_fp3232(ev->dy);
80935c4bbdfSmrg    barrier->dtime = ev->dt;
81035c4bbdfSmrg    barrier->flags = ev->flags;
81135c4bbdfSmrg    barrier->eventid = ev->event_id;
81235c4bbdfSmrg    barrier->barrier = ev->barrierid;
81335c4bbdfSmrg    barrier->root_x = double_to_fp1616(ev->root_x);
81435c4bbdfSmrg    barrier->root_y = double_to_fp1616(ev->root_y);
81535c4bbdfSmrg
81635c4bbdfSmrg    return Success;
81735c4bbdfSmrg}
81835c4bbdfSmrg
8196747b715Smrg/**
8206747b715Smrg * Return the corresponding core type for the given event or 0 if no core
8216747b715Smrg * equivalent exists.
8226747b715Smrg */
8236747b715Smrgint
82435c4bbdfSmrgGetCoreType(enum EventType type)
8256747b715Smrg{
8266747b715Smrg    int coretype = 0;
82735c4bbdfSmrg
82835c4bbdfSmrg    switch (type) {
82935c4bbdfSmrg    case ET_Motion:
83035c4bbdfSmrg        coretype = MotionNotify;
83135c4bbdfSmrg        break;
83235c4bbdfSmrg    case ET_ButtonPress:
83335c4bbdfSmrg        coretype = ButtonPress;
83435c4bbdfSmrg        break;
83535c4bbdfSmrg    case ET_ButtonRelease:
83635c4bbdfSmrg        coretype = ButtonRelease;
83735c4bbdfSmrg        break;
83835c4bbdfSmrg    case ET_KeyPress:
83935c4bbdfSmrg        coretype = KeyPress;
84035c4bbdfSmrg        break;
84135c4bbdfSmrg    case ET_KeyRelease:
84235c4bbdfSmrg        coretype = KeyRelease;
84335c4bbdfSmrg        break;
84435c4bbdfSmrg    default:
84535c4bbdfSmrg        break;
8466747b715Smrg    }
8476747b715Smrg    return coretype;
8486747b715Smrg}
8496747b715Smrg
8506747b715Smrg/**
8516747b715Smrg * Return the corresponding XI 1.x type for the given event or 0 if no
8526747b715Smrg * equivalent exists.
8536747b715Smrg */
8546747b715Smrgint
85535c4bbdfSmrgGetXIType(enum EventType type)
8566747b715Smrg{
8576747b715Smrg    int xitype = 0;
85835c4bbdfSmrg
85935c4bbdfSmrg    switch (type) {
86035c4bbdfSmrg    case ET_Motion:
86135c4bbdfSmrg        xitype = DeviceMotionNotify;
86235c4bbdfSmrg        break;
86335c4bbdfSmrg    case ET_ButtonPress:
86435c4bbdfSmrg        xitype = DeviceButtonPress;
86535c4bbdfSmrg        break;
86635c4bbdfSmrg    case ET_ButtonRelease:
86735c4bbdfSmrg        xitype = DeviceButtonRelease;
86835c4bbdfSmrg        break;
86935c4bbdfSmrg    case ET_KeyPress:
87035c4bbdfSmrg        xitype = DeviceKeyPress;
87135c4bbdfSmrg        break;
87235c4bbdfSmrg    case ET_KeyRelease:
87335c4bbdfSmrg        xitype = DeviceKeyRelease;
87435c4bbdfSmrg        break;
87535c4bbdfSmrg    case ET_ProximityIn:
87635c4bbdfSmrg        xitype = ProximityIn;
87735c4bbdfSmrg        break;
87835c4bbdfSmrg    case ET_ProximityOut:
87935c4bbdfSmrg        xitype = ProximityOut;
88035c4bbdfSmrg        break;
88135c4bbdfSmrg    default:
88235c4bbdfSmrg        break;
8836747b715Smrg    }
8846747b715Smrg    return xitype;
8856747b715Smrg}
8866747b715Smrg
8876747b715Smrg/**
8886747b715Smrg * Return the corresponding XI 2.x type for the given event or 0 if no
8896747b715Smrg * equivalent exists.
8906747b715Smrg */
8916747b715Smrgint
89235c4bbdfSmrgGetXI2Type(enum EventType type)
8936747b715Smrg{
8946747b715Smrg    int xi2type = 0;
8956747b715Smrg
89635c4bbdfSmrg    switch (type) {
89735c4bbdfSmrg    case ET_Motion:
89835c4bbdfSmrg        xi2type = XI_Motion;
89935c4bbdfSmrg        break;
90035c4bbdfSmrg    case ET_ButtonPress:
90135c4bbdfSmrg        xi2type = XI_ButtonPress;
90235c4bbdfSmrg        break;
90335c4bbdfSmrg    case ET_ButtonRelease:
90435c4bbdfSmrg        xi2type = XI_ButtonRelease;
90535c4bbdfSmrg        break;
90635c4bbdfSmrg    case ET_KeyPress:
90735c4bbdfSmrg        xi2type = XI_KeyPress;
90835c4bbdfSmrg        break;
90935c4bbdfSmrg    case ET_KeyRelease:
91035c4bbdfSmrg        xi2type = XI_KeyRelease;
91135c4bbdfSmrg        break;
91235c4bbdfSmrg    case ET_Enter:
91335c4bbdfSmrg        xi2type = XI_Enter;
91435c4bbdfSmrg        break;
91535c4bbdfSmrg    case ET_Leave:
91635c4bbdfSmrg        xi2type = XI_Leave;
91735c4bbdfSmrg        break;
91835c4bbdfSmrg    case ET_Hierarchy:
91935c4bbdfSmrg        xi2type = XI_HierarchyChanged;
92035c4bbdfSmrg        break;
92135c4bbdfSmrg    case ET_DeviceChanged:
92235c4bbdfSmrg        xi2type = XI_DeviceChanged;
92335c4bbdfSmrg        break;
92435c4bbdfSmrg    case ET_RawKeyPress:
92535c4bbdfSmrg        xi2type = XI_RawKeyPress;
92635c4bbdfSmrg        break;
92735c4bbdfSmrg    case ET_RawKeyRelease:
92835c4bbdfSmrg        xi2type = XI_RawKeyRelease;
92935c4bbdfSmrg        break;
93035c4bbdfSmrg    case ET_RawButtonPress:
93135c4bbdfSmrg        xi2type = XI_RawButtonPress;
93235c4bbdfSmrg        break;
93335c4bbdfSmrg    case ET_RawButtonRelease:
93435c4bbdfSmrg        xi2type = XI_RawButtonRelease;
93535c4bbdfSmrg        break;
93635c4bbdfSmrg    case ET_RawMotion:
93735c4bbdfSmrg        xi2type = XI_RawMotion;
93835c4bbdfSmrg        break;
93935c4bbdfSmrg    case ET_RawTouchBegin:
94035c4bbdfSmrg        xi2type = XI_RawTouchBegin;
94135c4bbdfSmrg        break;
94235c4bbdfSmrg    case ET_RawTouchUpdate:
94335c4bbdfSmrg        xi2type = XI_RawTouchUpdate;
94435c4bbdfSmrg        break;
94535c4bbdfSmrg    case ET_RawTouchEnd:
94635c4bbdfSmrg        xi2type = XI_RawTouchEnd;
94735c4bbdfSmrg        break;
94835c4bbdfSmrg    case ET_FocusIn:
94935c4bbdfSmrg        xi2type = XI_FocusIn;
95035c4bbdfSmrg        break;
95135c4bbdfSmrg    case ET_FocusOut:
95235c4bbdfSmrg        xi2type = XI_FocusOut;
95335c4bbdfSmrg        break;
95435c4bbdfSmrg    case ET_TouchBegin:
95535c4bbdfSmrg        xi2type = XI_TouchBegin;
95635c4bbdfSmrg        break;
95735c4bbdfSmrg    case ET_TouchEnd:
95835c4bbdfSmrg        xi2type = XI_TouchEnd;
95935c4bbdfSmrg        break;
96035c4bbdfSmrg    case ET_TouchUpdate:
96135c4bbdfSmrg        xi2type = XI_TouchUpdate;
96235c4bbdfSmrg        break;
96335c4bbdfSmrg    case ET_TouchOwnership:
96435c4bbdfSmrg        xi2type = XI_TouchOwnership;
96535c4bbdfSmrg        break;
96635c4bbdfSmrg    case ET_BarrierHit:
96735c4bbdfSmrg        xi2type = XI_BarrierHit;
96835c4bbdfSmrg        break;
96935c4bbdfSmrg    case ET_BarrierLeave:
97035c4bbdfSmrg        xi2type = XI_BarrierLeave;
97135c4bbdfSmrg        break;
97235c4bbdfSmrg    default:
97335c4bbdfSmrg        break;
9746747b715Smrg    }
9756747b715Smrg    return xi2type;
9766747b715Smrg}
977