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: