[RFC][PATCH] xf86-input-evdev: add pressure valuator
Matt Helsley
matt.helsley at gmail.com
Wed Jan 7 23:34:25 PST 2009
If it available report pressure as the third valuator.
Signed-off-by: Matt Helsley <matt.helsley at gmail.com>
---
I couldn't seem to get the third valuator from X with
xf86-input-evdev master when I was testing this over the
holidays. (tested using the GIMP)
So I backported to an older version of evdev available in
my distro (Ubuntu 8.10) and it tested successfully there.
What am I missing here?
src/evdev.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++------
src/evdev.h | 6 +++--
2 files changed, 60 insertions(+), 8 deletions(-)
Index: xf86-input-evdev/src/evdev.h
===================================================================
--- xf86-input-evdev.orig/src/evdev.h
+++ xf86-input-evdev/src/evdev.h
@@ -58,19 +58,21 @@ typedef struct {
typedef struct {
const char *device;
int grabDevice; /* grab the event device? */
int screen;
- int min_x, min_y, max_x, max_y;
- int abs_x, abs_y, old_x, old_y;
+ int min_x, min_y, max_x, max_y, min_p, max_p;
+ int abs_x, abs_y, abs_p, old_x, old_y;
int flags;
int tool;
int buttons; /* number of buttons */
BOOL swap_axes;
BOOL invert_x;
BOOL invert_y;
+ BOOL pressure_valuator;
+
/* XKB stuff has to be per-device rather than per-driver */
int noXkb;
#ifdef XKB
char *xkb_rules;
char *xkb_model;
Index: xf86-input-evdev/src/evdev.c
===================================================================
--- xf86-input-evdev.orig/src/evdev.c
+++ xf86-input-evdev/src/evdev.c
@@ -384,10 +384,14 @@ EvdevReadInput(InputInfoPtr pInfo)
break;
case ABS_Y:
pEvdev->abs_y = value;
abs = 1;
break;
+ case ABS_PRESSURE:
+ pEvdev->abs_p = value;
+ abs = 1;
+ break;
}
break;
case EV_KEY:
/* don't repeat mouse buttons */
@@ -475,11 +479,11 @@ EvdevReadInput(InputInfoPtr pInfo)
* pEvdev->digi here, lets us ignore that event. pEvdev is
* initialized to 1 so devices that doesn't use this scheme still
* just works.
*/
if (abs && pEvdev->tool) {
- int abs_x, abs_y;
+ int abs_x, abs_y, abs_p;
abs_x = (pEvdev->swap_axes) ? pEvdev->abs_y : pEvdev->abs_x;
abs_y = (pEvdev->swap_axes) ? pEvdev->abs_x : pEvdev->abs_y;
if (pEvdev->flags & EVDEV_CALIBRATED)
{
@@ -488,17 +492,23 @@ EvdevReadInput(InputInfoPtr pInfo)
pEvdev->calibration.max_x, pEvdev->calibration.min_x);
abs_y = xf86ScaleAxis(abs_y,
pEvdev->max_y, pEvdev->min_y,
pEvdev->calibration.max_y, pEvdev->calibration.min_y);
}
+ abs_p = pEvdev->abs_p;
if (pEvdev->invert_x)
abs_x = pEvdev->max_x - (abs_x - pEvdev->min_x);
if (pEvdev->invert_y)
abs_y = pEvdev->max_y - (abs_y - pEvdev->min_y);
- xf86PostMotionEvent(pInfo->dev, TRUE, 0, 2, abs_x, abs_y);
+ if (pEvdev->pressure_valuator)
+ xf86PostMotionEvent(pInfo->dev, TRUE, 0, 3,
+ abs_x, abs_y, abs_p);
+ else
+ xf86PostMotionEvent(pInfo->dev, TRUE, 0, 2,
+ abs_x, abs_y);
}
}
#define TestBit(bit, array) (array[(bit) / LONG_BITS]) & (1L << ((bit) % LONG_BITS))
@@ -878,11 +888,12 @@ EvdevAddKeyClass(DeviceIntPtr device)
static int
EvdevAddAbsClass(DeviceIntPtr device)
{
InputInfoPtr pInfo;
EvdevPtr pEvdev;
- struct input_absinfo absinfo_x, absinfo_y;
+ struct input_absinfo absinfo_x, absinfo_y, absinfo_p;
+ int num_valuators = 2;
pInfo = device->public.devicePrivate;
pEvdev = pInfo->private;
if (ioctl(pInfo->fd,
@@ -900,11 +911,24 @@ EvdevAddAbsClass(DeviceIntPtr device)
pEvdev->min_x = absinfo_x.minimum;
pEvdev->max_x = absinfo_x.maximum;
pEvdev->min_y = absinfo_y.minimum;
pEvdev->max_y = absinfo_y.maximum;
- if (!InitValuatorClassDeviceStruct(device, 2,
+ if (pEvdev->pressure_valuator && ioctl(pInfo->fd,
+ EVIOCGABS(ABS_PRESSURE), &absinfo_p) < 0) {
+ xf86Msg(X_ERROR, "ioctl EVIOCGABS ABS_PRESSURE failed: %s\n", strerror(errno));
+ return !Success;
+ }
+
+ if (pEvdev->pressure_valuator) {
+ num_valuators++;
+ pEvdev->max_p = absinfo_p.maximum;
+ pEvdev->min_p = absinfo_p.minimum;
+ }
+
+
+ if (!InitValuatorClassDeviceStruct(device, num_valuators,
#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 3
GetMotionHistory,
#endif
GetMotionHistorySize(), Absolute))
return !Success;
@@ -916,10 +940,17 @@ EvdevAddAbsClass(DeviceIntPtr device)
/* Y valuator */
xf86InitValuatorAxisStruct(device, 1, pEvdev->min_y, pEvdev->max_y,
10000, 0, 10000);
xf86InitValuatorDefaults(device, 1);
+
+ if (pEvdev->pressure_valuator) {
+ xf86InitValuatorAxisStruct(device, 2, pEvdev->min_p, pEvdev->max_p,
+ 10000, 0, 10000);
+ xf86InitValuatorDefaults(device, 2);
+ }
+
xf86MotionHistoryAllocate(pInfo);
if (!InitPtrFeedbackClassDeviceStruct(device, EvdevPtrCtrlProc))
return !Success;
@@ -1365,11 +1396,11 @@ EvdevProbe(InputInfoPtr pInfo)
}
if (TestBit(ABS_X, abs_bitmask) && TestBit(ABS_Y, abs_bitmask)) {
xf86Msg(X_INFO, "%s: Found x and y absolute axes\n", pInfo->name);
pEvdev->flags |= EVDEV_ABSOLUTE_EVENTS;
- if (TestBit(BTN_TOUCH, key_bitmask)) {
+ if (!pEvdev->pressure_valuator && TestBit(BTN_TOUCH, key_bitmask)) {
if (num_buttons) {
xf86Msg(X_INFO, "%s: Found absolute touchpad\n", pInfo->name);
pEvdev->flags |= EVDEV_TOUCHPAD;
pEvdev->old_x = pEvdev->old_y = -1;
} else {
@@ -1379,27 +1410,45 @@ EvdevProbe(InputInfoPtr pInfo)
}
}
has_axes = TRUE;
}
+ if (TestBit(ABS_PRESSURE, abs_bitmask)) {
+ struct input_absinfo absinfo_p;
+
+ /* More than two pressure levels indicate it's not a button */
+ if (ioctl(pInfo->fd,
+ EVIOCGABS(ABS_PRESSURE), &absinfo_p) == 0) {
+ if ((absinfo_p.maximum - absinfo_p.minimum) > 1)
+ pEvdev->pressure_valuator = TRUE;
+ }
+ }
+
for (i = 0; i < BTN_MISC; i++)
if (TestBit(i, key_bitmask))
break;
if (i < BTN_MISC) {
xf86Msg(X_INFO, "%s: Found keys\n", pInfo->name);
pEvdev->flags |= EVDEV_KEYBOARD_EVENTS;
has_keys = TRUE;
}
- if (has_axes && num_buttons) {
+ if (!pEvdev->pressure_valuator && has_axes && num_buttons) {
xf86Msg(X_INFO, "%s: Configuring as mouse\n", pInfo->name);
pInfo->flags |= XI86_POINTER_CAPABLE | XI86_SEND_DRAG_EVENTS |
XI86_CONFIGURED;
pInfo->type_name = XI_MOUSE;
}
+ if (pEvdev->pressure_valuator && has_axes && num_buttons) {
+ xf86Msg(X_INFO, "%s: Configuring as tablet\n", pInfo->name);
+ pInfo->flags |= XI86_POINTER_CAPABLE | XI86_SEND_DRAG_EVENTS |
+ XI86_CONFIGURED;
+ pInfo->type_name = XI_TABLET;
+ }
+
if (pEvdev->flags & EVDEV_TOUCHSCREEN) {
xf86Msg(X_INFO, "%s: Configuring as touchscreen\n", pInfo->name);
pInfo->type_name = XI_TOUCHSCREEN;
pInfo->flags |= XI86_POINTER_CAPABLE | XI86_SEND_DRAG_EVENTS |
XI86_CONFIGURED;
@@ -1473,10 +1522,11 @@ EvdevPreInit(InputDriverPtr drv, IDevPtr
/*
* We initialize pEvdev->tool to 1 so that device that doesn't use
* proximity will still report events.
*/
pEvdev->tool = 1;
+ pEvdev->pressure_valuator = FALSE;
device = xf86CheckStrOption(dev->commonOptions, "Device", NULL);
if (!device) {
xf86Msg(X_ERROR, "%s: No device specified.\n", pInfo->name);
xf86DeleteInput(pInfo, 0);
More information about the xorg
mailing list