ui/touch: Move event handling to a common helper

To share code between the GTK and DBus UI bakcends
see the next commit for details

Signed-off-by: Bilal Elmoussaoui <belmouss@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20230619095337.9899-2-belmouss@redhat.com>
This commit is contained in:
Bilal Elmoussaoui 2023-06-19 11:53:36 +02:00 committed by Marc-André Lureau
parent 1e0c544673
commit b659678598
3 changed files with 85 additions and 56 deletions

View File

@ -5,6 +5,7 @@
#include "qom/object.h" #include "qom/object.h"
#include "qemu/notify.h" #include "qemu/notify.h"
#include "qapi/qapi-types-ui.h" #include "qapi/qapi-types-ui.h"
#include "ui/input.h"
#ifdef CONFIG_OPENGL #ifdef CONFIG_OPENGL
# include <epoxy/gl.h> # include <epoxy/gl.h>
@ -95,6 +96,20 @@ bool kbd_put_qcode_console(QemuConsole *s, int qcode, bool ctrl);
void kbd_put_string_console(QemuConsole *s, const char *str, int len); void kbd_put_string_console(QemuConsole *s, const char *str, int len);
void kbd_put_keysym(int keysym); void kbd_put_keysym(int keysym);
/* Touch devices */
typedef struct touch_slot {
int x;
int y;
int tracking_id;
} touch_slot;
void console_handle_touch_event(QemuConsole *con,
struct touch_slot touch_slots[INPUT_EVENT_SLOTS_MAX],
uint64_t num_slot,
int width, int height,
double x, double y,
InputMultiTouchType type,
Error **errp);
/* consoles */ /* consoles */
#define TYPE_QEMU_CONSOLE "qemu-console" #define TYPE_QEMU_CONSOLE "qemu-console"

View File

@ -1635,6 +1635,71 @@ static bool console_compatible_with(QemuConsole *con,
return true; return true;
} }
void console_handle_touch_event(QemuConsole *con,
struct touch_slot touch_slots[INPUT_EVENT_SLOTS_MAX],
uint64_t num_slot,
int width, int height,
double x, double y,
InputMultiTouchType type,
Error **errp)
{
struct touch_slot *slot;
bool needs_sync = false;
int update;
int i;
if (num_slot >= INPUT_EVENT_SLOTS_MAX) {
error_setg(errp,
"Unexpected touch slot number: % " PRId64" >= %d",
num_slot, INPUT_EVENT_SLOTS_MAX);
return;
}
slot = &touch_slots[num_slot];
slot->x = x;
slot->y = y;
if (type == INPUT_MULTI_TOUCH_TYPE_BEGIN) {
slot->tracking_id = num_slot;
}
for (i = 0; i < INPUT_EVENT_SLOTS_MAX; ++i) {
if (i == num_slot) {
update = type;
} else {
update = INPUT_MULTI_TOUCH_TYPE_UPDATE;
}
slot = &touch_slots[i];
if (slot->tracking_id == -1) {
continue;
}
if (update == INPUT_MULTI_TOUCH_TYPE_END) {
slot->tracking_id = -1;
qemu_input_queue_mtt(con, update, i, slot->tracking_id);
needs_sync = true;
} else {
qemu_input_queue_mtt(con, update, i, slot->tracking_id);
qemu_input_queue_btn(con, INPUT_BUTTON_TOUCH, true);
qemu_input_queue_mtt_abs(con,
INPUT_AXIS_X, (int) slot->x,
0, width,
i, slot->tracking_id);
qemu_input_queue_mtt_abs(con,
INPUT_AXIS_Y, (int) slot->y,
0, height,
i, slot->tracking_id);
needs_sync = true;
}
}
if (needs_sync) {
qemu_input_event_sync();
}
}
void qemu_console_set_display_gl_ctx(QemuConsole *con, DisplayGLCtx *gl) void qemu_console_set_display_gl_ctx(QemuConsole *con, DisplayGLCtx *gl)
{ {
/* display has opengl support */ /* display has opengl support */

View File

@ -130,11 +130,6 @@ typedef struct VCChardev VCChardev;
DECLARE_INSTANCE_CHECKER(VCChardev, VC_CHARDEV, DECLARE_INSTANCE_CHECKER(VCChardev, VC_CHARDEV,
TYPE_CHARDEV_VC) TYPE_CHARDEV_VC)
struct touch_slot {
int x;
int y;
int tracking_id;
};
static struct touch_slot touch_slots[INPUT_EVENT_SLOTS_MAX]; static struct touch_slot touch_slots[INPUT_EVENT_SLOTS_MAX];
bool gtk_use_gl_area; bool gtk_use_gl_area;
@ -1068,27 +1063,12 @@ static gboolean gd_touch_event(GtkWidget *widget, GdkEventTouch *touch,
void *opaque) void *opaque)
{ {
VirtualConsole *vc = opaque; VirtualConsole *vc = opaque;
struct touch_slot *slot;
uint64_t num_slot = GPOINTER_TO_UINT(touch->sequence); uint64_t num_slot = GPOINTER_TO_UINT(touch->sequence);
bool needs_sync = false;
int update;
int type = -1; int type = -1;
int i;
if (num_slot >= INPUT_EVENT_SLOTS_MAX) {
warn_report("gtk: unexpected touch slot number: % " PRId64" >= %d\n",
num_slot, INPUT_EVENT_SLOTS_MAX);
return FALSE;
}
slot = &touch_slots[num_slot];
slot->x = touch->x;
slot->y = touch->y;
switch (touch->type) { switch (touch->type) {
case GDK_TOUCH_BEGIN: case GDK_TOUCH_BEGIN:
type = INPUT_MULTI_TOUCH_TYPE_BEGIN; type = INPUT_MULTI_TOUCH_TYPE_BEGIN;
slot->tracking_id = num_slot;
break; break;
case GDK_TOUCH_UPDATE: case GDK_TOUCH_UPDATE:
type = INPUT_MULTI_TOUCH_TYPE_UPDATE; type = INPUT_MULTI_TOUCH_TYPE_UPDATE;
@ -1099,44 +1079,13 @@ static gboolean gd_touch_event(GtkWidget *widget, GdkEventTouch *touch,
break; break;
default: default:
warn_report("gtk: unexpected touch event type\n"); warn_report("gtk: unexpected touch event type\n");
return FALSE;
} }
for (i = 0; i < INPUT_EVENT_SLOTS_MAX; ++i) { console_handle_touch_event(vc->gfx.dcl.con, touch_slots,
if (i == num_slot) { num_slot, surface_width(vc->gfx.ds),
update = type; surface_height(vc->gfx.ds), touch->x,
} else { touch->y, type, &error_warn);
update = INPUT_MULTI_TOUCH_TYPE_UPDATE;
}
slot = &touch_slots[i];
if (slot->tracking_id == -1) {
continue;
}
if (update == INPUT_MULTI_TOUCH_TYPE_END) {
slot->tracking_id = -1;
qemu_input_queue_mtt(vc->gfx.dcl.con, update, i, slot->tracking_id);
needs_sync = true;
} else {
qemu_input_queue_mtt(vc->gfx.dcl.con, update, i, slot->tracking_id);
qemu_input_queue_btn(vc->gfx.dcl.con, INPUT_BUTTON_TOUCH, true);
qemu_input_queue_mtt_abs(vc->gfx.dcl.con,
INPUT_AXIS_X, (int) slot->x,
0, surface_width(vc->gfx.ds),
i, slot->tracking_id);
qemu_input_queue_mtt_abs(vc->gfx.dcl.con,
INPUT_AXIS_Y, (int) slot->y,
0, surface_height(vc->gfx.ds),
i, slot->tracking_id);
needs_sync = true;
}
}
if (needs_sync) {
qemu_input_event_sync();
}
return TRUE; return TRUE;
} }