If it's available report pressure.

Signed-off-by: Matt Helsley <[email protected]>
---
Changes:
        Renamed pressure_valuator to has_pressure.
        Nested some code blocks rather than having separate nearly
                identical blocks.
        Use xf86PostMotionEventP instead of the varargs wrapper.

NOTES:
        I'm still working on generic valuator support.

        Should apply with an offset of 16 if my "ABS_CNT" patch is
        applied first.

 src/evdev.c |   75 ++++++++++++++++++++++++++++++++++++++++++++++++------------
 src/evdev.h |    5 ++--
 2 files changed, 63 insertions(+), 17 deletions(-)

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,30 +479,32 @@ 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;
-        abs_x = (pEvdev->swap_axes) ? pEvdev->abs_y : pEvdev->abs_x;
-        abs_y = (pEvdev->swap_axes) ? pEvdev->abs_x : pEvdev->abs_y;
+        int v[3];
+        v[0] = (pEvdev->swap_axes) ? pEvdev->abs_y : pEvdev->abs_x;
+        v[1] = (pEvdev->swap_axes) ? pEvdev->abs_x : pEvdev->abs_y;
+        v[2] = pEvdev->abs_p;
 
         if (pEvdev->flags & EVDEV_CALIBRATED)
         {
-            abs_x = xf86ScaleAxis(abs_x,
+            v[0] = xf86ScaleAxis(v[0],
                     pEvdev->max_x, pEvdev->min_x,
                     pEvdev->calibration.max_x, pEvdev->calibration.min_x);
-            abs_y = xf86ScaleAxis(abs_y,
+            v[1] = xf86ScaleAxis(v[1],
                     pEvdev->max_y, pEvdev->min_y,
                     pEvdev->calibration.max_y, pEvdev->calibration.min_y);
         }
 
         if (pEvdev->invert_x)
-            abs_x = pEvdev->max_x - (abs_x - pEvdev->min_x);
+            v[0] = pEvdev->max_x - (v[0] - pEvdev->min_x);
         if (pEvdev->invert_y)
-            abs_y = pEvdev->max_y - (abs_y - pEvdev->min_y);
+            v[1] = pEvdev->max_y - (v[1] - pEvdev->min_y);
 
-       xf86PostMotionEvent(pInfo->dev, TRUE, 0, 2, abs_x, abs_y);
+       xf86PostMotionEventP(pInfo->dev, TRUE, 0,
+                            2 + (pEvdev->has_pressure ? 1 : 0), v);
     }
 }
 
 #define TestBit(bit, array) (array[(bit) / LONG_BITS]) & (1L << ((bit) % 
LONG_BITS))
 
@@ -878,11 +884,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 +907,25 @@ 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->has_pressure &&
+       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->has_pressure) {
+           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 +937,17 @@ EvdevAddAbsClass(DeviceIntPtr device)
 
     /* Y valuator */
     xf86InitValuatorAxisStruct(device, 1, pEvdev->min_y, pEvdev->max_y,
                               10000, 0, 10000);
     xf86InitValuatorDefaults(device, 1);
+
+    if (pEvdev->has_pressure) {
+           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 +1393,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->has_pressure && 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,10 +1407,21 @@ 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->has_pressure = TRUE;
+        }
+    }
+
     for (i = 0; i < BTN_MISC; i++)
         if (TestBit(i, key_bitmask))
             break;
 
     if (i < BTN_MISC) {
@@ -1390,14 +1429,19 @@ EvdevProbe(InputInfoPtr pInfo)
        pEvdev->flags |= EVDEV_KEYBOARD_EVENTS;
        has_keys = TRUE;
     }
 
     if (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;
+        pInfo->flags |= XI86_POINTER_CAPABLE | XI86_SEND_DRAG_EVENTS |
+                        XI86_CONFIGURED;
+       if (pEvdev->has_pressure) {
+           xf86Msg(X_INFO, "%s: Configuring as tablet\n", pInfo->name);
+           pInfo->type_name = XI_TABLET;
+       } else {
+           xf86Msg(X_INFO, "%s: Configuring as mouse\n", pInfo->name);
+           pInfo->type_name = XI_MOUSE;
+       }
     }
 
     if (pEvdev->flags & EVDEV_TOUCHSCREEN) {
         xf86Msg(X_INFO, "%s: Configuring as touchscreen\n", pInfo->name);
         pInfo->type_name = XI_TOUCHSCREEN;
@@ -1473,10 +1517,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->has_pressure = FALSE;
 
     device = xf86CheckStrOption(dev->commonOptions, "Device", NULL);
     if (!device) {
         xf86Msg(X_ERROR, "%s: No device specified.\n", pInfo->name);
        xf86DeleteInput(pInfo, 0);
Index: xf86-input-evdev/src/evdev.h
===================================================================
--- xf86-input-evdev.orig/src/evdev.h
+++ xf86-input-evdev/src/evdev.h
@@ -58,18 +58,19 @@ 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 has_pressure;
 
     /* XKB stuff has to be per-device rather than per-driver */
     int noXkb;
 #ifdef XKB
     char                    *xkb_rules;


_______________________________________________
xorg mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/xorg

Reply via email to