[PATCH 2/2] Add support for per-axis valuator modes (Relative/Absolute)
Peter Hutterer
peter.hutterer at who-t.net
Tue Jul 27 21:55:32 PDT 2010
On Fri, Jul 16, 2010 at 09:21:19AM -0400, Chase Douglas wrote:
> The XI2 protocol supports per-axis modes, but the server so far does
> not. This change adds support in the server.
>
> A complication is the fact that XI1 does not support per-axis modes.
> The solution provided here is to set a per-device mode that defines the
> mode of at least the first two valuators (X and Y). The per-axis
> valuator mode defaults to Relative, so any absolute axes must be
> explicitly set. Note that initializing the first two axes to a different
> mode than the device mode will fail.
>
> For XI1 events, any axes following the first two that have the same mode
> will be sent to clients, up to the first axis that has a different mode.
> Thus, if a device has relative, then absolute, then relative mode axes,
> only the first block of relative axes will be sent over XI1.
>
> Since the XI2 protocol supports per-axis modes, all axes are sent to the
> client.
>
> Signed-off-by: Chase Douglas <chase.douglas at canonical.com>
> ---
> Xi/exevents.c | 1 +
> Xi/xiquerydevice.c | 2 +-
> dix/devices.c | 3 +--
> dix/eventconvert.c | 14 +++++++++++++-
> dix/getevents.c | 23 ++++++++++++++++-------
> hw/dmx/input/dmxmotion.c | 7 +++----
> include/inputstr.h | 1 +
> 7 files changed, 36 insertions(+), 15 deletions(-)
>
> diff --git a/Xi/exevents.c b/Xi/exevents.c
> index e990aeb..26084f5 100644
> --- a/Xi/exevents.c
> +++ b/Xi/exevents.c
> @@ -1145,6 +1145,7 @@ InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval, int
> ax->min_resolution = min_res;
> ax->max_resolution = max_res;
> ax->label = label;
> + ax->mode = dev->valuator->mode;
shouldn't this be another parameter then?
> }
>
> static void
> diff --git a/Xi/xiquerydevice.c b/Xi/xiquerydevice.c
> index 303c8b2..c8b3d7e 100644
> --- a/Xi/xiquerydevice.c
> +++ b/Xi/xiquerydevice.c
> @@ -349,7 +349,7 @@ ListValuatorInfo(DeviceIntPtr dev, xXIValuatorInfo* info, int axisnumber,
> info->value.frac = (int)(v->axisVal[axisnumber] * (1 << 16) * (1 << 16));
> info->resolution = v->axes[axisnumber].resolution;
> info->number = axisnumber;
> - info->mode = v->mode; /* Server doesn't have per-axis mode yet */
> + info->mode = v->axes[axisnumber].mode;
> info->sourceid = v->sourceid;
>
> if (!reportState)
> diff --git a/dix/devices.c b/dix/devices.c
> index ac5806a..e4048e4 100644
> --- a/dix/devices.c
> +++ b/dix/devices.c
> @@ -2366,8 +2366,7 @@ RecalculateMasterButtons(DeviceIntPtr slave)
> event.valuators[i].min = master->valuator->axes[i].min_value;
> event.valuators[i].max = master->valuator->axes[i].max_value;
> event.valuators[i].resolution = master->valuator->axes[i].resolution;
> - /* This should, eventually, be a per-axis mode */
> - event.valuators[i].mode = master->valuator->mode;
> + event.valuators[i].mode = master->valuator->axes[i].mode;
> event.valuators[i].name = master->valuator->axes[i].label;
> }
> }
> diff --git a/dix/eventconvert.c b/dix/eventconvert.c
> index 4e3de0b..991298e 100644
> --- a/dix/eventconvert.c
> +++ b/dix/eventconvert.c
> @@ -252,6 +252,12 @@ eventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count)
> }
>
> num_events = (countValuators(ev, &first) + 5)/6; /* valuator ev */
> + if (num_events <= 0)
> + {
> + *count = 0;
> + return BadMatch;
> + }
> +
> num_events++; /* the actual event event */
>
> *xi = calloc(num_events, sizeof(xEvent));
> @@ -309,6 +315,12 @@ countValuators(DeviceEvent *ev, int *first)
>
> for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++)
> {
> + /* Assume mode of 0th valuator matches XI1 device mode. Stop when the
> + * event mode changes since XI1 can't handle mixed mode devices.
> + */
why is this assumption necessary? valuator->mode still stores what the XI1
device mode is.
> + if (ev->valuators.mode[i] != ev->valuators.mode[0])
> + break;
> +
> if (BitIsOn(ev->valuators.mask, i))
> {
> if (first_valuator == -1)
> @@ -431,7 +443,7 @@ appendValuatorInfo(DeviceChangedEvent *dce, xXIValuatorInfo *info, int axisnumbe
> info->value.frac = 0;
> info->resolution = dce->valuators[axisnumber].resolution;
> info->number = axisnumber;
> - info->mode = dce->valuators[axisnumber].mode; /* Server doesn't have per-axis mode yet */
> + info->mode = dce->valuators[axisnumber].mode;
> info->sourceid = dce->sourceid;
>
> return info->length * 4;
> diff --git a/dix/getevents.c b/dix/getevents.c
> index 20cc79b..72daa16 100644
> --- a/dix/getevents.c
> +++ b/dix/getevents.c
> @@ -208,7 +208,7 @@ set_valuators(DeviceIntPtr dev, DeviceEvent* event, uint8_t *mask,
> if (BitIsOn(mask, i))
> {
> SetBit(event->valuators.mask, i);
> - if (dev->valuator->mode == Absolute)
> + if (dev->valuator->axes[i].mode == Absolute)
> SetBit(event->valuators.mode, i);
> event->valuators.data[i] = valuators[i];
> event->valuators.data_frac[i] =
> @@ -253,8 +253,7 @@ CreateClassesChangedEvent(EventList* event,
> dce->valuators[i].min = slave->valuator->axes[i].min_value;
> dce->valuators[i].max = slave->valuator->axes[i].max_value;
> dce->valuators[i].resolution = slave->valuator->axes[i].resolution;
> - /* This should, eventually, be a per-axis mode */
> - dce->valuators[i].mode = slave->valuator->mode;
> + dce->valuators[i].mode = slave->valuator->axes[i].mode;
> dce->valuators[i].name = slave->valuator->axes[i].label;
> }
> }
> @@ -372,8 +371,15 @@ AllocateMotionHistory(DeviceIntPtr pDev)
> */
> if (IsMaster(pDev))
> size = sizeof(INT32) * 3 * MAX_VALUATORS;
> - else
> - size = sizeof(INT32) * pDev->valuator->numAxes;
> + else {
> + int numAxes;
> + /* XI1 doesn't understand mixed mode devices */
> + for (numAxes = 0; numAxes < pDev->valuator->numAxes; numAxes++)
> + if ((pDev->valuator->axes[numAxes].mode & DeviceMode) !=
> + (pDev->valuator->mode & DeviceMode))
> + break;
i think having a ValuatorClassPtr v = pDev->valuator would make the code
easier to read.
> + size = sizeof(INT32) * numAxes;
> + }
>
> size += sizeof(Time);
>
> @@ -554,7 +560,10 @@ updateMotionHistory(DeviceIntPtr pDev, CARD32 ms, uint8_t *mask,
>
> for (i = 0; i < MAX_VALUATORS; i++)
> {
> - if (i >= v->numAxes)
> + /* XI1 doesn't support mixed mode devices */
> + if (i >= v->numAxes ||
> + (pDev->valuator->axes[i].mode & DeviceMode) !=
> + (pDev->valuator->mode & DeviceMode))
> break;
> if (!BitIsOn(mask, i))
> {
> @@ -768,7 +777,7 @@ moveRelative(DeviceIntPtr dev, int *x, int *y,
> if (BitIsOn(mask, i))
> {
> dev->last.valuators[i] += valuators[i];
> - if (dev->valuator->mode == Absolute)
> + if (dev->valuator->axes[i].mode == Absolute)
> clipAxis(dev, i, &dev->last.valuators[i]);
> valuators[i] = dev->last.valuators[i];
> }
> diff --git a/hw/dmx/input/dmxmotion.c b/hw/dmx/input/dmxmotion.c
> index a86b62e..1aae5fe 100644
> --- a/hw/dmx/input/dmxmotion.c
> +++ b/hw/dmx/input/dmxmotion.c
> @@ -125,12 +125,11 @@ void dmxPointerPutMotionEvent(DeviceIntPtr pDevice,
> /* Initialize the data from the known
> * values (if Absolute) or to zero (if
> * Relative) */
> - if (pDevice->valuator->mode == Absolute) {
> - for (i = 0; i < numAxes; i++)
> + for (i = 0; i < numAxes; i++) {
> + if (pDevice->valuator->axes[i].mode == Absolute)
> dmxLocal->history[OFFSET(dmxLocal->tail,i+1)]
> = dmxLocal->valuators[i];
> - } else {
> - for (i = 0; i < numAxes; i++)
> + else
> dmxLocal->history[OFFSET(dmxLocal->tail,i+1)] = 0;
> }
>
> diff --git a/include/inputstr.h b/include/inputstr.h
> index 1b504e9..d0e9f45 100644
> --- a/include/inputstr.h
> +++ b/include/inputstr.h
> @@ -217,6 +217,7 @@ typedef struct _AxisInfo {
> int min_value;
> int max_value;
> Atom label;
> + CARD8 mode;
> } AxisInfo, *AxisInfoPtr;
>
> typedef struct _ValuatorAccelerationRec {
> --
> 1.7.0.4
>
Cheers,
Peter
More information about the xorg-devel
mailing list