diff options
Diffstat (limited to 'dix/getevents.c')
-rw-r--r-- | dix/getevents.c | 518 |
1 files changed, 249 insertions, 269 deletions
diff --git a/dix/getevents.c b/dix/getevents.c index bf9331eae..d352ebe78 100644 --- a/dix/getevents.c +++ b/dix/getevents.c @@ -61,7 +61,7 @@ extern Bool XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies); #include "exevents.h" #include "exglobals.h" #include "extnsionst.h" - +#include "listdev.h" /* for sizing up DeviceClassesChangedEvent */ /* Maximum number of valuators, divided by six, rounded up, to get number * of events. */ @@ -70,6 +70,19 @@ extern Bool XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies); /* Number of motion history events to store. */ #define MOTION_HISTORY_SIZE 256 +/* InputEventList is the container list for all input events generated by the + * DDX. The DDX is expected to call GetEventList() and then pass the list into + * Get{Pointer|Keyboard}Events. + */ +EventListPtr InputEventList = NULL; +int InputEventListLen = 0; + +_X_EXPORT int +GetEventList(EventListPtr* list) +{ + *list = InputEventList; + return InputEventListLen; +} /** * Pick some arbitrary size for Xi motion history. @@ -105,6 +118,43 @@ key_autorepeats(DeviceIntPtr pDev, int key_code) (1 << (key_code & 7))); } +void +CreateClassesChangedEvent(EventList* event, + DeviceIntPtr master, + DeviceIntPtr slave) +{ + deviceClassesChangedEvent *dcce; + int len = sizeof(xEvent); + CARD32 ms = GetTimeInMillis(); + int namelen = 0; /* dummy */ + + /* XXX: ok, this is a bit weird. We need to alloc enough size for the + * event so it can be filled in in POE lateron. Reason being that if + * we realloc the event in POE we can get SIGABRT when we try to free + * or realloc the original pointer. + * We can only do it here as we don't have the EventList in the event + * processing any more. + */ + SizeDeviceInfo(slave, &namelen, &len); + + if (event->evlen < len) + { + event->event = realloc(event->event, len); + if (!event->event) + FatalError("[dix] Cannot allocate memory for " + "DeviceClassesChangedEvent.\n"); + event->evlen = len; + } + + dcce = (deviceClassesChangedEvent*)event->event; + dcce->type = GenericEvent; + dcce->extension = IReqCode; + dcce->evtype = XI_DeviceClassesChangedNotify; + dcce->time = ms; + dcce->new_slave = slave->id; + dcce->length = (len - sizeof(xEvent))/4; +} + /** * Allocate the motion history buffer. */ @@ -212,9 +262,9 @@ updateMotionHistory(DeviceIntPtr pDev, CARD32 ms, int first_valuator, */ _X_EXPORT int GetMaximumEventsNum(void) { - /* Two base events -- core and device, plus valuator events. Multiply - * by two if we're doing non-XKB key repeats. */ - int ret = 2 + MAX_VALUATOR_EVENTS; + /* One base event -- device, plus valuator events. + * Multiply by two if we're doing non-XKB key repeats. */ + int ret = 1 + MAX_VALUATOR_EVENTS; #ifdef XKB if (noXkbExtension) @@ -340,13 +390,14 @@ clipValuators(DeviceIntPtr pDev, int first_valuator, int num_valuators, * last posted, not just x and y; otherwise relative non-x/y * valuators, though a very narrow use case, will be broken. */ -static xEvent * -getValuatorEvents(xEvent *events, DeviceIntPtr pDev, int first_valuator, +static EventList * +getValuatorEvents(EventList *events, DeviceIntPtr pDev, int first_valuator, int num_valuators, int *valuators) { - deviceValuator *xv = (deviceValuator *) events; + deviceValuator *xv; int i = 0, final_valuator = first_valuator + num_valuators; - for (i = first_valuator; i < final_valuator; i += 6, xv++, events++) { + for (i = first_valuator; i < final_valuator; i += 6, events++) { + xv = (deviceValuator*)events->event; xv->type = DeviceValuator; xv->first_valuator = i; xv->num_valuators = ((final_valuator - i) > 6) ? 6 : (final_valuator - i); @@ -379,7 +430,7 @@ getValuatorEvents(xEvent *events, DeviceIntPtr pDev, int first_valuator, * valuators. */ _X_EXPORT int -GetKeyboardEvents(xEvent *events, DeviceIntPtr pDev, int type, int key_code) { +GetKeyboardEvents(EventList *events, DeviceIntPtr pDev, int type, int key_code) { return GetKeyboardValuatorEvents(events, pDev, type, key_code, 0, 0, NULL); } @@ -388,6 +439,9 @@ GetKeyboardEvents(xEvent *events, DeviceIntPtr pDev, int type, int key_code) { * Returns a set of keyboard events for KeyPress/KeyRelease, optionally * also with valuator events. Handles Xi and XKB. * + * DOES NOT GENERATE CORE EVENTS! Core events are created when processing the + * event (ProcessOtherEvent). + * * events is not NULL-terminated; the return value is the number of events. * The DDX is responsible for allocating the event structure in the first * place via GetMaximumEventsNum(), and for freeing it. @@ -402,7 +456,7 @@ GetKeyboardEvents(xEvent *events, DeviceIntPtr pDev, int type, int key_code) { * KeyPresses. */ _X_EXPORT int -GetKeyboardValuatorEvents(xEvent *events, DeviceIntPtr pDev, int type, +GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type, int key_code, int first_valuator, int num_valuators, int *valuators) { int numEvents = 0; @@ -410,6 +464,7 @@ GetKeyboardValuatorEvents(xEvent *events, DeviceIntPtr pDev, int type, KeySym *map = pDev->key->curKeySyms.map; KeySym sym = map[key_code * pDev->key->curKeySyms.mapWidth]; deviceKeyButtonPointer *kbp = NULL; + DeviceIntPtr master; if (!events) return 0; @@ -422,13 +477,25 @@ GetKeyboardValuatorEvents(xEvent *events, DeviceIntPtr pDev, int type, (pDev->coreEvents && !inputInfo.keyboard->key)) return 0; + numEvents = 1; + if (key_code < 8 || key_code > 255) return 0; - if (pDev->coreEvents) - numEvents = 2; - else - numEvents = 1; + master = pDev->u.master; + if (master && master->u.lastSlave != pDev) + { + CreateClassesChangedEvent(events, master, pDev); + + if (master->valuator && pDev->valuator) + { + pDev->lastx = master->lastx; + pDev->lasty = master->lasty; + } + master->u.lastSlave = pDev; + numEvents++; + events++; + } if (num_valuators) { if ((num_valuators / 6) + 1 > MAX_VALUATOR_EVENTS) @@ -477,18 +544,7 @@ GetKeyboardValuatorEvents(xEvent *events, DeviceIntPtr pDev, int type, ms = GetTimeInMillis(); - if (pDev->coreEvents) { - events->u.keyButtonPointer.time = ms; - events->u.u.type = type; - events->u.u.detail = key_code; - if (type == KeyPress) - set_key_down(inputInfo.keyboard, key_code); - else if (type == KeyRelease) - set_key_up(inputInfo.keyboard, key_code); - events++; - } - - kbp = (deviceKeyButtonPointer *) events; + kbp = (deviceKeyButtonPointer *) events->event; kbp->time = ms; kbp->deviceid = pDev->id; kbp->detail = key_code; @@ -512,26 +568,102 @@ GetKeyboardValuatorEvents(xEvent *events, DeviceIntPtr pDev, int type, return numEvents; } +/** + * Initialize an event list and fill with 32 byte sized events. + * This event list is to be passed into GetPointerEvents() and + * GetKeyboardEvents(). + * + * @param num_events Number of elements in list. + */ +_X_EXPORT EventListPtr +InitEventList(int num_events) +{ + EventListPtr events; + int i; + + events = (EventListPtr)xcalloc(num_events, sizeof(EventList)); + if (!events) + return NULL; + + for (i = 0; i < num_events; i++) + { + events[i].evlen = sizeof(xEvent); + events[i].event = xcalloc(1, sizeof(xEvent)); + if (!events[i].event) + { + /* rollback */ + while(i--) + xfree(events[i].event); + xfree(events); + events = NULL; + break; + } + } + + return events; +} + +/** + * Allocs min_size memory for each event in the list. + */ +_X_EXPORT void +SetMinimumEventSize(EventListPtr list, int num_events, int min_size) +{ + if (!list) + return; + + while(num_events--) + { + if (list[num_events].evlen < min_size) + { + list[num_events].evlen = min_size; + list[num_events].event = realloc(list[num_events].event, min_size); + if (!list[num_events].event) + { + FatalError("[dix] Failed to set event list's " + "min_size to %d.\n", min_size); + } + } + } +} /** - * Generate a series of xEvents (returned in xE) representing pointer - * motion, or button presses. Xi and XKB-aware. + * Free an event list. + * + * @param list The list to be freed. + * @param num_events Number of elements in list. + */ +_X_EXPORT void +FreeEventList(EventListPtr list, int num_events) +{ + if (!list) + return; + while(num_events--) + xfree(list[num_events].event); + xfree(list); +} + +/** + * Generate a series of xEvents (filled into the EventList) representing + * pointer motion, or button presses. Xi and XKB-aware. + * + * DOES NOT GENERATE CORE EVENTS! Core events are created when processing the + * event (ProcessOtherEvent). * * events is not NULL-terminated; the return value is the number of events. * The DDX is responsible for allocating the event structure in the first - * place via GetMaximumEventsNum(), and for freeing it. + * place via InitEventList() and GetMaximumEventsNum(), and for freeing it. + * */ _X_EXPORT int -GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons, +GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons, int flags, int first_valuator, int num_valuators, int *valuators) { int num_events = 0, final_valuator = 0; CARD32 ms = 0; deviceKeyButtonPointer *kbp = NULL; - DeviceIntPtr cp = inputInfo.pointer; + DeviceIntPtr master; int x = 0, y = 0; - Bool coreOnly = (pDev == inputInfo.pointer); - ScreenPtr scr = miPointerGetScreen(pDev); /* Sanity checks. */ if (type != MotionNotify && type != ButtonPress && type != ButtonRelease) @@ -545,16 +677,28 @@ GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons, if (!pDev->valuator) return 0; - if (!coreOnly && pDev->coreEvents) - num_events = 2; - else - num_events = 1; - if (type == MotionNotify && num_valuators <= 0) return 0; + ms = GetTimeInMillis(); + + num_events = 1; + + master = pDev->u.master; + if (master && master->u.lastSlave != pDev) + { + CreateClassesChangedEvent(events, master, pDev); + + pDev->lastx = master->lastx; + pDev->lasty = master->lasty; + master->u.lastSlave = pDev; + + num_events++; + events++; + } + /* Do we need to send a DeviceValuator event? */ - if (!coreOnly && num_valuators) { + if (num_valuators) { if ((((num_valuators - 1) / 6) + 1) > MAX_VALUATOR_EVENTS) num_valuators = MAX_VALUATOR_EVENTS * 6; num_events += ((num_valuators - 1) / 6) + 1; @@ -566,8 +710,6 @@ GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons, if (first_valuator < 0 || final_valuator > pDev->valuator->numAxes) return 0; - ms = GetTimeInMillis(); - /* Set x and y based on whether this is absolute or relative, and * accelerate if we need to. */ if (flags & POINTER_ABSOLUTE) { @@ -575,198 +717,82 @@ GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons, x = valuators[0]; } else { - /* If we're sending core events but didn't provide a value, - * translate the core value (but use the device coord if - * it translates to the same coord to preserve sub-pixel - * coord information). If we're not sending core events use - * whatever value we have */ - x = pDev->valuator->lastx; - if(pDev->coreEvents) { - int min = pDev->valuator->axes[0].min_value; - int max = pDev->valuator->axes[0].max_value; - if(min < max) { - if((int)((float)(x-min)*scr->width/(max-min+1)) != cp->valuator->lastx) - x = (int)((float)(cp->valuator->lastx)*(max-min+1)/scr->width)+min; - } - else - x = cp->valuator->lastx; - } + x = pDev->lastx; } if (first_valuator <= 1 && num_valuators >= (2 - first_valuator)) { y = valuators[1 - first_valuator]; } else { - y = pDev->valuator->lasty; - if(pDev->coreEvents) { - int min = pDev->valuator->axes[1].min_value; - int max = pDev->valuator->axes[1].max_value; - if(min < max) { - if((int)((float)(y-min)*scr->height/(max-min+1)) != cp->valuator->lasty) - y = (int)((float)(cp->valuator->lasty)*(max-min+1)/scr->height)+min; - } - else - y = cp->valuator->lasty; - } + y = pDev->lasty; } - - /* Clip both x and y to the defined limits (usually co-ord space limit). */ - clipAxis(pDev, 0, &x); - clipAxis(pDev, 1, &y); } else { if (flags & POINTER_ACCELERATE) acceleratePointer(pDev, first_valuator, num_valuators, valuators); - if (pDev->coreEvents) { - /* Get and convert the core pointer coordinate space into - * device coordinates. Use the device coords if it translates - * into the same position as the core to preserve relative sub- - * pixel movements from the device. */ - int min = pDev->valuator->axes[0].min_value; - int max = pDev->valuator->axes[0].max_value; - if(min < max) { - x = pDev->valuator->lastx; - if((int)((float)(x-min)*scr->width/(max-min+1)) != cp->valuator->lastx) - x = (int)((float)(cp->valuator->lastx)*(max-min+1)/scr->width)+min; - } - else - x = cp->valuator->lastx; - - min = pDev->valuator->axes[1].min_value; - max = pDev->valuator->axes[1].max_value; - if(min < max) { - y = pDev->valuator->lasty; - if((int)((float)(y-min)*scr->height/(max-min+1)) != cp->valuator->lasty) - y = (int)((float)(cp->valuator->lasty)*(max-min+1)/scr->height)+min; - } - else - y = cp->valuator->lasty; - - /* Add relative movement */ - if (first_valuator == 0 && num_valuators >= 1) - x += valuators[0]; - if (first_valuator <= 1 && num_valuators >= (2 - first_valuator)) - y += valuators[1 - first_valuator]; - } - else { - x = pDev->valuator->lastx; - y = pDev->valuator->lasty; - if (first_valuator == 0 && num_valuators >= 1) - x += valuators[0]; - if (first_valuator <= 1 && num_valuators >= (2 - first_valuator)) - y += valuators[1 - first_valuator]; - - if(!coreOnly) { - /* Since we're not sending core-events we must clip both x and y - * to the defined limits so we don't run outside the box. */ - clipAxis(pDev, 0, &x); - clipAxis(pDev, 1, &y); - } - } - } + if (first_valuator == 0 && num_valuators >= 1) + x = pDev->lastx + valuators[0]; + else + x = pDev->lastx; - pDev->valuator->lastx = x; - pDev->valuator->lasty = y; - /* Convert the dev coord back to screen coord if we're - * sending core events */ - if (pDev->coreEvents) { - int min = pDev->valuator->axes[0].min_value; - int max = pDev->valuator->axes[0].max_value; - if(min < max) - x = (int)((float)(x-min)*scr->width/(max-min+1)); - cp->valuator->lastx = x; - min = pDev->valuator->axes[1].min_value; - max = pDev->valuator->axes[1].max_value; - if(min < max) - y = (int)((float)(y-min)*scr->height/(max-min+1)); - cp->valuator->lasty = y; + if (first_valuator <= 1 && num_valuators >= (2 - first_valuator)) + y = pDev->lasty + valuators[1 - first_valuator]; + else + y = pDev->lasty; } + /* Clip both x and y to the defined limits (usually co-ord space limit). */ + clipAxis(pDev, 0, &x); + clipAxis(pDev, 1, &y); + /* This takes care of crossing screens for us, as well as clipping * to the current screen. Right now, we only have one history buffer, * so we don't set this for both the device and core.*/ miPointerSetPosition(pDev, &x, &y, ms); - if (pDev->coreEvents) { - /* miPointerSetPosition may have changed screen */ - scr = miPointerGetScreen(pDev); - if(x != cp->valuator->lastx) { - int min = pDev->valuator->axes[0].min_value; - int max = pDev->valuator->axes[0].max_value; - cp->valuator->lastx = pDev->valuator->lastx = x; - if(min < max) - pDev->valuator->lastx = (int)((float)(x)*(max-min+1)/scr->width)+min; - } - if(y != cp->valuator->lasty) { - int min = pDev->valuator->axes[1].min_value; - int max = pDev->valuator->axes[1].max_value; - cp->valuator->lasty = pDev->valuator->lasty = y; - if(min < max) - pDev->valuator->lasty = (int)((float)(y)*(max-min+1)/scr->height)+min; - } - } - else if (coreOnly) { - cp->valuator->lastx = x; - cp->valuator->lasty = y; - } - /* Drop x and y back into the valuators list, if they were originally * present. */ if (first_valuator == 0 && num_valuators >= 1) - valuators[0] = pDev->valuator->lastx; + valuators[0] = x; if (first_valuator <= 1 && num_valuators >= (2 - first_valuator)) - valuators[1 - first_valuator] = pDev->valuator->lasty; + valuators[1 - first_valuator] = y; updateMotionHistory(pDev, ms, first_valuator, num_valuators, valuators); - /* for some reason inputInfo.pointer does not have coreEvents set */ - if (coreOnly || pDev->coreEvents) { - events->u.u.type = type; - events->u.keyButtonPointer.time = ms; - events->u.keyButtonPointer.rootX = x; - events->u.keyButtonPointer.rootY = y; - - if (type == ButtonPress || type == ButtonRelease) { - /* We hijack SetPointerMapping to work on all core-sending - * devices, so we use the device-specific map here instead of - * the core one. */ - events->u.u.detail = pDev->button->map[buttons]; - } - else { - events->u.u.detail = 0; - } - - events++; + pDev->lastx = x; + pDev->lasty = y; + if (master) + { + master->lastx = x; + master->lasty = y; } - if (!coreOnly) { - kbp = (deviceKeyButtonPointer *) events; - kbp->time = ms; - kbp->deviceid = pDev->id; + kbp = (deviceKeyButtonPointer *) events->event; + kbp->time = ms; + kbp->deviceid = pDev->id; - if (type == MotionNotify) { - kbp->type = DeviceMotionNotify; - } - else { - if (type == ButtonPress) - kbp->type = DeviceButtonPress; - else if (type == ButtonRelease) - kbp->type = DeviceButtonRelease; - kbp->detail = pDev->button->map[buttons]; - } + if (type == MotionNotify) { + kbp->type = DeviceMotionNotify; + } + else { + if (type == ButtonPress) + kbp->type = DeviceButtonPress; + else if (type == ButtonRelease) + kbp->type = DeviceButtonRelease; + kbp->detail = pDev->button->map[buttons]; + } - kbp->root_x = pDev->valuator->lastx; - kbp->root_y = pDev->valuator->lasty; + kbp->root_x = x; + kbp->root_y = y; - events++; - if (num_valuators) { - kbp->deviceid |= MORE_EVENTS; - clipValuators(pDev, first_valuator, num_valuators, valuators); - events = getValuatorEvents(events, pDev, first_valuator, - num_valuators, valuators); - } + events++; + if (num_valuators) { + kbp->deviceid |= MORE_EVENTS; + clipValuators(pDev, first_valuator, num_valuators, valuators); + events = getValuatorEvents(events, pDev, first_valuator, + num_valuators, valuators); } return num_events; @@ -781,11 +807,12 @@ GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons, * place via GetMaximumEventsNum(), and for freeing it. */ _X_EXPORT int -GetProximityEvents(xEvent *events, DeviceIntPtr pDev, int type, +GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type, int first_valuator, int num_valuators, int *valuators) { int num_events = 1; - deviceKeyButtonPointer *kbp = (deviceKeyButtonPointer *) events; + deviceKeyButtonPointer *kbp; + DeviceIntPtr master; /* Sanity checks. */ if (type != ProximityIn && type != ProximityOut) @@ -809,6 +836,20 @@ GetProximityEvents(xEvent *events, DeviceIntPtr pDev, int type, (num_valuators + first_valuator) > pDev->valuator->numAxes) return 0; + master = pDev->u.master; + if (master && master->u.lastSlave != pDev) + { + CreateClassesChangedEvent(events, master, pDev); + + pDev->lastx = master->lastx; + pDev->lasty = master->lasty; + master->u.lastSlave = pDev; + + num_events++; + events++; + } + + kbp = (deviceKeyButtonPointer *) events->event; kbp->type = type; kbp->deviceid = pDev->id; kbp->detail = 0; @@ -825,71 +866,6 @@ GetProximityEvents(xEvent *events, DeviceIntPtr pDev, int type, return num_events; } - -/** - * Note that pDev was the last device to send a core event. This function - * copies the complete keymap from the originating device to the core - * device, and makes sure the appropriate notifications are generated. - * - * Call this just before processInputProc. - */ -_X_EXPORT void -SwitchCoreKeyboard(DeviceIntPtr pDev) -{ - KeyClassPtr ckeyc = inputInfo.keyboard->key; - int i = 0; - - if (pDev != dixLookupPrivate(&inputInfo.keyboard->devPrivates, - CoreDevicePrivateKey)) { - memcpy(ckeyc->modifierMap, pDev->key->modifierMap, MAP_LENGTH); - if (ckeyc->modifierKeyMap) - xfree(ckeyc->modifierKeyMap); - ckeyc->modifierKeyMap = xalloc(8 * pDev->key->maxKeysPerModifier); - memcpy(ckeyc->modifierKeyMap, pDev->key->modifierKeyMap, - (8 * pDev->key->maxKeysPerModifier)); - - ckeyc->maxKeysPerModifier = pDev->key->maxKeysPerModifier; - ckeyc->curKeySyms.minKeyCode = pDev->key->curKeySyms.minKeyCode; - ckeyc->curKeySyms.maxKeyCode = pDev->key->curKeySyms.maxKeyCode; - SetKeySymsMap(&ckeyc->curKeySyms, &pDev->key->curKeySyms); - - /* - * Copy state from the extended keyboard to core. If you omit this, - * holding Ctrl on keyboard one, and pressing Q on keyboard two, will - * cause your app to quit. This feels wrong to me, hence the below - * code. - * - * XXX: If you synthesise core modifier events, the state will get - * clobbered here. You'll have to work out something sensible - * to fix that. Good luck. - */ - -#define KEYBOARD_MASK (ShiftMask | LockMask | ControlMask | Mod1Mask | \ - Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask) - ckeyc->state &= ~(KEYBOARD_MASK); - ckeyc->state |= (pDev->key->state & KEYBOARD_MASK); -#undef KEYBOARD_MASK - for (i = 0; i < 8; i++) - ckeyc->modifierKeyCount[i] = pDev->key->modifierKeyCount[i]; - -#ifdef XKB - if (!noXkbExtension && pDev->key->xkbInfo && pDev->key->xkbInfo->desc) { - if (!XkbCopyKeymap(pDev->key->xkbInfo->desc, ckeyc->xkbInfo->desc, - True)) - FatalError("Couldn't pivot keymap from device to core!\n"); - } -#endif - - SendMappingNotify(MappingKeyboard, ckeyc->curKeySyms.minKeyCode, - (ckeyc->curKeySyms.maxKeyCode - - ckeyc->curKeySyms.minKeyCode), - serverClient); - dixSetPrivate(&inputInfo.keyboard->devPrivates, CoreDevicePrivateKey, - pDev); - } -} - - /** * Note that pDev was the last function to send a core pointer event. * Currently a no-op. @@ -913,7 +889,11 @@ SwitchCorePointer(DeviceIntPtr pDev) * to shift the pointer to get it inside the new bounds. */ void -PostSyntheticMotion(int x, int y, int screen, unsigned long time) +PostSyntheticMotion(DeviceIntPtr pDev, + int x, + int y, + int screen, + unsigned long time) { xEvent xE; @@ -933,5 +913,5 @@ PostSyntheticMotion(int x, int y, int screen, unsigned long time) xE.u.keyButtonPointer.rootY = y; xE.u.keyButtonPointer.time = time; - (*inputInfo.pointer->public.processInputProc)(&xE, inputInfo.pointer, 1); + (*pDev->public.processInputProc)(&xE, pDev, 1); } |