[PATCH 6/8] evdev-touchpad: Made hw_abs an array
Alexander E. Patrakov
patrakov at gmail.com
Mon Aug 5 03:34:35 PDT 2013
From: "Alexander E. Patrakov" <patrakov at gmail.com>
In the non-multitouch case, the 0th entry tracks motion just as the old
scalar hw_abs. In the multitouch case, there will be one entry for each
slot, and relevant_touch is used to select which one is motion-tracked.
---
src/evdev-touchpad.c | 146 +++++++++++++++++++++++++++++++++++----------------
1 file changed, 102 insertions(+), 44 deletions(-)
diff --git a/src/evdev-touchpad.c b/src/evdev-touchpad.c
index 1ed2dbb..01c52aa 100644
--- a/src/evdev-touchpad.c
+++ b/src/evdev-touchpad.c
@@ -51,6 +51,7 @@ enum touchpad_model {
enum interaction_model {
INTERACTION_MODEL_SIMPLE = 0,
INTERACTION_MODEL_APPLE,
+ INTERACTION_MODEL_SONY,
};
struct touchpad_model_spec {
@@ -103,6 +104,8 @@ struct touchpad_dispatch {
enum interaction_model interaction_model;
int finger_state;
int last_finger_state;
+ int slot;
+ int relevant_touch;
double constant_accel_factor;
double min_accel_factor;
@@ -114,6 +117,7 @@ struct touchpad_dispatch {
struct wl_event_source *timer_source;
} fsm;
+ /* the extra dummy slot is used for out-of-range slots reported by mtdev */
struct {
int32_t x;
int32_t y;
@@ -123,7 +127,7 @@ struct touchpad_dispatch {
bool is_moving;
bool is_pressed;
- } hw_abs;
+ } hw_abs[MAX_SLOTS + 1];
bool has_moved;
uint16_t touch_state;
@@ -436,29 +440,80 @@ fsm_timout_handler(void *data)
return 1;
}
+static bool
+is_valid_touch(struct touchpad_dispatch *touchpad, int slot)
+{
+ if (!touchpad->hw_abs[slot].x_valid)
+ return false;
+ if (!touchpad->hw_abs[slot].y_valid)
+ return false;
+ if (!touchpad->hw_abs[slot].is_pressed)
+ return false;
+ return true;
+}
+
static void
touchpad_update_state(struct touchpad_dispatch *touchpad, uint32_t time)
{
+ int i;
int motion_index;
int center_x, center_y;
double dx = 0.0, dy = 0.0;
/* For multitouch case, this will be a bitmask */
- uint16_t touch_state = touchpad->hw_abs.is_pressed;
- if (touch_state && !touchpad->touch_state)
+ uint16_t touch_state = 0;
+ int last_valid_touch = -1;
+ int relevant_touch = touchpad->relevant_touch;
+ bool reset_motion = false;
+
+ for (i = 0; i < MAX_SLOTS; i++)
+ if (is_valid_touch(touchpad, i)) {
+ touch_state |= 1 << i;
+ last_valid_touch = i;
+ }
+
+ if (touch_state && !touchpad->touch_state) {
push_fsm_event(touchpad, FSM_EVENT_TOUCH);
+ reset_motion = true;
+ }
+
if (!touch_state && touchpad->touch_state) {
push_fsm_event(touchpad, FSM_EVENT_RELEASE);
touchpad->has_moved = false;
+ reset_motion = true;
}
+ if (touch_state && touchpad->touch_state &&
+ !(touch_state & touchpad->touch_state)) {
+ push_fsm_event(touchpad, FSM_EVENT_RELEASE);
+ push_fsm_event(touchpad, FSM_EVENT_TOUCH);
+ touchpad->has_moved = false;
+ reset_motion = true;
+ }
+
+
+ if (relevant_touch != -1 && !(touch_state & (1 << relevant_touch))) {
+ reset_motion = true;
+ relevant_touch = -1;
+ }
+ if (relevant_touch == -1)
+ relevant_touch = last_valid_touch;
+
+ if (touchpad->last_finger_state != touchpad->finger_state)
+ reset_motion = true;
+
touchpad->touch_state = touch_state;
+ touchpad->last_finger_state = touchpad->finger_state;
+ touchpad->relevant_touch = relevant_touch;
- if (touchpad->last_finger_state != touchpad->finger_state) {
+ if (reset_motion) {
touchpad->motion_count = 0;
- touchpad->hw_abs.x_valid = touchpad->hw_abs.y_valid = false;
- touchpad->hw_abs.is_moving = false;
+ if (touchpad->interaction_model != INTERACTION_MODEL_SONY) {
+ touchpad->hw_abs[0].x_valid = false;
+ touchpad->hw_abs[0].y_valid = false;
+ touchpad->hw_abs[0].is_moving = false;
+ }
touchpad->last_finger_state = touchpad->finger_state;
@@ -466,37 +521,36 @@ touchpad_update_state(struct touchpad_dispatch *touchpad, uint32_t time)
return;
}
- touchpad->last_finger_state = touchpad->finger_state;
- if (!touchpad->hw_abs.x_valid || !touchpad->hw_abs.y_valid)
+ if (relevant_touch == -1)
return;
- if (!touchpad->hw_abs.is_moving)
+ if (!touchpad->hw_abs[relevant_touch].is_moving)
return;
/* Avoid noice by moving center only when delta reaches a threshold
* distance from the old center. */
if (touchpad->motion_count > 0) {
- center_x = hysteresis(touchpad->hw_abs.x,
+ center_x = hysteresis(touchpad->hw_abs[relevant_touch].x,
touchpad->hysteresis.center_x,
touchpad->hysteresis.margin_x);
- center_y = hysteresis(touchpad->hw_abs.y,
+ center_y = hysteresis(touchpad->hw_abs[relevant_touch].y,
touchpad->hysteresis.center_y,
touchpad->hysteresis.margin_y);
} else {
- center_x = touchpad->hw_abs.x;
- center_y = touchpad->hw_abs.y;
+ center_x = touchpad->hw_abs[relevant_touch].x;
+ center_y = touchpad->hw_abs[relevant_touch].y;
}
touchpad->hysteresis.center_x = center_x;
touchpad->hysteresis.center_y = center_y;
- touchpad->hw_abs.x = center_x;
- touchpad->hw_abs.y = center_y;
+ touchpad->hw_abs[relevant_touch].x = center_x;
+ touchpad->hw_abs[relevant_touch].y = center_y;
/* Update motion history tracker */
motion_index = (touchpad->motion_index + 1) % TOUCHPAD_HISTORY_LENGTH;
touchpad->motion_index = motion_index;
- touchpad->motion_history[motion_index].x = touchpad->hw_abs.x;
- touchpad->motion_history[motion_index].y = touchpad->hw_abs.y;
+ touchpad->motion_history[motion_index].x = touchpad->hw_abs[relevant_touch].x;
+ touchpad->motion_history[motion_index].y = touchpad->hw_abs[relevant_touch].y;
if (touchpad->motion_count < 4)
touchpad->motion_count++;
@@ -534,17 +588,17 @@ touchpad_update_state(struct touchpad_dispatch *touchpad, uint32_t time)
}
static void
-on_touch(struct touchpad_dispatch *touchpad)
+on_touch(struct touchpad_dispatch *touchpad, int slot)
{
- touchpad->hw_abs.is_pressed = true;
+ touchpad->hw_abs[slot].is_pressed = true;
}
static void
-on_release(struct touchpad_dispatch *touchpad)
+on_release(struct touchpad_dispatch *touchpad, int slot)
{
- touchpad->hw_abs.is_pressed = false;
- touchpad->hw_abs.is_moving = false;
- touchpad->hw_abs.x_valid = touchpad->hw_abs.y_valid = false;
+ touchpad->hw_abs[slot].is_pressed = false;
+ touchpad->hw_abs[slot].is_moving = false;
+ touchpad->hw_abs[slot].x_valid = touchpad->hw_abs[slot].y_valid = false;
}
static inline void
@@ -555,25 +609,25 @@ process_absolute(struct touchpad_dispatch *touchpad,
switch (e->code) {
case ABS_PRESSURE:
if (e->value > touchpad->pressure.touch_high &&
- !touchpad->hw_abs.is_pressed)
- on_touch(touchpad);
+ !touchpad->hw_abs[0].is_pressed)
+ on_touch(touchpad, 0);
else if (e->value < touchpad->pressure.touch_low &&
- touchpad->hw_abs.is_pressed)
- on_release(touchpad);
+ touchpad->hw_abs[0].is_pressed)
+ on_release(touchpad, 0);
break;
case ABS_X:
- if (touchpad->hw_abs.is_pressed) {
- touchpad->hw_abs.x = e->value;
- touchpad->hw_abs.x_valid = true;
- touchpad->hw_abs.is_moving = true;
+ if (touchpad->hw_abs[0].is_pressed) {
+ touchpad->hw_abs[0].x = e->value;
+ touchpad->hw_abs[0].x_valid = true;
+ touchpad->hw_abs[0].is_moving = true;
}
break;
case ABS_Y:
- if (touchpad->hw_abs.is_pressed) {
- touchpad->hw_abs.y = e->value;
- touchpad->hw_abs.y_valid = true;
- touchpad->hw_abs.is_moving = true;
+ if (touchpad->hw_abs[0].is_pressed) {
+ touchpad->hw_abs[0].y = e->value;
+ touchpad->hw_abs[0].y_valid = true;
+ touchpad->hw_abs[0].is_moving = true;
}
break;
}
@@ -590,10 +644,10 @@ process_key(struct touchpad_dispatch *touchpad,
switch (e->code) {
case BTN_TOUCH:
if (!touchpad->has_pressure) {
- if (e->value && !touchpad->hw_abs.is_pressed)
- on_touch(touchpad);
+ if (e->value && !touchpad->hw_abs[0].is_pressed)
+ on_touch(touchpad, 0);
else if (!e->value)
- on_release(touchpad);
+ on_release(touchpad, 0);
}
break;
case BTN_LEFT:
@@ -624,8 +678,11 @@ process_key(struct touchpad_dispatch *touchpad,
/* The reset-logic below was copied without understanding
* and may be inappropriate */
touchpad->motion_count = 0;
- touchpad->hw_abs.x_valid = touchpad->hw_abs.y_valid = false;
- touchpad->hw_abs.is_moving = false;
+ if (touchpad->interaction_model != INTERACTION_MODEL_SONY) {
+ touchpad->hw_abs[0].x_valid = false;
+ touchpad->hw_abs[0].y_valid = false;
+ touchpad->hw_abs[0].is_moving = false;
+ }
break;
case BTN_TOOL_FINGER:
if (e->value)
@@ -746,10 +803,11 @@ touchpad_init(struct touchpad_dispatch *touchpad,
touchpad->motion_index = 0;
touchpad->motion_count = 0;
- touchpad->hw_abs.x_valid = false;
- touchpad->hw_abs.y_valid = false;
- touchpad->hw_abs.is_pressed = false;
- touchpad->hw_abs.is_moving = false;
+ memset(touchpad->hw_abs, 0, sizeof touchpad->hw_abs);
+
+ touchpad->slot = MAX_SLOTS;
+ touchpad->relevant_touch = -1;
+
touchpad->has_moved = false;
touchpad->touch_state = 0;
--
1.8.3.2
More information about the wayland-devel
mailing list