Message ID | 20230615090635.160734-2-belmouss@redhat.com |
---|---|
State | New |
Headers | show |
Series | [v2,1/2] ui/touch: Move event handling to a common helper | expand |
On Thu, Jun 15, 2023 at 11:07 AM Bilal Elmoussaoui <belmouss@redhat.com> wrote: > So that clients making use of the DBus backend could > send touch events through the new org.qemu.Display1.Touch > interface > > Signed-off-by: Bilal Elmoussaoui <belmouss@redhat.com> > Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> > --- > ui/dbus-console.c | 59 +++++++++++++++++++++++++++++++++++++++++++- > ui/dbus-display1.xml | 45 +++++++++++++++++++++++++++++++-- > ui/trace-events | 1 + > 3 files changed, 102 insertions(+), 3 deletions(-) > > diff --git a/ui/dbus-console.c b/ui/dbus-console.c > index f77bc49..7722f39 100644 > --- a/ui/dbus-console.c > +++ b/ui/dbus-console.c > @@ -32,6 +32,8 @@ > > #include "dbus.h" > > +static struct touch_slot touch_slots[INPUT_EVENT_SLOTS_MAX]; > + > struct _DBusDisplayConsole { > GDBusObjectSkeleton parent_instance; > DisplayChangeListener dcl; > @@ -44,6 +46,7 @@ struct _DBusDisplayConsole { > QKbdState *kbd; > > QemuDBusDisplay1Mouse *iface_mouse; > + QemuDBusDisplay1Touch *iface_touch; > gboolean last_set; > guint last_x; > guint last_y; > @@ -345,6 +348,46 @@ dbus_mouse_rel_motion(DBusDisplayConsole *ddc, > return DBUS_METHOD_INVOCATION_HANDLED; > } > > +static gboolean > +dbus_touch_send_event(DBusDisplayConsole *ddc, > + GDBusMethodInvocation *invocation, > + guint kind, uint64_t num_slot, > + double x, double y) > +{ > + Error *error = NULL; > + int width, height; > + trace_dbus_touch_send_event(kind, num_slot, x, y); > + > + if (kind != INPUT_MULTI_TOUCH_TYPE_BEGIN && > + kind != INPUT_MULTI_TOUCH_TYPE_UPDATE && > + kind != INPUT_MULTI_TOUCH_TYPE_CANCEL && > + kind != INPUT_MULTI_TOUCH_TYPE_END) > + { > + g_dbus_method_invocation_return_error( > + invocation, DBUS_DISPLAY_ERROR, > + DBUS_DISPLAY_ERROR_INVALID, > + "Invalid touch event kind"); > + return DBUS_METHOD_INVOCATION_HANDLED; > + } > + width = qemu_console_get_width(ddc->dcl.con, 0); > + height = qemu_console_get_height(ddc->dcl.con, 0); > + > + console_handle_touch_event(ddc->dcl.con, touch_slots, > + num_slot, width, height, > + x, y, kind, &error); > + if (error != NULL) { > + g_dbus_method_invocation_return_error( > + invocation, DBUS_DISPLAY_ERROR, > + DBUS_DISPLAY_ERROR_INVALID, > + error_get_pretty(error), NULL); > + error_free(error); > + } else { > + qemu_dbus_display1_touch_complete_send_event(ddc->iface_touch, > + invocation); > + } > + return DBUS_METHOD_INVOCATION_HANDLED; > +} > + > static gboolean > dbus_mouse_set_pos(DBusDisplayConsole *ddc, > GDBusMethodInvocation *invocation, > @@ -440,7 +483,7 @@ dbus_display_console_new(DBusDisplay *display, > QemuConsole *con) > g_autofree char *label = NULL; > char device_addr[256] = ""; > DBusDisplayConsole *ddc; > - int idx; > + int idx, i; > > assert(display); > assert(con); > @@ -495,6 +538,20 @@ dbus_display_console_new(DBusDisplay *display, > QemuConsole *con) > g_dbus_object_skeleton_add_interface(G_DBUS_OBJECT_SKELETON(ddc), > G_DBUS_INTERFACE_SKELETON(ddc->iface_mouse)); > > + ddc->iface_touch = qemu_dbus_display1_touch_skeleton_new(); > + g_object_connect(ddc->iface_touch, > + "swapped-signal::handle-send-event", dbus_touch_send_event, ddc, > + NULL); > + qemu_dbus_display1_touch_set_max_slots(ddc->iface_touch, > + INPUT_EVENT_SLOTS_MAX); > + g_dbus_object_skeleton_add_interface(G_DBUS_OBJECT_SKELETON(ddc), > + G_DBUS_INTERFACE_SKELETON(ddc->iface_touch)); > + > + for (i = 0; i < INPUT_EVENT_SLOTS_MAX; i++) { > + struct touch_slot *slot = &touch_slots[i]; > + slot->tracking_id = -1; > + } > + > register_displaychangelistener(&ddc->dcl); > ddc->mouse_mode_notifier.notify = dbus_mouse_mode_change; > qemu_add_mouse_mode_change_notifier(&ddc->mouse_mode_notifier); > diff --git a/ui/dbus-display1.xml b/ui/dbus-display1.xml > index c3b2293..a98cfd1 100644 > --- a/ui/dbus-display1.xml > +++ b/ui/dbus-display1.xml > @@ -39,8 +39,9 @@ > "Text" (see :dbus:prop:`Type` and other properties). > > Interactions with a console may be done with > - :dbus:iface:`org.qemu.Display1.Keyboard` and > - :dbus:iface:`org.qemu.Display1.Mouse` interfaces when available. > + :dbus:iface:`org.qemu.Display1.Keyboard`, > + :dbus:iface:`org.qemu.Display1.Mouse` and > + :dbus:iface:`org.qemu.Display1.Touch` interfaces when available. > --> > <interface name="org.qemu.Display1.Console"> > <!-- > @@ -236,6 +237,46 @@ > <property name="IsAbsolute" type="b" access="read"/> > </interface> > > + <!-- > + org.qemu.Display1.Touch: > + > + This interface in implemented on ``/org/qemu/Display1/Console_$id`` > (see > + :dbus:iface:`~org.qemu.Display1.Console` documentation). > + > + .. _dbus-kind-values: > + > + **Kind values**:: > + > + Begin = 0 > + Update = 1 > + End = 2 > + Cancel = 3 > + --> > + <interface name="org.qemu.Display1.Touch"> > + <!-- > + SendEvent: > + @kind: The touch event kind > + @num_slot: The slot number. > + @x: The x coordinates. > + @y: The y coordinates. > + > + Send a touch gesture event. > + --> > + <method name="SendEvent"> > + <arg type="u" name="kind" direction="in"/> > + <arg type="t" name="num_slot" direction="in"/> > + <arg type="d" name="x" direction="in"/> > + <arg type="d" name="y" direction="in"/> > + </method> > + > + <!-- > + MaxSlots: > + > + The maximum number of slots. > + --> > + <property name="MaxSlots" type="i" access="read"/> > + </interface> > + > <!-- > org.qemu.Display1.Listener: > > diff --git a/ui/trace-events b/ui/trace-events > index 6747361..138a09c 100644 > --- a/ui/trace-events > +++ b/ui/trace-events > @@ -154,6 +154,7 @@ dbus_mouse_press(unsigned int button) "button %u" > dbus_mouse_release(unsigned int button) "button %u" > dbus_mouse_set_pos(unsigned int x, unsigned int y) "x=%u, y=%u" > dbus_mouse_rel_motion(int dx, int dy) "dx=%d, dy=%d" > +dbus_touch_send_event(unsigned int kind, uint32_t num_slot, uint32_t x, > uint32_t y) "kind=%u, num_slot=%u, x=%d, y=%d" > dbus_update(int x, int y, int w, int h) "x=%d, y=%d, w=%d, h=%d" > dbus_clipboard_grab_failed(void) "" > dbus_clipboard_register(const char *bus_name) "peer %s" > -- > 2.40.1 > > >
diff --git a/ui/dbus-console.c b/ui/dbus-console.c index f77bc49..7722f39 100644 --- a/ui/dbus-console.c +++ b/ui/dbus-console.c @@ -32,6 +32,8 @@ #include "dbus.h" +static struct touch_slot touch_slots[INPUT_EVENT_SLOTS_MAX]; + struct _DBusDisplayConsole { GDBusObjectSkeleton parent_instance; DisplayChangeListener dcl; @@ -44,6 +46,7 @@ struct _DBusDisplayConsole { QKbdState *kbd; QemuDBusDisplay1Mouse *iface_mouse; + QemuDBusDisplay1Touch *iface_touch; gboolean last_set; guint last_x; guint last_y; @@ -345,6 +348,46 @@ dbus_mouse_rel_motion(DBusDisplayConsole *ddc, return DBUS_METHOD_INVOCATION_HANDLED; } +static gboolean +dbus_touch_send_event(DBusDisplayConsole *ddc, + GDBusMethodInvocation *invocation, + guint kind, uint64_t num_slot, + double x, double y) +{ + Error *error = NULL; + int width, height; + trace_dbus_touch_send_event(kind, num_slot, x, y); + + if (kind != INPUT_MULTI_TOUCH_TYPE_BEGIN && + kind != INPUT_MULTI_TOUCH_TYPE_UPDATE && + kind != INPUT_MULTI_TOUCH_TYPE_CANCEL && + kind != INPUT_MULTI_TOUCH_TYPE_END) + { + g_dbus_method_invocation_return_error( + invocation, DBUS_DISPLAY_ERROR, + DBUS_DISPLAY_ERROR_INVALID, + "Invalid touch event kind"); + return DBUS_METHOD_INVOCATION_HANDLED; + } + width = qemu_console_get_width(ddc->dcl.con, 0); + height = qemu_console_get_height(ddc->dcl.con, 0); + + console_handle_touch_event(ddc->dcl.con, touch_slots, + num_slot, width, height, + x, y, kind, &error); + if (error != NULL) { + g_dbus_method_invocation_return_error( + invocation, DBUS_DISPLAY_ERROR, + DBUS_DISPLAY_ERROR_INVALID, + error_get_pretty(error), NULL); + error_free(error); + } else { + qemu_dbus_display1_touch_complete_send_event(ddc->iface_touch, + invocation); + } + return DBUS_METHOD_INVOCATION_HANDLED; +} + static gboolean dbus_mouse_set_pos(DBusDisplayConsole *ddc, GDBusMethodInvocation *invocation, @@ -440,7 +483,7 @@ dbus_display_console_new(DBusDisplay *display, QemuConsole *con) g_autofree char *label = NULL; char device_addr[256] = ""; DBusDisplayConsole *ddc; - int idx; + int idx, i; assert(display); assert(con); @@ -495,6 +538,20 @@ dbus_display_console_new(DBusDisplay *display, QemuConsole *con) g_dbus_object_skeleton_add_interface(G_DBUS_OBJECT_SKELETON(ddc), G_DBUS_INTERFACE_SKELETON(ddc->iface_mouse)); + ddc->iface_touch = qemu_dbus_display1_touch_skeleton_new(); + g_object_connect(ddc->iface_touch, + "swapped-signal::handle-send-event", dbus_touch_send_event, ddc, + NULL); + qemu_dbus_display1_touch_set_max_slots(ddc->iface_touch, + INPUT_EVENT_SLOTS_MAX); + g_dbus_object_skeleton_add_interface(G_DBUS_OBJECT_SKELETON(ddc), + G_DBUS_INTERFACE_SKELETON(ddc->iface_touch)); + + for (i = 0; i < INPUT_EVENT_SLOTS_MAX; i++) { + struct touch_slot *slot = &touch_slots[i]; + slot->tracking_id = -1; + } + register_displaychangelistener(&ddc->dcl); ddc->mouse_mode_notifier.notify = dbus_mouse_mode_change; qemu_add_mouse_mode_change_notifier(&ddc->mouse_mode_notifier); diff --git a/ui/dbus-display1.xml b/ui/dbus-display1.xml index c3b2293..a98cfd1 100644 --- a/ui/dbus-display1.xml +++ b/ui/dbus-display1.xml @@ -39,8 +39,9 @@ "Text" (see :dbus:prop:`Type` and other properties). Interactions with a console may be done with - :dbus:iface:`org.qemu.Display1.Keyboard` and - :dbus:iface:`org.qemu.Display1.Mouse` interfaces when available. + :dbus:iface:`org.qemu.Display1.Keyboard`, + :dbus:iface:`org.qemu.Display1.Mouse` and + :dbus:iface:`org.qemu.Display1.Touch` interfaces when available. --> <interface name="org.qemu.Display1.Console"> <!-- @@ -236,6 +237,46 @@ <property name="IsAbsolute" type="b" access="read"/> </interface> + <!-- + org.qemu.Display1.Touch: + + This interface in implemented on ``/org/qemu/Display1/Console_$id`` (see + :dbus:iface:`~org.qemu.Display1.Console` documentation). + + .. _dbus-kind-values: + + **Kind values**:: + + Begin = 0 + Update = 1 + End = 2 + Cancel = 3 + --> + <interface name="org.qemu.Display1.Touch"> + <!-- + SendEvent: + @kind: The touch event kind + @num_slot: The slot number. + @x: The x coordinates. + @y: The y coordinates. + + Send a touch gesture event. + --> + <method name="SendEvent"> + <arg type="u" name="kind" direction="in"/> + <arg type="t" name="num_slot" direction="in"/> + <arg type="d" name="x" direction="in"/> + <arg type="d" name="y" direction="in"/> + </method> + + <!-- + MaxSlots: + + The maximum number of slots. + --> + <property name="MaxSlots" type="i" access="read"/> + </interface> + <!-- org.qemu.Display1.Listener: diff --git a/ui/trace-events b/ui/trace-events index 6747361..138a09c 100644 --- a/ui/trace-events +++ b/ui/trace-events @@ -154,6 +154,7 @@ dbus_mouse_press(unsigned int button) "button %u" dbus_mouse_release(unsigned int button) "button %u" dbus_mouse_set_pos(unsigned int x, unsigned int y) "x=%u, y=%u" dbus_mouse_rel_motion(int dx, int dy) "dx=%d, dy=%d" +dbus_touch_send_event(unsigned int kind, uint32_t num_slot, uint32_t x, uint32_t y) "kind=%u, num_slot=%u, x=%d, y=%d" dbus_update(int x, int y, int w, int h) "x=%d, y=%d, w=%d, h=%d" dbus_clipboard_grab_failed(void) "" dbus_clipboard_register(const char *bus_name) "peer %s"
So that clients making use of the DBus backend could send touch events through the new org.qemu.Display1.Touch interface Signed-off-by: Bilal Elmoussaoui <belmouss@redhat.com> --- ui/dbus-console.c | 59 +++++++++++++++++++++++++++++++++++++++++++- ui/dbus-display1.xml | 45 +++++++++++++++++++++++++++++++-- ui/trace-events | 1 + 3 files changed, 102 insertions(+), 3 deletions(-)