1153 lines
		
	
	
		
			32 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			1153 lines
		
	
	
		
			32 KiB
		
	
	
	
		
			C
		
	
	
	
/*
 | 
						|
 * Copyright © 2009 Red Hat, Inc.
 | 
						|
 *
 | 
						|
 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
						|
 * copy of this software and associated documentation files (the "Software"),
 | 
						|
 * to deal in the Software without restriction, including without limitation
 | 
						|
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
						|
 * and/or sell copies of the Software, and to permit persons to whom the
 | 
						|
 * Software is furnished to do so, subject to the following conditions:
 | 
						|
 *
 | 
						|
 * The above copyright notice and this permission notice (including the next
 | 
						|
 * paragraph) shall be included in all copies or substantial portions of the
 | 
						|
 * Software.
 | 
						|
 *
 | 
						|
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
						|
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
						|
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 | 
						|
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
						|
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
						|
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 | 
						|
 * DEALINGS IN THE SOFTWARE.
 | 
						|
 *
 | 
						|
 */
 | 
						|
 | 
						|
/**
 | 
						|
 * @file eventconvert.c
 | 
						|
 * This file contains event conversion routines from InternalEvent to the
 | 
						|
 * matching protocol events.
 | 
						|
 */
 | 
						|
 | 
						|
#include <dix-config.h>
 | 
						|
 | 
						|
#include <stdint.h>
 | 
						|
#include <X11/X.h>
 | 
						|
#include <X11/extensions/XIproto.h>
 | 
						|
#include <X11/extensions/XI2proto.h>
 | 
						|
#include <X11/extensions/XI.h>
 | 
						|
#include <X11/extensions/XI2.h>
 | 
						|
 | 
						|
#include "dix/dix_priv.h"
 | 
						|
#include "dix/eventconvert.h"
 | 
						|
#include "dix/exevents_priv.h"
 | 
						|
 | 
						|
#include "dix.h"
 | 
						|
#include "inputstr.h"
 | 
						|
#include "misc.h"
 | 
						|
#include "eventstr.h"
 | 
						|
#include "exglobals.h"
 | 
						|
#include "inpututils.h"
 | 
						|
#include "xiquerydevice.h"
 | 
						|
#include "xkbsrv.h"
 | 
						|
#include "inpututils.h"
 | 
						|
 | 
						|
static int countValuators(DeviceEvent *ev, int *first);
 | 
						|
static int getValuatorEvents(DeviceEvent *ev, deviceValuator * xv);
 | 
						|
static int eventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count);
 | 
						|
static int eventToDeviceChanged(DeviceChangedEvent *ev, xEvent **dcce);
 | 
						|
static int eventToDeviceEvent(DeviceEvent *ev, xEvent **xi);
 | 
						|
static int eventToRawEvent(RawDeviceEvent *ev, xEvent **xi);
 | 
						|
static int eventToBarrierEvent(BarrierEvent *ev, xEvent **xi);
 | 
						|
static int eventToTouchOwnershipEvent(TouchOwnershipEvent *ev, xEvent **xi);
 | 
						|
static int eventToGestureSwipeEvent(GestureEvent *ev, xEvent **xi);
 | 
						|
static int eventToGesturePinchEvent(GestureEvent *ev, xEvent **xi);
 | 
						|
 | 
						|
/* Do not use, read comments below */
 | 
						|
BOOL EventIsKeyRepeat(xEvent *event);
 | 
						|
 | 
						|
/**
 | 
						|
 * Hack to allow detectable autorepeat for core and XI1 events.
 | 
						|
 * The sequence number is unused until we send to the client and can be
 | 
						|
 * misused to store data. More or less, anyway.
 | 
						|
 *
 | 
						|
 * Do not use this. It may change any time without warning, eat your babies
 | 
						|
 * and piss on your cat.
 | 
						|
 */
 | 
						|
static void
 | 
						|
EventSetKeyRepeatFlag(xEvent *event, BOOL on)
 | 
						|
{
 | 
						|
    event->u.u.sequenceNumber = on;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Check if the event was marked as a repeat event before.
 | 
						|
 * NOTE: This is a nasty hack and should NOT be used by anyone else but
 | 
						|
 * TryClientEvents.
 | 
						|
 */
 | 
						|
BOOL
 | 
						|
EventIsKeyRepeat(xEvent *event)
 | 
						|
{
 | 
						|
    return ! !event->u.u.sequenceNumber;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Convert the given event to the respective core event.
 | 
						|
 *
 | 
						|
 * Return values:
 | 
						|
 * Success ... core contains the matching core event.
 | 
						|
 * BadValue .. One or more values in the internal event are invalid.
 | 
						|
 * BadMatch .. The event has no core equivalent.
 | 
						|
 *
 | 
						|
 * @param[in] event The event to convert into a core event.
 | 
						|
 * @param[in] core The memory location to store the core event at.
 | 
						|
 * @return Success or the matching error code.
 | 
						|
 */
 | 
						|
int
 | 
						|
EventToCore(InternalEvent *event, xEvent **core_out, int *count_out)
 | 
						|
{
 | 
						|
    xEvent *core = NULL;
 | 
						|
    int count = 0;
 | 
						|
    int ret = BadImplementation;
 | 
						|
 | 
						|
    switch (event->any.type) {
 | 
						|
    case ET_Motion:
 | 
						|
    {
 | 
						|
        DeviceEvent *e = &event->device_event;
 | 
						|
 | 
						|
        /* Don't create core motion event if neither x nor y are
 | 
						|
         * present */
 | 
						|
        if (!BitIsOn(e->valuators.mask, 0) && !BitIsOn(e->valuators.mask, 1)) {
 | 
						|
            ret = BadMatch;
 | 
						|
            goto out;
 | 
						|
        }
 | 
						|
    }
 | 
						|
        /* fallthrough */
 | 
						|
    case ET_ButtonPress:
 | 
						|
    case ET_ButtonRelease:
 | 
						|
    case ET_KeyPress:
 | 
						|
    case ET_KeyRelease:
 | 
						|
    {
 | 
						|
        DeviceEvent *e = &event->device_event;
 | 
						|
 | 
						|
        if (e->detail.key > 0xFF) {
 | 
						|
            ret = BadMatch;
 | 
						|
            goto out;
 | 
						|
        }
 | 
						|
 | 
						|
        core = calloc(1, sizeof(*core));
 | 
						|
        if (!core)
 | 
						|
            return BadAlloc;
 | 
						|
        count = 1;
 | 
						|
        core->u.u.type = e->type - ET_KeyPress + KeyPress;
 | 
						|
        core->u.u.detail = e->detail.key & 0xFF;
 | 
						|
        core->u.keyButtonPointer.time = e->time;
 | 
						|
        core->u.keyButtonPointer.rootX = e->root_x;
 | 
						|
        core->u.keyButtonPointer.rootY = e->root_y;
 | 
						|
        core->u.keyButtonPointer.state = e->corestate;
 | 
						|
        core->u.keyButtonPointer.root = e->root;
 | 
						|
        EventSetKeyRepeatFlag(core, (e->type == ET_KeyPress && e->key_repeat));
 | 
						|
        ret = Success;
 | 
						|
    }
 | 
						|
        break;
 | 
						|
    case ET_ProximityIn:
 | 
						|
    case ET_ProximityOut:
 | 
						|
    case ET_RawKeyPress:
 | 
						|
    case ET_RawKeyRelease:
 | 
						|
    case ET_RawButtonPress:
 | 
						|
    case ET_RawButtonRelease:
 | 
						|
    case ET_RawMotion:
 | 
						|
    case ET_RawTouchBegin:
 | 
						|
    case ET_RawTouchUpdate:
 | 
						|
    case ET_RawTouchEnd:
 | 
						|
    case ET_TouchBegin:
 | 
						|
    case ET_TouchUpdate:
 | 
						|
    case ET_TouchEnd:
 | 
						|
    case ET_TouchOwnership:
 | 
						|
    case ET_BarrierHit:
 | 
						|
    case ET_BarrierLeave:
 | 
						|
    case ET_GesturePinchBegin:
 | 
						|
    case ET_GesturePinchUpdate:
 | 
						|
    case ET_GesturePinchEnd:
 | 
						|
    case ET_GestureSwipeBegin:
 | 
						|
    case ET_GestureSwipeUpdate:
 | 
						|
    case ET_GestureSwipeEnd:
 | 
						|
        ret = BadMatch;
 | 
						|
        break;
 | 
						|
    default:
 | 
						|
        /* XXX: */
 | 
						|
        ErrorF("[dix] EventToCore: Not implemented yet \n");
 | 
						|
        ret = BadImplementation;
 | 
						|
    }
 | 
						|
 | 
						|
 out:
 | 
						|
    *core_out = core;
 | 
						|
    *count_out = count;
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Convert the given event to the respective XI 1.x event and store it in
 | 
						|
 * xi. xi is allocated on demand and must be freed by the caller.
 | 
						|
 * count returns the number of events in xi. If count is 1, and the type of
 | 
						|
 * xi is GenericEvent, then xi may be larger than 32 bytes.
 | 
						|
 *
 | 
						|
 * Return values:
 | 
						|
 * Success ... core contains the matching core event.
 | 
						|
 * BadValue .. One or more values in the internal event are invalid.
 | 
						|
 * BadMatch .. The event has no XI equivalent.
 | 
						|
 *
 | 
						|
 * @param[in] ev The event to convert into an XI 1 event.
 | 
						|
 * @param[out] xi Future memory location for the XI event.
 | 
						|
 * @param[out] count Number of elements in xi.
 | 
						|
 *
 | 
						|
 * @return Success or the error code.
 | 
						|
 */
 | 
						|
int
 | 
						|
EventToXI(InternalEvent *ev, xEvent **xi, int *count)
 | 
						|
{
 | 
						|
    switch (ev->any.type) {
 | 
						|
    case ET_Motion:
 | 
						|
    case ET_ButtonPress:
 | 
						|
    case ET_ButtonRelease:
 | 
						|
    case ET_KeyPress:
 | 
						|
    case ET_KeyRelease:
 | 
						|
    case ET_ProximityIn:
 | 
						|
    case ET_ProximityOut:
 | 
						|
        return eventToKeyButtonPointer(&ev->device_event, xi, count);
 | 
						|
    case ET_DeviceChanged:
 | 
						|
    case ET_RawKeyPress:
 | 
						|
    case ET_RawKeyRelease:
 | 
						|
    case ET_RawButtonPress:
 | 
						|
    case ET_RawButtonRelease:
 | 
						|
    case ET_RawMotion:
 | 
						|
    case ET_RawTouchBegin:
 | 
						|
    case ET_RawTouchUpdate:
 | 
						|
    case ET_RawTouchEnd:
 | 
						|
    case ET_TouchBegin:
 | 
						|
    case ET_TouchUpdate:
 | 
						|
    case ET_TouchEnd:
 | 
						|
    case ET_TouchOwnership:
 | 
						|
    case ET_BarrierHit:
 | 
						|
    case ET_BarrierLeave:
 | 
						|
    case ET_GesturePinchBegin:
 | 
						|
    case ET_GesturePinchUpdate:
 | 
						|
    case ET_GesturePinchEnd:
 | 
						|
    case ET_GestureSwipeBegin:
 | 
						|
    case ET_GestureSwipeUpdate:
 | 
						|
    case ET_GestureSwipeEnd:
 | 
						|
        *count = 0;
 | 
						|
        *xi = NULL;
 | 
						|
        return BadMatch;
 | 
						|
    default:
 | 
						|
        break;
 | 
						|
    }
 | 
						|
 | 
						|
    ErrorF("[dix] EventToXI: Not implemented for %d \n", ev->any.type);
 | 
						|
    return BadImplementation;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Convert the given event to the respective XI 2.x event and store it in xi.
 | 
						|
 * xi is allocated on demand and must be freed by the caller.
 | 
						|
 *
 | 
						|
 * Return values:
 | 
						|
 * Success ... core contains the matching core event.
 | 
						|
 * BadValue .. One or more values in the internal event are invalid.
 | 
						|
 * BadMatch .. The event has no XI2 equivalent.
 | 
						|
 *
 | 
						|
 * @param[in] ev The event to convert into an XI2 event
 | 
						|
 * @param[out] xi Future memory location for the XI2 event.
 | 
						|
 *
 | 
						|
 * @return Success or the error code.
 | 
						|
 */
 | 
						|
int
 | 
						|
EventToXI2(InternalEvent *ev, xEvent **xi)
 | 
						|
{
 | 
						|
    switch (ev->any.type) {
 | 
						|
        /* Enter/FocusIn are for grabs. We don't need an actual event, since
 | 
						|
         * the real events delivered are triggered elsewhere */
 | 
						|
    case ET_Enter:
 | 
						|
    case ET_FocusIn:
 | 
						|
        *xi = NULL;
 | 
						|
        return Success;
 | 
						|
    case ET_Motion:
 | 
						|
    case ET_ButtonPress:
 | 
						|
    case ET_ButtonRelease:
 | 
						|
    case ET_KeyPress:
 | 
						|
    case ET_KeyRelease:
 | 
						|
    case ET_TouchBegin:
 | 
						|
    case ET_TouchUpdate:
 | 
						|
    case ET_TouchEnd:
 | 
						|
        return eventToDeviceEvent(&ev->device_event, xi);
 | 
						|
    case ET_TouchOwnership:
 | 
						|
        return eventToTouchOwnershipEvent(&ev->touch_ownership_event, xi);
 | 
						|
    case ET_ProximityIn:
 | 
						|
    case ET_ProximityOut:
 | 
						|
        *xi = NULL;
 | 
						|
        return BadMatch;
 | 
						|
    case ET_DeviceChanged:
 | 
						|
        return eventToDeviceChanged(&ev->changed_event, xi);
 | 
						|
    case ET_RawKeyPress:
 | 
						|
    case ET_RawKeyRelease:
 | 
						|
    case ET_RawButtonPress:
 | 
						|
    case ET_RawButtonRelease:
 | 
						|
    case ET_RawMotion:
 | 
						|
    case ET_RawTouchBegin:
 | 
						|
    case ET_RawTouchUpdate:
 | 
						|
    case ET_RawTouchEnd:
 | 
						|
        return eventToRawEvent(&ev->raw_event, xi);
 | 
						|
    case ET_BarrierHit:
 | 
						|
    case ET_BarrierLeave:
 | 
						|
        return eventToBarrierEvent(&ev->barrier_event, xi);
 | 
						|
    case ET_GesturePinchBegin:
 | 
						|
    case ET_GesturePinchUpdate:
 | 
						|
    case ET_GesturePinchEnd:
 | 
						|
        return eventToGesturePinchEvent(&ev->gesture_event, xi);
 | 
						|
    case ET_GestureSwipeBegin:
 | 
						|
    case ET_GestureSwipeUpdate:
 | 
						|
    case ET_GestureSwipeEnd:
 | 
						|
        return eventToGestureSwipeEvent(&ev->gesture_event, xi);
 | 
						|
    default:
 | 
						|
        break;
 | 
						|
    }
 | 
						|
 | 
						|
    ErrorF("[dix] EventToXI2: Not implemented for %d \n", ev->any.type);
 | 
						|
    return BadImplementation;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
eventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count)
 | 
						|
{
 | 
						|
    int num_events;
 | 
						|
    int first;                  /* dummy */
 | 
						|
    deviceKeyButtonPointer *kbp;
 | 
						|
 | 
						|
    /* Sorry, XI 1.x protocol restrictions. */
 | 
						|
    if (ev->detail.button > 0xFF || ev->deviceid >= 0x80) {
 | 
						|
        *count = 0;
 | 
						|
        return Success;
 | 
						|
    }
 | 
						|
 | 
						|
    num_events = (countValuators(ev, &first) + 5) / 6;  /* valuator ev */
 | 
						|
    if (num_events <= 0) {
 | 
						|
        switch (ev->type) {
 | 
						|
        case ET_KeyPress:
 | 
						|
        case ET_KeyRelease:
 | 
						|
        case ET_ButtonPress:
 | 
						|
        case ET_ButtonRelease:
 | 
						|
            /* no axes is ok */
 | 
						|
            break;
 | 
						|
        case ET_Motion:
 | 
						|
        case ET_ProximityIn:
 | 
						|
        case ET_ProximityOut:
 | 
						|
            *count = 0;
 | 
						|
            return BadMatch;
 | 
						|
        default:
 | 
						|
            *count = 0;
 | 
						|
            return BadImplementation;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    num_events++;               /* the actual event event */
 | 
						|
 | 
						|
    *xi = calloc(num_events, sizeof(xEvent));
 | 
						|
    if (!(*xi)) {
 | 
						|
        return BadAlloc;
 | 
						|
    }
 | 
						|
 | 
						|
    kbp = (deviceKeyButtonPointer *) (*xi);
 | 
						|
    kbp->detail = ev->detail.button;
 | 
						|
    kbp->time = ev->time;
 | 
						|
    kbp->root = ev->root;
 | 
						|
    kbp->root_x = ev->root_x;
 | 
						|
    kbp->root_y = ev->root_y;
 | 
						|
    kbp->deviceid = ev->deviceid;
 | 
						|
    kbp->state = ev->corestate;
 | 
						|
    EventSetKeyRepeatFlag((xEvent *) kbp,
 | 
						|
                          (ev->type == ET_KeyPress && ev->key_repeat));
 | 
						|
 | 
						|
    if (num_events > 1)
 | 
						|
        kbp->deviceid |= MORE_EVENTS;
 | 
						|
 | 
						|
    switch (ev->type) {
 | 
						|
    case ET_Motion:
 | 
						|
        kbp->type = DeviceMotionNotify;
 | 
						|
        break;
 | 
						|
    case ET_ButtonPress:
 | 
						|
        kbp->type = DeviceButtonPress;
 | 
						|
        break;
 | 
						|
    case ET_ButtonRelease:
 | 
						|
        kbp->type = DeviceButtonRelease;
 | 
						|
        break;
 | 
						|
    case ET_KeyPress:
 | 
						|
        kbp->type = DeviceKeyPress;
 | 
						|
        break;
 | 
						|
    case ET_KeyRelease:
 | 
						|
        kbp->type = DeviceKeyRelease;
 | 
						|
        break;
 | 
						|
    case ET_ProximityIn:
 | 
						|
        kbp->type = ProximityIn;
 | 
						|
        break;
 | 
						|
    case ET_ProximityOut:
 | 
						|
        kbp->type = ProximityOut;
 | 
						|
        break;
 | 
						|
    default:
 | 
						|
        break;
 | 
						|
    }
 | 
						|
 | 
						|
    if (num_events > 1) {
 | 
						|
        getValuatorEvents(ev, (deviceValuator *) (kbp + 1));
 | 
						|
    }
 | 
						|
 | 
						|
    *count = num_events;
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Set first to the first valuator in the event ev and return the number of
 | 
						|
 * valuators from first to the last set valuator.
 | 
						|
 */
 | 
						|
static int
 | 
						|
countValuators(DeviceEvent *ev, int *first)
 | 
						|
{
 | 
						|
    int first_valuator = -1, last_valuator = -1, num_valuators = 0;
 | 
						|
    int i;
 | 
						|
 | 
						|
    for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++) {
 | 
						|
        if (BitIsOn(ev->valuators.mask, i)) {
 | 
						|
            if (first_valuator == -1)
 | 
						|
                first_valuator = i;
 | 
						|
            last_valuator = i;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    if (first_valuator != -1) {
 | 
						|
        num_valuators = last_valuator - first_valuator + 1;
 | 
						|
        *first = first_valuator;
 | 
						|
    }
 | 
						|
 | 
						|
    return num_valuators;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
getValuatorEvents(DeviceEvent *ev, deviceValuator * xv)
 | 
						|
{
 | 
						|
    int i;
 | 
						|
    int state = 0;
 | 
						|
    int first_valuator, num_valuators;
 | 
						|
 | 
						|
    num_valuators = countValuators(ev, &first_valuator);
 | 
						|
    if (num_valuators > 0) {
 | 
						|
        DeviceIntPtr dev = NULL;
 | 
						|
 | 
						|
        dixLookupDevice(&dev, ev->deviceid, serverClient, DixUseAccess);
 | 
						|
        /* State needs to be assembled BEFORE the device is updated. */
 | 
						|
        state = (dev &&
 | 
						|
                 dev->key) ? XkbStateFieldFromRec(&dev->key->xkbInfo->
 | 
						|
                                                  state) : 0;
 | 
						|
        state |= (dev && dev->button) ? (dev->button->state) : 0;
 | 
						|
    }
 | 
						|
 | 
						|
    for (i = 0; i < num_valuators; i += 6, xv++) {
 | 
						|
        INT32 *valuators = &xv->valuator0;      // Treat all 6 vals as an array
 | 
						|
        int j;
 | 
						|
 | 
						|
        xv->type = DeviceValuator;
 | 
						|
        xv->first_valuator = first_valuator + i;
 | 
						|
        xv->num_valuators = ((num_valuators - i) > 6) ? 6 : (num_valuators - i);
 | 
						|
        xv->deviceid = ev->deviceid;
 | 
						|
        xv->device_state = state;
 | 
						|
 | 
						|
        /* Unset valuators in masked valuator events have the proper data values
 | 
						|
         * in the case of an absolute axis in between two set valuators. */
 | 
						|
        for (j = 0; j < xv->num_valuators; j++)
 | 
						|
            valuators[j] = ev->valuators.data[xv->first_valuator + j];
 | 
						|
 | 
						|
        if (i + 6 < num_valuators)
 | 
						|
            xv->deviceid |= MORE_EVENTS;
 | 
						|
    }
 | 
						|
 | 
						|
    return (num_valuators + 5) / 6;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
appendKeyInfo(DeviceChangedEvent *dce, xXIKeyInfo * info)
 | 
						|
{
 | 
						|
    uint32_t *kc;
 | 
						|
    int i;
 | 
						|
 | 
						|
    info->type = XIKeyClass;
 | 
						|
    info->num_keycodes = dce->keys.max_keycode - dce->keys.min_keycode + 1;
 | 
						|
    info->length = sizeof(xXIKeyInfo) / 4 + info->num_keycodes;
 | 
						|
    info->sourceid = dce->sourceid;
 | 
						|
 | 
						|
    kc = (uint32_t *) &info[1];
 | 
						|
    for (i = 0; i < info->num_keycodes; i++)
 | 
						|
        *kc++ = i + dce->keys.min_keycode;
 | 
						|
 | 
						|
    return info->length * 4;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
appendButtonInfo(DeviceChangedEvent *dce, xXIButtonInfo * info)
 | 
						|
{
 | 
						|
    unsigned char *bits;
 | 
						|
    int mask_len;
 | 
						|
 | 
						|
    mask_len = bytes_to_int32(bits_to_bytes(dce->buttons.num_buttons));
 | 
						|
 | 
						|
    info->type = XIButtonClass;
 | 
						|
    info->num_buttons = dce->buttons.num_buttons;
 | 
						|
    info->length = bytes_to_int32(sizeof(xXIButtonInfo)) +
 | 
						|
        info->num_buttons + mask_len;
 | 
						|
    info->sourceid = dce->sourceid;
 | 
						|
 | 
						|
    bits = (unsigned char *) &info[1];
 | 
						|
    memset(bits, 0, mask_len * 4);
 | 
						|
    /* FIXME: is_down? */
 | 
						|
 | 
						|
    bits += mask_len * 4;
 | 
						|
    memcpy(bits, dce->buttons.names, dce->buttons.num_buttons * sizeof(Atom));
 | 
						|
 | 
						|
    return info->length * 4;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
appendValuatorInfo(DeviceChangedEvent *dce, xXIValuatorInfo * info,
 | 
						|
                   int axisnumber)
 | 
						|
{
 | 
						|
    info->type = XIValuatorClass;
 | 
						|
    info->length = sizeof(xXIValuatorInfo) / 4;
 | 
						|
    info->label = dce->valuators[axisnumber].name;
 | 
						|
    info->min.integral = dce->valuators[axisnumber].min;
 | 
						|
    info->min.frac = 0;
 | 
						|
    info->max.integral = dce->valuators[axisnumber].max;
 | 
						|
    info->max.frac = 0;
 | 
						|
    info->value = double_to_fp3232(dce->valuators[axisnumber].value);
 | 
						|
    info->resolution = dce->valuators[axisnumber].resolution;
 | 
						|
    info->number = axisnumber;
 | 
						|
    info->mode = dce->valuators[axisnumber].mode;
 | 
						|
    info->sourceid = dce->sourceid;
 | 
						|
 | 
						|
    return info->length * 4;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
appendScrollInfo(DeviceChangedEvent *dce, xXIScrollInfo * info, int axisnumber)
 | 
						|
{
 | 
						|
    if (dce->valuators[axisnumber].scroll.type == SCROLL_TYPE_NONE)
 | 
						|
        return 0;
 | 
						|
 | 
						|
    info->type = XIScrollClass;
 | 
						|
    info->length = sizeof(xXIScrollInfo) / 4;
 | 
						|
    info->number = axisnumber;
 | 
						|
    switch (dce->valuators[axisnumber].scroll.type) {
 | 
						|
    case SCROLL_TYPE_VERTICAL:
 | 
						|
        info->scroll_type = XIScrollTypeVertical;
 | 
						|
        break;
 | 
						|
    case SCROLL_TYPE_HORIZONTAL:
 | 
						|
        info->scroll_type = XIScrollTypeHorizontal;
 | 
						|
        break;
 | 
						|
    default:
 | 
						|
        ErrorF("[Xi] Unknown scroll type %d. This is a bug.\n",
 | 
						|
               dce->valuators[axisnumber].scroll.type);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    info->increment =
 | 
						|
        double_to_fp3232(dce->valuators[axisnumber].scroll.increment);
 | 
						|
    info->sourceid = dce->sourceid;
 | 
						|
 | 
						|
    info->flags = 0;
 | 
						|
 | 
						|
    if (dce->valuators[axisnumber].scroll.flags & SCROLL_FLAG_DONT_EMULATE)
 | 
						|
        info->flags |= XIScrollFlagNoEmulation;
 | 
						|
    if (dce->valuators[axisnumber].scroll.flags & SCROLL_FLAG_PREFERRED)
 | 
						|
        info->flags |= XIScrollFlagPreferred;
 | 
						|
 | 
						|
    return info->length * 4;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
eventToDeviceChanged(DeviceChangedEvent *dce, xEvent **xi)
 | 
						|
{
 | 
						|
    xXIDeviceChangedEvent *dcce;
 | 
						|
    int len = sizeof(xXIDeviceChangedEvent);
 | 
						|
    int nkeys;
 | 
						|
    char *ptr;
 | 
						|
 | 
						|
    if (dce->buttons.num_buttons) {
 | 
						|
        len += sizeof(xXIButtonInfo);
 | 
						|
        len += dce->buttons.num_buttons * sizeof(Atom); /* button names */
 | 
						|
        len += pad_to_int32(bits_to_bytes(dce->buttons.num_buttons));
 | 
						|
    }
 | 
						|
    if (dce->num_valuators) {
 | 
						|
        int i;
 | 
						|
 | 
						|
        len += sizeof(xXIValuatorInfo) * dce->num_valuators;
 | 
						|
 | 
						|
        for (i = 0; i < dce->num_valuators; i++)
 | 
						|
            if (dce->valuators[i].scroll.type != SCROLL_TYPE_NONE)
 | 
						|
                len += sizeof(xXIScrollInfo);
 | 
						|
    }
 | 
						|
 | 
						|
    nkeys = (dce->keys.max_keycode > 0) ?
 | 
						|
        dce->keys.max_keycode - dce->keys.min_keycode + 1 : 0;
 | 
						|
    if (nkeys > 0) {
 | 
						|
        len += sizeof(xXIKeyInfo);
 | 
						|
        len += sizeof(CARD32) * nkeys;  /* keycodes */
 | 
						|
    }
 | 
						|
 | 
						|
    dcce = calloc(1, len);
 | 
						|
    if (!dcce) {
 | 
						|
        ErrorF("[Xi] BadAlloc in SendDeviceChangedEvent.\n");
 | 
						|
        return BadAlloc;
 | 
						|
    }
 | 
						|
 | 
						|
    dcce->type = GenericEvent;
 | 
						|
    dcce->extension = IReqCode;
 | 
						|
    dcce->evtype = XI_DeviceChanged;
 | 
						|
    dcce->time = dce->time;
 | 
						|
    dcce->deviceid = dce->deviceid;
 | 
						|
    dcce->sourceid = dce->sourceid;
 | 
						|
    dcce->reason =
 | 
						|
        (dce->flags & DEVCHANGE_DEVICE_CHANGE) ? XIDeviceChange : XISlaveSwitch;
 | 
						|
    dcce->num_classes = 0;
 | 
						|
    dcce->length = bytes_to_int32(len - sizeof(xEvent));
 | 
						|
 | 
						|
    ptr = (char *) &dcce[1];
 | 
						|
    if (dce->buttons.num_buttons) {
 | 
						|
        dcce->num_classes++;
 | 
						|
        ptr += appendButtonInfo(dce, (xXIButtonInfo *) ptr);
 | 
						|
    }
 | 
						|
 | 
						|
    if (nkeys) {
 | 
						|
        dcce->num_classes++;
 | 
						|
        ptr += appendKeyInfo(dce, (xXIKeyInfo *) ptr);
 | 
						|
    }
 | 
						|
 | 
						|
    if (dce->num_valuators) {
 | 
						|
        int i;
 | 
						|
 | 
						|
        dcce->num_classes += dce->num_valuators;
 | 
						|
        for (i = 0; i < dce->num_valuators; i++)
 | 
						|
            ptr += appendValuatorInfo(dce, (xXIValuatorInfo *) ptr, i);
 | 
						|
 | 
						|
        for (i = 0; i < dce->num_valuators; i++) {
 | 
						|
            if (dce->valuators[i].scroll.type != SCROLL_TYPE_NONE) {
 | 
						|
                dcce->num_classes++;
 | 
						|
                ptr += appendScrollInfo(dce, (xXIScrollInfo *) ptr, i);
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    *xi = (xEvent *) dcce;
 | 
						|
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
count_bits(unsigned char *ptr, int len)
 | 
						|
{
 | 
						|
    int bits = 0;
 | 
						|
    unsigned int i;
 | 
						|
    unsigned char x;
 | 
						|
 | 
						|
    for (i = 0; i < len; i++) {
 | 
						|
        x = ptr[i];
 | 
						|
        while (x > 0) {
 | 
						|
            bits += (x & 0x1);
 | 
						|
            x >>= 1;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    return bits;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
eventToDeviceEvent(DeviceEvent *ev, xEvent **xi)
 | 
						|
{
 | 
						|
    int len = sizeof(xXIDeviceEvent);
 | 
						|
    xXIDeviceEvent *xde;
 | 
						|
    int i, btlen, vallen;
 | 
						|
    char *ptr;
 | 
						|
    FP3232 *axisval;
 | 
						|
 | 
						|
    /* FIXME: this should just send the buttons we have, not MAX_BUTTONs. Same
 | 
						|
     * with MAX_VALUATORS below */
 | 
						|
    /* btlen is in 4 byte units */
 | 
						|
    btlen = bytes_to_int32(bits_to_bytes(MAX_BUTTONS));
 | 
						|
    len += btlen * 4;           /* buttonmask len */
 | 
						|
 | 
						|
    vallen = count_bits(ev->valuators.mask, ARRAY_SIZE(ev->valuators.mask));
 | 
						|
    len += vallen * 2 * sizeof(uint32_t);       /* axisvalues */
 | 
						|
    vallen = bytes_to_int32(bits_to_bytes(MAX_VALUATORS));
 | 
						|
    len += vallen * 4;          /* valuators mask */
 | 
						|
 | 
						|
    *xi = calloc(1, len);
 | 
						|
    if (*xi == NULL)
 | 
						|
        return BadAlloc;
 | 
						|
    xde = (xXIDeviceEvent *) * xi;
 | 
						|
    xde->type = GenericEvent;
 | 
						|
    xde->extension = IReqCode;
 | 
						|
    xde->evtype = GetXI2Type(ev->type);
 | 
						|
    xde->time = ev->time;
 | 
						|
    xde->length = bytes_to_int32(len - sizeof(xEvent));
 | 
						|
    if (IsTouchEvent((InternalEvent *) ev))
 | 
						|
        xde->detail = ev->touchid;
 | 
						|
    else
 | 
						|
        xde->detail = ev->detail.button;
 | 
						|
 | 
						|
    xde->root = ev->root;
 | 
						|
    xde->buttons_len = btlen;
 | 
						|
    xde->valuators_len = vallen;
 | 
						|
    xde->deviceid = ev->deviceid;
 | 
						|
    xde->sourceid = ev->sourceid;
 | 
						|
    xde->root_x = double_to_fp1616(ev->root_x + ev->root_x_frac);
 | 
						|
    xde->root_y = double_to_fp1616(ev->root_y + ev->root_y_frac);
 | 
						|
 | 
						|
    if (IsTouchEvent((InternalEvent *)ev)) {
 | 
						|
        if (ev->type == ET_TouchUpdate)
 | 
						|
            xde->flags |= (ev->flags & TOUCH_PENDING_END) ? XITouchPendingEnd : 0;
 | 
						|
 | 
						|
        if (ev->flags & TOUCH_POINTER_EMULATED)
 | 
						|
            xde->flags |= XITouchEmulatingPointer;
 | 
						|
    } else {
 | 
						|
        xde->flags = ev->flags;
 | 
						|
 | 
						|
        if (ev->key_repeat)
 | 
						|
            xde->flags |= XIKeyRepeat;
 | 
						|
    }
 | 
						|
 | 
						|
    xde->mods.base_mods = ev->mods.base;
 | 
						|
    xde->mods.latched_mods = ev->mods.latched;
 | 
						|
    xde->mods.locked_mods = ev->mods.locked;
 | 
						|
    xde->mods.effective_mods = ev->mods.effective;
 | 
						|
 | 
						|
    xde->group.base_group = ev->group.base;
 | 
						|
    xde->group.latched_group = ev->group.latched;
 | 
						|
    xde->group.locked_group = ev->group.locked;
 | 
						|
    xde->group.effective_group = ev->group.effective;
 | 
						|
 | 
						|
    ptr = (char *) &xde[1];
 | 
						|
    for (i = 0; i < sizeof(ev->buttons) * 8; i++) {
 | 
						|
        if (BitIsOn(ev->buttons, i))
 | 
						|
            SetBit(ptr, i);
 | 
						|
    }
 | 
						|
 | 
						|
    ptr += xde->buttons_len * 4;
 | 
						|
    axisval = (FP3232 *) (ptr + xde->valuators_len * 4);
 | 
						|
    for (i = 0; i < MAX_VALUATORS; i++) {
 | 
						|
        if (BitIsOn(ev->valuators.mask, i)) {
 | 
						|
            SetBit(ptr, i);
 | 
						|
            *axisval = double_to_fp3232(ev->valuators.data[i]);
 | 
						|
            axisval++;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
eventToTouchOwnershipEvent(TouchOwnershipEvent *ev, xEvent **xi)
 | 
						|
{
 | 
						|
    int len = sizeof(xXITouchOwnershipEvent);
 | 
						|
    xXITouchOwnershipEvent *xtoe;
 | 
						|
 | 
						|
    *xi = calloc(1, len);
 | 
						|
    if (*xi == NULL)
 | 
						|
        return BadAlloc;
 | 
						|
    xtoe = (xXITouchOwnershipEvent *) * xi;
 | 
						|
    xtoe->type = GenericEvent;
 | 
						|
    xtoe->extension = IReqCode;
 | 
						|
    xtoe->length = bytes_to_int32(len - sizeof(xEvent));
 | 
						|
    xtoe->evtype = GetXI2Type(ev->type);
 | 
						|
    xtoe->deviceid = ev->deviceid;
 | 
						|
    xtoe->time = ev->time;
 | 
						|
    xtoe->sourceid = ev->sourceid;
 | 
						|
    xtoe->touchid = ev->touchid;
 | 
						|
    xtoe->flags = 0;            /* we don't have wire flags for ownership yet */
 | 
						|
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
eventToRawEvent(RawDeviceEvent *ev, xEvent **xi)
 | 
						|
{
 | 
						|
    xXIRawEvent *raw;
 | 
						|
    int vallen, nvals;
 | 
						|
    int i, len = sizeof(xXIRawEvent);
 | 
						|
    char *ptr;
 | 
						|
    FP3232 *axisval, *axisval_raw;
 | 
						|
 | 
						|
    nvals = count_bits(ev->valuators.mask, sizeof(ev->valuators.mask));
 | 
						|
    len += nvals * sizeof(FP3232) * 2;  /* 8 byte per valuator, once
 | 
						|
                                           raw, once processed */
 | 
						|
    vallen = bytes_to_int32(bits_to_bytes(MAX_VALUATORS));
 | 
						|
    len += vallen * 4;          /* valuators mask */
 | 
						|
 | 
						|
    *xi = calloc(1, len);
 | 
						|
    if (*xi == NULL)
 | 
						|
        return BadAlloc;
 | 
						|
    raw = (xXIRawEvent *) * xi;
 | 
						|
    raw->type = GenericEvent;
 | 
						|
    raw->extension = IReqCode;
 | 
						|
    raw->evtype = GetXI2Type(ev->type);
 | 
						|
    raw->time = ev->time;
 | 
						|
    raw->length = bytes_to_int32(len - sizeof(xEvent));
 | 
						|
    raw->detail = ev->detail.button;
 | 
						|
    raw->deviceid = ev->deviceid;
 | 
						|
    raw->sourceid = ev->sourceid;
 | 
						|
    raw->valuators_len = vallen;
 | 
						|
    raw->flags = ev->flags;
 | 
						|
 | 
						|
    ptr = (char *) &raw[1];
 | 
						|
    axisval = (FP3232 *) (ptr + raw->valuators_len * 4);
 | 
						|
    axisval_raw = axisval + nvals;
 | 
						|
    for (i = 0; i < MAX_VALUATORS; i++) {
 | 
						|
        if (BitIsOn(ev->valuators.mask, i)) {
 | 
						|
            SetBit(ptr, i);
 | 
						|
            *axisval = double_to_fp3232(ev->valuators.data[i]);
 | 
						|
            *axisval_raw = double_to_fp3232(ev->valuators.data_raw[i]);
 | 
						|
            axisval++;
 | 
						|
            axisval_raw++;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
eventToBarrierEvent(BarrierEvent *ev, xEvent **xi)
 | 
						|
{
 | 
						|
    xXIBarrierEvent *barrier;
 | 
						|
    int len = sizeof(xXIBarrierEvent);
 | 
						|
 | 
						|
    *xi = calloc(1, len);
 | 
						|
    if (*xi == NULL)
 | 
						|
        return BadAlloc;
 | 
						|
    barrier = (xXIBarrierEvent*) *xi;
 | 
						|
    barrier->type = GenericEvent;
 | 
						|
    barrier->extension = IReqCode;
 | 
						|
    barrier->evtype = GetXI2Type(ev->type);
 | 
						|
    barrier->length = bytes_to_int32(len - sizeof(xEvent));
 | 
						|
    barrier->deviceid = ev->deviceid;
 | 
						|
    barrier->sourceid = ev->sourceid;
 | 
						|
    barrier->time = ev->time;
 | 
						|
    barrier->event = ev->window;
 | 
						|
    barrier->root = ev->root;
 | 
						|
    barrier->dx = double_to_fp3232(ev->dx);
 | 
						|
    barrier->dy = double_to_fp3232(ev->dy);
 | 
						|
    barrier->dtime = ev->dt;
 | 
						|
    barrier->flags = ev->flags;
 | 
						|
    barrier->eventid = ev->event_id;
 | 
						|
    barrier->barrier = ev->barrierid;
 | 
						|
    barrier->root_x = double_to_fp1616(ev->root_x);
 | 
						|
    barrier->root_y = double_to_fp1616(ev->root_y);
 | 
						|
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
eventToGesturePinchEvent(GestureEvent *ev, xEvent **xi)
 | 
						|
{
 | 
						|
    int len = sizeof(xXIGesturePinchEvent);
 | 
						|
    xXIGesturePinchEvent *xpe;
 | 
						|
 | 
						|
    *xi = calloc(1, len);
 | 
						|
    if (*xi == NULL)
 | 
						|
        return BadAlloc;
 | 
						|
    xpe = (xXIGesturePinchEvent *) * xi;
 | 
						|
    xpe->type = GenericEvent;
 | 
						|
    xpe->extension = IReqCode;
 | 
						|
    xpe->evtype = GetXI2Type(ev->type);
 | 
						|
    xpe->time = ev->time;
 | 
						|
    xpe->length = bytes_to_int32(len - sizeof(xEvent));
 | 
						|
    xpe->detail = ev->num_touches;
 | 
						|
 | 
						|
    xpe->root = ev->root;
 | 
						|
    xpe->deviceid = ev->deviceid;
 | 
						|
    xpe->sourceid = ev->sourceid;
 | 
						|
    xpe->root_x = double_to_fp1616(ev->root_x);
 | 
						|
    xpe->root_y = double_to_fp1616(ev->root_y);
 | 
						|
    xpe->flags |= (ev->flags & GESTURE_CANCELLED) ? XIGesturePinchEventCancelled : 0;
 | 
						|
 | 
						|
    xpe->delta_x = double_to_fp1616(ev->delta_x);
 | 
						|
    xpe->delta_y = double_to_fp1616(ev->delta_y);
 | 
						|
    xpe->delta_unaccel_x = double_to_fp1616(ev->delta_unaccel_x);
 | 
						|
    xpe->delta_unaccel_y = double_to_fp1616(ev->delta_unaccel_y);
 | 
						|
    xpe->scale = double_to_fp1616(ev->scale);
 | 
						|
    xpe->delta_angle = double_to_fp1616(ev->delta_angle);
 | 
						|
 | 
						|
    xpe->mods.base_mods = ev->mods.base;
 | 
						|
    xpe->mods.latched_mods = ev->mods.latched;
 | 
						|
    xpe->mods.locked_mods = ev->mods.locked;
 | 
						|
    xpe->mods.effective_mods = ev->mods.effective;
 | 
						|
 | 
						|
    xpe->group.base_group = ev->group.base;
 | 
						|
    xpe->group.latched_group = ev->group.latched;
 | 
						|
    xpe->group.locked_group = ev->group.locked;
 | 
						|
    xpe->group.effective_group = ev->group.effective;
 | 
						|
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
eventToGestureSwipeEvent(GestureEvent *ev, xEvent **xi)
 | 
						|
{
 | 
						|
    int len = sizeof(xXIGestureSwipeEvent);
 | 
						|
    xXIGestureSwipeEvent *xde;
 | 
						|
 | 
						|
    *xi = calloc(1, len);
 | 
						|
    if (*xi == NULL)
 | 
						|
        return BadAlloc;
 | 
						|
    xde = (xXIGestureSwipeEvent *) * xi;
 | 
						|
    xde->type = GenericEvent;
 | 
						|
    xde->extension = IReqCode;
 | 
						|
    xde->evtype = GetXI2Type(ev->type);
 | 
						|
    xde->time = ev->time;
 | 
						|
    xde->length = bytes_to_int32(len - sizeof(xEvent));
 | 
						|
    xde->detail = ev->num_touches;
 | 
						|
 | 
						|
    xde->root = ev->root;
 | 
						|
    xde->deviceid = ev->deviceid;
 | 
						|
    xde->sourceid = ev->sourceid;
 | 
						|
    xde->root_x = double_to_fp1616(ev->root_x);
 | 
						|
    xde->root_y = double_to_fp1616(ev->root_y);
 | 
						|
    xde->flags |= (ev->flags & GESTURE_CANCELLED) ? XIGestureSwipeEventCancelled : 0;
 | 
						|
 | 
						|
    xde->delta_x = double_to_fp1616(ev->delta_x);
 | 
						|
    xde->delta_y = double_to_fp1616(ev->delta_y);
 | 
						|
    xde->delta_unaccel_x = double_to_fp1616(ev->delta_unaccel_x);
 | 
						|
    xde->delta_unaccel_y = double_to_fp1616(ev->delta_unaccel_y);
 | 
						|
 | 
						|
    xde->mods.base_mods = ev->mods.base;
 | 
						|
    xde->mods.latched_mods = ev->mods.latched;
 | 
						|
    xde->mods.locked_mods = ev->mods.locked;
 | 
						|
    xde->mods.effective_mods = ev->mods.effective;
 | 
						|
 | 
						|
    xde->group.base_group = ev->group.base;
 | 
						|
    xde->group.latched_group = ev->group.latched;
 | 
						|
    xde->group.locked_group = ev->group.locked;
 | 
						|
    xde->group.effective_group = ev->group.effective;
 | 
						|
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Return the corresponding core type for the given event or 0 if no core
 | 
						|
 * equivalent exists.
 | 
						|
 */
 | 
						|
int
 | 
						|
GetCoreType(enum EventType type)
 | 
						|
{
 | 
						|
    int coretype = 0;
 | 
						|
 | 
						|
    switch (type) {
 | 
						|
    case ET_Motion:
 | 
						|
        coretype = MotionNotify;
 | 
						|
        break;
 | 
						|
    case ET_ButtonPress:
 | 
						|
        coretype = ButtonPress;
 | 
						|
        break;
 | 
						|
    case ET_ButtonRelease:
 | 
						|
        coretype = ButtonRelease;
 | 
						|
        break;
 | 
						|
    case ET_KeyPress:
 | 
						|
        coretype = KeyPress;
 | 
						|
        break;
 | 
						|
    case ET_KeyRelease:
 | 
						|
        coretype = KeyRelease;
 | 
						|
        break;
 | 
						|
    default:
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    return coretype;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Return the corresponding XI 1.x type for the given event or 0 if no
 | 
						|
 * equivalent exists.
 | 
						|
 */
 | 
						|
int
 | 
						|
GetXIType(enum EventType type)
 | 
						|
{
 | 
						|
    int xitype = 0;
 | 
						|
 | 
						|
    switch (type) {
 | 
						|
    case ET_Motion:
 | 
						|
        xitype = DeviceMotionNotify;
 | 
						|
        break;
 | 
						|
    case ET_ButtonPress:
 | 
						|
        xitype = DeviceButtonPress;
 | 
						|
        break;
 | 
						|
    case ET_ButtonRelease:
 | 
						|
        xitype = DeviceButtonRelease;
 | 
						|
        break;
 | 
						|
    case ET_KeyPress:
 | 
						|
        xitype = DeviceKeyPress;
 | 
						|
        break;
 | 
						|
    case ET_KeyRelease:
 | 
						|
        xitype = DeviceKeyRelease;
 | 
						|
        break;
 | 
						|
    case ET_ProximityIn:
 | 
						|
        xitype = ProximityIn;
 | 
						|
        break;
 | 
						|
    case ET_ProximityOut:
 | 
						|
        xitype = ProximityOut;
 | 
						|
        break;
 | 
						|
    default:
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    return xitype;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Return the corresponding XI 2.x type for the given event or 0 if no
 | 
						|
 * equivalent exists.
 | 
						|
 */
 | 
						|
int
 | 
						|
GetXI2Type(enum EventType type)
 | 
						|
{
 | 
						|
    int xi2type = 0;
 | 
						|
 | 
						|
    switch (type) {
 | 
						|
    case ET_Motion:
 | 
						|
        xi2type = XI_Motion;
 | 
						|
        break;
 | 
						|
    case ET_ButtonPress:
 | 
						|
        xi2type = XI_ButtonPress;
 | 
						|
        break;
 | 
						|
    case ET_ButtonRelease:
 | 
						|
        xi2type = XI_ButtonRelease;
 | 
						|
        break;
 | 
						|
    case ET_KeyPress:
 | 
						|
        xi2type = XI_KeyPress;
 | 
						|
        break;
 | 
						|
    case ET_KeyRelease:
 | 
						|
        xi2type = XI_KeyRelease;
 | 
						|
        break;
 | 
						|
    case ET_Enter:
 | 
						|
        xi2type = XI_Enter;
 | 
						|
        break;
 | 
						|
    case ET_Leave:
 | 
						|
        xi2type = XI_Leave;
 | 
						|
        break;
 | 
						|
    case ET_Hierarchy:
 | 
						|
        xi2type = XI_HierarchyChanged;
 | 
						|
        break;
 | 
						|
    case ET_DeviceChanged:
 | 
						|
        xi2type = XI_DeviceChanged;
 | 
						|
        break;
 | 
						|
    case ET_RawKeyPress:
 | 
						|
        xi2type = XI_RawKeyPress;
 | 
						|
        break;
 | 
						|
    case ET_RawKeyRelease:
 | 
						|
        xi2type = XI_RawKeyRelease;
 | 
						|
        break;
 | 
						|
    case ET_RawButtonPress:
 | 
						|
        xi2type = XI_RawButtonPress;
 | 
						|
        break;
 | 
						|
    case ET_RawButtonRelease:
 | 
						|
        xi2type = XI_RawButtonRelease;
 | 
						|
        break;
 | 
						|
    case ET_RawMotion:
 | 
						|
        xi2type = XI_RawMotion;
 | 
						|
        break;
 | 
						|
    case ET_RawTouchBegin:
 | 
						|
        xi2type = XI_RawTouchBegin;
 | 
						|
        break;
 | 
						|
    case ET_RawTouchUpdate:
 | 
						|
        xi2type = XI_RawTouchUpdate;
 | 
						|
        break;
 | 
						|
    case ET_RawTouchEnd:
 | 
						|
        xi2type = XI_RawTouchEnd;
 | 
						|
        break;
 | 
						|
    case ET_FocusIn:
 | 
						|
        xi2type = XI_FocusIn;
 | 
						|
        break;
 | 
						|
    case ET_FocusOut:
 | 
						|
        xi2type = XI_FocusOut;
 | 
						|
        break;
 | 
						|
    case ET_TouchBegin:
 | 
						|
        xi2type = XI_TouchBegin;
 | 
						|
        break;
 | 
						|
    case ET_TouchEnd:
 | 
						|
        xi2type = XI_TouchEnd;
 | 
						|
        break;
 | 
						|
    case ET_TouchUpdate:
 | 
						|
        xi2type = XI_TouchUpdate;
 | 
						|
        break;
 | 
						|
    case ET_TouchOwnership:
 | 
						|
        xi2type = XI_TouchOwnership;
 | 
						|
        break;
 | 
						|
    case ET_BarrierHit:
 | 
						|
        xi2type = XI_BarrierHit;
 | 
						|
        break;
 | 
						|
    case ET_BarrierLeave:
 | 
						|
        xi2type = XI_BarrierLeave;
 | 
						|
        break;
 | 
						|
    case ET_GesturePinchBegin:
 | 
						|
        xi2type = XI_GesturePinchBegin;
 | 
						|
        break;
 | 
						|
    case ET_GesturePinchUpdate:
 | 
						|
        xi2type = XI_GesturePinchUpdate;
 | 
						|
        break;
 | 
						|
    case ET_GesturePinchEnd:
 | 
						|
        xi2type = XI_GesturePinchEnd;
 | 
						|
        break;
 | 
						|
    case ET_GestureSwipeBegin:
 | 
						|
        xi2type = XI_GestureSwipeBegin;
 | 
						|
        break;
 | 
						|
    case ET_GestureSwipeUpdate:
 | 
						|
        xi2type = XI_GestureSwipeUpdate;
 | 
						|
        break;
 | 
						|
    case ET_GestureSwipeEnd:
 | 
						|
        xi2type = XI_GestureSwipeEnd;
 | 
						|
        break;
 | 
						|
    default:
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    return xi2type;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Converts a gesture type to corresponding Gesture{Pinch,Swipe}Begin.
 | 
						|
 * Returns 0 if the input type is not a gesture.
 | 
						|
 */
 | 
						|
enum EventType
 | 
						|
GestureTypeToBegin(enum EventType type)
 | 
						|
{
 | 
						|
    switch (type) {
 | 
						|
    case ET_GesturePinchBegin:
 | 
						|
    case ET_GesturePinchUpdate:
 | 
						|
    case ET_GesturePinchEnd:
 | 
						|
        return ET_GesturePinchBegin;
 | 
						|
    case ET_GestureSwipeBegin:
 | 
						|
    case ET_GestureSwipeUpdate:
 | 
						|
    case ET_GestureSwipeEnd:
 | 
						|
        return ET_GestureSwipeBegin;
 | 
						|
    default:
 | 
						|
        return 0;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Converts a gesture type to corresponding Gesture{Pinch,Swipe}End.
 | 
						|
 * Returns 0 if the input type is not a gesture.
 | 
						|
 */
 | 
						|
enum EventType
 | 
						|
GestureTypeToEnd(enum EventType type)
 | 
						|
{
 | 
						|
    switch (type) {
 | 
						|
    case ET_GesturePinchBegin:
 | 
						|
    case ET_GesturePinchUpdate:
 | 
						|
    case ET_GesturePinchEnd:
 | 
						|
        return ET_GesturePinchEnd;
 | 
						|
    case ET_GestureSwipeBegin:
 | 
						|
    case ET_GestureSwipeUpdate:
 | 
						|
    case ET_GestureSwipeEnd:
 | 
						|
        return ET_GestureSwipeEnd;
 | 
						|
    default:
 | 
						|
        return 0;
 | 
						|
    }
 | 
						|
}
 |