eventconvert.c revision 6747b715
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"
466747b715Smrg#include "exglobals.h"
476747b715Smrg#include "eventconvert.h"
486747b715Smrg#include "xiquerydevice.h"
496747b715Smrg#include "xkbsrv.h"
506747b715Smrg
516747b715Smrg
526747b715Smrgstatic int countValuators(DeviceEvent *ev, int *first);
536747b715Smrgstatic int getValuatorEvents(DeviceEvent *ev, deviceValuator *xv);
546747b715Smrgstatic int eventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count);
556747b715Smrgstatic int eventToDeviceChanged(DeviceChangedEvent *ev, xEvent **dcce);
566747b715Smrgstatic int eventToDeviceEvent(DeviceEvent *ev, xEvent **xi);
576747b715Smrgstatic int eventToRawEvent(RawDeviceEvent *ev, xEvent **xi);
586747b715Smrg
596747b715Smrg/* Do not use, read comments below */
606747b715SmrgBOOL EventIsKeyRepeat(xEvent *event);
616747b715Smrg
626747b715Smrg/**
636747b715Smrg * Hack to allow detectable autorepeat for core and XI1 events.
646747b715Smrg * The sequence number is unused until we send to the client and can be
656747b715Smrg * misused to store data. More or less, anyway.
666747b715Smrg *
676747b715Smrg * Do not use this. It may change any time without warning, eat your babies
686747b715Smrg * and piss on your cat.
696747b715Smrg */
706747b715Smrgstatic void
716747b715SmrgEventSetKeyRepeatFlag(xEvent *event, BOOL on)
726747b715Smrg{
736747b715Smrg    event->u.u.sequenceNumber = on;
746747b715Smrg}
756747b715Smrg
766747b715Smrg/**
776747b715Smrg * Check if the event was marked as a repeat event before.
786747b715Smrg * NOTE: This is a nasty hack and should NOT be used by anyone else but
796747b715Smrg * TryClientEvents.
806747b715Smrg */
816747b715SmrgBOOL
826747b715SmrgEventIsKeyRepeat(xEvent *event)
836747b715Smrg{
846747b715Smrg    return !!event->u.u.sequenceNumber;
856747b715Smrg}
866747b715Smrg
876747b715Smrg/**
886747b715Smrg * Convert the given event to the respective core event.
896747b715Smrg *
906747b715Smrg * Return values:
916747b715Smrg * Success ... core contains the matching core event.
926747b715Smrg * BadValue .. One or more values in the internal event are invalid.
936747b715Smrg * BadMatch .. The event has no core equivalent.
946747b715Smrg *
956747b715Smrg * @param[in] event The event to convert into a core event.
966747b715Smrg * @param[in] core The memory location to store the core event at.
976747b715Smrg * @return Success or the matching error code.
986747b715Smrg */
996747b715Smrgint
1006747b715SmrgEventToCore(InternalEvent *event, xEvent *core)
1016747b715Smrg{
1026747b715Smrg    switch(event->any.type)
1036747b715Smrg    {
1046747b715Smrg        case ET_Motion:
1056747b715Smrg        case ET_ButtonPress:
1066747b715Smrg        case ET_ButtonRelease:
1076747b715Smrg        case ET_KeyPress:
1086747b715Smrg        case ET_KeyRelease:
1096747b715Smrg            {
1106747b715Smrg                DeviceEvent *e = &event->device_event;
1116747b715Smrg
1126747b715Smrg                if (e->detail.key > 0xFF)
1136747b715Smrg                    return BadMatch;
1146747b715Smrg
1156747b715Smrg                memset(core, 0, sizeof(xEvent));
1166747b715Smrg                core->u.u.type = e->type - ET_KeyPress + KeyPress;
1176747b715Smrg                core->u.u.detail = e->detail.key & 0xFF;
1186747b715Smrg                core->u.keyButtonPointer.time = e->time;
1196747b715Smrg                core->u.keyButtonPointer.rootX = e->root_x;
1206747b715Smrg                core->u.keyButtonPointer.rootY = e->root_y;
1216747b715Smrg                core->u.keyButtonPointer.state = e->corestate;
1226747b715Smrg                core->u.keyButtonPointer.root = e->root;
1236747b715Smrg                EventSetKeyRepeatFlag(core, (e->type == ET_KeyPress && e->key_repeat));
1246747b715Smrg            }
1256747b715Smrg            break;
1266747b715Smrg        case ET_ProximityIn:
1276747b715Smrg        case ET_ProximityOut:
1286747b715Smrg        case ET_RawKeyPress:
1296747b715Smrg        case ET_RawKeyRelease:
1306747b715Smrg        case ET_RawButtonPress:
1316747b715Smrg        case ET_RawButtonRelease:
1326747b715Smrg        case ET_RawMotion:
1336747b715Smrg            return BadMatch;
1346747b715Smrg        default:
1356747b715Smrg            /* XXX: */
1366747b715Smrg            ErrorF("[dix] EventToCore: Not implemented yet \n");
1376747b715Smrg            return BadImplementation;
1386747b715Smrg    }
1396747b715Smrg    return Success;
1406747b715Smrg}
1416747b715Smrg
1426747b715Smrg/**
1436747b715Smrg * Convert the given event to the respective XI 1.x event and store it in
1446747b715Smrg * xi. xi is allocated on demand and must be freed by the caller.
1456747b715Smrg * count returns the number of events in xi. If count is 1, and the type of
1466747b715Smrg * xi is GenericEvent, then xi may be larger than 32 bytes.
1476747b715Smrg *
1486747b715Smrg * Return values:
1496747b715Smrg * Success ... core contains the matching core event.
1506747b715Smrg * BadValue .. One or more values in the internal event are invalid.
1516747b715Smrg * BadMatch .. The event has no XI equivalent.
1526747b715Smrg *
1536747b715Smrg * @param[in] ev The event to convert into an XI 1 event.
1546747b715Smrg * @param[out] xi Future memory location for the XI event.
1556747b715Smrg * @param[out] count Number of elements in xi.
1566747b715Smrg *
1576747b715Smrg * @return Success or the error code.
1586747b715Smrg */
1596747b715Smrgint
1606747b715SmrgEventToXI(InternalEvent *ev, xEvent **xi, int *count)
1616747b715Smrg{
1626747b715Smrg    switch (ev->any.type)
1636747b715Smrg    {
1646747b715Smrg        case ET_Motion:
1656747b715Smrg        case ET_ButtonPress:
1666747b715Smrg        case ET_ButtonRelease:
1676747b715Smrg        case ET_KeyPress:
1686747b715Smrg        case ET_KeyRelease:
1696747b715Smrg        case ET_ProximityIn:
1706747b715Smrg        case ET_ProximityOut:
1716747b715Smrg            return eventToKeyButtonPointer(&ev->device_event, xi, count);
1726747b715Smrg        case ET_DeviceChanged:
1736747b715Smrg        case ET_RawKeyPress:
1746747b715Smrg        case ET_RawKeyRelease:
1756747b715Smrg        case ET_RawButtonPress:
1766747b715Smrg        case ET_RawButtonRelease:
1776747b715Smrg        case ET_RawMotion:
1786747b715Smrg            *count = 0;
1796747b715Smrg            *xi = NULL;
1806747b715Smrg            return BadMatch;
1816747b715Smrg        default:
1826747b715Smrg            break;
1836747b715Smrg    }
1846747b715Smrg
1856747b715Smrg    ErrorF("[dix] EventToXI: Not implemented for %d \n", ev->any.type);
1866747b715Smrg    return BadImplementation;
1876747b715Smrg}
1886747b715Smrg
1896747b715Smrg/**
1906747b715Smrg * Convert the given event to the respective XI 2.x event and store it in xi.
1916747b715Smrg * xi is allocated on demand and must be freed by the caller.
1926747b715Smrg *
1936747b715Smrg * Return values:
1946747b715Smrg * Success ... core contains the matching core event.
1956747b715Smrg * BadValue .. One or more values in the internal event are invalid.
1966747b715Smrg * BadMatch .. The event has no XI2 equivalent.
1976747b715Smrg *
1986747b715Smrg * @param[in] ev The event to convert into an XI2 event
1996747b715Smrg * @param[out] xi Future memory location for the XI2 event.
2006747b715Smrg *
2016747b715Smrg * @return Success or the error code.
2026747b715Smrg */
2036747b715Smrgint
2046747b715SmrgEventToXI2(InternalEvent *ev, xEvent **xi)
2056747b715Smrg{
2066747b715Smrg    switch (ev->any.type)
2076747b715Smrg    {
2086747b715Smrg        /* Enter/FocusIn are for grabs. We don't need an actual event, since
2096747b715Smrg         * the real events delivered are triggered elsewhere */
2106747b715Smrg        case ET_Enter:
2116747b715Smrg        case ET_FocusIn:
2126747b715Smrg            *xi = NULL;
2136747b715Smrg            return Success;
2146747b715Smrg        case ET_Motion:
2156747b715Smrg        case ET_ButtonPress:
2166747b715Smrg        case ET_ButtonRelease:
2176747b715Smrg        case ET_KeyPress:
2186747b715Smrg        case ET_KeyRelease:
2196747b715Smrg            return eventToDeviceEvent(&ev->device_event, xi);
2206747b715Smrg        case ET_ProximityIn:
2216747b715Smrg        case ET_ProximityOut:
2226747b715Smrg            *xi = NULL;
2236747b715Smrg            return BadMatch;
2246747b715Smrg        case ET_DeviceChanged:
2256747b715Smrg            return eventToDeviceChanged(&ev->changed_event, xi);
2266747b715Smrg        case ET_RawKeyPress:
2276747b715Smrg        case ET_RawKeyRelease:
2286747b715Smrg        case ET_RawButtonPress:
2296747b715Smrg        case ET_RawButtonRelease:
2306747b715Smrg        case ET_RawMotion:
2316747b715Smrg            return eventToRawEvent(&ev->raw_event, xi);
2326747b715Smrg        default:
2336747b715Smrg            break;
2346747b715Smrg    }
2356747b715Smrg
2366747b715Smrg    ErrorF("[dix] EventToXI2: Not implemented for %d \n", ev->any.type);
2376747b715Smrg    return BadImplementation;
2386747b715Smrg}
2396747b715Smrg
2406747b715Smrgstatic int
2416747b715SmrgeventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count)
2426747b715Smrg{
2436747b715Smrg    int num_events;
2446747b715Smrg    int first; /* dummy */
2456747b715Smrg    deviceKeyButtonPointer *kbp;
2466747b715Smrg
2476747b715Smrg    /* Sorry, XI 1.x protocol restrictions. */
2486747b715Smrg    if (ev->detail.button > 0xFF || ev->deviceid >= 0x80)
2496747b715Smrg    {
2506747b715Smrg        *count = 0;
2516747b715Smrg        return Success;
2526747b715Smrg    }
2536747b715Smrg
2546747b715Smrg    num_events = (countValuators(ev, &first) + 5)/6; /* valuator ev */
2556747b715Smrg    num_events++; /* the actual event event */
2566747b715Smrg
2576747b715Smrg    *xi = calloc(num_events, sizeof(xEvent));
2586747b715Smrg    if (!(*xi))
2596747b715Smrg    {
2606747b715Smrg        return BadAlloc;
2616747b715Smrg    }
2626747b715Smrg
2636747b715Smrg    kbp           = (deviceKeyButtonPointer*)(*xi);
2646747b715Smrg    kbp->detail   = ev->detail.button;
2656747b715Smrg    kbp->time     = ev->time;
2666747b715Smrg    kbp->root     = ev->root;
2676747b715Smrg    kbp->root_x   = ev->root_x;
2686747b715Smrg    kbp->root_y   = ev->root_y;
2696747b715Smrg    kbp->deviceid = ev->deviceid;
2706747b715Smrg    kbp->state    = ev->corestate;
2716747b715Smrg    EventSetKeyRepeatFlag((xEvent*)kbp,
2726747b715Smrg                          (ev->type == ET_KeyPress && ev->key_repeat));
2736747b715Smrg
2746747b715Smrg    if (num_events > 1)
2756747b715Smrg        kbp->deviceid |= MORE_EVENTS;
2766747b715Smrg
2776747b715Smrg    switch(ev->type)
2786747b715Smrg    {
2796747b715Smrg        case ET_Motion:        kbp->type = DeviceMotionNotify;  break;
2806747b715Smrg        case ET_ButtonPress:   kbp->type = DeviceButtonPress;   break;
2816747b715Smrg        case ET_ButtonRelease: kbp->type = DeviceButtonRelease; break;
2826747b715Smrg        case ET_KeyPress:      kbp->type = DeviceKeyPress;      break;
2836747b715Smrg        case ET_KeyRelease:    kbp->type = DeviceKeyRelease;    break;
2846747b715Smrg        case ET_ProximityIn:   kbp->type = ProximityIn;         break;
2856747b715Smrg        case ET_ProximityOut:  kbp->type = ProximityOut;        break;
2866747b715Smrg        default:
2876747b715Smrg            break;
2886747b715Smrg    }
2896747b715Smrg
2906747b715Smrg    if (num_events > 1)
2916747b715Smrg    {
2926747b715Smrg        getValuatorEvents(ev, (deviceValuator*)(kbp + 1));
2936747b715Smrg    }
2946747b715Smrg
2956747b715Smrg    *count = num_events;
2966747b715Smrg    return Success;
2976747b715Smrg}
2986747b715Smrg
2996747b715Smrg
3006747b715Smrg/**
3016747b715Smrg * Set first to the first valuator in the event ev and return the number of
3026747b715Smrg * valuators from first to the last set valuator.
3036747b715Smrg */
3046747b715Smrgstatic int
3056747b715SmrgcountValuators(DeviceEvent *ev, int *first)
3066747b715Smrg{
3076747b715Smrg    int first_valuator = -1, last_valuator = -1, num_valuators = 0;
3086747b715Smrg    int i;
3096747b715Smrg
3106747b715Smrg    for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++)
3116747b715Smrg    {
3126747b715Smrg        if (BitIsOn(ev->valuators.mask, i))
3136747b715Smrg        {
3146747b715Smrg            if (first_valuator == -1)
3156747b715Smrg                first_valuator = i;
3166747b715Smrg            last_valuator = i;
3176747b715Smrg        }
3186747b715Smrg    }
3196747b715Smrg
3206747b715Smrg    if (first_valuator != -1)
3216747b715Smrg    {
3226747b715Smrg        num_valuators = last_valuator - first_valuator + 1;
3236747b715Smrg        *first = first_valuator;
3246747b715Smrg    }
3256747b715Smrg
3266747b715Smrg    return num_valuators;
3276747b715Smrg}
3286747b715Smrg
3296747b715Smrgstatic int
3306747b715SmrggetValuatorEvents(DeviceEvent *ev, deviceValuator *xv)
3316747b715Smrg{
3326747b715Smrg    int i;
3336747b715Smrg    int state = 0;
3346747b715Smrg    int first_valuator, num_valuators;
3356747b715Smrg
3366747b715Smrg
3376747b715Smrg    num_valuators = countValuators(ev, &first_valuator);
3386747b715Smrg    if (num_valuators > 0)
3396747b715Smrg    {
3406747b715Smrg        DeviceIntPtr dev = NULL;
3416747b715Smrg        dixLookupDevice(&dev, ev->deviceid, serverClient, DixUseAccess);
3426747b715Smrg        /* State needs to be assembled BEFORE the device is updated. */
3436747b715Smrg        state = (dev && dev->key) ? XkbStateFieldFromRec(&dev->key->xkbInfo->state) : 0;
3446747b715Smrg        state |= (dev && dev->button) ? (dev->button->state) : 0;
3456747b715Smrg    }
3466747b715Smrg
3476747b715Smrg    /* FIXME: non-continuous valuator data in internal events*/
3486747b715Smrg    for (i = 0; i < num_valuators; i += 6, xv++) {
3496747b715Smrg        xv->type = DeviceValuator;
3506747b715Smrg        xv->first_valuator = first_valuator + i;
3516747b715Smrg        xv->num_valuators = ((num_valuators - i) > 6) ? 6 : (num_valuators - i);
3526747b715Smrg        xv->deviceid = ev->deviceid;
3536747b715Smrg        xv->device_state = state;
3546747b715Smrg        switch (xv->num_valuators) {
3556747b715Smrg        case 6:
3566747b715Smrg            xv->valuator5 = ev->valuators.data[xv->first_valuator + 5];
3576747b715Smrg        case 5:
3586747b715Smrg            xv->valuator4 = ev->valuators.data[xv->first_valuator + 4];
3596747b715Smrg        case 4:
3606747b715Smrg            xv->valuator3 = ev->valuators.data[xv->first_valuator + 3];
3616747b715Smrg        case 3:
3626747b715Smrg            xv->valuator2 = ev->valuators.data[xv->first_valuator + 2];
3636747b715Smrg        case 2:
3646747b715Smrg            xv->valuator1 = ev->valuators.data[xv->first_valuator + 1];
3656747b715Smrg        case 1:
3666747b715Smrg            xv->valuator0 = ev->valuators.data[xv->first_valuator + 0];
3676747b715Smrg        }
3686747b715Smrg
3696747b715Smrg        if (i + 6 < num_valuators)
3706747b715Smrg            xv->deviceid |= MORE_EVENTS;
3716747b715Smrg    }
3726747b715Smrg
3736747b715Smrg    return (num_valuators + 5) / 6;
3746747b715Smrg}
3756747b715Smrg
3766747b715Smrg
3776747b715Smrgstatic int
3786747b715SmrgappendKeyInfo(DeviceChangedEvent *dce, xXIKeyInfo* info)
3796747b715Smrg{
3806747b715Smrg    uint32_t *kc;
3816747b715Smrg    int i;
3826747b715Smrg
3836747b715Smrg    info->type = XIKeyClass;
3846747b715Smrg    info->num_keycodes = dce->keys.max_keycode - dce->keys.min_keycode + 1;
3856747b715Smrg    info->length = sizeof(xXIKeyInfo)/4 + info->num_keycodes;
3866747b715Smrg    info->sourceid = dce->sourceid;
3876747b715Smrg
3886747b715Smrg    kc = (uint32_t*)&info[1];
3896747b715Smrg    for (i = 0; i < info->num_keycodes; i++)
3906747b715Smrg        *kc++ = i + dce->keys.min_keycode;
3916747b715Smrg
3926747b715Smrg    return info->length * 4;
3936747b715Smrg}
3946747b715Smrg
3956747b715Smrgstatic int
3966747b715SmrgappendButtonInfo(DeviceChangedEvent *dce, xXIButtonInfo *info)
3976747b715Smrg{
3986747b715Smrg    unsigned char *bits;
3996747b715Smrg    int mask_len;
4006747b715Smrg
4016747b715Smrg    mask_len = bytes_to_int32(bits_to_bytes(dce->buttons.num_buttons));
4026747b715Smrg
4036747b715Smrg    info->type = XIButtonClass;
4046747b715Smrg    info->num_buttons = dce->buttons.num_buttons;
4056747b715Smrg    info->length = bytes_to_int32(sizeof(xXIButtonInfo)) +
4066747b715Smrg                   info->num_buttons + mask_len;
4076747b715Smrg    info->sourceid = dce->sourceid;
4086747b715Smrg
4096747b715Smrg    bits = (unsigned char*)&info[1];
4106747b715Smrg    memset(bits, 0, mask_len * 4);
4116747b715Smrg    /* FIXME: is_down? */
4126747b715Smrg
4136747b715Smrg    bits += mask_len * 4;
4146747b715Smrg    memcpy(bits, dce->buttons.names, dce->buttons.num_buttons * sizeof(Atom));
4156747b715Smrg
4166747b715Smrg    return info->length * 4;
4176747b715Smrg}
4186747b715Smrg
4196747b715Smrgstatic int
4206747b715SmrgappendValuatorInfo(DeviceChangedEvent *dce, xXIValuatorInfo *info, int axisnumber)
4216747b715Smrg{
4226747b715Smrg    info->type = XIValuatorClass;
4236747b715Smrg    info->length = sizeof(xXIValuatorInfo)/4;
4246747b715Smrg    info->label = dce->valuators[axisnumber].name;
4256747b715Smrg    info->min.integral = dce->valuators[axisnumber].min;
4266747b715Smrg    info->min.frac = 0;
4276747b715Smrg    info->max.integral = dce->valuators[axisnumber].max;
4286747b715Smrg    info->max.frac = 0;
4296747b715Smrg    /* FIXME: value */
4306747b715Smrg    info->value.integral = 0;
4316747b715Smrg    info->value.frac = 0;
4326747b715Smrg    info->resolution = dce->valuators[axisnumber].resolution;
4336747b715Smrg    info->number = axisnumber;
4346747b715Smrg    info->mode = dce->valuators[axisnumber].mode; /* Server doesn't have per-axis mode yet */
4356747b715Smrg    info->sourceid = dce->sourceid;
4366747b715Smrg
4376747b715Smrg    return info->length * 4;
4386747b715Smrg}
4396747b715Smrg
4406747b715Smrgstatic int
4416747b715SmrgeventToDeviceChanged(DeviceChangedEvent *dce, xEvent **xi)
4426747b715Smrg{
4436747b715Smrg    xXIDeviceChangedEvent *dcce;
4446747b715Smrg    int len = sizeof(xXIDeviceChangedEvent);
4456747b715Smrg    int nkeys;
4466747b715Smrg    char *ptr;
4476747b715Smrg
4486747b715Smrg    if (dce->buttons.num_buttons)
4496747b715Smrg    {
4506747b715Smrg        len += sizeof(xXIButtonInfo);
4516747b715Smrg        len += dce->buttons.num_buttons * sizeof(Atom); /* button names */
4526747b715Smrg        len += pad_to_int32(bits_to_bytes(dce->buttons.num_buttons));
4536747b715Smrg    }
4546747b715Smrg    if (dce->num_valuators)
4556747b715Smrg        len += sizeof(xXIValuatorInfo) * dce->num_valuators;
4566747b715Smrg
4576747b715Smrg    nkeys = (dce->keys.max_keycode > 0) ?
4586747b715Smrg                dce->keys.max_keycode - dce->keys.min_keycode + 1 : 0;
4596747b715Smrg    if (nkeys > 0)
4606747b715Smrg    {
4616747b715Smrg        len += sizeof(xXIKeyInfo);
4626747b715Smrg        len += sizeof(CARD32) * nkeys; /* keycodes */
4636747b715Smrg    }
4646747b715Smrg
4656747b715Smrg    dcce = calloc(1, len);
4666747b715Smrg    if (!dcce)
4676747b715Smrg    {
4686747b715Smrg        ErrorF("[Xi] BadAlloc in SendDeviceChangedEvent.\n");
4696747b715Smrg        return BadAlloc;
4706747b715Smrg    }
4716747b715Smrg
4726747b715Smrg    dcce->type         = GenericEvent;
4736747b715Smrg    dcce->extension    = IReqCode;
4746747b715Smrg    dcce->evtype       = XI_DeviceChanged;
4756747b715Smrg    dcce->time         = dce->time;
4766747b715Smrg    dcce->deviceid     = dce->deviceid;
4776747b715Smrg    dcce->sourceid     = dce->sourceid;
4786747b715Smrg    dcce->reason       = (dce->flags & DEVCHANGE_DEVICE_CHANGE) ? XIDeviceChange : XISlaveSwitch;
4796747b715Smrg    dcce->num_classes  = 0;
4806747b715Smrg    dcce->length = bytes_to_int32(len - sizeof(xEvent));
4816747b715Smrg
4826747b715Smrg    ptr = (char*)&dcce[1];
4836747b715Smrg    if (dce->buttons.num_buttons)
4846747b715Smrg    {
4856747b715Smrg        dcce->num_classes++;
4866747b715Smrg        ptr += appendButtonInfo(dce, (xXIButtonInfo*)ptr);
4876747b715Smrg    }
4886747b715Smrg
4896747b715Smrg    if (nkeys)
4906747b715Smrg    {
4916747b715Smrg        dcce->num_classes++;
4926747b715Smrg        ptr += appendKeyInfo(dce, (xXIKeyInfo*)ptr);
4936747b715Smrg    }
4946747b715Smrg
4956747b715Smrg    if (dce->num_valuators)
4966747b715Smrg    {
4976747b715Smrg        int i;
4986747b715Smrg
4996747b715Smrg        dcce->num_classes += dce->num_valuators;
5006747b715Smrg        for (i = 0; i < dce->num_valuators; i++)
5016747b715Smrg            ptr += appendValuatorInfo(dce, (xXIValuatorInfo*)ptr, i);
5026747b715Smrg    }
5036747b715Smrg
5046747b715Smrg    *xi = (xEvent*)dcce;
5056747b715Smrg
5066747b715Smrg    return Success;
5076747b715Smrg}
5086747b715Smrg
5096747b715Smrgstatic int count_bits(unsigned char* ptr, int len)
5106747b715Smrg{
5116747b715Smrg    int bits = 0;
5126747b715Smrg    unsigned int i;
5136747b715Smrg    unsigned char x;
5146747b715Smrg
5156747b715Smrg    for (i = 0; i < len; i++)
5166747b715Smrg    {
5176747b715Smrg        x = ptr[i];
5186747b715Smrg        while(x > 0)
5196747b715Smrg        {
5206747b715Smrg            bits += (x & 0x1);
5216747b715Smrg            x >>= 1;
5226747b715Smrg        }
5236747b715Smrg    }
5246747b715Smrg    return bits;
5256747b715Smrg}
5266747b715Smrg
5276747b715Smrgstatic int
5286747b715SmrgeventToDeviceEvent(DeviceEvent *ev, xEvent **xi)
5296747b715Smrg{
5306747b715Smrg    int len = sizeof(xXIDeviceEvent);
5316747b715Smrg    xXIDeviceEvent *xde;
5326747b715Smrg    int i, btlen, vallen;
5336747b715Smrg    char *ptr;
5346747b715Smrg    FP3232 *axisval;
5356747b715Smrg
5366747b715Smrg    /* FIXME: this should just send the buttons we have, not MAX_BUTTONs. Same
5376747b715Smrg     * with MAX_VALUATORS below */
5386747b715Smrg    /* btlen is in 4 byte units */
5396747b715Smrg    btlen = bytes_to_int32(bits_to_bytes(MAX_BUTTONS));
5406747b715Smrg    len += btlen * 4; /* buttonmask len */
5416747b715Smrg
5426747b715Smrg
5436747b715Smrg    vallen = count_bits(ev->valuators.mask, sizeof(ev->valuators.mask)/sizeof(ev->valuators.mask[0]));
5446747b715Smrg    len += vallen * 2 * sizeof(uint32_t); /* axisvalues */
5456747b715Smrg    vallen = bytes_to_int32(bits_to_bytes(MAX_VALUATORS));
5466747b715Smrg    len += vallen * 4; /* valuators mask */
5476747b715Smrg
5486747b715Smrg    *xi = calloc(1, len);
5496747b715Smrg    xde = (xXIDeviceEvent*)*xi;
5506747b715Smrg    xde->type           = GenericEvent;
5516747b715Smrg    xde->extension      = IReqCode;
5526747b715Smrg    xde->evtype         = GetXI2Type((InternalEvent*)ev);
5536747b715Smrg    xde->time           = ev->time;
5546747b715Smrg    xde->length         = bytes_to_int32(len - sizeof(xEvent));
5556747b715Smrg    xde->detail         = ev->detail.button;
5566747b715Smrg    xde->root           = ev->root;
5576747b715Smrg    xde->buttons_len    = btlen;
5586747b715Smrg    xde->valuators_len  = vallen;
5596747b715Smrg    xde->deviceid       = ev->deviceid;
5606747b715Smrg    xde->sourceid       = ev->sourceid;
5616747b715Smrg    xde->root_x         = FP1616(ev->root_x, ev->root_x_frac);
5626747b715Smrg    xde->root_y         = FP1616(ev->root_y, ev->root_y_frac);
5636747b715Smrg
5646747b715Smrg    if (ev->key_repeat)
5656747b715Smrg        xde->flags      |= XIKeyRepeat;
5666747b715Smrg
5676747b715Smrg    xde->mods.base_mods         = ev->mods.base;
5686747b715Smrg    xde->mods.latched_mods      = ev->mods.latched;
5696747b715Smrg    xde->mods.locked_mods       = ev->mods.locked;
5706747b715Smrg    xde->mods.effective_mods    = ev->mods.effective;
5716747b715Smrg
5726747b715Smrg    xde->group.base_group       = ev->group.base;
5736747b715Smrg    xde->group.latched_group    = ev->group.latched;
5746747b715Smrg    xde->group.locked_group     = ev->group.locked;
5756747b715Smrg    xde->group.effective_group  = ev->group.effective;
5766747b715Smrg
5776747b715Smrg    ptr = (char*)&xde[1];
5786747b715Smrg    for (i = 0; i < sizeof(ev->buttons) * 8; i++)
5796747b715Smrg    {
5806747b715Smrg        if (BitIsOn(ev->buttons, i))
5816747b715Smrg            SetBit(ptr, i);
5826747b715Smrg    }
5836747b715Smrg
5846747b715Smrg    ptr += xde->buttons_len * 4;
5856747b715Smrg    axisval = (FP3232*)(ptr + xde->valuators_len * 4);
5866747b715Smrg    for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++)
5876747b715Smrg    {
5886747b715Smrg        if (BitIsOn(ev->valuators.mask, i))
5896747b715Smrg        {
5906747b715Smrg            SetBit(ptr, i);
5916747b715Smrg            axisval->integral = ev->valuators.data[i];
5926747b715Smrg            axisval->frac = ev->valuators.data_frac[i];
5936747b715Smrg            axisval++;
5946747b715Smrg        }
5956747b715Smrg    }
5966747b715Smrg
5976747b715Smrg    return Success;
5986747b715Smrg}
5996747b715Smrg
6006747b715Smrgstatic int
6016747b715SmrgeventToRawEvent(RawDeviceEvent *ev, xEvent **xi)
6026747b715Smrg{
6036747b715Smrg    xXIRawEvent* raw;
6046747b715Smrg    int vallen, nvals;
6056747b715Smrg    int i, len = sizeof(xXIRawEvent);
6066747b715Smrg    char *ptr;
6076747b715Smrg    FP3232 *axisval;
6086747b715Smrg
6096747b715Smrg    nvals = count_bits(ev->valuators.mask, sizeof(ev->valuators.mask));
6106747b715Smrg    len += nvals * sizeof(FP3232) * 2; /* 8 byte per valuator, once
6116747b715Smrg                                    raw, once processed */
6126747b715Smrg    vallen = bytes_to_int32(bits_to_bytes(MAX_VALUATORS));
6136747b715Smrg    len += vallen * 4; /* valuators mask */
6146747b715Smrg
6156747b715Smrg    *xi = calloc(1, len);
6166747b715Smrg    raw = (xXIRawEvent*)*xi;
6176747b715Smrg    raw->type           = GenericEvent;
6186747b715Smrg    raw->extension      = IReqCode;
6196747b715Smrg    raw->evtype         = GetXI2Type((InternalEvent*)ev);
6206747b715Smrg    raw->time           = ev->time;
6216747b715Smrg    raw->length         = bytes_to_int32(len - sizeof(xEvent));
6226747b715Smrg    raw->detail         = ev->detail.button;
6236747b715Smrg    raw->deviceid       = ev->deviceid;
6246747b715Smrg    raw->valuators_len  = vallen;
6256747b715Smrg
6266747b715Smrg    ptr = (char*)&raw[1];
6276747b715Smrg    axisval = (FP3232*)(ptr + raw->valuators_len * 4);
6286747b715Smrg    for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++)
6296747b715Smrg    {
6306747b715Smrg        if (BitIsOn(ev->valuators.mask, i))
6316747b715Smrg        {
6326747b715Smrg            SetBit(ptr, i);
6336747b715Smrg            axisval->integral = ev->valuators.data[i];
6346747b715Smrg            axisval->frac = ev->valuators.data_frac[i];
6356747b715Smrg            (axisval + nvals)->integral = ev->valuators.data_raw[i];
6366747b715Smrg            (axisval + nvals)->frac = ev->valuators.data_raw_frac[i];
6376747b715Smrg            axisval++;
6386747b715Smrg        }
6396747b715Smrg    }
6406747b715Smrg
6416747b715Smrg    return Success;
6426747b715Smrg}
6436747b715Smrg
6446747b715Smrg/**
6456747b715Smrg * Return the corresponding core type for the given event or 0 if no core
6466747b715Smrg * equivalent exists.
6476747b715Smrg */
6486747b715Smrgint
6496747b715SmrgGetCoreType(InternalEvent *event)
6506747b715Smrg{
6516747b715Smrg    int coretype = 0;
6526747b715Smrg    switch(event->any.type)
6536747b715Smrg    {
6546747b715Smrg        case ET_Motion:         coretype = MotionNotify;  break;
6556747b715Smrg        case ET_ButtonPress:    coretype = ButtonPress;   break;
6566747b715Smrg        case ET_ButtonRelease:  coretype = ButtonRelease; break;
6576747b715Smrg        case ET_KeyPress:       coretype = KeyPress;      break;
6586747b715Smrg        case ET_KeyRelease:     coretype = KeyRelease;    break;
6596747b715Smrg        default:
6606747b715Smrg            break;
6616747b715Smrg    }
6626747b715Smrg    return coretype;
6636747b715Smrg}
6646747b715Smrg
6656747b715Smrg/**
6666747b715Smrg * Return the corresponding XI 1.x type for the given event or 0 if no
6676747b715Smrg * equivalent exists.
6686747b715Smrg */
6696747b715Smrgint
6706747b715SmrgGetXIType(InternalEvent *event)
6716747b715Smrg{
6726747b715Smrg    int xitype = 0;
6736747b715Smrg    switch(event->any.type)
6746747b715Smrg    {
6756747b715Smrg        case ET_Motion:         xitype = DeviceMotionNotify;  break;
6766747b715Smrg        case ET_ButtonPress:    xitype = DeviceButtonPress;   break;
6776747b715Smrg        case ET_ButtonRelease:  xitype = DeviceButtonRelease; break;
6786747b715Smrg        case ET_KeyPress:       xitype = DeviceKeyPress;      break;
6796747b715Smrg        case ET_KeyRelease:     xitype = DeviceKeyRelease;    break;
6806747b715Smrg        case ET_ProximityIn:    xitype = ProximityIn;         break;
6816747b715Smrg        case ET_ProximityOut:   xitype = ProximityOut;        break;
6826747b715Smrg        default:
6836747b715Smrg            break;
6846747b715Smrg    }
6856747b715Smrg    return xitype;
6866747b715Smrg}
6876747b715Smrg
6886747b715Smrg/**
6896747b715Smrg * Return the corresponding XI 2.x type for the given event or 0 if no
6906747b715Smrg * equivalent exists.
6916747b715Smrg */
6926747b715Smrgint
6936747b715SmrgGetXI2Type(InternalEvent *event)
6946747b715Smrg{
6956747b715Smrg    int xi2type = 0;
6966747b715Smrg
6976747b715Smrg    switch(event->any.type)
6986747b715Smrg    {
6996747b715Smrg        case ET_Motion:         xi2type = XI_Motion;           break;
7006747b715Smrg        case ET_ButtonPress:    xi2type = XI_ButtonPress;      break;
7016747b715Smrg        case ET_ButtonRelease:  xi2type = XI_ButtonRelease;    break;
7026747b715Smrg        case ET_KeyPress:       xi2type = XI_KeyPress;         break;
7036747b715Smrg        case ET_KeyRelease:     xi2type = XI_KeyRelease;       break;
7046747b715Smrg        case ET_Enter:          xi2type = XI_Enter;            break;
7056747b715Smrg        case ET_Leave:          xi2type = XI_Leave;            break;
7066747b715Smrg        case ET_Hierarchy:      xi2type = XI_HierarchyChanged; break;
7076747b715Smrg        case ET_DeviceChanged:  xi2type = XI_DeviceChanged;    break;
7086747b715Smrg        case ET_RawKeyPress:    xi2type = XI_RawKeyPress;      break;
7096747b715Smrg        case ET_RawKeyRelease:  xi2type = XI_RawKeyRelease;    break;
7106747b715Smrg        case ET_RawButtonPress: xi2type = XI_RawButtonPress;   break;
7116747b715Smrg        case ET_RawButtonRelease: xi2type = XI_RawButtonRelease; break;
7126747b715Smrg        case ET_RawMotion:      xi2type = XI_RawMotion;        break;
7136747b715Smrg        case ET_FocusIn:        xi2type = XI_FocusIn;          break;
7146747b715Smrg        case ET_FocusOut:       xi2type = XI_FocusOut;         break;
7156747b715Smrg        default:
7166747b715Smrg            break;
7176747b715Smrg    }
7186747b715Smrg    return xi2type;
7196747b715Smrg}
720