[gpm] [PATCH 14/18] evdev-2.6-update.patch
Dmitry Torokhov
dtor_core@ameritech.net
Tue Aug 10 09:00:36 CEST 2004
===================================================================
ChangeSet@1.18, 2004-08-10 00:53:37-05:00, dtor_core@ameritech.net
Update evdev protocol to support kernels >= 2.6.0-test.
Do not use Oops in evdev in case of crazy input parameters.
Use "get ID" IOCTL to detect Synaptics hardware.
configure.ac | 1
src/evdev.c | 402 +++++++++++++++++++++++++++++---------------
src/headers/input-defines.h | 81 ++++++++
3 files changed, 347 insertions(+), 137 deletions(-)
===================================================================
diff -Nru a/configure.ac b/configure.ac
--- a/configure.ac 2004-08-10 01:18:01 -05:00
+++ b/configure.ac 2004-08-10 01:18:01 -05:00
@@ -86,6 +86,7 @@
if test ${ac_cv_header_linux_input_h} = yes ; then
EVDEV_SRCS=evdev.c ;
AC_CHECK_TYPE(struct input_absinfo,AC_DEFINE_UNQUOTED(HAVE_INPUT_ABSINFO, 1, [define if struct input_absinfo defined in linux/input.h]),,[#include <linux/input.h>])
+ AC_CHECK_TYPE(struct input_id,AC_DEFINE_UNQUOTED(HAVE_INPUT_ID, 1, [define if struct input_id defined in linux/input.h]),,[#include <linux/input.h>])
fi
ITZ_CHECK_TYPE(__u32,linux/types.h)
diff -Nru a/src/evdev.c b/src/evdev.c
--- a/src/evdev.c 2004-08-10 01:18:01 -05:00
+++ b/src/evdev.c 2004-08-10 01:18:01 -05:00
@@ -29,6 +29,7 @@
#include <sys/time.h>
#include <linux/input.h>
+#include "headers/input-defines.h" /* misisng bits in case <linux/input.h> is old */
#include "headers/gpm.h"
#include "headers/gpmInt.h"
@@ -36,29 +37,8 @@
#include "headers/message.h"
#include "headers/optparser.h"
-#ifndef MSC_GESTURE
-#define MSC_GESTURE 2
-#endif
-
-#ifndef EV_SYNC
-#define EV_SYNC 0
-#endif
-
-#ifndef SYN_REPORT
-#define SYN_REPORT 0
-#endif
-
-#ifndef HAVE_INPUT_ABSINFO
-struct input_absinfo {
- int value;
- int minimum;
- int maximum;
- int fuzz;
- int flat;
-};
-#endif
-
enum evdev_type {
+ EVDEV_UNKNOWN,
EVDEV_RELATIVE,
EVDEV_ABSOLUTE,
EVDEV_TOUCHPAD,
@@ -96,19 +76,21 @@
int wdx, wdy;
int abs_x, abs_y;
int buttons;
+ int touch; /* dumb touchpad report touch events, smart ones - pressure */
int pressure;
int w;
+ int finger_count;
int synced;
};
struct touch_data {
- enum touch_type type;
- enum gesture_type gesture;
- int finger_count;
+ int touching;
int x, y;
+ int finger_count;
int buttons;
int clicks;
struct timeval start;
+ enum gesture_type gesture;
};
struct event_device {
@@ -127,6 +109,9 @@
int touch_high, touch_low;
int tap_time, tap_move;
int y_inverted;
+
+ enum touch_type (*detect_touch)(struct event_device *evdev);
+ void (*update_finger_count)(struct event_device *evdev);
};
struct evdev_capabilities {
@@ -186,6 +171,10 @@
case ABS_PRESSURE:
data->pressure = event->value;
break;
+
+ case ABS_TOOL_WIDTH:
+ data->w = event->value;
+ break;
}
break;
@@ -201,21 +190,39 @@
case EV_KEY:
switch(event->code) {
case BTN_0:
- case BTN_TOUCH:
case BTN_LEFT:
toggle_btn(GPM_B_LEFT, event->value);
break;
+
case BTN_2:
case BTN_STYLUS2:
case BTN_SIDE:
case BTN_MIDDLE:
toggle_btn(GPM_B_MIDDLE, event->value);
break;
+
case BTN_STYLUS:
case BTN_1:
case BTN_RIGHT:
toggle_btn(GPM_B_RIGHT, event->value);
break;
+
+ case BTN_TOUCH:
+ data->touch = event->value ? 1 : 0;
+ break;
+
+ case BTN_TOOL_FINGER:
+ if (event->value) data->finger_count = 1;
+ break;
+
+ case BTN_TOOL_DOUBLETAP:
+ if (event->value) data->finger_count = 2;
+ break;
+
+ case BTN_TOOL_TRIPLETAP:
+ if (event->value) data->finger_count = 3;
+ break;
+
}
break;
@@ -234,7 +241,7 @@
struct event_data *pkt = &evdev->pkt;
state->dx = state->dy = 0;
- if (evdev->touch.type == TOUCH_FINGERS) {
+ if (evdev->touch.touching) {
fx(0) = pkt->abs_x;
fy(0) = pkt->abs_y;
if (evdev->pkt_count >= 2 &&
@@ -248,9 +255,14 @@
}
}
-static enum touch_type tp_detect_touch(struct event_device *evdev)
+static enum touch_type dumb_tp_detect_touch(struct event_device *evdev)
{
- if (evdev->touch.type == TOUCH_FINGERS)
+ return evdev->pkt.touch ? TOUCH_FINGERS : TOUCH_NONE;
+}
+
+static enum touch_type smart_tp_detect_touch(struct event_device *evdev)
+{
+ if (evdev->touch.touching)
return evdev->pkt.pressure > evdev->touch_low ? TOUCH_FINGERS : TOUCH_NONE;
else
return evdev->pkt.pressure > evdev->touch_high ? TOUCH_FINGERS : TOUCH_NONE;
@@ -262,19 +274,21 @@
enum touch_type type = TOUCH_NONE;
if (pkt->pressure > 200 || pkt->w > 10)
- return TOUCH_PALM; /* palm */
+ return TOUCH_PALM;
if (pkt->abs_x == 0)
evdev->avg_w = 0;
else
evdev->avg_w = (pkt->w - evdev->avg_w + 1) / 2;
- if (evdev->touch.type == TOUCH_FINGERS)
+ if (evdev->touch.touching) {
type = pkt->pressure > evdev->touch_low ? TOUCH_FINGERS : TOUCH_NONE;
- else if (pkt->pressure > evdev->touch_high) {
+ } else if (pkt->pressure > evdev->touch_high) {
int safe_w = max(pkt->w, evdev->avg_w);
- if (pkt->w < 2)
+ if (pkt->finger_count > 1)
+ type = TOUCH_FINGERS;
+ else if (pkt->w < 2)
type = TOUCH_FINGERS; /* more than one finger -> not a palm */
else if (safe_w < 6 && evdev->prev_pressure < evdev->touch_high)
type = TOUCH_FINGERS; /* thin finger, distinct touch -> not a palm */
@@ -301,9 +315,9 @@
else if (x < evdev->left_edge)
edge |= LEFT_EDGE;
- if (y > evdev->top_edge)
+ if (y < evdev->top_edge)
edge |= TOP_EDGE;
- else if (y < evdev->bottom_edge)
+ else if (y > evdev->bottom_edge)
edge |= BOTTOM_EDGE;
return edge;
@@ -319,17 +333,16 @@
static int tp_detect_tap(struct event_device *evdev)
{
- return evdev->touch.finger_count > 0 ||
- (!tp_touch_expired(evdev) &&
- abs(evdev->pkt.abs_x - evdev->touch.x) < evdev->tap_move &&
- abs(evdev->pkt.abs_y - evdev->touch.y) < evdev->tap_move);
+ return !tp_touch_expired(evdev) &&
+ (evdev->touch.finger_count > 1 ||
+ (abs(evdev->pkt.abs_x - evdev->touch.x) < evdev->tap_move &&
+ abs(evdev->pkt.abs_y - evdev->touch.y) < evdev->tap_move));
}
static int tp_tap_to_buttons(struct event_device *evdev)
{
enum edge_type edge;
-
- if (!evdev->touch.finger_count) {
+ if (evdev->touch.finger_count < 2) {
edge = tp_detect_edges(evdev, evdev->pkt.abs_x, evdev->pkt.abs_y);
switch (edge) {
case RIGHT_TOP_EDGE:
@@ -354,18 +367,17 @@
}
}
-static void tp_detect_gesture(struct event_device *evdev, int timed_out, struct Gpm_Event *state)
+static void tp_detect_gesture(struct event_device *evdev, int timed_out, enum touch_type touch_type)
{
struct touch_data *touch = &evdev->touch;
- int was_touching = touch->type == TOUCH_FINGERS;
+ int was_touching = touch->touching;
- touch->type = timed_out ?
- TOUCH_NONE : (evdev->type == EVDEV_SYNAPTICS ?
- syn_detect_touch(evdev) : tp_detect_touch(evdev));
+ touch->touching = touch_type == TOUCH_FINGERS;
- if (touch->type == TOUCH_FINGERS) {
+ if (touch->touching) {
if (!was_touching) {
GET_TIME(touch->start);
+ touch->finger_count = 0;
if (touch->gesture == GESTURE_TAP_PENDING) {
touch->gesture = GESTURE_DRAG_PENDING;
} else {
@@ -376,9 +388,9 @@
} else if (touch->gesture == GESTURE_DRAG_PENDING && tp_touch_expired(evdev)) {
touch->gesture = GESTURE_DRAG;
}
- } else if (touch->type == TOUCH_NONE) {
+ } else {
if (was_touching) {
- if (tp_detect_tap(evdev)) {
+ if (tp_detect_tap(evdev)) {
if (touch->gesture == GESTURE_DRAG_PENDING) {
touch->gesture = GESTURE_DOUBLE_TAP;
touch->clicks = 4;
@@ -402,18 +414,74 @@
}
}
+static int tp_process_gesture(struct event_device *evdev, struct Gpm_Event *state)
+{
+ int next_timeout = -1;
+
+ switch(evdev->touch.gesture) {
+ case GESTURE_DOUBLE_TAP:
+ case GESTURE_TAP:
+ if (--evdev->touch.clicks == 0)
+ evdev->touch.gesture = GESTURE_NONE;
+ else
+ next_timeout = 0;
+
+ if (evdev->touch.clicks % 2)
+ state->buttons |= evdev->touch.buttons;
+ else
+ state->buttons &= ~evdev->touch.buttons;
+ break;
+
+ case GESTURE_DRAG:
+ state->buttons |= evdev->touch.buttons;
+ break;
+
+ case GESTURE_DRAG_PENDING:
+ case GESTURE_TAP_PENDING:
+ next_timeout = evdev->tap_time;
+ break;
+
+ default:
+ break;
+ }
+ return next_timeout;
+}
+
+static void tp_update_finger_count(struct event_device *evdev)
+{
+ evdev->touch.finger_count = max(evdev->pkt.finger_count, evdev->touch.finger_count);
+}
+
+static void syn_update_finger_count(struct event_device *evdev)
+{
+ if (evdev->pkt.w == 1)
+ evdev->touch.finger_count = 3;
+ else if (evdev->pkt.w == 0 && evdev->touch.finger_count != 3)
+ evdev->touch.finger_count = 2;
+ else
+ evdev->touch.finger_count = 1;
+}
+
static int compose_gpm_event(struct event_device *evdev, int timed_out, Gpm_Event *state)
{
struct event_data *pkt = &evdev->pkt;
+ enum touch_type touch_type;
int next_timeout = -1;
- state->buttons = pkt->buttons;
- state->wdx = pkt->wdx; state->wdy = pkt->wdy;
+ if (!timed_out) {
+ state->buttons = pkt->buttons;
+ state->wdx = pkt->wdx; state->wdy = pkt->wdy;
+ }
switch (evdev->type) {
case EVDEV_RELATIVE:
- if (!timed_out)
+ if (!timed_out) {
state->dx = pkt->dx; state->dy = pkt->dy;
+ if (evdev->pkt.touch)
+ state->buttons |= GPM_B_LEFT;
+ else
+ state->buttons &= ~GPM_B_LEFT;
+ }
break;
case EVDEV_ABSOLUTE:
@@ -423,61 +491,45 @@
else if (pkt->abs_x > evdev->right_edge)
pkt->abs_x = evdev->right_edge;
- if (pkt->abs_y < evdev->bottom_edge)
+ if (pkt->abs_y > evdev->bottom_edge)
pkt->abs_y = evdev->bottom_edge;
- else if (pkt->abs_y > evdev->top_edge)
+ else if (pkt->abs_y < evdev->top_edge)
pkt->abs_y = evdev->top_edge;
state->x = (pkt->abs_x - evdev->left_edge) *
console.max_x / (evdev->right_edge - evdev->left_edge);
- state->y = (pkt->abs_y - evdev->bottom_edge) *
- console.max_y / (evdev->top_edge - evdev->bottom_edge);
+ state->y = (pkt->abs_y - evdev->top_edge) *
+ console.max_y / (evdev->bottom_edge - evdev->top_edge);
if (evdev->y_inverted) state->y = console.max_y - state->y;
+
+ if (evdev->pkt.touch)
+ state->buttons |= GPM_B_LEFT;
+ else
+ state->buttons &= ~GPM_B_LEFT;
}
break;
case EVDEV_TOUCHPAD:
case EVDEV_SYNAPTICS:
- tp_detect_gesture(evdev, timed_out, state);
- tp_figure_deltas(evdev, state);
+ touch_type = timed_out ? TOUCH_NONE : evdev->detect_touch(evdev);
- if (evdev->type == EVDEV_SYNAPTICS &&
- evdev->touch.type == TOUCH_FINGERS &&
- !tp_touch_expired(evdev)) {
- if (evdev->pkt.w == 0 && evdev->touch.finger_count == 0)
- evdev->touch.finger_count = 2;
- if (evdev->pkt.w == 1)
- evdev->touch.finger_count = 3;
- } else
- evdev->touch.finger_count = 0;
-
- switch(evdev->touch.gesture) {
- case GESTURE_DOUBLE_TAP:
- case GESTURE_TAP:
- if (evdev->touch.clicks <= 0) {
- evdev->touch.gesture = GESTURE_NONE;
- } else {
- if (--evdev->touch.clicks % 2)
- state->buttons |= evdev->touch.buttons;
- else
- state->buttons &= ~evdev->touch.buttons;
- next_timeout = 0;
- }
- break;
- case GESTURE_DRAG:
- state->buttons |= evdev->touch.buttons;
- break;
- case GESTURE_DRAG_PENDING:
- next_timeout = evdev->tap_time;
- break;
- case GESTURE_TAP_PENDING:
- next_timeout = evdev->tap_time;
- break;
- default:
- break;
+ if (touch_type != TOUCH_PALM) {
+ tp_detect_gesture(evdev, timed_out, touch_type);
+
+ if (evdev->touch.touching && !tp_touch_expired(evdev))
+ evdev->update_finger_count(evdev);
+
+ if (evdev->touch.finger_count < 2)
+ tp_figure_deltas(evdev, state);
+
+ next_timeout = tp_process_gesture(evdev, state);
}
+ break;
+ default:
+ /* should not happen */
+ gpm_report(GPM_PR_OOPS, "Bad evdev type %d", evdev->type);
break;
}
@@ -498,6 +550,9 @@
if (timed_out || evdev->pkt.synced || evdev->dont_sync) {
dev->timeout = compose_gpm_event(evdev, timed_out, state);
+ evdev->pkt.dx = evdev->pkt.dy = 0;
+ evdev->pkt.wdx = evdev->pkt.wdy = 0;
+ evdev->pkt.finger_count = 0;
evdev->pkt.synced = 0;
return 0;
}
@@ -508,55 +563,96 @@
/* ------------- evdev initialization routines ---------------------*/
-static void evdev_get_capabilities(int fd, struct evdev_capabilities *caps)
+static int evdev_get_id(int fd, struct input_id *id)
+{
+ if (ioctl(fd, EVIOCGID, id) < 0) {
+ gpm_report(GPM_PR_ERR, "evdev: cannot query device identification");
+ return -1;
+ }
+ return 0;
+}
+
+static int evdev_get_capabilities(int fd, struct evdev_capabilities *caps)
{
memset(caps, 0, sizeof(*caps));
+
if (ioctl(fd, EVIOCGBIT(0, EV_MAX), caps->evbits) < 0) {
- gpm_report(GPM_PR_OOPS, "evdev: cannot query device capabilities");
+ gpm_report(GPM_PR_ERR, "evdev: cannot query device capabilities");
+ return -1;
}
if (test_bit(EV_ABS, caps->evbits) &&
ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(caps->absbits)), caps->absbits) < 0) {
- gpm_report(GPM_PR_OOPS, "evdev: cannot query ABS device capabilities");
+ gpm_report(GPM_PR_ERR, "evdev: cannot query ABS device capabilities");
+ return -1;
}
if (test_bit(EV_KEY, caps->evbits) &&
ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(caps->keybits)), caps->keybits) < 0) {
- gpm_report(GPM_PR_OOPS, "evdev: cannot query KEY device capabilities");
+ gpm_report(GPM_PR_ERR, "evdev: cannot query KEY device capabilities");
+ return -1;
}
if (test_bit(EV_MSC, caps->evbits) &&
ioctl(fd, EVIOCGBIT(EV_MSC, sizeof(caps->mscbits)), caps->mscbits) < 0) {
- /* dont complain as 2.4 kernels didnt have it
- gpm_report(GPM_PR_OOPS, "evdev: cannot query MSC device capabilities");
+ /* don't complain as 2.4 kernels didnt have it
+ gpm_report(GPM_PR_ERR, "evdev: cannot query MSC device capabilities");
+ return -1;
*/
}
+ return 0;
}
-static void evdev_query_axis(int fd, int axis, int *axis_min, int *axis_max)
+static int evdev_query_axis(int fd, int axis, int *axis_min, int *axis_max)
{
struct input_absinfo axis_info;
- if (ioctl(fd, EVIOCGABS(axis), &axis_info) == 0) {
- *axis_min = axis_info.minimum;
- *axis_max = axis_info.maximum;
- } else
+ if (ioctl(fd, EVIOCGABS(axis), &axis_info) == -1) {
gpm_report(GPM_PR_ERR, "evdev: could not query axis data");
+ return -1;
+ }
+
+ *axis_min = axis_info.minimum;
+ *axis_max = axis_info.maximum;
+ return 0;
}
-static enum evdev_type evdev_guess_type(struct evdev_capabilities *caps)
+static int evdev_get_limits(int fd, struct event_device *evdev,
+ struct evdev_capabilities *caps)
+{
+ if (test_bit(ABS_X, caps->absbits) &&
+ evdev_query_axis(fd, ABS_X, &evdev->left_edge, &evdev->right_edge) < 0)
+ return -1;
+
+ if (test_bit(ABS_Y, caps->absbits) &&
+ evdev_query_axis(fd, ABS_Y, &evdev->top_edge, &evdev->bottom_edge) < 0)
+ return -1;
+
+ return 0;
+}
+
+static int is_synaptics(struct input_id *id)
+{
+ return id->bustype == BUS_I8042 && id->vendor == 0x0002 && id->product == PSMOUSE_SYNAPTICS;
+}
+
+static enum evdev_type evdev_guess_type(struct input_id *id, struct evdev_capabilities *caps)
{
if (test_bit(EV_ABS, caps->evbits)) {
- if (caps->keybits[BTN_DIGI / 8] || !test_bit(ABS_PRESSURE, caps->absbits))
- return EVDEV_ABSOLUTE;
+ if (is_synaptics(id))
+ return EVDEV_SYNAPTICS;
+
+ if (test_bit(BTN_TOUCH, caps->keybits) && caps->keybits[BTN_MOUSE / 8])
+ return EVDEV_TOUCHPAD;
- return test_bit(EV_MSC, caps->evbits) && test_bit(MSC_GESTURE, caps->mscbits) ?
- EVDEV_SYNAPTICS : EVDEV_TOUCHPAD;
+ return EVDEV_ABSOLUTE;
}
- if (!test_bit(EV_REL, caps->evbits))
- gpm_report(GPM_PR_OOPS,
+ if (!test_bit(EV_REL, caps->evbits)) {
+ gpm_report(GPM_PR_ERR,
"evdev: device does not report neither absolute nor relative coordinates");
+ return EVDEV_UNKNOWN;
+ }
return EVDEV_RELATIVE;
}
@@ -572,8 +668,8 @@
} else if (!strcmp(type, "synaptics")) {
return EVDEV_SYNAPTICS;
} else {
- gpm_report(GPM_PR_OOPS, "evdev: unknown type '%s'", type);
- return 0; /* won't happen as gpm_report(OOPS) does not return */
+ gpm_report(GPM_PR_ERR, "evdev: unknown type '%s'", type);
+ return EVDEV_UNKNOWN;
}
}
@@ -588,7 +684,7 @@
// -o type=(auto|synaptics|touchpad|relative|absolute),y_inverted,
// left=1234,right=1234,top=1234,bottom=1234,
// touch_high=30,touch_low=25,tap_time=30,tap_move=100
-static void evdev_apply_options(struct event_device *evdev, char *optstring)
+static int evdev_apply_options(struct event_device *evdev, char *optstring)
{
char *type = "auto";
struct option_helper optinfo[] = {
@@ -606,7 +702,7 @@
};
if (parse_options("evdev", optstring, ',', optinfo) < 0)
- gpm_report(GPM_PR_OOPS, "evdev: failed to parse option string");
+ return -1;
if (strcmp(type, "auto"))
evdev->type = evdev_str_to_type(type);
@@ -636,11 +732,16 @@
case EVDEV_SYNAPTICS:
warn_if_present(optinfo, "y_inverted", type);
break;
+
+ default:
+ return -1;
}
+ return 0;
}
int I_evdev(struct micedev *dev, struct miceopt *opts, Gpm_Type *type)
{
+ struct input_id id;
struct evdev_capabilities caps;
struct event_device *evdev;
@@ -650,33 +751,37 @@
memset(evdev, 0, sizeof(*evdev));
- evdev_get_capabilities(dev->fd, &caps);
- evdev->type = evdev_guess_type(&caps);
+ if (evdev_get_id(dev->fd, &id))
+ goto init_fail;
+
+ if (evdev_get_capabilities(dev->fd, &caps))
+ goto init_fail;
+
+ evdev->type = evdev_guess_type(&id, &caps);
/* load default values - suitable for my synaptics ;P */
evdev->left_edge = 1900;
- evdev->right_edge = 5400;
- evdev->top_edge = 3900;
- evdev->bottom_edge = 1800;
+ evdev->right_edge = 5300;
+ evdev->top_edge = 2000;
+ evdev->bottom_edge = 3900;
evdev->tap_time = 180;
evdev->tap_move = 220;
evdev->touch_high = 30;
evdev->touch_low = 25;
- if (evdev->type == EVDEV_ABSOLUTE) {
- if (test_bit(ABS_X, caps.absbits))
- evdev_query_axis(dev->fd, ABS_X, &evdev->left_edge, &evdev->right_edge);
- if (test_bit(ABS_Y, caps.absbits))
- evdev_query_axis(dev->fd, ABS_Y, &evdev->bottom_edge, &evdev->top_edge);
- }
+ if (evdev->type == EVDEV_ABSOLUTE && evdev_get_limits(dev->fd, evdev, &caps) < 0)
+ goto init_fail;
- evdev_apply_options(evdev, opts->text);
+ if (evdev_apply_options(evdev, opts->text) < 0)
+ goto init_fail;
if (!test_bit(EV_SYNC, caps.evbits)) {
evdev->dont_sync = 1;
- if (evdev->type == EVDEV_TOUCHPAD || evdev->type == EVDEV_SYNAPTICS)
- gpm_report(GPM_PR_OOPS,
+ if (evdev->type == EVDEV_TOUCHPAD || evdev->type == EVDEV_SYNAPTICS) {
+ gpm_report(GPM_PR_ERR,
"evdev: The running kernel lacks EV_SYNC support which is required for touchpad/synaptics mode");
+ goto init_fail;
+ }
}
switch (evdev->type) {
@@ -688,10 +793,14 @@
case EVDEV_ABSOLUTE:
gpm_report(GPM_PR_INFO, "evdev: selected Absolute mode");
- if (evdev->right_edge <= evdev->left_edge)
- gpm_report(GPM_PR_OOPS, "evdev: right edge value should be gerater then left");
- if (evdev->top_edge <= evdev->bottom_edge)
- gpm_report(GPM_PR_OOPS, "evdev: top edge value should be gerater then bottom");
+ if (evdev->right_edge <= evdev->left_edge) {
+ gpm_report(GPM_PR_ERR, "evdev: right edge value should be gerater than left");
+ goto init_fail;
+ }
+ if (evdev->bottom_edge <= evdev->top_edge) {
+ gpm_report(GPM_PR_ERR, "evdev: bottom edge value should be gerater than top");
+ goto init_fail;
+ }
if (!test_bit(EV_ABS, caps.evbits))
gpm_report(GPM_PR_WARN, "evdev: selected absolute mode but device does not report any absolute events");
opts->absolute = 1;
@@ -701,23 +810,42 @@
gpm_report(GPM_PR_INFO, "evdev: selected Touchpad mode");
if (!test_bit(EV_ABS, caps.evbits))
gpm_report(GPM_PR_WARN, "evdev: selected touchpad mode but device does not report any absolute events");
- if (!test_bit(ABS_PRESSURE, caps.absbits))
- gpm_report(GPM_PR_WARN, "evdev: selected touchpad mode but device does not report pressure");
+ if (test_bit(ABS_PRESSURE, caps.absbits))
+ evdev->detect_touch = smart_tp_detect_touch;
+ else if (test_bit(BTN_TOUCH, caps.keybits))
+ evdev->detect_touch = dumb_tp_detect_touch;
+ else
+ gpm_report(GPM_PR_WARN, "evdev: selected touchpad mode but device does not report pressure not touch events");
+ evdev->update_finger_count = tp_update_finger_count;
break;
case EVDEV_SYNAPTICS:
gpm_report(GPM_PR_INFO, "evdev: selected Synaptics mode");
+ if (!is_synaptics(&id))
+ gpm_report(GPM_PR_WARN, "evdev: idevice isn't identified as Synaptics");
if (!test_bit(EV_ABS, caps.evbits))
gpm_report(GPM_PR_WARN, "evdev: selected synaptics mode but device does not report any absolute events");
if (!test_bit(ABS_PRESSURE, caps.absbits))
gpm_report(GPM_PR_WARN, "evdev: selected synaptics mode but device does not report pressure");
- if (!test_bit(EV_MSC, caps.evbits) || !test_bit(MSC_GESTURE, caps.mscbits))
- gpm_report(GPM_PR_WARN, "evdev: selected synaptics mode but device does not report gesture events");
- evdev->y_inverted = 1; /* Synaptics always has Y inverted */
+ if (test_bit(EV_MSC, caps.evbits) && test_bit(MSC_GESTURE, caps.mscbits)) {
+ /* this is compatibility mode with pre 2.6-test6 kernels */
+ evdev->update_finger_count = syn_update_finger_count;
+ evdev->y_inverted = 1;
+ } else {
+ evdev->update_finger_count = tp_update_finger_count;
+ }
+ evdev->detect_touch = syn_detect_touch;
+ break;
+
+ default:
break;
}
}
return 0;
+
+init_fail:
+ free(dev->private);
+ return -1;
}
diff -Nru a/src/headers/input-defines.h b/src/headers/input-defines.h
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/src/headers/input-defines.h 2004-08-10 01:18:01 -05:00
@@ -0,0 +1,81 @@
+/*
+ * input-defines.h - complements <linux/input.h> adding missing bits
+ *
+ * Copyright (C) 2003 Dmitry Torokhov <dtor@mail.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ ********/
+#ifndef __GPM_INPUT_DEFINES_H
+#define __GPM_INPUT_DEFINES_H
+
+#include <linux/input.h>
+#include "headers/config.h"
+
+#ifndef ABS_TOOL_WIDTH
+#define ABS_TOOL_WIDTH 0x1c
+#endif
+
+#ifndef BTN_TOOL_FINGER
+#define BTN_TOOL_FINGER 0x145
+#endif
+
+#ifndef BTN_TOUCH
+#define BTN_TOUCH 0x14a
+#endif
+
+#ifndef BTN_TOOL_DOUBLETAP
+#define BTN_TOOL_DOUBLETAP 0x14d
+#endif
+
+#ifndef BTN_TOOL_TRIPLETAP
+#define BTN_TOOL_TRIPLETAP 0x14e
+#endif
+
+#ifndef MSC_GESTURE
+#define MSC_GESTURE 2
+#endif
+
+#ifndef EV_SYNC
+#define EV_SYNC 0
+#endif
+
+#ifndef SYN_REPORT
+#define SYN_REPORT 0
+#endif
+
+#ifndef PSMOUSE_SYNAPTICS
+#define PSMOUSE_SYNAPTICS 7
+#endif
+
+#ifndef HAVE_INPUT_ID
+struct input_id {
+ unsigned short bustype;
+ unsigned short vendor;
+ unsigned short product;
+ unsigned short version;
+};
+#endif
+
+#ifndef HAVE_INPUT_ABSINFO
+struct input_absinfo {
+ int value;
+ int minimum;
+ int maximum;
+ int fuzz;
+ int flat;
+};
+#endif
+
+#endif
More information about the gpm
mailing list