* On Thu, Jun 03, 2004 at 01:08:29AM -0500, I received from [EMAIL PROTECTED]: > 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