aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/dix/getevents.c
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2009-07-25 20:12:58 +0000
committermarha <marha@users.sourceforge.net>2009-07-25 20:12:58 +0000
commit2553bdd7c359cd87525d367761c86932cec5adff (patch)
treeae71245933c98474a699d3e392de5820879b2018 /xorg-server/dix/getevents.c
parente2c51f2ee7b0a3ea1a052fc49324057b4a4bbc78 (diff)
parent4a3dbb926ae3f5410198d7cc4f4ebe4f62eebf05 (diff)
downloadvcxsrv-2553bdd7c359cd87525d367761c86932cec5adff.tar.gz
vcxsrv-2553bdd7c359cd87525d367761c86932cec5adff.tar.bz2
vcxsrv-2553bdd7c359cd87525d367761c86932cec5adff.zip
svn merge file:///D:/svnrepos/vcxsrv/branches/released .
Diffstat (limited to 'xorg-server/dix/getevents.c')
-rw-r--r--xorg-server/dix/getevents.c1144
1 files changed, 668 insertions, 476 deletions
diff --git a/xorg-server/dix/getevents.c b/xorg-server/dix/getevents.c
index 1e0edbf00..9747b35a6 100644
--- a/xorg-server/dix/getevents.c
+++ b/xorg-server/dix/getevents.c
@@ -47,7 +47,6 @@
#ifdef XKB
#include <X11/extensions/XKBproto.h>
#include <xkbsrv.h>
-extern Bool XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies);
#endif
#ifdef PANORAMIX
@@ -62,14 +61,22 @@ extern Bool XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies);
#include "exglobals.h"
#include "extnsionst.h"
-
-/* Maximum number of valuators, divided by six, rounded up, to get number
- * of events. */
-#define MAX_VALUATOR_EVENTS 6
-
/* 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.
@@ -106,43 +113,151 @@ key_autorepeats(DeviceIntPtr pDev, int key_code)
}
/**
+ * Rescale the coord between the two axis ranges.
+ */
+static int
+rescaleValuatorAxis(int coord, AxisInfoPtr from, AxisInfoPtr to,
+ int defmax)
+{
+ int fmin = 0, tmin = 0, fmax = defmax, tmax = defmax;
+
+ if(from && from->min_value < from->max_value) {
+ fmin = from->min_value;
+ fmax = from->max_value;
+ }
+ if(to && to->min_value < to->max_value) {
+ tmin = to->min_value;
+ tmax = to->max_value;
+ }
+
+ if(fmin == tmin && fmax == tmax)
+ return coord;
+
+ if(fmax == fmin) /* avoid division by 0 */
+ return 0;
+
+ return roundf(((float)(coord - fmin)) * (tmax - tmin) /
+ (fmax - fmin)) + tmin;
+}
+
+/**
+ * Update all coordinates when changing to a different SD
+ * to ensure that relative reporting will work as expected
+ * without loss of precision.
+ *
+ * pDev->last.valuators will be in absolute device coordinates after this
+ * function.
+ */
+static void
+updateSlaveDeviceCoords(DeviceIntPtr master, DeviceIntPtr pDev)
+{
+ ScreenPtr scr = miPointerGetScreen(pDev);
+ int i;
+ DeviceIntPtr lastSlave;
+
+ /* master->last.valuators[0]/[1] is in screen coords and the actual
+ * position of the pointer */
+ pDev->last.valuators[0] = master->last.valuators[0];
+ pDev->last.valuators[1] = master->last.valuators[1];
+
+ if (!pDev->valuator)
+ return;
+
+ /* scale back to device coordinates */
+ if(pDev->valuator->numAxes > 0)
+ pDev->last.valuators[0] = rescaleValuatorAxis(pDev->last.valuators[0], NULL, pDev->valuator->axes + 0, scr->width);
+ if(pDev->valuator->numAxes > 1)
+ pDev->last.valuators[1] = rescaleValuatorAxis(pDev->last.valuators[1], NULL, pDev->valuator->axes + 1, scr->height);
+
+ /* calculate the other axis as well based on info from the old
+ * slave-device. If the old slave had less axes than this one,
+ * last.valuators is reset to 0.
+ */
+ if ((lastSlave = master->u.lastSlave) && lastSlave->valuator) {
+ for (i = 2; i < pDev->valuator->numAxes; i++) {
+ if (i >= lastSlave->valuator->numAxes)
+ pDev->last.valuators[i] = 0;
+ else
+ pDev->last.valuators[i] =
+ rescaleValuatorAxis(pDev->last.valuators[i],
+ lastSlave->valuator->axes + i,
+ pDev->valuator->axes + i, 0);
+ }
+ }
+
+}
+
+/**
* Allocate the motion history buffer.
*/
_X_EXPORT void
AllocateMotionHistory(DeviceIntPtr pDev)
{
+ int size;
if (pDev->valuator->motion)
xfree(pDev->valuator->motion);
if (pDev->valuator->numMotionEvents < 1)
return;
- pDev->valuator->motion = xalloc(((sizeof(INT32) * pDev->valuator->numAxes) +
- sizeof(Time)) *
- pDev->valuator->numMotionEvents);
+ /* An MD must have a motion history size large enough to keep all
+ * potential valuators, plus the respective range of the valuators.
+ * 3 * INT32 for (min_val, max_val, curr_val))
+ */
+ if (pDev->isMaster)
+ size = sizeof(INT32) * 3 * MAX_VALUATORS;
+ else
+ size = sizeof(INT32) * pDev->valuator->numAxes;
+
+ size += sizeof(Time);
+
+ pDev->valuator->motion = xcalloc(pDev->valuator->numMotionEvents, size);
pDev->valuator->first_motion = 0;
pDev->valuator->last_motion = 0;
+ if (!pDev->valuator->motion)
+ ErrorF("[dix] %s: Failed to alloc motion history (%d bytes).\n",
+ pDev->name, size * pDev->valuator->numMotionEvents);
}
-
/**
* Dump the motion history between start and stop into the supplied buffer.
* Only records the event for a given screen in theory, but in practice, we
* sort of ignore this.
+ *
+ * If core is set, we only generate x/y, in INT16, scaled to screen coords.
*/
_X_EXPORT int
-GetMotionHistory(DeviceIntPtr pDev, xTimecoord *buff, unsigned long start,
- unsigned long stop, ScreenPtr pScreen)
+GetMotionHistory(DeviceIntPtr pDev, xTimecoord **buff, unsigned long start,
+ unsigned long stop, ScreenPtr pScreen, BOOL core)
{
- char *ibuff = NULL, *obuff = (char *) buff;
+ char *ibuff = NULL, *obuff;
int i = 0, ret = 0;
+ int j, coord;
Time current;
/* The size of a single motion event. */
- int size = (sizeof(INT32) * pDev->valuator->numAxes) + sizeof(Time);
+ int size;
+ int dflt;
+ AxisInfo from, *to; /* for scaling */
+ INT32 *ocbuf, *icbuf; /* pointer to coordinates for copying */
+ INT16 *corebuf;
+ AxisInfo core_axis = {0};
if (!pDev->valuator || !pDev->valuator->numMotionEvents)
return 0;
+ if (core && !pScreen)
+ return 0;
+
+ if (pDev->isMaster)
+ size = (sizeof(INT32) * 3 * MAX_VALUATORS) + sizeof(Time);
+ else
+ size = (sizeof(INT32) * pDev->valuator->numAxes) + sizeof(Time);
+
+ *buff = xalloc(size * pDev->valuator->numMotionEvents);
+ if (!(*buff))
+ return 0;
+ obuff = (char *)*buff;
+
for (i = pDev->valuator->first_motion;
i != pDev->valuator->last_motion;
i = (i + 1) % pDev->valuator->numMotionEvents) {
@@ -156,8 +271,80 @@ GetMotionHistory(DeviceIntPtr pDev, xTimecoord *buff, unsigned long start,
return ret;
}
else if (current >= start) {
- memcpy(obuff, ibuff, size);
- obuff += size;
+ if (core)
+ {
+ memcpy(obuff, ibuff, sizeof(Time)); /* copy timestamp */
+
+ icbuf = (INT32*)(ibuff + sizeof(Time));
+ corebuf = (INT16*)(obuff + sizeof(Time));
+
+ /* fetch x coordinate + range */
+ memcpy(&from.min_value, icbuf++, sizeof(INT32));
+ memcpy(&from.max_value, icbuf++, sizeof(INT32));
+ memcpy(&coord, icbuf++, sizeof(INT32));
+
+ /* scale to screen coords */
+ to = &core_axis;
+ to->max_value = pScreen->width;
+ coord = rescaleValuatorAxis(coord, &from, to, pScreen->width);
+
+ memcpy(corebuf, &coord, sizeof(INT16));
+ corebuf++;
+
+ /* fetch y coordinate + range */
+ memcpy(&from.min_value, icbuf++, sizeof(INT32));
+ memcpy(&from.max_value, icbuf++, sizeof(INT32));
+ memcpy(&coord, icbuf++, sizeof(INT32));
+
+ to->max_value = pScreen->height;
+ coord = rescaleValuatorAxis(coord, &from, to, pScreen->height);
+ memcpy(corebuf, &coord, sizeof(INT16));
+
+ } else if (pDev->isMaster)
+ {
+ memcpy(obuff, ibuff, sizeof(Time)); /* copy timestamp */
+
+ ocbuf = (INT32*)(obuff + sizeof(Time));
+ icbuf = (INT32*)(ibuff + sizeof(Time));
+ for (j = 0; j < MAX_VALUATORS; j++)
+ {
+ if (j >= pDev->valuator->numAxes)
+ break;
+
+ /* fetch min/max/coordinate */
+ memcpy(&from.min_value, icbuf++, sizeof(INT32));
+ memcpy(&from.max_value, icbuf++, sizeof(INT32));
+ memcpy(&coord, icbuf++, sizeof(INT32));
+
+ to = (j < pDev->valuator->numAxes) ? &pDev->valuator->axes[j] : NULL;
+
+ /* x/y scaled to screen if no range is present */
+ if (j == 0 && (from.max_value < from.min_value))
+ from.max_value = pScreen->width;
+ else if (j == 1 && (from.max_value < from.min_value))
+ from.max_value = pScreen->height;
+
+ if (j == 0 && (to->max_value < to->min_value))
+ dflt = pScreen->width;
+ else if (j == 1 && (to->max_value < to->min_value))
+ dflt = pScreen->height;
+ else
+ dflt = 0;
+
+ /* scale from stored range into current range */
+ coord = rescaleValuatorAxis(coord, &from, to, 0);
+ memcpy(ocbuf, &coord, sizeof(INT32));
+ ocbuf++;
+ }
+ } else
+ memcpy(obuff, ibuff, size);
+
+ /* don't advance by size here. size may be different to the
+ * actually written size if the MD has less valuators than MAX */
+ if (core)
+ obuff += sizeof(INT32) + sizeof(Time);
+ else
+ obuff += (sizeof(INT32) * pDev->valuator->numAxes) + sizeof(Time);
ret++;
}
}
@@ -169,29 +356,65 @@ GetMotionHistory(DeviceIntPtr pDev, xTimecoord *buff, unsigned long start,
/**
* Update the motion history for a specific device, with the list of
* valuators.
+ *
+ * Layout of the history buffer:
+ * for SDs: [time] [val0] [val1] ... [valn]
+ * for MDs: [time] [min_val0] [max_val0] [val0] [min_val1] ... [valn]
+ *
+ * For events that have some valuators unset (first_valuator > 0):
+ * min_val == max_val == val == 0.
*/
static void
updateMotionHistory(DeviceIntPtr pDev, CARD32 ms, int first_valuator,
int num_valuators, int *valuators)
{
char *buff = (char *) pDev->valuator->motion;
+ ValuatorClassPtr v;
+ int i;
if (!pDev->valuator->numMotionEvents)
return;
- buff += ((sizeof(INT32) * pDev->valuator->numAxes) + sizeof(CARD32)) *
+ v = pDev->valuator;
+ if (pDev->isMaster)
+ {
+ buff += ((sizeof(INT32) * 3 * MAX_VALUATORS) + sizeof(CARD32)) *
+ v->last_motion;
+
+ memcpy(buff, &ms, sizeof(Time));
+ buff += sizeof(Time);
+
+ memset(buff, 0, sizeof(INT32) * 3 * MAX_VALUATORS);
+ buff += 3 * sizeof(INT32) * first_valuator;
+
+ for (i = first_valuator; i < first_valuator + num_valuators; i++)
+ {
+ if (i >= v->numAxes)
+ break;
+ memcpy(buff, &v->axes[i].min_value, sizeof(INT32));
+ buff += sizeof(INT32);
+ memcpy(buff, &v->axes[i].max_value, sizeof(INT32));
+ buff += sizeof(INT32);
+ memcpy(buff, &valuators[i - first_valuator], sizeof(INT32));
+ buff += sizeof(INT32);
+ }
+ } else
+ {
+
+ buff += ((sizeof(INT32) * pDev->valuator->numAxes) + sizeof(CARD32)) *
pDev->valuator->last_motion;
- memcpy(buff, &ms, sizeof(Time));
- buff += sizeof(Time);
- bzero(buff, sizeof(INT32) * pDev->valuator->numAxes);
+ memcpy(buff, &ms, sizeof(Time));
+ buff += sizeof(Time);
- buff += sizeof(INT32) * first_valuator;
- memcpy(buff, valuators, sizeof(INT32) * num_valuators);
+ memset(buff, 0, sizeof(INT32) * pDev->valuator->numAxes);
+ buff += sizeof(INT32) * first_valuator;
- pDev->valuator->last_motion = (pDev->valuator->last_motion + 1) %
- pDev->valuator->numMotionEvents;
+ memcpy(buff, valuators, sizeof(INT32) * num_valuators);
+ }
+ pDev->valuator->last_motion = (pDev->valuator->last_motion + 1) %
+ pDev->valuator->numMotionEvents;
/* If we're wrapping around, just keep the circular buffer going. */
if (pDev->valuator->first_motion == pDev->valuator->last_motion)
pDev->valuator->first_motion = (pDev->valuator->first_motion + 1) %
@@ -212,9 +435,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)
@@ -225,80 +448,6 @@ GetMaximumEventsNum(void) {
}
-/* Originally a part of xf86PostMotionEvent; modifies valuators
- * in-place. */
-static void
-acceleratePointer(DeviceIntPtr pDev, int first_valuator, int num_valuators,
- int *valuators)
-{
- float mult = 0.0;
- int dx = 0, dy = 0;
- int *px = NULL, *py = NULL;
-
- if (!num_valuators || !valuators)
- return;
-
- if (first_valuator == 0) {
- dx = valuators[0];
- px = &valuators[0];
- }
- if (first_valuator <= 1 && num_valuators >= (2 - first_valuator)) {
- dy = valuators[1 - first_valuator];
- py = &valuators[1 - first_valuator];
- }
-
- if (!dx && !dy)
- return;
-
- if (pDev->ptrfeed && pDev->ptrfeed->ctrl.num) {
- /* modeled from xf86Events.c */
- if (pDev->ptrfeed->ctrl.threshold) {
- if ((abs(dx) + abs(dy)) >= pDev->ptrfeed->ctrl.threshold) {
- pDev->valuator->dxremaind = ((float)dx *
- (float)(pDev->ptrfeed->ctrl.num)) /
- (float)(pDev->ptrfeed->ctrl.den) +
- pDev->valuator->dxremaind;
- if (px) {
- *px = (int)pDev->valuator->dxremaind;
- pDev->valuator->dxremaind = pDev->valuator->dxremaind -
- (float)(*px);
- }
-
- pDev->valuator->dyremaind = ((float)dy *
- (float)(pDev->ptrfeed->ctrl.num)) /
- (float)(pDev->ptrfeed->ctrl.den) +
- pDev->valuator->dyremaind;
- if (py) {
- *py = (int)pDev->valuator->dyremaind;
- pDev->valuator->dyremaind = pDev->valuator->dyremaind -
- (float)(*py);
- }
- }
- }
- else {
- mult = pow((float)dx * (float)dx + (float)dy * (float)dy,
- ((float)(pDev->ptrfeed->ctrl.num) /
- (float)(pDev->ptrfeed->ctrl.den) - 1.0) /
- 2.0) / 2.0;
- if (dx) {
- pDev->valuator->dxremaind = mult * (float)dx +
- pDev->valuator->dxremaind;
- *px = (int)pDev->valuator->dxremaind;
- pDev->valuator->dxremaind = pDev->valuator->dxremaind -
- (float)(*px);
- }
- if (dy) {
- pDev->valuator->dyremaind = mult * (float)dy +
- pDev->valuator->dyremaind;
- *py = (int)pDev->valuator->dyremaind;
- pDev->valuator->dyremaind = pDev->valuator->dyremaind -
- (float)(*py);
- }
- }
- }
-}
-
-
/**
* Clip an axis to its bounds, which are declared in the call to
* InitValuatorAxisClassStruct.
@@ -306,15 +455,17 @@ acceleratePointer(DeviceIntPtr pDev, int first_valuator, int num_valuators,
static void
clipAxis(DeviceIntPtr pDev, int axisNum, int *val)
{
- AxisInfoPtr axes = pDev->valuator->axes + axisNum;
-
- /* No clipping if the value-range <= 0 */
- if(axes->min_value < axes->min_value) {
- if (*val < axes->min_value)
- *val = axes->min_value;
- if (*val > axes->max_value)
- *val = axes->max_value;
- }
+ AxisInfoPtr axis = pDev->valuator->axes + axisNum;
+ /* InitValuatoraAxisStruct ensures that (min < max). */
+
+ /* If a value range is defined, clip. If not, do nothing */
+ if (axis->max_value <= axis->min_value)
+ return;
+
+ if (*val < axis->min_value)
+ *val = axis->min_value;
+ if (*val > axis->max_value)
+ *val = axis->max_value;
}
/**
@@ -335,23 +486,20 @@ clipValuators(DeviceIntPtr pDev, int first_valuator, int num_valuators,
/**
* Fills events with valuator events for pDev, as given by the other
* parameters.
- *
- * FIXME: Need to fix ValuatorClassRec to store all the valuators as
- * 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,
- int num_valuators, int *valuators) {
- deviceValuator *xv = (deviceValuator *) events;
- int i = 0, final_valuator = first_valuator + num_valuators;
+static EventList *
+getValuatorEvents(EventList *events, DeviceIntPtr pDev,
+ int first_valuator, int num_valuators, int *valuators) {
+ deviceValuator *xv;
+ int i;
- for (i = first_valuator; i < final_valuator; i += 6, xv++, events++) {
+ for (i = 0; i < num_valuators; 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);
+ xv->first_valuator = first_valuator + i;
+ xv->num_valuators = ((num_valuators - i) > 6) ? 6 : (num_valuators - i);
xv->deviceid = pDev->id;
- switch (final_valuator - i) {
+ switch (num_valuators - i) {
case 6:
xv->valuator5 = valuators[i + 5];
case 5:
@@ -363,23 +511,235 @@ getValuatorEvents(xEvent *events, DeviceIntPtr pDev, int first_valuator,
case 2:
xv->valuator1 = valuators[i + 1];
case 1:
- xv->valuator0 = valuators[i];
+ xv->valuator0 = valuators[i + 0];
}
- if (i + 6 < final_valuator)
+ if (i + 6 < num_valuators)
xv->deviceid |= MORE_EVENTS;
}
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)
+ {
+ updateSlaveDeviceCoords(master, dev);
+ master->u.lastSlave = dev;
+ master->last.numValuators = dev->last.numValuators;
+ }
+ 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);
+ }
+
+ /* dropy x/y (device coordinates) back into valuators for next event */
+ dev->last.valuators[0] = *x;
+ dev->last.valuators[1] = *y;
+}
+
+/**
+ * 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 - 1) / 6) + 1 > MAX_VALUATOR_EVENTS)
+ num_valuators = MAX_VALUATOR_EVENTS * 6;
+ return ((num_valuators - 1)/ 6) + 1;
+ } else
+ return 0;
+}
/**
* Convenience wrapper around GetKeyboardValuatorEvents, that takes no
* 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 +748,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,42 +765,29 @@ 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;
CARD32 ms = 0;
- KeySym *map = pDev->key->curKeySyms.map;
+ KeySym *map;
KeySym sym;
deviceKeyButtonPointer *kbp = NULL;
- if (!events)
- return 0;
-
- /* DO NOT WANT */
- if (type != KeyPress && type != KeyRelease)
+ if (!events ||!pDev->key || !pDev->focus || !pDev->kbdfeed ||
+ (type != KeyPress && type != KeyRelease) ||
+ (key_code < 8 || key_code > 255))
return 0;
- if (!pDev->key || !pDev->focus || !pDev->kbdfeed ||
- (pDev->coreEvents && !inputInfo.keyboard->key))
- return 0;
-
- if (key_code < 8 || key_code > 255)
- return 0;
+ numEvents = 1;
+ map = pDev->key->curKeySyms.map;
sym = map[(key_code - pDev->key->curKeySyms.minKeyCode)
* pDev->key->curKeySyms.mapWidth];
- if (pDev->coreEvents)
- numEvents = 2;
- else
- numEvents = 1;
+ 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)
@@ -470,28 +820,21 @@ GetKeyboardValuatorEvents(xEvent *events, DeviceIntPtr pDev, int type,
if (noXkbExtension)
#endif
{
- numEvents += GetKeyboardValuatorEvents(events, pDev,
- KeyRelease, key_code,
- first_valuator, num_valuators,
- valuators);
- events += numEvents;
+ int numReleaseEvents;
+
+ numReleaseEvents = GetKeyboardValuatorEvents(events, pDev,
+ KeyRelease, key_code,
+ first_valuator,
+ num_valuators,
+ valuators);
+ numEvents += numReleaseEvents;
+ events += numReleaseEvents;
}
}
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;
@@ -515,261 +858,179 @@ 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.
+ */
+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);
+ }
+ }
+ }
+}
+
+/**
+ * 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 (returned in xE) representing pointer
- * motion, or button presses. Xi and XKB-aware.
+ * 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.
+ *
+ * In the generated events rootX/Y will be in absolute screen coords and
+ * the valuator information in the absolute or relative device coords.
+ *
+ * last.valuators[x] of the device is always in absolute device coords.
+ * last.valuators[x] of the master device is in absolute screen coords.
+ *
+ * master->last.valuators[x] for x > 2 is undefined.
*/
_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;
+ int num_events = 1;
+ CARD32 ms;
deviceKeyButtonPointer *kbp = NULL;
- DeviceIntPtr cp = inputInfo.pointer;
- int x = 0, y = 0;
- Bool coreOnly = (pDev == inputInfo.pointer);
+ int x, y, /* switches between device and screen coords */
+ cx, cy; /* only screen coordinates */
ScreenPtr scr = miPointerGetScreen(pDev);
- /* Sanity checks. */
- if (type != MotionNotify && type != ButtonPress && type != ButtonRelease)
- return 0;
-
- if ((type == ButtonPress || type == ButtonRelease) && !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 (!coreOnly && pDev->coreEvents)
- num_events = 2;
- else
- num_events = 1;
+ ms = GetTimeInMillis(); /* before pointer update to help precision */
- 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 (!coreOnly && num_valuators) {
- if ((((num_valuators - 1) / 6) + 1) > MAX_VALUATOR_EVENTS)
- num_valuators = MAX_VALUATOR_EVENTS * 6;
- num_events += ((num_valuators - 1) / 6) + 1;
- }
-
- final_valuator = num_valuators + first_valuator;
-
- /* You fail. */
- if (first_valuator < 0 || final_valuator > pDev->valuator->numAxes)
- return 0;
+ num_events += countValuatorEvents(num_valuators);
- ms = GetTimeInMillis();
+ events = updateFromMaster(events, pDev, &num_events);
- /* Set x and y based on whether this is absolute or relative, and
- * accelerate if we need to. */
- if (flags & POINTER_ABSOLUTE) {
- if (num_valuators >= 1 && first_valuator == 0) {
- 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;
- }
- }
+ if (flags & POINTER_ABSOLUTE)
+ {
+ if (flags & POINTER_SCREEN) /* valuators are in screen coords */
+ {
- 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;
- }
+ valuators[0] = rescaleValuatorAxis(valuators[0], NULL,
+ pDev->valuator->axes + 0,
+ scr->width);
+ valuators[1] = rescaleValuatorAxis(valuators[1], NULL,
+ pDev->valuator->axes + 1,
+ scr->height);
}
- /* Clip both x and y to the defined limits (usually co-ord space limit). */
- clipAxis(pDev, 0, &x);
- clipAxis(pDev, 1, &y);
- }
- else {
+ moveAbsolute(pDev, &x, &y, first_valuator, num_valuators, valuators);
+ } 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);
- }
- }
+ accelPointer(pDev, first_valuator, num_valuators, valuators, ms);
+ moveRelative(pDev, &x, &y, first_valuator, num_valuators, valuators);
}
- 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;
- }
+ positionSprite(pDev, &x, &y, scr, &cx, &cy);
+ updateHistory(pDev, first_valuator, num_valuators, ms);
- /* 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;
+ /* 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] = pDev->valuator->lasty;
-
- 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;
- }
+ valuators[1 - first_valuator] = y;
- events++;
- }
-
- 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 = buttons;
+ }
- kbp->root_x = pDev->valuator->lastx;
- kbp->root_y = pDev->valuator->lasty;
+ kbp->root_x = cx; /* root_x/y always in screen coords */
+ kbp->root_y = cy;
- events++;
- if (num_valuators) {
- kbp->deviceid |= MORE_EVENTS;
+ events++;
+ if (num_valuators) {
+ kbp->deviceid |= MORE_EVENTS;
+ if (flags & POINTER_ABSOLUTE)
clipValuators(pDev, first_valuator, num_valuators, valuators);
- events = getValuatorEvents(events, pDev, first_valuator,
- num_valuators, valuators);
- }
+ events = getValuatorEvents(events, pDev, first_valuator,
+ num_valuators, valuators);
}
return num_events;
@@ -784,19 +1045,18 @@ 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)
return 0;
-
if (!pDev->valuator)
return 0;
-
/* Do we need to send a DeviceValuator event? */
if ((pDev->valuator->mode & 1) == Relative)
num_valuators = 0;
@@ -812,6 +1072,15 @@ 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)
+ {
+ updateSlaveDeviceCoords(master, pDev);
+ master->u.lastSlave = pDev;
+ master->last.numValuators = pDev->last.numValuators;
+ }
+
+ kbp = (deviceKeyButtonPointer *) events->event;
kbp->type = type;
kbp->deviceid = pDev->id;
kbp->detail = 0;
@@ -828,87 +1097,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.
- *
- * Call this just before processInputProc.
- */
-_X_EXPORT void
-SwitchCorePointer(DeviceIntPtr pDev)
-{
- if (pDev != dixLookupPrivate(&inputInfo.pointer->devPrivates,
- CoreDevicePrivateKey))
- dixSetPrivate(&inputInfo.pointer->devPrivates,
- CoreDevicePrivateKey, pDev);
-}
-
-
/**
* Synthesize a single motion event for the core pointer.
*
@@ -916,7 +1104,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;
@@ -936,5 +1128,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);
}