* 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

Reply via email to