wpevideosrc: Add touch event support

Dispatches a list of active touch events to the wpe view on each
received TOUCH_FRAME event. Touch inputs currently only move the cursor,
since wpe doesn't seem to support clicking/scrolling or zooming with
touch input.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1633>
This commit is contained in:
Vivienne Watermeier 2022-02-10 10:21:01 +01:00 committed by GStreamer Marge Bot
parent 9389754d1a
commit e6b187032b
3 changed files with 108 additions and 1 deletions

View file

@ -857,3 +857,10 @@ void WPEView::dispatchAxisEvent(struct wpe_input_axis_event& wpe_event)
wpe_view_backend_dispatch_axis_event(backend(), &wpe_event);
});
}
void WPEView::dispatchTouchEvent(struct wpe_input_touch_event& wpe_event)
{
s_view->dispatch([&]() {
wpe_view_backend_dispatch_touch_event(backend(), &wpe_event);
});
}

View file

@ -51,6 +51,7 @@ public:
void dispatchKeyboardEvent(struct wpe_input_keyboard_event&);
void dispatchPointerEvent(struct wpe_input_pointer_event&);
void dispatchAxisEvent(struct wpe_input_axis_event&);
void dispatchTouchEvent(struct wpe_input_touch_event&);
/* Used by WPEContextThread */
bool hasUri() const { return webkit.uri; }

View file

@ -129,6 +129,9 @@ struct _GstWpeVideoSrc
WPEView *view;
GArray *touch_points;
struct wpe_input_touch_event_raw *last_touch;
GMutex lock;
};
@ -550,6 +553,19 @@ gst_wpe_video_src_get_property (GObject * object, guint prop_id, GValue * value,
}
}
static void
_set_touch_point (struct wpe_input_touch_event_raw * point,
GstEvent * event, enum wpe_input_touch_event_type type, guint id, gdouble x,
gdouble y)
{
point->time = GST_TIME_AS_MSECONDS (GST_EVENT_TIMESTAMP (event));
point->type = type;
point->id = (int) id;
point->x = (int32_t) x;
point->y = (int32_t) y;
}
static gboolean
gst_wpe_video_src_event (GstBaseSrc * base_src, GstEvent * event)
{
@ -559,6 +575,7 @@ gst_wpe_video_src_event (GstBaseSrc * base_src, GstEvent * event)
if (src->view && GST_EVENT_TYPE (event) == GST_EVENT_NAVIGATION) {
const gchar *key;
gint button;
guint touch_id;
gdouble x, y, delta_x, delta_y;
GST_DEBUG_OBJECT (src, "Processing event %" GST_PTR_FORMAT, event);
@ -637,10 +654,90 @@ gst_wpe_video_src_event (GstBaseSrc * base_src, GstEvent * event)
ret = TRUE;
}
break;
case GST_NAVIGATION_EVENT_TOUCH_DOWN:
if (gst_navigation_event_parse_touch_event (event, &touch_id, &x, &y,
NULL)) {
struct wpe_input_touch_event_raw *point = g_new
(struct wpe_input_touch_event_raw, 1);
_set_touch_point (point, event, wpe_input_touch_event_type_down,
touch_id, x, y);
src->touch_points = g_array_append_vals(src->touch_points, point, 1);
src->last_touch = point;
ret = TRUE;
}
break;
case GST_NAVIGATION_EVENT_TOUCH_MOTION:
if (gst_navigation_event_parse_touch_event (event, &touch_id, &x, &y,
NULL)) {
struct wpe_input_touch_event_raw *touch_points;
guint idx;
touch_points = (struct wpe_input_touch_event_raw *)
src->touch_points->data;
for (idx = 0; idx < src->touch_points->len; idx++) {
if (touch_points[idx].id == (int32_t) touch_id) {
_set_touch_point (&touch_points[idx], event,
wpe_input_touch_event_type_motion, touch_id, x, y);
src->last_touch = &touch_points[idx];
break;
}
}
ret = TRUE;
}
break;
case GST_NAVIGATION_EVENT_TOUCH_UP:
if (gst_navigation_event_parse_touch_up_event (event, &touch_id, &x,
&y)) {
struct wpe_input_touch_event_raw *touch_points;
guint idx;
touch_points = (struct wpe_input_touch_event_raw *)
src->touch_points->data;
for (idx = 0; idx < src->touch_points->len; idx++) {
if (touch_points[idx].id == (int32_t) touch_id) {
_set_touch_point (&touch_points[idx], event,
wpe_input_touch_event_type_up, touch_id, x, y);
src->last_touch = &touch_points[idx];
break;
}
}
ret = TRUE;
}
break;
case GST_NAVIGATION_EVENT_TOUCH_FRAME:
if (src->last_touch && src->touch_points->len > 0)
{
struct wpe_input_touch_event_raw *touch_points;
struct wpe_input_touch_event wpe_event;
guint idx;
wpe_event.touchpoints =
(struct wpe_input_touch_event_raw *) src->touch_points->data;
wpe_event.touchpoints_length = src->touch_points->len;
wpe_event.type = src->last_touch->type;
wpe_event.id = src->last_touch->id;
wpe_event.time = src->last_touch->time;
src->view->dispatchTouchEvent (wpe_event);
touch_points = (struct wpe_input_touch_event_raw *)
src->touch_points->data;
for (idx = 0; idx < src->touch_points->len; idx++) {
if (touch_points[idx].type == wpe_input_touch_event_type_up ||
touch_points[idx].type == wpe_input_touch_event_type_null) {
g_array_remove_index_fast(src->touch_points, idx);
idx--;
}
}
src->last_touch = NULL;
ret = TRUE;
}
break;
case GST_NAVIGATION_EVENT_TOUCH_CANCEL:
break;
default:
break;
}
/* FIXME: No touch events handling support in GstNavigation */
}
if (!ret) {
@ -658,6 +755,7 @@ gst_wpe_video_src_init (GstWpeVideoSrc * src)
gst_base_src_set_live (GST_BASE_SRC_CAST (src), TRUE);
src->touch_points = g_array_sized_new (FALSE, FALSE, sizeof (void *), 10);
g_mutex_init (&src->lock);
}
@ -668,6 +766,7 @@ gst_wpe_video_src_finalize (GObject * object)
g_free (src->location);
g_clear_pointer (&src->bytes, g_bytes_unref);
g_array_unref (src->touch_points);
g_mutex_clear (&src->lock);
G_OBJECT_CLASS (parent_class)->finalize (object);