summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2009-03-10 16:08:14 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2009-03-20 15:17:56 +1000
commit4cc6a96d7171e567a9bd5a10f552bb953077aafb (patch)
tree332195d0122f66753a046e9736e38bf7b0d80b2d
parenta668d91e28d5a3042a8ce0d087474883b046869a (diff)
input: add support for RawDeviceEvents.
-rw-r--r--Xi/exevents.c34
-rw-r--r--dix/eventconvert.c49
-rw-r--r--dix/events.c6
-rw-r--r--dix/getevents.c55
-rw-r--r--include/events.h26
-rw-r--r--mi/mieq.c3
6 files changed, 169 insertions, 4 deletions
diff --git a/Xi/exevents.c b/Xi/exevents.c
index 84043357a..5dae990c6 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -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);
diff --git a/dix/eventconvert.c b/dix/eventconvert.c
index 553d95330..4cd5567e8 100644
--- a/dix/eventconvert.c
+++ b/dix/eventconvert.c
@@ -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;
}
diff --git a/dix/events.c b/dix/events.c
index d4eea2c44..adc180bcd 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -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)
diff --git a/dix/getevents.c b/dix/getevents.c
index 01a98646a..b0bacbdbc 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -137,6 +137,33 @@ init_event(DeviceIntPtr dev, DeviceEvent* event, Time ms)
}
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;
}
diff --git a/include/events.h b/include/events.h
index c6eeae4d4..a289662d4 100644
--- a/include/events.h
+++ b/include/events.h
@@ -59,6 +59,7 @@ enum {
#if XFreeXDGA
ET_DGAEvent,
#endif
+ ET_Raw,
ET_Internal = 0xFF /* First byte */
} EventType;
@@ -171,6 +172,30 @@ typedef struct
#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;
diff --git a/mi/mieq.c b/mi/mieq.c
index efec55a63..0dedbee77 100644
--- a/mi/mieq.c
+++ b/mi/mieq.c
@@ -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);