Re: Trackpad scrolling?
* On Thu, Jun 03, 2004 at 01:08:29AM -0500, I received from dotto@uchicago.edu:
> Something I've been looking for for a while now is a trackpad driver for the
> powerbook that would allow me to scroll on one of the edges of the trackpad.
> Someone created sidewinder for OSX, but I haven't seen this for linux. Seems
> kind of strange to me...
I grabbed this patch a while ago from this list or the Gentoo
ppc forums. It doesn't apply cleanly, but with some "manual
intervention" i got it to work on every kernel I tried,
including the 2.6.6-rc2 I am using now.
--
Ben
--- linuxppc-2.5-benh/drivers/macintosh/adbhid.c.vanilla 2003-12-05 01:42:00.000000000 +0100
+++ linuxppc-2.5-benh/drivers/macintosh/adbhid.c 2004-01-10 11:02:14.769705832 +0100
@@ -239,6 +239,93 @@
}
static void
+emulate_relative_trackpad_mode(unsigned char *data)
+{
+ static int prev_x[16] = {-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1};
+ static int prev_y[16] = {-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1};
+ static int max_x[16] = {1400,1400,1400,1400,1400,1400,1400,1400,
+ 1400,1400,1400,1400,1400,1400,1400,1400};
+ int btn1, btn2, x_axis, y_axis;
+ int rel_x, rel_y;
+ int id = (data[0] >> 4) & 0x0f;
+
+ x_axis = (data[2] & 0x7f) |
+ ((data[3] & 0x07) << 7) |
+ ((data[4] & 0x07) << 10);
+ y_axis = (data[1] & 0x7f) |
+ ((data[3] & 0x70) << 3) |
+ ((data[4] & 0x70) << 6);
+ btn1 = (!(data[1] >> 7)) & 1;
+ btn2 = (!(data[2] >> 7)) & 1;
+ /* Map btn2 (tap-click) to the left button */
+ btn1 |= btn2;
+ btn2 = 0;
+
+ if (x_axis > max_x[id])
+ max_x[id] = x_axis;
+
+ rel_x = rel_y = 0;
+ if (x_axis == 0 && y_axis == 0) {
+ /* No finger on the pad */
+ prev_x[id] = prev_y[id] = -1;
+ }
+ else if (x_axis > 0 && prev_x[id] > 0 &&
+ y_axis > 0 && prev_y[id] > 0) {
+
+ /* "filter" the position somewhat */
+ x_axis = (prev_x[id] + x_axis) / 2;
+ y_axis = (prev_y[id] + y_axis) / 2;
+
+ rel_x = (x_axis - prev_x[id]);
+ rel_y = (y_axis - prev_y[id]);
+ /* Slow it down somewhat */
+ if (rel_x > 1 || rel_x < -1)
+ rel_x /= 2;
+ if (rel_y > 1 || rel_y < -1)
+ rel_y /= 2;
+ /* Make sure we don't overflow the 7 bits allocated
+ * for the relative movement */
+ if (rel_x > 63)
+ rel_x = 63;
+ if (rel_x < -64)
+ rel_x = -64;
+ if (rel_y > 63)
+ rel_y = 63;
+ if (rel_y < -64)
+ rel_y = -64;
+ prev_x[id] = x_axis;
+ prev_y[id] = y_axis;
+ }
+ else {
+ prev_x[id] = x_axis;
+ prev_y[id] = y_axis;
+ }
+ /* Is the finger positioned in the scrolling area? */
+ if (x_axis > max_x[id] - 150) {
+ static int count = 0;
+
+ if (++count == 6) {
+ int diff = - rel_y;
+ count = 0;
+ if (diff > 0)
+ input_report_rel(&adbhid[id]->input,
+ REL_WHEEL, diff / 4 + 1);
+ else if (diff < 0)
+ input_report_rel(&adbhid[id]->input,
+ REL_WHEEL, diff / 4 - 1);
+ }
+ /* cancel all movment and clicks */
+ btn1 = 0;
+ rel_x = rel_y = 0;
+ }
+ /* Format the data so adbhid_mouse_input can use it */
+ data[1] = (rel_y & 0x7f) | (((!btn1) & 1) << 7);
+ data[2] = (rel_x & 0x7f) | 0x80;
+}
+
+static void
adbhid_mouse_input(unsigned char *data, int nb, struct pt_regs *regs, int autopoll)
{
int id = (data[0] >> 4) & 0x0f;
@@ -295,8 +382,12 @@
switch (adbhid[id]->mouse_kind)
{
case ADBMOUSE_TRACKPAD:
+#ifdef CONFIG_ADB_TRACKPAD_SCROLLING
+ emulate_relative_trackpad_mode(data);
+#else
data[1] = (data[1] & 0x7f) | ((data[1] & data[2]) & 0x80);
data[2] = data[2] | 0x80;
+#endif
break;
case ADBMOUSE_MICROSPEED:
data[1] = (data[1] & 0x7f) | ((data[3] & 0x01) << 7);
@@ -619,7 +710,11 @@
adbhid[id]->input.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
adbhid[id]->input.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+#ifdef CONFIG_ADB_TRACKPAD_SCROLLING
+ adbhid[id]->input.relbit[0] = BIT(REL_X) | BIT(REL_Y) | BIT(REL_WHEEL);
+#else
adbhid[id]->input.relbit[0] = BIT(REL_X) | BIT(REL_Y);
+#endif
break;
case ADB_MISC:
@@ -889,8 +984,12 @@
r1_buffer[3],
r1_buffer[4],
r1_buffer[5],
+#ifdef CONFIG_ADB_TRACKPAD_SCROLLING
+ 0x00, /* Enable absolute mode */
+#else
0x03, /*r1_buffer[6],*/
+#endif
r1_buffer[7]);
/* Without this flush, the trackpad may be locked up */
--- linuxppc-2.5-benh/drivers/macintosh/Kconfig.vanilla 2004-01-10 11:04:42.336272304 +0100
+++ linuxppc-2.5-benh/drivers/macintosh/Kconfig 2004-01-10 10:58:08.892084912 +0100
@@ -113,6 +113,14 @@
If unsure, say Y.
+config ADB_TRACKPAD_SCROLLING
+ bool "Scrolling for ADB input devices (trackpad)"
+ depends on INPUT_ADBHID
+ help
+ Add the scrolling feature commonly seen on Windows laptops. If you
+ say Y here you can easily scroll in your applications by moving your
+ finger at the right border of your trackpad.
+
config MAC_EMUMOUSEBTN
bool "Support for mouse button 2+3 emulation"
depends on INPUT_ADBHID
Reply to: