input: add multitouch support functions

The goal of multitouch support is to interpret as little as possible:
mpv just stores the touch point information and makes the position
available for query. Does not participate in the deprecated input section
system.

The API is modeled after the common part of the touch input APIs of
Win32, X11, and Wayland, to make sure the platform-specific implementations
are as simple as possible.
This commit is contained in:
nanahi authored and Kacper Michajłow committed 2024-05-03 16:14:03 +02:00
1 parent 91bb2f2543
commit 28a4fb8e4e
2 files changed
+102

No files matched your search

+92
View File
@@ -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"), "<internal>");
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;
+10
View File
@@ -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);