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:
1 parent
91bb2f2543
commit
28a4fb8e4e
2 files changed
+102
No files matched your search
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in new issue
Block a user