diff --git a/input/input.c b/input/input.c index b24e82fe50..1f747f01cd 100644 --- a/input/input.c +++ b/input/input.c @@ -93,6 +93,11 @@ struct wheel_state { double unit_accum; }; +struct touch_point { + int id; + int x, y; +}; + struct input_ctx { mp_mutex mutex; struct mp_log *log; @@ -143,6 +148,10 @@ struct input_ctx { struct active_section *active_sections; int num_active_sections; + // List currently active touch points + struct touch_point *touch_points; + int num_touch_points; + unsigned int mouse_event_counter; struct mp_input_src *sources[MP_MAX_SOURCES]; @@ -894,6 +903,88 @@ void mp_input_set_mouse_pos(struct input_ctx *ictx, int x, int y) input_unlock(ictx); } +static int find_touch_point_index(struct input_ctx *ictx, int id) +{ + for (int i = 0; i < ictx->num_touch_points; i++) { + if (ictx->touch_points[i].id == id) + return i; + } + return -1; +} + +static void notify_touch_update(struct input_ctx *ictx) +{ + // queue dummy cmd so that touch-pos can notify observers + mp_cmd_t *cmd = mp_input_parse_cmd(ictx, bstr0("ignore"), ""); + queue_cmd(ictx, cmd); +} + +static void update_touch_point(struct input_ctx *ictx, int idx, int id, int x, int y) +{ + MP_TRACE(ictx, "Touch point %d update (id %d) %d/%d\n", + idx, id, x, y); + if (ictx->touch_points[idx].x == x && ictx->touch_points[idx].y == y) + return; + ictx->touch_points[idx].x = x; + ictx->touch_points[idx].y = y; + notify_touch_update(ictx); +} + +void mp_input_add_touch_point(struct input_ctx *ictx, int id, int x, int y) +{ + input_lock(ictx); + int idx = find_touch_point_index(ictx, id); + if (idx != -1) { + MP_WARN(ictx, "Touch point %d (id %d) already exists! Treat as update.\n", + idx, id); + update_touch_point(ictx, idx, id, x, y); + } else { + MP_TRACE(ictx, "Touch point %d add (id %d) %d/%d\n", + ictx->num_touch_points, id, x, y); + MP_TARRAY_APPEND(ictx, ictx->touch_points, ictx->num_touch_points, + (struct touch_point){id, x, y}); + notify_touch_update(ictx); + } + input_unlock(ictx); +} + +void mp_input_update_touch_point(struct input_ctx *ictx, int id, int x, int y) +{ + input_lock(ictx); + int idx = find_touch_point_index(ictx, id); + if (idx != -1) { + update_touch_point(ictx, idx, id, x, y); + } else { + MP_WARN(ictx, "Touch point id %d does not exist!\n", id); + } + input_unlock(ictx); +} + +void mp_input_remove_touch_point(struct input_ctx *ictx, int id) +{ + input_lock(ictx); + int idx = find_touch_point_index(ictx, id); + if (idx != -1) { + MP_TRACE(ictx, "Touch point %d remove (id %d)\n", idx, id); + MP_TARRAY_REMOVE_AT(ictx->touch_points, ictx->num_touch_points, idx); + notify_touch_update(ictx); + } + input_unlock(ictx); +} + +int mp_input_get_touch_pos(struct input_ctx *ictx, int count, int *x, int *y, int *id) +{ + input_lock(ictx); + int num_touch_points = ictx->num_touch_points; + for (int i = 0; i < MPMIN(num_touch_points, count); i++) { + x[i] = ictx->touch_points[i].x; + y[i] = ictx->touch_points[i].y; + id[i] = ictx->touch_points[i].id; + } + input_unlock(ictx); + return num_touch_points; +} + static bool test_mouse(struct input_ctx *ictx, int x, int y, int rej_flags) { bool res = false; @@ -1348,6 +1439,7 @@ struct input_ctx *mp_input_init(struct mpv_global *global, .wakeup_cb = wakeup_cb, .wakeup_ctx = wakeup_ctx, .active_sections = talloc_array(ictx, struct active_section, 0), + .touch_points = talloc_array(ictx, struct touch_point, 0), }; ictx->opts = ictx->opts_cache->opts; diff --git a/input/input.h b/input/input.h index 7f6707eeca..aafabdb9cb 100644 --- a/input/input.h +++ b/input/input.h @@ -102,6 +102,16 @@ void mp_input_set_mouse_pos_artificial(struct input_ctx *ictx, int x, int y); void mp_input_get_mouse_pos(struct input_ctx *ictx, int *x, int *y, int *hover); +// Add/Update/Remove a touch point (in window coordinates). +void mp_input_add_touch_point(struct input_ctx *ictx, int id, int x, int y); +void mp_input_update_touch_point(struct input_ctx *ictx, int id, int x, int y); +void mp_input_remove_touch_point(struct input_ctx *ictx, int id); + +// Get the positions of the touch points. xs and ys are arrays of at least +// count elements. ids is an array of at least count elements to uniquely +// identify touch points. Return the current number of touch points. +int mp_input_get_touch_pos(struct input_ctx *ictx, int count, int *xs, int *ys, int *ids); + // Return whether we want/accept mouse input. bool mp_input_mouse_enabled(struct input_ctx *ictx);