Message ID | 20230613104535.356842-2-belmouss@redhat.com |
---|---|
State | New |
Headers | show |
Series | [1/2] ui/touch: Move event handling to a common helper | expand |
Hi Bilal On Tue, Jun 13, 2023 at 1:39 PM 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> > --- > ui/dbus-console.c | 56 +++++++++++++++++++++++++++++++++++++++++++- > ui/dbus-display1.xml | 38 ++++++++++++++++++++++++++++-- > ui/trace-events | 1 + > 3 files changed, 92 insertions(+), 3 deletions(-) > > diff --git a/ui/dbus-console.c b/ui/dbus-console.c > index f77bc49..c744dd3 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,45 @@ 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) > +{ > + int width, height; > + gboolean ret; > + 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); > + > + ret = console_handle_touch_event(ddc->dcl.con, touch_slots, > + num_slot, width, height, > + x, y, kind); > + if (!ret) { > + g_dbus_method_invocation_return_error( > > + invocation, DBUS_DISPLAY_ERROR, > + DBUS_DISPLAY_ERROR_INVALID, > + "Unexpected touch slot number"); > With Error* usage, we won't have to "guess" the 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 +482,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 +537,18 @@ 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); > + 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..ef30ab3 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,39 @@ > <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> > We should expose a max-slots property. + </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..c744dd3 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,45 @@ 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) +{ + int width, height; + gboolean ret; + 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); + + ret = console_handle_touch_event(ddc->dcl.con, touch_slots, + num_slot, width, height, + x, y, kind); + if (!ret) { + g_dbus_method_invocation_return_error( + invocation, DBUS_DISPLAY_ERROR, + DBUS_DISPLAY_ERROR_INVALID, + "Unexpected touch slot number"); + } 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 +482,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 +537,18 @@ 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); + 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..ef30ab3 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,39 @@ <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> + </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 | 56 +++++++++++++++++++++++++++++++++++++++++++- ui/dbus-display1.xml | 38 ++++++++++++++++++++++++++++-- ui/trace-events | 1 + 3 files changed, 92 insertions(+), 3 deletions(-)