[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Patch to handle touchpads in g-i available



Hi

I recently wrote a patch against DFB 0.9.25 which adds to linux_input the capability to translate absolute x,y coordinates generated by touchpads into relative ones: this allows using Synaptic touchpads with the g-i. The patch was sent for review to directfb-dev [1] and was said to be ok, updated patch is attached to this mail. I prepared an iso image [2] which includes the fix: i'm asking testers who previously reported their synaptics touchpad not working within g-i to test this iso and report results and feelings about how the touchpad works.

cheers

Attilio

[1] http://mail.directfb.org/pipermail/directfb-dev/2006-November/002414.html
[2] https://debian.polito.it/downloads/mini_synaptics.iso
--- linux_input.c.orig	2006-11-15 12:23:52.000000000 +0100
+++ linux_input.c	2006-11-20 17:56:23.000000000 +0100
@@ -283,6 +283,21 @@
 };
 
 /*
+ * Synaptics touchpads related stuff
+ */
+#define SYNAPTICS_SCALING_FACTOR 3
+#define SYNAPTICS_FSM_START  0
+#define SYNAPTICS_FSM_MAIN   1
+#define SYNAPTICS_FSM_END    2
+
+static int x_old, y_old, dx, dy;
+static int synaptics_state = SYNAPTICS_FSM_START;
+
+static int
+synaptics_fsm ( struct input_event *levt,
+               DFBInputEvent      *devt );
+
+/*
  * Translates a Linux input keycode into a DirectFB keycode.
  */
 static int
@@ -484,11 +499,11 @@
 key_event( struct input_event *levt,
            DFBInputEvent      *devt )
 {
-     /* map touchscreen and smartpad events to button mouse */
-     if (levt->code == BTN_TOUCH || levt->code == BTN_TOOL_FINGER)
-          levt->code = BTN_MOUSE;
+     /* don't map touchscreen and smartpad events to button mouse */
+//     if (levt->code == BTN_TOUCH || levt->code == BTN_TOOL_FINGER)
+//          levt->code = BTN_MOUSE;
 
-     if (levt->code >= BTN_MOUSE && levt->code < BTN_JOYSTICK) {
+     if ( (levt->code >= BTN_MOUSE && levt->code < BTN_JOYSTICK) || levt->code == BTN_TOUCH) {
           devt->type   = levt->value ? DIET_BUTTONPRESS : DIET_BUTTONRELEASE;
           /* don't set DIEF_BUTTONS, it will be set by the input core */
           devt->button = DIBI_FIRST + levt->code - BTN_MOUSE;
@@ -685,6 +700,11 @@
                if (!translate_event( &levt[i], &devt ))
                     continue;
 
+               if ( (devt.type == DIET_AXISMOTION && (devt.flags & DIEF_AXISABS)) || levt->code == BTN_TOUCH || ( levt->type == EV_ABS && levt->code == ABS_PRESSURE ) ) {
+                    if (synaptics_fsm ( levt, &devt ) == 0)
+                         continue;
+               }
+
                if (devt.type == DIET_AXISMOTION && (devt.flags & DIEF_AXISREL)) {
                     switch (devt.axis) {
                          case DIAI_X:
@@ -1082,3 +1102,93 @@
      /* free private data */
      D_FREE( data );
 }
+
+/*
+ * This FSM takes into accout finger landing on touchpad and leaving and
+ * translates absolute DFBInputEvent into a relative one
+ */
+static int
+synaptics_fsm ( struct input_event *levt,
+               DFBInputEvent      *devt )
+{
+     int ret_val;
+
+     /* is there something useful ABS_PRESSURE could be used to ? */
+     if ( levt->type == EV_ABS && levt->code == ABS_PRESSURE )
+          return 0;
+
+     switch (synaptics_state) {
+
+          case SYNAPTICS_FSM_START:
+               /* storing initial position of touchpad */
+               if (devt->type == DIET_AXISMOTION) {
+                    switch (devt->axis) {
+                    case DIAI_X:
+                         if (devt->axisabs > 1)
+                              x_old = devt->axisabs;
+                         break;
+                    case DIAI_Y:
+                         if (devt->axisabs > 1)
+                              y_old = devt->axisabs;
+                         break;
+                    default:
+                         break;
+                    }
+                    ret_val = 0;
+               }
+
+               /* finger is landing */
+               if (levt->type == EV_KEY && levt->code == BTN_TOUCH && levt->value == 1)
+                    synaptics_state = SYNAPTICS_FSM_MAIN;
+               ret_val = 0;
+               break;
+
+          case SYNAPTICS_FSM_MAIN:
+               /* translating mouse movements into relative coordinates */
+               if (devt->type == DIET_AXISMOTION) {
+                    switch (devt->axis) {
+                         case DIAI_X:
+                              if (x_old == -1)
+                                   x_old = devt->axisabs;
+                              dx = (devt->axisabs - x_old ) / SYNAPTICS_SCALING_FACTOR;
+                              x_old = devt->axisabs;
+                              devt->axisrel = dx;
+                              devt->flags = devt->flags |= DIEF_AXISABS;
+                              devt->flags = devt->flags |= DIEF_AXISREL;
+                              ret_val = 1;
+                              break;
+                         case DIAI_Y:
+                              if (y_old == -1)
+                                   y_old = devt->axisabs;
+                              dy = (devt->axisabs - y_old ) / SYNAPTICS_SCALING_FACTOR;
+                              y_old = devt->axisabs;
+                              devt->axisrel = dy;
+                              devt->flags = devt->flags |= DIEF_AXISABS;
+                              devt->flags = devt->flags |= DIEF_AXISREL;
+                              ret_val = 1;
+                              break;
+                         default:
+                              ret_val = 0;
+                              break;
+                    }
+               }
+               /* finger is leaving */
+               else if (levt->type == EV_KEY && levt->code == BTN_TOUCH && levt->value == 0) {
+                    synaptics_state = SYNAPTICS_FSM_END;
+                    ret_val = 0;
+               }           
+          break;
+
+          case SYNAPTICS_FSM_END:
+               x_old = y_old = -1;
+               synaptics_state = SYNAPTICS_FSM_START;
+               ret_val = 0;
+               break;
+
+          default:
+               ret_val = 0;
+               break;
+     }
+
+     return ret_val;
+}

Reply to: