input: add support for RawDeviceEvents.

This commit is contained in:
Peter Hutterer 2009-03-10 16:08:14 +10:00
parent a668d91e28
commit 4cc6a96d71
6 changed files with 169 additions and 4 deletions

View File

@ -75,6 +75,7 @@ SOFTWARE.
#include "listdev.h" /* for CopySwapXXXClass */
#include "xace.h"
#include "querydev.h" /* For List*Info */
#include "eventconvert.h"
#include <X11/extensions/XKBproto.h>
#include "xkbsrv.h"
@ -914,6 +915,33 @@ UpdateDeviceState(DeviceIntPtr device, DeviceEvent* event)
return DEFAULT;
}
static void
ProcessRawEvent(RawDeviceEvent *ev, DeviceIntPtr device)
{
GrabPtr grab = device->deviceGrab.grab;
if (grab)
DeliverGrabbedEvent(ev, device, FALSE);
else { /* deliver to all root windows */
xEvent *xi;
int i;
i = EventToXI2((InternalEvent*)ev, (xEvent**)&xi);
if (i != Success)
{
ErrorF("[Xi] %s: XI2 conversion failed in ProcessRawEvent (%d)\n",
device->name, i);
return;
}
for (i = 0; i < screenInfo.numScreens; i++)
DeliverEventsToWindow(device, WindowTable[i], xi, 1,
GetEventFilter(device, xi), NULL,
device->id);
xfree(xi);
}
}
/**
* Main device event processing function.
* Called from when processing the events from the event queue.
@ -935,6 +963,12 @@ ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device)
CHECKEVENT(ev);
if (ev->u.any.type == ET_Raw)
{
ProcessRawEvent((RawDeviceEvent*)ev, device);
return;
}
if (IsPointerDevice(device))
{
kbd = GetPairedDevice(device);

View File

@ -52,6 +52,7 @@ static int getValuatorEvents(DeviceEvent *ev, deviceValuator *xv);
static int eventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count);
static int eventToClassesChanged(DeviceChangedEvent *ev, xEvent **dcce);
static int eventToDeviceEvent(DeviceEvent *ev, xEvent **xi);
static int eventToRawEvent(RawDeviceEvent *ev, xEvent **xi);
/**
* Convert the given event to the respective core event.
*
@ -126,6 +127,7 @@ EventToXI(InternalEvent *ev, xEvent **xi, int *count)
case ET_ProximityOut:
return eventToKeyButtonPointer((DeviceEvent*)ev, xi, count);
case ET_DeviceChanged:
case ET_Raw:
*count = 0;
*xi = NULL;
return Success;
@ -164,6 +166,8 @@ EventToXI2(InternalEvent *ev, xEvent **xi)
return Success;
case ET_DeviceChanged:
return eventToClassesChanged((DeviceChangedEvent*)ev, xi);
case ET_Raw:
return eventToRawEvent((RawDeviceEvent*)ev, xi);
}
@ -412,6 +416,50 @@ eventToDeviceEvent(DeviceEvent *ev, xEvent **xi)
return Success;
}
static int
eventToRawEvent(RawDeviceEvent *ev, xEvent **xi)
{
xXIRawDeviceEvent* raw;
int vallen, nvals;
int i, len = sizeof(xXIRawDeviceEvent);
char *ptr;
FP3232 *axisval;
nvals = count_bits(ev->valuators.mask, sizeof(ev->valuators.mask)/sizeof(ev->valuators.mask[0]));
len += nvals * (2 * sizeof(uint32_t)) * 2; /* 8 byte per valuator, once
raw, once processed */
vallen = (((MAX_VALUATORS + 7)/8) + 3)/4;
len += vallen * 4; /* valuators mask */
*xi = xcalloc(1, len);
raw = (xXIRawDeviceEvent*)*xi;
raw->type = GenericEvent;
raw->extension = IReqCode;
raw->evtype = GetXI2Type((InternalEvent*)ev);
raw->time = ev->time;
raw->length = (len - sizeof(xEvent) + 3)/4;
raw->eventtype = ev->subtype;
raw->detail = ev->detail.button;
raw->deviceid = ev->deviceid;
raw->valuators_len = vallen;
ptr = (char*)&raw[1];
axisval = (FP3232*)(ptr + raw->valuators_len * 4);
for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++)
{
if (BitIsOn(ev->valuators.mask, i))
{
SetBit(ptr, i);
axisval->integral = ev->valuators.data[i];
(axisval + nvals)->integral = ev->valuators.data_raw[i];
axisval++;
/* FIXME: frac part */
}
}
return Success;
}
/**
* Return the corresponding core type for the given event or 0 if no core
* equivalent exists.
@ -472,6 +520,7 @@ GetXI2Type(InternalEvent *event)
case ET_Leave: xi2type = XI_Leave; break;
case ET_Hierarchy: xi2type = XI_HierarchyChanged; break;
case ET_DeviceChanged: xi2type = XI_DeviceChanged; break;
case ET_Raw: xi2type = XI_RawEvent; break;
default:
break;
}

View File

@ -420,7 +420,7 @@ static Mask filters[MAXDEVICES][128] = {
*
* @see GetEventMask
*/
static Mask
Mask
GetEventFilter(DeviceIntPtr dev, xEvent *event)
{
if (event->u.u.type != GenericEvent)
@ -2215,6 +2215,10 @@ FixUpEventFromWindow(
if (XI2_EVENT(xE))
{
xXIDeviceEvent* event = (xXIDeviceEvent*)xE;
if (event->evtype == XI_RawEvent)
return;
event->root = RootWindow(pDev)->drawable.id;
event->event = pWin->drawable.id;
if (pSprite->hot.pScreen == pWin->drawable.pScreen)

View File

@ -136,6 +136,33 @@ init_event(DeviceIntPtr dev, DeviceEvent* event, Time ms)
event->sourceid = dev->id;
}
static void
init_raw(DeviceIntPtr dev, RawDeviceEvent *event, Time ms, int subtype,
int detail)
{
memset(event, 0, sizeof(RawDeviceEvent));
event->header = ET_Internal;
event->length = sizeof(RawDeviceEvent);
event->type = ET_Raw;
event->subtype = subtype;
event->time = ms;
event->deviceid = dev->id;
event->sourceid = dev->id;
event->detail.button = detail;
}
static void
set_raw_valuators(RawDeviceEvent *event, int first, int num, int *valuators, int32_t* data)
{
int i;
for (i = first; i < first + num; i++)
{
SetBit(event->valuators.mask, i);
data[i] = valuators[i - first];
}
}
static void
set_valuators(DeviceIntPtr dev, DeviceEvent* event, int first_valuator,
int num_valuators, int *valuators)
@ -802,6 +829,7 @@ GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
int num_events = 0;
CARD32 ms = 0;
DeviceEvent *event;
RawDeviceEvent *raw;
if (!events ||!pDev->key || !pDev->focus || !pDev->kbdfeed ||
(type != KeyPress && type != KeyRelease) ||
@ -822,10 +850,21 @@ GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
return 0;
}
ms = GetTimeInMillis();
raw = (RawDeviceEvent*)events->event;
events++;
num_events++;
init_raw(pDev, raw, ms, type, key_code);
set_raw_valuators(raw, first_valuator, num_valuators, valuators,
raw->valuators.data_raw);
if (num_valuators)
clipValuators(pDev, first_valuator, num_valuators, valuators);
ms = GetTimeInMillis();
set_raw_valuators(raw, first_valuator, num_valuators, valuators,
raw->valuators.data);
event = (DeviceEvent*) events->event;
init_event(pDev, event, ms);
@ -949,6 +988,7 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
int num_events = 1;
CARD32 ms;
DeviceEvent *event;
RawDeviceEvent *raw;
int x, y, /* switches between device and screen coords */
cx, cy; /* only screen coordinates */
ScreenPtr scr = miPointerGetScreen(pDev);
@ -965,6 +1005,14 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
events = updateFromMaster(events, pDev, &num_events);
raw = (RawDeviceEvent*)events->event;
events++;
num_events++;
init_raw(pDev, raw, ms, type, buttons);
set_raw_valuators(raw, first_valuator, num_valuators, valuators,
raw->valuators.data_raw);
if (flags & POINTER_ABSOLUTE)
{
if (flags & POINTER_SCREEN) /* valuators are in screen coords */
@ -985,10 +1033,12 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
moveRelative(pDev, &x, &y, first_valuator, num_valuators, valuators);
}
set_raw_valuators(raw, first_valuator, num_valuators, valuators,
raw->valuators.data);
positionSprite(pDev, &x, &y, scr, &cx, &cy);
updateHistory(pDev, first_valuator, num_valuators, ms);
/* Update the valuators with the true value sent to the client*/
if (num_valuators >= 1 && first_valuator == 0)
valuators[0] = x;
@ -1023,7 +1073,6 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
set_valuators(pDev, event, first_valuator, num_valuators, valuators);
return num_events;
}

View File

@ -59,6 +59,7 @@ enum {
#if XFreeXDGA
ET_DGAEvent,
#endif
ET_Raw,
ET_Internal = 0xFF /* First byte */
} EventType;
@ -170,6 +171,30 @@ typedef struct
} DGAEvent;
#endif
/**
* Raw event, contains the data as posted by the device.
*/
typedef struct
{
unsigned char header; /**< Always ET_Internal */
int type; /**< ET_Raw */
int length; /**< Length in bytes */
Time time; /**< Time in ms */
int subtype; /**< KeyPress, KeyRelease, ButtonPress,
ButtonRelease, MotionNotify */
int deviceid; /**< Device to post this event for */
int sourceid; /**< The physical source device */
union {
uint32_t button; /**< Button number */
uint32_t key; /**< Key code */
} detail;
struct {
uint8_t mask[(MAX_VALUATORS + 7)/8]; /**< Valuator mask */
int32_t data[MAX_VALUATORS]; /**< Valuator data */
int32_t data_raw[MAX_VALUATORS]; /**< Valuator data as posted */
} valuators;
} RawDeviceEvent;
/**
* Event type used inside the X server for input event
* processing.
@ -188,6 +213,7 @@ typedef struct
#if XFreeXDGA
DGAEvent dga;
#endif
RawDeviceEvent raw;
} u;
} InternalEvent;

View File

@ -277,6 +277,9 @@ ChangeDeviceID(DeviceIntPtr dev, InternalEvent* event)
case ET_DeviceChanged:
event->u.device.deviceid = dev->id;
break;
case ET_Raw:
event->u.raw.deviceid = dev->id;
break;
default:
ErrorF("[mi] Unknown event type (%d), cannot change id.\n",
event->u.any.type);