Re: Patch to handle touchpads in g-i available
whops, forget the previous patch, that was an old one: the up to date
one is attached to this mail.
the iso i prepared was however built using the right patchfile.
cheers
attilio
--- linux_input.c.orig 2006-11-15 12:23:52.000000000 +0100
+++ linux_input.c 2006-11-21 23:26:36.000000000 +0100
@@ -59,6 +59,8 @@
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/kd.h>
+#include <stdlib.h>
+
#include <linux/keyboard.h>
@@ -283,6 +285,35 @@
};
/*
+ * Touchpads related stuff
+ */
+#define TOUCHPAD_SCALING_FACTOR 5
+#define TOUCHPAD_FSM_START 0
+#define TOUCHPAD_FSM_MAIN 1
+#define TOUCHPAD_FSM_END 2
+
+/* expressed in usecs
+ */
+#define TOUCHPAD_SINGLE_CLICK_TIMEOUT 250000
+
+/* lower touchpad pressure treshold for the mouse cursor to start moving
+ */
+#define TOUCHPAD_START_MOTION_PRESSURE_TRESHOLD 20
+
+/* motion is reduced in a indirectly proportional way to finger pressure,
+ * this is the unit treshold
+ */
+#define TOUCHPAD_SCALING_FACTOR_PRESSURE 35
+
+int x_old = -1, y_old = -1, dx, dy, last_pressure, fire_single_click_flag = 0;
+struct timeval *last_mousetouch;
+int touchpad_state = TOUCHPAD_FSM_START;
+
+static int
+touchpad_fsm ( struct input_event *levt,
+ DFBInputEvent *devt );
+
+/*
* Translates a Linux input keycode into a DirectFB keycode.
*/
static int
@@ -484,11 +515,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;
@@ -579,8 +610,9 @@
break;
default:
- if (levt->code >= ABS_PRESSURE || levt->code > DIAI_LAST)
- return 0;
+// why this ?
+// if (levt->code >= ABS_PRESSURE || levt->code > DIAI_LAST)
+// return 0;
devt->axis = levt->code;
}
@@ -669,6 +701,8 @@
int readlen;
struct input_event levt[64];
+ last_mousetouch = malloc ( sizeof(struct timeval));
+
while ((readlen = read(data->fd, levt, sizeof(levt)) / sizeof(levt[0])) > 0
|| (readlen < 0 && errno == EINTR))
{
@@ -681,10 +715,15 @@
for (i=0; i<readlen; i++) {
DFBInputEvent devt;
-
+//printf("levt->type = %d, levt->code = %d, levt->value = %d\n", levt[i].type, levt[i].code, levt->value );
if (!translate_event( &levt[i], &devt ))
continue;
+ if ( (devt.type == DIET_AXISMOTION && (devt.flags & DIEF_AXISABS)) || levt[i].code == BTN_TOUCH || ( levt[i].type == EV_ABS && levt[i].code == ABS_PRESSURE ) ) {
+ if (touchpad_fsm ( &levt[i], &devt ) == 0)
+ continue;
+ }
+
if (devt.type == DIET_AXISMOTION && (devt.flags & DIEF_AXISREL)) {
switch (devt.axis) {
case DIAI_X:
@@ -700,7 +739,7 @@
}
}
- flush_xy( data );
+// flush_xy( data );
dfb_input_dispatch( data->device, &devt );
@@ -1082,3 +1121,104 @@
/* 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
+touchpad_fsm ( struct input_event *levt,
+ DFBInputEvent *devt )
+{
+ int ret_val;
+
+ if ( levt->type == EV_ABS && levt->code == ABS_PRESSURE ) {
+ last_pressure = levt->value;
+ return 0;
+ }
+
+ switch (touchpad_state) {
+
+ case TOUCHPAD_FSM_START:
+ /* finger is landing */
+ if ((levt->type == EV_KEY && levt->code == BTN_TOUCH && levt->value == 1) || (last_pressure > TOUCHPAD_START_MOTION_PRESSURE_TRESHOLD)) {
+ last_mousetouch->tv_sec = (levt->time).tv_sec;
+ last_mousetouch->tv_usec = (levt->time).tv_usec;
+ if (last_pressure > TOUCHPAD_START_MOTION_PRESSURE_TRESHOLD)
+ touchpad_state = TOUCHPAD_FSM_MAIN;
+ }
+ ret_val = 0;
+ break;
+
+ case TOUCHPAD_FSM_MAIN:
+ /* translating mouse movements into relative coordinates */
+ if (levt->type == EV_ABS && (levt->code == ABS_X || levt->code == ABS_Y)) {
+ switch (devt->axis) {
+ case DIAI_X:
+ if (x_old == -1)
+ x_old = devt->axisabs;
+ dx = (devt->axisabs - x_old ) / TOUCHPAD_SCALING_FACTOR;
+ dx = dx * (last_pressure/ TOUCHPAD_SCALING_FACTOR_PRESSURE);
+ 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 ) / TOUCHPAD_SCALING_FACTOR;
+ dy = dy * (last_pressure/ TOUCHPAD_SCALING_FACTOR_PRESSURE);
+ 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) {
+ if ( ((levt->time).tv_sec * 1000000 + (levt->time).tv_usec) -\
+ (last_mousetouch->tv_sec * 1000000 + last_mousetouch->tv_usec)\
+ <= TOUCHPAD_SINGLE_CLICK_TIMEOUT) {
+ devt->type = DIET_BUTTONPRESS;
+ devt->button = DIBI_FIRST;
+ fire_single_click_flag = 1;
+ ret_val = 1;
+ }
+ else
+ ret_val = 0;
+
+ touchpad_state = TOUCHPAD_FSM_END;
+ }
+ else
+ ret_val = 0;
+ break;
+
+ case TOUCHPAD_FSM_END:
+ x_old = y_old = last_pressure = -1;
+ touchpad_state = TOUCHPAD_FSM_START;
+
+ if (fire_single_click_flag == 1) {
+ fire_single_click_flag = 0;
+ devt->type = DIET_BUTTONRELEASE;
+ devt->button = DIBI_FIRST;
+ ret_val = 1;
+ }
+ else
+ ret_val = 0;
+ break;
+
+ default:
+ ret_val = 0;
+ break;
+ }
+
+ return ret_val;
+}
Reply to: