diff options
author | Peter Hutterer <peter.hutterer@redhat.com> | 2008-11-03 17:47:36 +1030 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@redhat.com> | 2008-11-04 16:02:25 +1030 |
commit | 4971315296cbf868dd738c1c0c1c504fcfe1b619 (patch) | |
tree | c0e98a5204d6dac9b88965d3459e3e57f16383dd /dix | |
parent | 6bb0e0a53656db6168a053fb51b242a8640c1461 (diff) |
dix: clean up GetPointerEvents and GetKeyboardValuatorEvents.
Split into several functions, remove some stale comments.
Signed-off-by: Peter Hutterer <peter.hutterer@redhat.com>
Diffstat (limited to 'dix')
-rw-r--r-- | dix/getevents.c | 392 |
1 files changed, 237 insertions, 155 deletions
diff --git a/dix/getevents.c b/dix/getevents.c index bf8b77c5f..620ce937d 100644 --- a/dix/getevents.c +++ b/dix/getevents.c @@ -563,6 +563,218 @@ getValuatorEvents(EventList *events, DeviceIntPtr pDev, return events; } +/** + * Create the DCCE event (does not update the master's device state yet, this + * is done in the event processing). + * Pull in the coordinates from the MD if necessary. + * + * @param events Pointer to a pre-allocated event list. + * @param dev The slave device that generated an event. + * @param num_events The current number of events, returns the number of + * events if a DCCE was generated. + * @return The updated @events pointer. + */ +static EventListPtr +updateFromMaster(EventListPtr events, DeviceIntPtr dev, int *num_events) +{ + DeviceIntPtr master = dev->u.master; + if (master && master->u.lastSlave != dev) + { + CreateClassesChangedEvent(events, master, dev); + updateSlaveDeviceCoords(master, dev); + master->u.lastSlave = dev; + master->last.numValuators = dev->last.numValuators; + (*num_events)++; + events++; + } + return events; +} + +/** + * Move the device's pointer to the position given in the valuators. + * + * @param dev The device which's pointer is to be moved. + * @param x Returns the x position of the pointer after the move. + * @param y Returns the y position of the pointer after the move. + * @param first The first valuator in @valuators + * @param num Total number of valuators in @valuators. + * @param valuators Valuator data for each axis between @first and + * @first+@num. + */ +static void +moveAbsolute(DeviceIntPtr dev, int *x, int *y, + int first, int num, int *valuators) +{ + int i; + + + if (num >= 1 && first == 0) + *x = *(valuators + 0); + else + *x = dev->last.valuators[0]; + + if (first <= 1 && num >= (2 - first)) + *y = *(valuators + 1 - first); + else + *y = dev->last.valuators[1]; + + clipAxis(dev, 0, x); + clipAxis(dev, 1, y); + + i = (first > 2) ? 0 : 2; + for (; i < num; i++) + { + dev->last.valuators[i + first] = valuators[i]; + clipAxis(dev, i, &dev->last.valuators[i + first]); + } +} + +/** + * Move the device's pointer by the values given in @valuators. + * + * @param dev The device which's pointer is to be moved. + * @param x Returns the x position of the pointer after the move. + * @param y Returns the y position of the pointer after the move. + * @param first The first valuator in @valuators + * @param num Total number of valuators in @valuators. + * @param valuators Valuator data for each axis between @first and + * @first+@num. + */ +static void +moveRelative(DeviceIntPtr dev, int *x, int *y, + int first, int num, int *valuators) +{ + int i; + + *x = dev->last.valuators[0]; + *y = dev->last.valuators[1]; + + if (num >= 1 && first == 0) + *x += *(valuators +0); + + if (first <= 1 && num >= (2 - first)) + *y += *(valuators + 1 - first); + + /* if attached, clip both x and y to the defined limits (usually + * co-ord space limit). If it is attached, we need x/y to go over the + * limits to be able to change screens. */ + if(dev->u.master) { + clipAxis(dev, 0, x); + clipAxis(dev, 1, y); + } + + /* calc other axes, clip, drop back into valuators */ + i = (first > 2) ? 0 : 2; + for (; i < num; i++) + { + dev->last.valuators[i + first] += valuators[i]; + clipAxis(dev, i, &dev->last.valuators[i + first]); + valuators[i] = dev->last.valuators[i + first]; + } +} + +/** + * Accelerate the data in valuators based on the device's acceleration scheme. + * + * @param dev The device which's pointer is to be moved. + * @param first The first valuator in @valuators + * @param num Total number of valuators in @valuators. + * @param valuators Valuator data for each axis between @first and + * @first+@num. + * @param ms Current time. + */ +static void +accelPointer(DeviceIntPtr dev, int first, int num, int *valuators, CARD32 ms) +{ + if (dev->valuator->accelScheme.AccelSchemeProc) + dev->valuator->accelScheme.AccelSchemeProc(dev, first, num, valuators, ms); +} + +/** + * If we have HW cursors, this actually moves the visible sprite. If not, we + * just do all the screen crossing, etc. + * + * We scale from device to screen coordinates here, call + * miPointerSetPosition() and then scale back into device coordinates (if + * needed). miPSP will change x/y if the screen was crossed. + * + * @param dev The device to be moved. + * @param x Pointer to current x-axis value, may be modified. + * @param y Pointer to current y-axis value, may be modified. + * @param scr Screen the device's sprite is currently on. + * @param screenx Screen x coordinate the sprite is on after the update. + * @param screeny Screen y coordinate the sprite is on after the update. + */ +static void +positionSprite(DeviceIntPtr dev, int *x, int *y, + ScreenPtr scr, int *screenx, int *screeny) +{ + /* scale x&y to screen */ + *screenx = rescaleValuatorAxis(*x, dev->valuator->axes + 0, NULL, scr->width); + *screeny = rescaleValuatorAxis(*y, dev->valuator->axes + 1, NULL, scr->height); + dev->last.valuators[0] = *screenx; + dev->last.valuators[1] = *screeny; + + /* This takes care of crossing screens for us, as well as clipping + * to the current screen. */ + miPointerSetPosition(dev, &dev->last.valuators[0], &dev->last.valuators[1]); + + if (dev->u.master) { + dev->u.master->last.valuators[0] = dev->last.valuators[0]; + dev->u.master->last.valuators[1] = dev->last.valuators[1]; + } + + /* Crossed screen? Scale back to device coordiantes */ + if(*screenx != dev->last.valuators[0]) + { + scr = miPointerGetScreen(dev); + *x = rescaleValuatorAxis(dev->last.valuators[0], NULL, + dev->valuator->axes + 0, scr->width); + *screenx = dev->last.valuators[0]; + } + if(*screeny != dev->last.valuators[1]) + { + scr = miPointerGetScreen(dev); + *screeny = dev->last.valuators[1]; + *y = rescaleValuatorAxis(dev->last.valuators[1], NULL, + dev->valuator->axes + 1, scr->height); + } + +} + +/** + * Update the motion history for the device and (if appropriate) for its + * master device. + * @param dev Slave device to update. + * @param first First valuator to append to history. + * @param num Total number of valuators to append to history. + * @param ms Current time + */ +static void +updateHistory(DeviceIntPtr dev, int first, int num, CARD32 ms) +{ + updateMotionHistory(dev, ms, first, num, &dev->last.valuators[first]); + if (dev->u.master) + updateMotionHistory(dev->u.master, ms, first, num, + &dev->last.valuators[first]); +} + +/** + * Calculate how many DeviceValuator events are needed given a number of + * valuators. + * @param num_valuators Number of valuators to attach to event. + * @return the number of DeviceValuator events needed. + */ +static int +countValuatorEvents(int num_valuators) +{ + if (num_valuators) { + if ((num_valuators / 6) + 1 > MAX_VALUATOR_EVENTS) + num_valuators = MAX_VALUATOR_EVENTS; + return (num_valuators / 6) + 1; + } else + return 0; +} /** * Convenience wrapper around GetKeyboardValuatorEvents, that takes no @@ -603,43 +815,21 @@ GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type, KeySym *map; KeySym sym; deviceKeyButtonPointer *kbp = NULL; - DeviceIntPtr master; - if (!events) - return 0; - - /* DO NOT WANT */ - if (type != KeyPress && type != KeyRelease) - return 0; - - if (!pDev->key || !pDev->focus || !pDev->kbdfeed) + if (!events ||!pDev->key || !pDev->focus || !pDev->kbdfeed || + (type != KeyPress && type != KeyRelease) || + (key_code < 8 || key_code > 255)) return 0; numEvents = 1; - if (key_code < 8 || key_code > 255) - return 0; - map = pDev->key->curKeySyms.map; sym = map[(key_code - pDev->key->curKeySyms.minKeyCode) * pDev->key->curKeySyms.mapWidth]; - master = pDev->u.master; - if (master && master->u.lastSlave != pDev) - { - CreateClassesChangedEvent(events, master, pDev); - updateSlaveDeviceCoords(master, pDev); - master->u.lastSlave = pDev; - master->last.numValuators = pDev->last.numValuators; - numEvents++; - events++; - } + events = updateFromMaster(events, pDev, &numEvents); - if (num_valuators) { - if ((num_valuators / 6) + 1 > MAX_VALUATOR_EVENTS) - num_valuators = MAX_VALUATOR_EVENTS; - numEvents += (num_valuators / 6) + 1; - } + numEvents += countValuatorEvents(num_valuators); #ifdef XKB if (noXkbExtension) @@ -807,152 +997,44 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons, int num_events = 1; CARD32 ms; deviceKeyButtonPointer *kbp = NULL; - DeviceIntPtr master; int x, y, /* switches between device and screen coords */ cx, cy; /* only screen coordinates */ ScreenPtr scr = miPointerGetScreen(pDev); - int *v0 = NULL, *v1 = NULL; - int i; ms = GetTimeInMillis(); /* before pointer update to help precision */ - /* Sanity checks. */ - if (!scr) /* can happen during server shutdown */ - return 0; - if (type != MotionNotify && type != ButtonPress && type != ButtonRelease) - return 0; - if (type != MotionNotify && !pDev->button) - return 0; - /* FIXME: I guess it should, in theory, be possible to post button events - * from devices without valuators. */ - if (!pDev->valuator) - return 0; - if (type == MotionNotify && num_valuators <= 0) + if (!scr || !pDev->valuator || first_valuator < 0 || + ((num_valuators + first_valuator) > pDev->valuator->numAxes) || + (type != MotionNotify && type != ButtonPress && type != ButtonRelease) || + (type != MotionNotify && !pDev->button) || + (type == MotionNotify && num_valuators <= 0)) return 0; - /* Do we need to send a DeviceValuator event? */ - 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; - } - - /* You fail. */ - if (first_valuator < 0 || - (num_valuators + first_valuator) > pDev->valuator->numAxes) - return 0; + num_events += countValuatorEvents(num_valuators); - master = pDev->u.master; - if (master && master->u.lastSlave != pDev) - { - CreateClassesChangedEvent(events, master, pDev); - updateSlaveDeviceCoords(master, pDev); - master->u.lastSlave = pDev; - master->last.numValuators = pDev->last.numValuators; - num_events++; - events++; - } + events = updateFromMaster(events, pDev, &num_events); - /* Fetch pointers into the valuator array for more easy to read code */ - if (num_valuators >= 1 && first_valuator == 0) - v0 = valuators + 0; - if (first_valuator <= 1 && num_valuators >= (2 - first_valuator)) - v1 = valuators + 1 - first_valuator; - - /* Set x and y based on whether this is absolute or relative, and - * accelerate if we need to. */ - x = pDev->last.valuators[0]; - y = pDev->last.valuators[1]; - if (flags & POINTER_ABSOLUTE) { - if(v0) x = *v0; - if(v1) y = *v1; - - /* Clip both x and y to the defined limits (usually co-ord space limit). */ - clipAxis(pDev, 0, &x); - clipAxis(pDev, 1, &y); - - i = (first_valuator > 2) ? 0 : 2; - for (; i < num_valuators; i++) - { - pDev->last.valuators[i + first_valuator] = valuators[i]; - clipAxis(pDev, i, &pDev->last.valuators[i + first_valuator]); - } - } + if (flags & POINTER_ABSOLUTE) + moveAbsolute(pDev, &x, &y, first_valuator, num_valuators, valuators); else { - if (flags & POINTER_ACCELERATE && - pDev->valuator->accelScheme.AccelSchemeProc){ - pDev->valuator->accelScheme.AccelSchemeProc( - pDev, first_valuator, num_valuators, valuators, ms); - } - - if(v0) x += *v0; - if(v1) y += *v1; - - /* if attached, clip both x and y to the defined limits (usually - * co-ord space limit). If it is attached, we need x/y to go over the - * limits to be able to change screens. */ - if(master) { - clipAxis(pDev, 0, &x); - clipAxis(pDev, 1, &y); - } - - /* calc other axes, clip, drop back into valuators */ - i = (first_valuator > 2) ? 0 : 2; - for (; i < num_valuators; i++) - { - pDev->last.valuators[i + first_valuator] += valuators[i]; - clipAxis(pDev, i, &pDev->last.valuators[i + first_valuator]); - valuators[i] = pDev->last.valuators[i + first_valuator]; - } + if (flags & POINTER_ACCELERATE) + accelPointer(pDev, first_valuator, num_valuators, valuators, ms); + moveRelative(pDev, &x, &y, first_valuator, num_valuators, valuators); } - /* scale x&y to screen */ - pDev->last.valuators[0] = cx = rescaleValuatorAxis(x, pDev->valuator->axes + 0, - NULL, scr->width); - pDev->last.valuators[1] = cy = rescaleValuatorAxis(y, pDev->valuator->axes + 1, - NULL, scr->height); - - /* 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, &pDev->last.valuators[0], &pDev->last.valuators[1]); - - if (master) { - master->last.valuators[0] = pDev->last.valuators[0]; - master->last.valuators[1] = pDev->last.valuators[1]; - } - - /* Crossed screen? Scale back to device coordiantes */ - if(cx != pDev->last.valuators[0]) - { - scr = miPointerGetScreen(pDev); - x = rescaleValuatorAxis(pDev->last.valuators[0], NULL, - pDev->valuator->axes + 0, scr->width); - cx = pDev->last.valuators[0]; - } - if(cy != pDev->last.valuators[1]) - { - scr = miPointerGetScreen(pDev); - cy = pDev->last.valuators[1]; - y = rescaleValuatorAxis(pDev->last.valuators[1], NULL, - pDev->valuator->axes + 1, scr->height); - } - - - updateMotionHistory(pDev, ms, first_valuator, num_valuators, - &pDev->last.valuators[first_valuator]); - if (master) - updateMotionHistory(master, ms, first_valuator, num_valuators, - &pDev->last.valuators[first_valuator]); - - /* Update the valuators with the true value sent to the client*/ - if(v0) *v0 = x; - if(v1) *v1 = y; + positionSprite(pDev, &x, &y, scr, &cx, &cy); + updateHistory(pDev, first_valuator, num_valuators, ms); /* dropy x/y (device coordinates) back into valuators for next event */ pDev->last.valuators[0] = x; pDev->last.valuators[1] = y; + /* Update the valuators with the true value sent to the client*/ + if (num_valuators >= 1 && first_valuator == 0) + valuators[0] = x; + if (first_valuator <= 1 && num_valuators >= (2 - first_valuator)) + valuators[1 - first_valuator] = y; + kbp = (deviceKeyButtonPointer *) events->event; kbp->time = ms; kbp->deviceid = pDev->id; |