From: Katharine Chui <[email protected]>
Signed-off-by: Katharine Chui [email protected]
---
include/ui/sdl2.h | 9 +++++
ui/sdl2.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 106 insertions(+), 1 deletion(-)
diff --git a/include/ui/sdl2.h b/include/ui/sdl2.h
index dbe6e3d9739..d965554e185 100644
--- a/include/ui/sdl2.h
+++ b/include/ui/sdl2.h
@@ -26,6 +26,9 @@
# include "ui/egl-helpers.h"
#endif
+#include "input.h"
+#include "console.h"
+
struct sdl2_console {
DisplayGLCtx dgc;
DisplayChangeListener dcl;
@@ -52,6 +55,12 @@ struct sdl2_console {
bool y0_top;
bool scanout_mode;
#endif
+ struct {
+ bool pressing;
+ SDL_TouchID touch_id;
+ SDL_FingerID finger_id;
+ } fingers[INPUT_EVENT_SLOTS_MAX];
+ struct touch_slot touch_slots[INPUT_EVENT_SLOTS_MAX];
};
void sdl2_window_create(struct sdl2_console *scon);
diff --git a/ui/sdl2.c b/ui/sdl2.c
index 032dc14bc39..56ec0c5a97e 100644
--- a/ui/sdl2.c
+++ b/ui/sdl2.c
@@ -651,6 +651,92 @@ static void handle_windowevent(SDL_Event *ev)
}
}
+static void handle_touch(SDL_Event *ev){
+ SDL_TouchFingerEvent *finger_ev = (SDL_TouchFingerEvent *)ev;
+ struct sdl2_console *scon = get_scon_from_window(finger_ev->windowID);
+ Error *err = NULL;
+ int num_slot = -1;
+ int type = -1;
+ int width, height;
+ double x, y;
+ int i;
+
+ if (!scon) {
+ return;
+ }
+
+ switch (finger_ev->type) {
+ case SDL_FINGERDOWN:
+ for (i = 0; i < INPUT_EVENT_SLOTS_MAX; i++){
+ if (scon->fingers[i].pressing &&
+ scon->fingers[i].touch_id == finger_ev->touchId &&
+ scon->fingers[i].finger_id == finger_ev->fingerId){
+ // it is possible for sdl2 to send this twice, in that case
treat it as an update
+ num_slot = i;
+ type = INPUT_MULTI_TOUCH_TYPE_UPDATE;
+ break;
+ }
+ }
+ if (num_slot != -1){
+ break;
+ }
+ for (i = 0; i < INPUT_EVENT_SLOTS_MAX; i++){
+ if (!scon->fingers[i].pressing){
+ scon->fingers[i].pressing = true;
+ scon->fingers[i].touch_id = finger_ev->touchId;
+ scon->fingers[i].finger_id = finger_ev->fingerId;
+ num_slot = i;
+ type = INPUT_MULTI_TOUCH_TYPE_BEGIN;
+ break;
+ }
+ }
+ break;
+ case SDL_FINGERMOTION:
+ for (i = 0; i < INPUT_EVENT_SLOTS_MAX; i++){
+ if (scon->fingers[i].pressing &&
+ scon->fingers[i].touch_id == finger_ev->touchId &&
+ scon->fingers[i].finger_id == finger_ev->fingerId){
+ num_slot = i;
+ type = INPUT_MULTI_TOUCH_TYPE_UPDATE;
+ break;
+ }
+ }
+ break;
+ case SDL_FINGERUP:
+ for (i = 0; i < INPUT_EVENT_SLOTS_MAX; i++){
+ if (scon->fingers[i].pressing &&
+ scon->fingers[i].touch_id == finger_ev->touchId &&
+ scon->fingers[i].finger_id == finger_ev->fingerId){
+ scon->fingers[i].pressing = false;
+ num_slot = i;
+ type = INPUT_MULTI_TOUCH_TYPE_END;
+ break;
+ }
+ }
+ break;
+ }
+
+ if (num_slot == -1){
+ error_setg(&err, "Cannot handle more than %d fingers",
+ INPUT_EVENT_SLOTS_MAX);
+ warn_report_err(err);
+ return;
+ }
+
+ width = surface_width(scon->surface);
+ height = surface_height(scon->surface);
+ x = finger_ev->x * width;
+ y = finger_ev->y * height;
+
+ console_handle_touch_event(scon->dcl.con, scon->touch_slots,
+ num_slot, width, height, x, y,
+ type, &err);
+
+ if (err) {
+ warn_report_err(err);
+ }
+}
+
void sdl2_poll_events(struct sdl2_console *scon)
{
SDL_Event ev1, *ev = &ev1;
@@ -701,6 +787,12 @@ void sdl2_poll_events(struct sdl2_console *scon)
case SDL_WINDOWEVENT:
handle_windowevent(ev);
break;
+ case SDL_FINGERMOTION:
+ case SDL_FINGERDOWN:
+ case SDL_FINGERUP:
+ idle = 0;
+ handle_touch(ev);
+ break;
default:
break;
}
@@ -838,7 +930,7 @@ static void sdl2_display_early_init(DisplayOptions *o)
static void sdl2_display_init(DisplayState *ds, DisplayOptions *o)
{
uint8_t data = 0;
- int i;
+ int i, j;
SDL_SysWMinfo info;
SDL_Surface *icon = NULL;
char *dir;
@@ -920,6 +1012,10 @@ static void sdl2_display_init(DisplayState *ds,
DisplayOptions *o)
#endif
}
#endif
+
+ for (j = 0; j < INPUT_EVENT_SLOTS_MAX; j++) {
+ sdl2_console[i].touch_slots[j].tracking_id = -1;
+ }
}
#ifdef CONFIG_SDL_IMAGE
--
2.49.1