summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChase Douglas <chase.douglas@canonical.com>2010-07-16 09:21:19 -0400
committerPeter Hutterer <peter.hutterer@who-t.net>2010-10-22 13:37:57 +1000
commit65c0fc81eb920085e650b8c9e874c9dd26c7ec98 (patch)
treeac513fa8127b4dc8d4e8003d3cd4f1be21fe060e
parent9696c782c8cb86b06d12949899582533a2e04cfe (diff)
Add support for per-axis valuator modes (Relative/Absolute)
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). 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@canonical.com>
-rw-r--r--Xi/exevents.c3
-rw-r--r--Xi/xiquerydevice.c2
-rw-r--r--dix/devices.c5
-rw-r--r--dix/eventconvert.c14
-rw-r--r--dix/getevents.c23
-rw-r--r--hw/dmx/input/dmxinputinit.c8
-rw-r--r--hw/dmx/input/dmxmotion.c7
-rw-r--r--hw/xfree86/common/xf86Xinput.c4
-rw-r--r--hw/xfree86/common/xf86Xinput.h2
-rw-r--r--hw/xquartz/darwin.c14
-rw-r--r--include/exevents.h3
-rw-r--r--include/inputstr.h1
12 files changed, 56 insertions, 30 deletions
diff --git a/Xi/exevents.c b/Xi/exevents.c
index 9689ef8f8..1f59001cf 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1127,7 +1127,7 @@ InitProximityClassDeviceStruct(DeviceIntPtr dev)
*/
void
InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval, int maxval,
- int resolution, int min_res, int max_res)
+ int resolution, int min_res, int max_res, int mode)
{
AxisInfoPtr ax;
@@ -1144,6 +1144,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 = mode;
}
static void
diff --git a/Xi/xiquerydevice.c b/Xi/xiquerydevice.c
index 303c8b27d..c8b3d7e1b 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 6f6f0fa7f..3548be4e4 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -1260,7 +1260,7 @@ InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes, Atom *labels,
for (i=0; i<numAxes; i++) {
InitValuatorAxisStruct(dev, i, labels[i], NO_AXIS_LIMITS, NO_AXIS_LIMITS,
- 0, 0, 0);
+ 0, 0, 0, mode);
valc->axisVal[i]=0;
}
@@ -2357,8 +2357,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 0f747c1a0..46eb4ffd8 100644
--- a/dix/eventconvert.c
+++ b/dix/eventconvert.c
@@ -261,6 +261,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));
@@ -318,6 +324,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.
+ */
+ if (ev->valuators.mode[i] != ev->valuators.mode[0])
+ break;
+
if (BitIsOn(ev->valuators.mask, i))
{
if (first_valuator == -1)
@@ -440,7 +452,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 6a443561b..0b6d6d39c 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -210,7 +210,7 @@ set_valuators(DeviceIntPtr dev, DeviceEvent* event, ValuatorMask *mask)
if (valuator_mask_isset(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] = valuator_mask_get(mask, i);
event->valuators.data_frac[i] =
@@ -255,8 +255,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;
}
}
@@ -374,8 +373,16 @@ AllocateMotionHistory(DeviceIntPtr pDev)
*/
if (IsMaster(pDev))
size = sizeof(INT32) * 3 * MAX_VALUATORS;
- else
- size = sizeof(INT32) * pDev->valuator->numAxes;
+ else {
+ ValuatorClassPtr v = pDev->valuator;
+ int numAxes;
+ /* XI1 doesn't understand mixed mode devices */
+ for (numAxes = 0; numAxes < v->numAxes; numAxes++)
+ if ((v->axes[numAxes].mode & DeviceMode) !=
+ (v->mode & DeviceMode))
+ break;
+ size = sizeof(INT32) * numAxes;
+ }
size += sizeof(Time);
@@ -556,6 +563,10 @@ updateMotionHistory(DeviceIntPtr pDev, CARD32 ms, ValuatorMask *mask,
for (i = 0; i < v->numAxes; i++)
{
+ /* XI1 doesn't support mixed mode devices */
+ if ((pDev->valuator->axes[i].mode & DeviceMode) !=
+ (pDev->valuator->mode & DeviceMode))
+ break;
if (valuator_mask_size(mask) <= i || !valuator_mask_isset(mask, i))
{
buff += 3 * sizeof(INT32);
@@ -769,7 +780,7 @@ moveRelative(DeviceIntPtr dev, int *x, int *y, ValuatorMask *mask)
if (valuator_mask_isset(mask, i))
{
dev->last.valuators[i] += valuator_mask_get(mask, i);
- if (dev->valuator->mode == Absolute)
+ if (dev->valuator->axes[i].mode == Absolute)
clipAxis(dev, i, &dev->last.valuators[i]);
valuator_mask_set(mask, i, dev->last.valuators[i]);
}
diff --git a/hw/dmx/input/dmxinputinit.c b/hw/dmx/input/dmxinputinit.c
index 829a28950..7cac86f79 100644
--- a/hw/dmx/input/dmxinputinit.c
+++ b/hw/dmx/input/dmxinputinit.c
@@ -476,7 +476,8 @@ static int dmxDeviceOnOff(DeviceIntPtr pDevice, int what)
InitValuatorAxisStruct(pDevice, i, axis_labels[i],
info.minval[i], info.maxval[i],
info.res[i],
- info.minres[i], info.maxres[i]);
+ info.minres[i], info.maxres[i],
+ Relative);
} else if (info.numRelAxes) {
InitValuatorClassDeviceStruct(pDevice, info.numRelAxes,
axis_labels,
@@ -486,7 +487,8 @@ static int dmxDeviceOnOff(DeviceIntPtr pDevice, int what)
InitValuatorAxisStruct(pDevice, i, axis_labels[i],
info.minval[i],
info.maxval[i], info.res[i],
- info.minres[i], info.maxres[i]);
+ info.minres[i], info.maxres[i],
+ Relative);
} else if (info.numAbsAxes) {
InitValuatorClassDeviceStruct(pDevice, info.numAbsAxes,
axis_labels,
@@ -497,7 +499,7 @@ static int dmxDeviceOnOff(DeviceIntPtr pDevice, int what)
axis_labels[i],
info.minval[i], info.maxval[i],
info.res[i], info.minres[i],
- info.maxres[i]);
+ info.maxres[i], Absolute);
}
}
if (info.focusClass) InitFocusClassDeviceStruct(pDevice);
diff --git a/hw/dmx/input/dmxmotion.c b/hw/dmx/input/dmxmotion.c
index a86b62e5c..1aae5feb5 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/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 72c93223f..b910cf8c5 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -1325,13 +1325,13 @@ xf86XInputSetScreen(InputInfoPtr pInfo,
void
xf86InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval, int maxval,
- int resolution, int min_res, int max_res)
+ int resolution, int min_res, int max_res, int mode)
{
if (!dev || !dev->valuator)
return;
InitValuatorAxisStruct(dev, axnum, label, minval, maxval, resolution, min_res,
- max_res);
+ max_res, mode);
}
/*
diff --git a/hw/xfree86/common/xf86Xinput.h b/hw/xfree86/common/xf86Xinput.h
index 829bf781a..8ee0c681f 100644
--- a/hw/xfree86/common/xf86Xinput.h
+++ b/hw/xfree86/common/xf86Xinput.h
@@ -147,7 +147,7 @@ extern _X_EXPORT void xf86XInputSetScreen(InputInfoPtr pInfo, int screen_number,
extern _X_EXPORT void xf86ProcessCommonOptions(InputInfoPtr pInfo, pointer options);
extern _X_EXPORT void xf86InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval,
int maxval, int resolution, int min_res,
- int max_res);
+ int max_res, int mode);
extern _X_EXPORT void xf86InitValuatorDefaults(DeviceIntPtr dev, int axnum);
extern _X_EXPORT void xf86AddEnabledDevice(InputInfoPtr pInfo);
extern _X_EXPORT void xf86RemoveEnabledDevice(InputInfoPtr pInfo);
diff --git a/hw/xquartz/darwin.c b/hw/xquartz/darwin.c
index 2362faca5..018ce7824 100644
--- a/hw/xquartz/darwin.c
+++ b/hw/xquartz/darwin.c
@@ -316,8 +316,8 @@ static int DarwinMouseProc(DeviceIntPtr pPointer, int what) {
axes_labels);
pPointer->valuator->mode = Absolute; // Relative
InitAbsoluteClassDeviceStruct(pPointer);
-// InitValuatorAxisStruct(pPointer, 0, 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1);
-// InitValuatorAxisStruct(pPointer, 1, 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1);
+// InitValuatorAxisStruct(pPointer, 0, 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1, Absolute);
+// InitValuatorAxisStruct(pPointer, 1, 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1, Absolute);
break;
case DEVICE_ON:
pPointer->public.on = TRUE;
@@ -366,11 +366,11 @@ static int DarwinTabletProc(DeviceIntPtr pPointer, int what) {
InitProximityClassDeviceStruct(pPointer);
InitAbsoluteClassDeviceStruct(pPointer);
- InitValuatorAxisStruct(pPointer, 0, axes_labels[0], 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1);
- InitValuatorAxisStruct(pPointer, 1, axes_labels[1], 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1);
- InitValuatorAxisStruct(pPointer, 2, axes_labels[2], 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1);
- InitValuatorAxisStruct(pPointer, 3, axes_labels[3], -XQUARTZ_VALUATOR_LIMIT, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1);
- InitValuatorAxisStruct(pPointer, 4, axes_labels[4], -XQUARTZ_VALUATOR_LIMIT, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1);
+ InitValuatorAxisStruct(pPointer, 0, axes_labels[0], 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1, Absolute);
+ InitValuatorAxisStruct(pPointer, 1, axes_labels[1], 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1, Absolute);
+ InitValuatorAxisStruct(pPointer, 2, axes_labels[2], 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1, Absolute);
+ InitValuatorAxisStruct(pPointer, 3, axes_labels[3], -XQUARTZ_VALUATOR_LIMIT, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1, Absolute);
+ InitValuatorAxisStruct(pPointer, 4, axes_labels[4], -XQUARTZ_VALUATOR_LIMIT, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1, Absolute);
// pPointer->use = IsXExtensionDevice;
break;
case DEVICE_ON:
diff --git a/include/exevents.h b/include/exevents.h
index b64252f36..bfee385d3 100644
--- a/include/exevents.h
+++ b/include/exevents.h
@@ -48,7 +48,8 @@ extern _X_EXPORT void InitValuatorAxisStruct(
int /* maxval */,
int /* resolution */,
int /* min_res */,
- int /* max_res */);
+ int /* max_res */,
+ int /* mode */);
/* Input device properties */
extern _X_EXPORT void XIDeleteAllDeviceProperties(
diff --git a/include/inputstr.h b/include/inputstr.h
index ec9749e36..dfab791e6 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -218,6 +218,7 @@ typedef struct _AxisInfo {
int min_value;
int max_value;
Atom label;
+ CARD8 mode;
} AxisInfo, *AxisInfoPtr;
typedef struct _ValuatorAccelerationRec {