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 #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 @@ -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; } 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; @@ -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; 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);