SDL: 3DS: Ensure that touchscreen events are associated with a window (8bc80)

From 8bc8047b6f6f86f0969471b9bf5bf43a60a7ac62 Mon Sep 17 00:00:00 2001
From: Cameron Cawley <[EMAIL REDACTED]>
Date: Sat, 13 Apr 2024 23:21:33 +0100
Subject: [PATCH] 3DS: Ensure that touchscreen events are associated with a
 window

---
 src/video/n3ds/SDL_n3dsevents.c |  2 +-
 src/video/n3ds/SDL_n3dstouch.c  | 14 +++++++++++---
 src/video/n3ds/SDL_n3dstouch.h  |  2 +-
 src/video/n3ds/SDL_n3dsvideo.c  | 25 ++++++++++++++++++++-----
 src/video/n3ds/SDL_n3dsvideo.h  |  6 ++++++
 5 files changed, 39 insertions(+), 10 deletions(-)

diff --git a/src/video/n3ds/SDL_n3dsevents.c b/src/video/n3ds/SDL_n3dsevents.c
index 8c963d9775376..cecf444849d7b 100644
--- a/src/video/n3ds/SDL_n3dsevents.c
+++ b/src/video/n3ds/SDL_n3dsevents.c
@@ -31,7 +31,7 @@
 void N3DS_PumpEvents(SDL_VideoDevice *_this)
 {
     hidScanInput();
-    N3DS_PollTouch();
+    N3DS_PollTouch(_this);
 
     if (!aptMainLoop()) {
         SDL_Event ev;
diff --git a/src/video/n3ds/SDL_n3dstouch.c b/src/video/n3ds/SDL_n3dstouch.c
index 9d3b94596ab95..4661d09429778 100644
--- a/src/video/n3ds/SDL_n3dstouch.c
+++ b/src/video/n3ds/SDL_n3dstouch.c
@@ -26,7 +26,9 @@
 #include <3ds.h>
 
 #include "../../events/SDL_touch_c.h"
+#include "../SDL_sysvideo.h"
 #include "SDL_n3dstouch.h"
+#include "SDL_n3dsvideo.h"
 
 #define N3DS_TOUCH_ID 1
 #define N3DS_TOUCH_FINGER 1
@@ -50,25 +52,31 @@ void N3DS_QuitTouch(void)
     SDL_DelTouch(N3DS_TOUCH_ID);
 }
 
-void N3DS_PollTouch(void)
+void N3DS_PollTouch(SDL_VideoDevice *_this)
 {
+    SDL_VideoData *driverdata = (SDL_VideoData *)_this->driverdata;
     touchPosition touch;
+    SDL_Window *window;
+    SDL_VideoDisplay *display;
     static SDL_bool was_pressed = SDL_FALSE;
     SDL_bool pressed;
     hidTouchRead(&touch);
     pressed = (touch.px != 0 || touch.py != 0);
 
+    display = SDL_GetVideoDisplay(driverdata->touch_display);
+    window = display ? display->fullscreen_window : NULL;
+
     if (pressed != was_pressed) {
         was_pressed = pressed;
         SDL_SendTouch(0, N3DS_TOUCH_ID, N3DS_TOUCH_FINGER,
-                      NULL,
+                      window,
                       pressed,
                       touch.px * TOUCHSCREEN_SCALE_X,
                       touch.py * TOUCHSCREEN_SCALE_Y,
                       pressed ? 1.0f : 0.0f);
     } else if (pressed) {
         SDL_SendTouchMotion(0, N3DS_TOUCH_ID, N3DS_TOUCH_FINGER,
-                            NULL,
+                            window,
                             touch.px * TOUCHSCREEN_SCALE_X,
                             touch.py * TOUCHSCREEN_SCALE_Y,
                             1.0f);
diff --git a/src/video/n3ds/SDL_n3dstouch.h b/src/video/n3ds/SDL_n3dstouch.h
index 495688cb6bbba..c5787cc0aa6b4 100644
--- a/src/video/n3ds/SDL_n3dstouch.h
+++ b/src/video/n3ds/SDL_n3dstouch.h
@@ -24,6 +24,6 @@
 
 void N3DS_InitTouch(void);
 void N3DS_QuitTouch(void);
-void N3DS_PollTouch(void);
+void N3DS_PollTouch(SDL_VideoDevice *_this);
 
 #endif /* SDL_n3dstouch_h_ */
diff --git a/src/video/n3ds/SDL_n3dsvideo.c b/src/video/n3ds/SDL_n3dsvideo.c
index 0cc788fa34519..3f75111fe9e18 100644
--- a/src/video/n3ds/SDL_n3dsvideo.c
+++ b/src/video/n3ds/SDL_n3dsvideo.c
@@ -54,11 +54,25 @@ static void N3DS_DeleteDevice(SDL_VideoDevice *device)
 
 static SDL_VideoDevice *N3DS_CreateDevice(void)
 {
-    SDL_VideoDevice *device = (SDL_VideoDevice *)SDL_calloc(1, sizeof(SDL_VideoDevice));
+    SDL_VideoDevice *device;
+    SDL_VideoData *phdata;
+
+    /* Initialize all variables that we clean on shutdown */
+    device = (SDL_VideoDevice *)SDL_calloc(1, sizeof(SDL_VideoDevice));
     if (!device) {
         return 0;
     }
 
+    /* Initialize internal data */
+    phdata = (SDL_VideoData *)SDL_calloc(1, sizeof(SDL_VideoData));
+    if (!phdata) {
+        SDL_OutOfMemory();
+        SDL_free(device);
+        return NULL;
+    }
+
+    device->driverdata = phdata;
+
     device->VideoInit = N3DS_VideoInit;
     device->VideoQuit = N3DS_VideoQuit;
 
@@ -86,11 +100,13 @@ VideoBootStrap N3DS_bootstrap = { N3DSVID_DRIVER_NAME, "N3DS Video Driver", N3DS
 
 static int N3DS_VideoInit(SDL_VideoDevice *_this)
 {
+    SDL_VideoData *driverdata = (SDL_VideoData *)_this->driverdata;
+
     gfxInit(GSP_RGBA8_OES, GSP_RGBA8_OES, false);
     hidInit();
 
-    AddN3DSDisplay(GFX_TOP);
-    AddN3DSDisplay(GFX_BOTTOM);
+    driverdata->top_display = AddN3DSDisplay(GFX_TOP);
+    driverdata->touch_display = AddN3DSDisplay(GFX_BOTTOM);
 
     N3DS_InitTouch();
     N3DS_SwkbInit();
@@ -121,8 +137,7 @@ static int AddN3DSDisplay(gfxScreen_t screen)
     display.desktop_mode = mode;
     display.driverdata = display_driver_data;
 
-    SDL_AddVideoDisplay(&display, SDL_FALSE);
-    return 0;
+    return SDL_AddVideoDisplay(&display, SDL_FALSE);
 }
 
 static void N3DS_VideoQuit(SDL_VideoDevice *_this)
diff --git a/src/video/n3ds/SDL_n3dsvideo.h b/src/video/n3ds/SDL_n3dsvideo.h
index b5c501568cbc7..5ed72aaed8600 100644
--- a/src/video/n3ds/SDL_n3dsvideo.h
+++ b/src/video/n3ds/SDL_n3dsvideo.h
@@ -27,6 +27,12 @@
 
 #include "../SDL_sysvideo.h"
 
+struct SDL_VideoData
+{
+    int top_display;
+    int touch_display;
+};
+
 struct SDL_WindowData
 {
     gfxScreen_t screen; /**< Keeps track of which N3DS screen is targeted */