evdev-touchpad: Cleanup and refactoring
Signed-off-by: Jonas Ådahl <jadahl@gmail.com>
This commit is contained in:
committed by
Kristian Høgsberg
parent
b2f957a9f1
commit
c689493b1a
+117
-110
@@ -42,11 +42,13 @@ enum touchpad_model {
|
|||||||
TOUCHPAD_MODEL_ELANTECH
|
TOUCHPAD_MODEL_ELANTECH
|
||||||
};
|
};
|
||||||
|
|
||||||
#define TOUCHPAD_EVENT_NONE 0
|
enum touchpad_event {
|
||||||
#define TOUCHPAD_EVENT_ABSOLUTE_ANY (1 << 0)
|
TOUCHPAD_EVENT_NONE = 0,
|
||||||
#define TOUCHPAD_EVENT_ABSOLUTE_X (1 << 1)
|
TOUCHPAD_EVENT_ABSOLUTE_ANY = (1 << 0),
|
||||||
#define TOUCHPAD_EVENT_ABSOLUTE_Y (1 << 2)
|
TOUCHPAD_EVENT_ABSOLUTE_X = (1 << 1),
|
||||||
#define TOUCHPAD_EVENT_REPORT (1 << 3)
|
TOUCHPAD_EVENT_ABSOLUTE_Y = (1 << 2),
|
||||||
|
TOUCHPAD_EVENT_REPORT = (1 << 3)
|
||||||
|
};
|
||||||
|
|
||||||
struct touchpad_model_spec {
|
struct touchpad_model_spec {
|
||||||
short vendor;
|
short vendor;
|
||||||
@@ -63,9 +65,9 @@ static struct touchpad_model_spec touchpad_spec_table[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum touchpad_state {
|
enum touchpad_state {
|
||||||
TOUCHPAD_STATE_NONE = 0,
|
TOUCHPAD_STATE_NONE = 0,
|
||||||
TOUCHPAD_STATE_TOUCH,
|
TOUCHPAD_STATE_TOUCH = (1 << 0),
|
||||||
TOUCHPAD_STATE_PRESS
|
TOUCHPAD_STATE_MOVE = (1 << 1)
|
||||||
};
|
};
|
||||||
|
|
||||||
#define TOUCHPAD_HISTORY_LENGTH 4
|
#define TOUCHPAD_HISTORY_LENGTH 4
|
||||||
@@ -86,7 +88,7 @@ struct touchpad_dispatch {
|
|||||||
struct evdev_device *device;
|
struct evdev_device *device;
|
||||||
|
|
||||||
enum touchpad_model model;
|
enum touchpad_model model;
|
||||||
enum touchpad_state state;
|
unsigned int state;
|
||||||
int finger_state;
|
int finger_state;
|
||||||
int last_finger_state;
|
int last_finger_state;
|
||||||
|
|
||||||
@@ -108,7 +110,6 @@ struct touchpad_dispatch {
|
|||||||
struct {
|
struct {
|
||||||
int32_t touch_low;
|
int32_t touch_low;
|
||||||
int32_t touch_high;
|
int32_t touch_high;
|
||||||
int32_t press;
|
|
||||||
} pressure;
|
} pressure;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
@@ -122,7 +123,7 @@ struct touchpad_dispatch {
|
|||||||
int motion_index;
|
int motion_index;
|
||||||
unsigned int motion_count;
|
unsigned int motion_count;
|
||||||
|
|
||||||
struct wl_list motion_filters;
|
struct weston_motion_filter *filter;
|
||||||
};
|
};
|
||||||
|
|
||||||
static enum touchpad_model
|
static enum touchpad_model
|
||||||
@@ -163,8 +164,6 @@ configure_touchpad_pressure(struct touchpad_dispatch *touchpad,
|
|||||||
touchpad->pressure.touch_high =
|
touchpad->pressure.touch_high =
|
||||||
pressure_min + range * (30.0/256.0);
|
pressure_min + range * (30.0/256.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
touchpad->pressure.press = pressure_min + range;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static double
|
static double
|
||||||
@@ -188,65 +187,6 @@ touchpad_profile(struct weston_motion_filter *filter,
|
|||||||
return accel_factor;
|
return accel_factor;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
configure_touchpad(struct touchpad_dispatch *touchpad,
|
|
||||||
struct evdev_device *device)
|
|
||||||
{
|
|
||||||
struct weston_motion_filter *accel;
|
|
||||||
|
|
||||||
struct input_absinfo absinfo;
|
|
||||||
unsigned long abs_bits[NBITS(ABS_MAX)];
|
|
||||||
|
|
||||||
double width;
|
|
||||||
double height;
|
|
||||||
double diagonal;
|
|
||||||
|
|
||||||
/* Detect model */
|
|
||||||
touchpad->model = get_touchpad_model(device);
|
|
||||||
|
|
||||||
/* Configure pressure */
|
|
||||||
ioctl(device->fd, EVIOCGBIT(EV_ABS, sizeof(abs_bits)), abs_bits);
|
|
||||||
if (TEST_BIT(abs_bits, ABS_PRESSURE)) {
|
|
||||||
ioctl(device->fd, EVIOCGABS(ABS_PRESSURE), &absinfo);
|
|
||||||
configure_touchpad_pressure(touchpad,
|
|
||||||
absinfo.minimum,
|
|
||||||
absinfo.maximum);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Configure acceleration factor */
|
|
||||||
width = abs(device->abs.max_x - device->abs.min_x);
|
|
||||||
height = abs(device->abs.max_y - device->abs.min_y);
|
|
||||||
diagonal = sqrt(width*width + height*height);
|
|
||||||
|
|
||||||
touchpad->constant_accel_factor =
|
|
||||||
DEFAULT_CONSTANT_ACCEL_NUMERATOR / diagonal;
|
|
||||||
|
|
||||||
touchpad->min_accel_factor = DEFAULT_MIN_ACCEL_FACTOR;
|
|
||||||
touchpad->max_accel_factor = DEFAULT_MAX_ACCEL_FACTOR;
|
|
||||||
|
|
||||||
touchpad->hysteresis.margin_x =
|
|
||||||
diagonal / DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR;
|
|
||||||
touchpad->hysteresis.margin_y =
|
|
||||||
diagonal / DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR;
|
|
||||||
touchpad->hysteresis.center_x = 0;
|
|
||||||
touchpad->hysteresis.center_y = 0;
|
|
||||||
|
|
||||||
/* Configure acceleration profile */
|
|
||||||
accel = create_pointer_accelator_filter(touchpad_profile);
|
|
||||||
wl_list_insert(&touchpad->motion_filters, &accel->link);
|
|
||||||
|
|
||||||
/* Setup initial state */
|
|
||||||
touchpad->reset = 1;
|
|
||||||
|
|
||||||
memset(touchpad->motion_history, 0, sizeof touchpad->motion_history);
|
|
||||||
touchpad->motion_index = 0;
|
|
||||||
touchpad->motion_count = 0;
|
|
||||||
|
|
||||||
touchpad->state = TOUCHPAD_STATE_NONE;
|
|
||||||
touchpad->last_finger_state = 0;
|
|
||||||
touchpad->finger_state = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline struct touchpad_motion *
|
static inline struct touchpad_motion *
|
||||||
motion_history_offset(struct touchpad_dispatch *touchpad, int offset)
|
motion_history_offset(struct touchpad_dispatch *touchpad, int offset)
|
||||||
{
|
{
|
||||||
@@ -294,14 +234,12 @@ static void
|
|||||||
filter_motion(struct touchpad_dispatch *touchpad,
|
filter_motion(struct touchpad_dispatch *touchpad,
|
||||||
double *dx, double *dy, uint32_t time)
|
double *dx, double *dy, uint32_t time)
|
||||||
{
|
{
|
||||||
struct weston_motion_filter *filter;
|
|
||||||
struct weston_motion_params motion;
|
struct weston_motion_params motion;
|
||||||
|
|
||||||
motion.dx = *dx;
|
motion.dx = *dx;
|
||||||
motion.dy = *dy;
|
motion.dy = *dy;
|
||||||
|
|
||||||
wl_list_for_each(filter, &touchpad->motion_filters, link)
|
weston_filter_dispatch(touchpad->filter, &motion, touchpad, time);
|
||||||
weston_filter_dispatch(filter, &motion, touchpad, time);
|
|
||||||
|
|
||||||
*dx = motion.dx;
|
*dx = motion.dx;
|
||||||
*dy = motion.dy;
|
*dy = motion.dy;
|
||||||
@@ -312,7 +250,7 @@ touchpad_update_state(struct touchpad_dispatch *touchpad, uint32_t time)
|
|||||||
{
|
{
|
||||||
int motion_index;
|
int motion_index;
|
||||||
int center_x, center_y;
|
int center_x, center_y;
|
||||||
double dx, dy;
|
double dx = 0.0, dy = 0.0;
|
||||||
|
|
||||||
if (touchpad->reset ||
|
if (touchpad->reset ||
|
||||||
touchpad->last_finger_state != touchpad->finger_state) {
|
touchpad->last_finger_state != touchpad->finger_state) {
|
||||||
@@ -349,8 +287,7 @@ touchpad_update_state(struct touchpad_dispatch *touchpad, uint32_t time)
|
|||||||
center_y = hysteresis(touchpad->hw_abs.y,
|
center_y = hysteresis(touchpad->hw_abs.y,
|
||||||
touchpad->hysteresis.center_y,
|
touchpad->hysteresis.center_y,
|
||||||
touchpad->hysteresis.margin_y);
|
touchpad->hysteresis.margin_y);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
center_x = touchpad->hw_abs.x;
|
center_x = touchpad->hw_abs.x;
|
||||||
center_y = touchpad->hw_abs.y;
|
center_y = touchpad->hw_abs.y;
|
||||||
}
|
}
|
||||||
@@ -376,6 +313,25 @@ touchpad_update_state(struct touchpad_dispatch *touchpad, uint32_t time)
|
|||||||
touchpad->device->rel.dy = wl_fixed_from_double(dy);
|
touchpad->device->rel.dy = wl_fixed_from_double(dy);
|
||||||
touchpad->device->pending_events |= EVDEV_RELATIVE_MOTION;
|
touchpad->device->pending_events |= EVDEV_RELATIVE_MOTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(touchpad->state & TOUCHPAD_STATE_MOVE) &&
|
||||||
|
((int)dx || (int)dy)) {
|
||||||
|
touchpad->state |= TOUCHPAD_STATE_MOVE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_touch(struct touchpad_dispatch *touchpad)
|
||||||
|
{
|
||||||
|
touchpad->state |= TOUCHPAD_STATE_TOUCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_release(struct touchpad_dispatch *touchpad)
|
||||||
|
{
|
||||||
|
|
||||||
|
touchpad->reset = 1;
|
||||||
|
touchpad->state &= ~(TOUCHPAD_STATE_MOVE | TOUCHPAD_STATE_TOUCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
@@ -385,27 +341,23 @@ process_absolute(struct touchpad_dispatch *touchpad,
|
|||||||
{
|
{
|
||||||
switch (e->code) {
|
switch (e->code) {
|
||||||
case ABS_PRESSURE:
|
case ABS_PRESSURE:
|
||||||
if (e->value > touchpad->pressure.press)
|
if (e->value > touchpad->pressure.touch_high &&
|
||||||
touchpad->state = TOUCHPAD_STATE_PRESS;
|
!(touchpad->state & TOUCHPAD_STATE_TOUCH))
|
||||||
else if (e->value > touchpad->pressure.touch_high)
|
on_touch(touchpad);
|
||||||
touchpad->state = TOUCHPAD_STATE_TOUCH;
|
else if (e->value < touchpad->pressure.touch_low &&
|
||||||
else if (e->value < touchpad->pressure.touch_low) {
|
touchpad->state & TOUCHPAD_STATE_TOUCH)
|
||||||
if (touchpad->state > TOUCHPAD_STATE_NONE)
|
on_release(touchpad);
|
||||||
touchpad->reset = 1;
|
|
||||||
|
|
||||||
touchpad->state = TOUCHPAD_STATE_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case ABS_X:
|
case ABS_X:
|
||||||
if (touchpad->state >= TOUCHPAD_STATE_TOUCH) {
|
if (touchpad->state & TOUCHPAD_STATE_TOUCH) {
|
||||||
touchpad->hw_abs.x = e->value;
|
touchpad->hw_abs.x = e->value;
|
||||||
touchpad->event_mask |= TOUCHPAD_EVENT_ABSOLUTE_ANY;
|
touchpad->event_mask |= TOUCHPAD_EVENT_ABSOLUTE_ANY;
|
||||||
touchpad->event_mask |= TOUCHPAD_EVENT_ABSOLUTE_X;
|
touchpad->event_mask |= TOUCHPAD_EVENT_ABSOLUTE_X;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ABS_Y:
|
case ABS_Y:
|
||||||
if (touchpad->state >= TOUCHPAD_STATE_TOUCH) {
|
if (touchpad->state & TOUCHPAD_STATE_TOUCH) {
|
||||||
touchpad->hw_abs.y = e->value;
|
touchpad->hw_abs.y = e->value;
|
||||||
touchpad->event_mask |= TOUCHPAD_EVENT_ABSOLUTE_ANY;
|
touchpad->event_mask |= TOUCHPAD_EVENT_ABSOLUTE_ANY;
|
||||||
touchpad->event_mask |= TOUCHPAD_EVENT_ABSOLUTE_Y;
|
touchpad->event_mask |= TOUCHPAD_EVENT_ABSOLUTE_Y;
|
||||||
@@ -423,15 +375,10 @@ process_key(struct touchpad_dispatch *touchpad,
|
|||||||
switch (e->code) {
|
switch (e->code) {
|
||||||
case BTN_TOUCH:
|
case BTN_TOUCH:
|
||||||
if (!touchpad->has_pressure) {
|
if (!touchpad->has_pressure) {
|
||||||
if (!e->value) {
|
if (e->value && !(touchpad->state & TOUCHPAD_STATE_TOUCH))
|
||||||
touchpad->state = TOUCHPAD_STATE_NONE;
|
on_touch(touchpad);
|
||||||
touchpad->reset = 1;
|
else if (!e->value)
|
||||||
} else {
|
on_release(touchpad);
|
||||||
touchpad->state =
|
|
||||||
e->value ?
|
|
||||||
TOUCHPAD_STATE_TOUCH :
|
|
||||||
TOUCHPAD_STATE_NONE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BTN_LEFT:
|
case BTN_LEFT:
|
||||||
@@ -504,12 +451,8 @@ touchpad_destroy(struct evdev_dispatch *dispatch)
|
|||||||
{
|
{
|
||||||
struct touchpad_dispatch *touchpad =
|
struct touchpad_dispatch *touchpad =
|
||||||
(struct touchpad_dispatch *) dispatch;
|
(struct touchpad_dispatch *) dispatch;
|
||||||
struct weston_motion_filter *filter;
|
|
||||||
struct weston_motion_filter *next;
|
|
||||||
|
|
||||||
wl_list_for_each_safe(filter, next, &touchpad->motion_filters, link)
|
|
||||||
filter->interface->destroy(filter);
|
|
||||||
|
|
||||||
|
touchpad->filter->interface->destroy(touchpad->filter);
|
||||||
free(dispatch);
|
free(dispatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -518,6 +461,72 @@ struct evdev_dispatch_interface touchpad_interface = {
|
|||||||
touchpad_destroy
|
touchpad_destroy
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
touchpad_init(struct touchpad_dispatch *touchpad,
|
||||||
|
struct evdev_device *device)
|
||||||
|
{
|
||||||
|
struct weston_motion_filter *accel;
|
||||||
|
|
||||||
|
struct input_absinfo absinfo;
|
||||||
|
unsigned long abs_bits[NBITS(ABS_MAX)];
|
||||||
|
|
||||||
|
double width;
|
||||||
|
double height;
|
||||||
|
double diagonal;
|
||||||
|
|
||||||
|
touchpad->base.interface = &touchpad_interface;
|
||||||
|
touchpad->device = device;
|
||||||
|
|
||||||
|
/* Detect model */
|
||||||
|
touchpad->model = get_touchpad_model(device);
|
||||||
|
|
||||||
|
/* Configure pressure */
|
||||||
|
ioctl(device->fd, EVIOCGBIT(EV_ABS, sizeof(abs_bits)), abs_bits);
|
||||||
|
if (TEST_BIT(abs_bits, ABS_PRESSURE)) {
|
||||||
|
ioctl(device->fd, EVIOCGABS(ABS_PRESSURE), &absinfo);
|
||||||
|
configure_touchpad_pressure(touchpad,
|
||||||
|
absinfo.minimum,
|
||||||
|
absinfo.maximum);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Configure acceleration factor */
|
||||||
|
width = abs(device->abs.max_x - device->abs.min_x);
|
||||||
|
height = abs(device->abs.max_y - device->abs.min_y);
|
||||||
|
diagonal = sqrt(width*width + height*height);
|
||||||
|
|
||||||
|
touchpad->constant_accel_factor =
|
||||||
|
DEFAULT_CONSTANT_ACCEL_NUMERATOR / diagonal;
|
||||||
|
|
||||||
|
touchpad->min_accel_factor = DEFAULT_MIN_ACCEL_FACTOR;
|
||||||
|
touchpad->max_accel_factor = DEFAULT_MAX_ACCEL_FACTOR;
|
||||||
|
|
||||||
|
touchpad->hysteresis.margin_x =
|
||||||
|
diagonal / DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR;
|
||||||
|
touchpad->hysteresis.margin_y =
|
||||||
|
diagonal / DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR;
|
||||||
|
touchpad->hysteresis.center_x = 0;
|
||||||
|
touchpad->hysteresis.center_y = 0;
|
||||||
|
|
||||||
|
/* Configure acceleration profile */
|
||||||
|
accel = create_pointer_accelator_filter(touchpad_profile);
|
||||||
|
if (accel == NULL)
|
||||||
|
return -1;
|
||||||
|
touchpad->filter = accel;
|
||||||
|
|
||||||
|
/* Setup initial state */
|
||||||
|
touchpad->reset = 1;
|
||||||
|
|
||||||
|
memset(touchpad->motion_history, 0, sizeof touchpad->motion_history);
|
||||||
|
touchpad->motion_index = 0;
|
||||||
|
touchpad->motion_count = 0;
|
||||||
|
|
||||||
|
touchpad->state = TOUCHPAD_STATE_NONE;
|
||||||
|
touchpad->last_finger_state = 0;
|
||||||
|
touchpad->finger_state = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
struct evdev_dispatch *
|
struct evdev_dispatch *
|
||||||
evdev_touchpad_create(struct evdev_device *device)
|
evdev_touchpad_create(struct evdev_device *device)
|
||||||
{
|
{
|
||||||
@@ -527,12 +536,10 @@ evdev_touchpad_create(struct evdev_device *device)
|
|||||||
if (touchpad == NULL)
|
if (touchpad == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
touchpad->base.interface = &touchpad_interface;
|
if (touchpad_init(touchpad, device) != 0) {
|
||||||
|
free(touchpad);
|
||||||
touchpad->device = device;
|
return NULL;
|
||||||
wl_list_init(&touchpad->motion_filters);
|
}
|
||||||
|
|
||||||
configure_touchpad(touchpad, device);
|
|
||||||
|
|
||||||
return &touchpad->base;
|
return &touchpad->base;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user