Fixing the Pen Tablet

Michael Stone michael at laptop.org
Sun Mar 23 22:00:38 EDT 2008


Folks,

Below are patches to the kernel source code and the xorg-x11-server and
xorg-x11-drv-evdev packages which restore function to the ALPS Pen
Tablet (dlo#5268), which fix the "twin clicks" bug that plagued previous
approaches (dlo#6079), and which cause X to configure the Pen Tablet in
absolute mode (mapped to the entire screen, dlo#1002) while leaving
Glide Sensor in relative mode (discussion at dlo#4260).

Blake & Michael
-------------- next part --------------
>From 827d3ab4637a72b9cb0eede4d071234df20cc24c Mon Sep 17 00:00:00 2001
From: Blake Setlow <csetlow at tower-research.com>
Date: Sun, 23 Mar 2008 21:32:07 -0400
Subject: [PATCH] OLPC: psmouse: Make the OLPC/ALPS Pen Tablet and Glide Sensor play together.

The Pen Tablet has been disabled for some time [1] because enabling it caused
a "twin clicks" bug [2]. One minimal way to fix the first bug while avoiding
the second is to enable the Pen Tablet and its buttons while turning off some
of the buttons on the Glide Sensor. We do this and we attempt to explain why
each bit in the PT and GS device structs is set or unset.

This patch was coauthored by Blake Setlow and Michael Stone.

[1]: http://dev.laptop.org/ticket/5628
[2]: http://dev.laptop.org/ticket/6079

Signed-off-by: Michael Stone <michael at laptop.org>
---
 drivers/input/mouse/olpc.c |   54 +++++++++++++++++++++++++++++++------------
 1 files changed, 39 insertions(+), 15 deletions(-)

diff --git a/drivers/input/mouse/olpc.c b/drivers/input/mouse/olpc.c
index 9479658..80604bb 100644
--- a/drivers/input/mouse/olpc.c
+++ b/drivers/input/mouse/olpc.c
@@ -3,6 +3,7 @@
  *
  * Copyright (c) 2006 One Laptop Per Child, inc.
  * Authors Zephaniah E. Hull and Andres Salomon <dilinger at laptop.org>
+ * Authors Blake Setlow <csetlow at tower-research.com>
  *
  * This driver is partly based on the ALPS driver, which is:
  *
@@ -487,21 +488,30 @@ int olpc_init(struct psmouse *psmouse)
 		goto init_fail;
 	}
 
-	/*
-	 * Unset some of the default bits for things we don't have.
-	 */
+	/* Mode: our Pen Tablet (PT) should be used in its absolute mode */
 	dev->evbit[LONG(EV_REL)] &= ~BIT(EV_REL);
-	dev->relbit[LONG(REL_X)] &= ~(BIT(REL_X) | BIT(REL_Y));
-	dev->keybit[LONG(BTN_MIDDLE)] &= ~BIT(BTN_MIDDLE);
-
+	dev->evbit[LONG(EV_ABS)] |= BIT(EV_ABS);
 	dev->evbit[LONG(EV_KEY)] |= BIT(EV_KEY);
+
+	/* Axes: give us absolute and not relative data. */
+	dev->relbit[LONG(REL_X)] &= ~BIT(REL_X);
+	dev->relbit[LONG(REL_Y)] &= ~BIT(REL_Y);
+	dev->absbit[LONG(ABS_X)] |= BIT(ABS_X);
+	dev->absbit[LONG(ABS_Y)] |= BIT(ABS_Y);
+	dev->absbit[LONG(ABS_PRESSURE)] |= BIT(ABS_PRESSURE);
+
+	/* Buttons: without BTN_TOUCH but with BTN_TOOL_PEN, evtest reports
+	 * nothing! */
 	dev->keybit[LONG(BTN_TOUCH)] |= BIT(BTN_TOUCH);
 	dev->keybit[LONG(BTN_TOOL_PEN)] |= BIT(BTN_TOOL_PEN);
-	dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT);
+	dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT);
+	dev->keybit[LONG(BTN_RIGHT)] |= BIT(BTN_RIGHT);
+	dev->keybit[LONG(BTN_MIDDLE)] &= ~BIT(BTN_MIDDLE);
 
-	dev->evbit[LONG(EV_ABS)] |= BIT(EV_ABS);
-	input_set_abs_params(dev, ABS_X, 2, 1000, 0, 0);
-	input_set_abs_params(dev, ABS_Y, 0, 717, 0, 0);
+	/* Finally, some magic range numbers governing device output ranges. */
+	input_set_abs_params(dev, ABS_X, 2, 998, 0, 0);
+	input_set_abs_params(dev, ABS_Y, 2, 238, 0, 0);
+	input_set_abs_params(dev, ABS_PRESSURE, 0, 63, 0, 0);
 
 	snprintf(priv->phys, sizeof(priv->phys),
 		"%s/input1", psmouse->ps2dev.serio->phys);
@@ -512,17 +522,31 @@ int olpc_init(struct psmouse *psmouse)
 	dev2->id.product = PSMOUSE_OLPC;
 	dev2->id.version = 0x0000;
 
+	/* Mode: we want to use the Glide Sensor (GS) in its relative mode, but
+	 * for some reason, it needs to be in absolute mode (with relative
+	 * axes) in order for HAL, evdev, and X to be happy. */
+	dev2->evbit[LONG(EV_REL)] &= ~BIT(EV_REL);
+	dev2->evbit[LONG(EV_ABS)] |= BIT(EV_ABS);
 	dev2->evbit[LONG(EV_KEY)] |= BIT(EV_KEY);
+
+	/* Axes: we want relative data for the GS. */
+	dev2->relbit[LONG(REL_X)] |= BIT(REL_X);
+	dev2->relbit[LONG(REL_Y)] |= BIT(REL_Y);
+	dev2->absbit[LONG(ABS_X)] &= ~BIT(ABS_X);
+	dev2->absbit[LONG(ABS_Y)] &= ~BIT(ABS_Y);
+	dev2->absbit[LONG(ABS_PRESSURE)] &= ~BIT(ABS_PRESSURE);
+
+	/* Buttons: We disable some of the GlideSensor buttons to avoid
+	 * receiving twinned clicks. See http://dev.laptop.org/ticket/6745. */
 	dev2->keybit[LONG(BTN_TOUCH)] |= BIT(BTN_TOUCH);
 	dev2->keybit[LONG(BTN_TOOL_FINGER)] |= BIT(BTN_TOOL_FINGER);
-	dev2->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT);
+	dev2->keybit[LONG(BTN_LEFT)] &= ~BIT(BTN_LEFT);
+	dev2->keybit[LONG(BTN_RIGHT)] &= ~BIT(BTN_RIGHT);
+	dev2->keybit[LONG(BTN_MIDDLE)] &= ~BIT(BTN_MIDDLE);
 
-	/* bernie: argh -- needed for hal to see it as a mouse */
-	dev2->relbit[LONG(REL_X)] |= BIT(REL_X) | BIT(REL_Y);
-	dev2->evbit[LONG(EV_ABS)] |= BIT(EV_ABS);
+	/* Finally, more magic range numbers governing device output ranges. */
 	input_set_abs_params(dev2, ABS_X, 350, 512, 0, 0);
 	input_set_abs_params(dev2, ABS_Y, 70, 325, 0, 0);
-	/* bernie: argh -- needed for hal to see it as a mouse */
 	/* input_set_abs_params(dev2, ABS_PRESSURE, 0, 63, 0, 0); */
 
 	if (input_register_device(dev2)) {
-- 
1.5.3.3

-------------- next part --------------
diff -ru xf86-input-evdev-1.2.0/src/evdev_btn.c xf86-input-evdev-1.2.0-blake/src/evdev_btn.c
--- xf-input-evdev-1.2.0/src/evdev_btn.c	2007-06-06 14:10:27.000000000 -0400
+++ xf-input-evdev-1.2.0-blake/src/evdev_btn.c	2008-03-23 16:58:00.000000000 -0400
@@ -412,13 +412,7 @@
 	if (btn->b_flags[i] & EV_BTN_B_PRESENT)
 	    btn->buttons = i + 1;
 
-    if (state->btn->buttons)
 	xf86Msg(X_INFO, "%s: Configured %d mouse buttons.\n", pInfo->name, state->btn->buttons);
-    else {
-	Xfree (state->btn);
-	state->btn = NULL;
-	return !Success;
-    }
 
     pInfo->flags |= XI86_SEND_DRAG_EVENTS | XI86_CONFIGURED;
     /*
-------------- next part --------------
diff --git a/config/hal.c b/config/hal.c
index 3479be9..a235876 100644
--- a/config/hal.c
+++ b/config/hal.c
@@ -177,7 +177,13 @@ device_added(LibHalContext *hal_ctx, const char *udi)
         if (strcmp(props[i], "input.keys") == 0 ||
             strcmp(props[i], "input.keyboard") == 0)
             type |= TYPE_KEYS;
         if (strcmp(props[i], "input.mouse") == 0)
+        {
+            type |= TYPE_POINTER;
+            add_option(&options, "Mode", "Relative");
+        } else if (strcmp(props[i], "input.touchpad") == 0) {
             type |= TYPE_POINTER;
+            add_option(&options, "Mode", "Absolute");
+        }
     }
     libhal_free_string_array(props);


More information about the Devel mailing list