pen: Fix enabling touch emulation while a pen is connected
diff --git a/src/events/SDL_mouse.c b/src/events/SDL_mouse.c
index e389e47..5dd25d7 100644
--- a/src/events/SDL_mouse.c
+++ b/src/events/SDL_mouse.c
@@ -188,18 +188,6 @@
     mouse->pen_mouse_events = SDL_GetStringBoolean(hint, true);
 }
 
-static void SDLCALL SDL_PenTouchEventsChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
-{
-    SDL_Mouse *mouse = (SDL_Mouse *)userdata;
-
-    mouse->pen_touch_events = SDL_GetStringBoolean(hint, true);
-
-    if (!mouse->pen_touch_events && mouse->added_pen_touch_device) {
-        SDL_DelTouch(SDL_PEN_TOUCHID);
-        mouse->added_pen_touch_device = false;
-    }
-}
-
 static void SDLCALL SDL_MouseAutoCaptureChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
 {
     SDL_Mouse *mouse = (SDL_Mouse *)userdata;
@@ -282,9 +270,6 @@
     SDL_AddHintCallback(SDL_HINT_PEN_MOUSE_EVENTS,
                         SDL_PenMouseEventsChanged, mouse);
 
-    SDL_AddHintCallback(SDL_HINT_PEN_TOUCH_EVENTS,
-                        SDL_PenTouchEventsChanged, mouse);
-
     SDL_AddHintCallback(SDL_HINT_MOUSE_AUTO_CAPTURE,
                         SDL_MouseAutoCaptureChanged, mouse);
 
@@ -1149,9 +1134,6 @@
     SDL_RemoveHintCallback(SDL_HINT_PEN_MOUSE_EVENTS,
                         SDL_PenMouseEventsChanged, mouse);
 
-    SDL_RemoveHintCallback(SDL_HINT_PEN_TOUCH_EVENTS,
-                        SDL_PenTouchEventsChanged, mouse);
-
     SDL_RemoveHintCallback(SDL_HINT_MOUSE_AUTO_CAPTURE,
                         SDL_MouseAutoCaptureChanged, mouse);
 
diff --git a/src/events/SDL_pen.c b/src/events/SDL_pen.c
index 83543a6..d70542b 100644
--- a/src/events/SDL_pen.c
+++ b/src/events/SDL_pen.c
@@ -93,6 +93,33 @@
     return result;
 }
 
+static void UpdateTouchEmulationDevicePresence(void)
+{
+    SDL_Mouse *mouse = SDL_GetMouse();
+
+    SDL_LockRWLockForReading(pen_device_rwlock);
+    bool has_pen = (pen_device_count != 0);
+    SDL_UnlockRWLock(pen_device_rwlock);
+
+    if (!mouse->pen_touch_events || !has_pen) {
+        if (mouse->added_pen_touch_device) {
+            SDL_DelTouch(SDL_PEN_TOUCHID);
+            mouse->added_pen_touch_device = false;
+        }
+    } else if (!mouse->added_pen_touch_device) {
+        SDL_AddTouch(SDL_PEN_TOUCHID, SDL_TOUCH_DEVICE_DIRECT, "pen_input");
+        mouse->added_pen_touch_device = true;
+    }
+}
+
+static void SDLCALL SDL_PenTouchEventsChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
+{
+    SDL_Mouse *mouse = SDL_GetMouse();
+
+    mouse->pen_touch_events = SDL_GetStringBoolean(hint, true);
+
+    UpdateTouchEmulationDevicePresence();
+}
 
 
 // public API ...
@@ -106,11 +133,18 @@
     if (!pen_device_rwlock) {
         return false;
     }
+
+    SDL_AddHintCallback(SDL_HINT_PEN_TOUCH_EVENTS,
+                        SDL_PenTouchEventsChanged, NULL);
+
     return true;
 }
 
 void SDL_QuitPen(void)
 {
+    SDL_RemoveHintCallback(SDL_HINT_PEN_TOUCH_EVENTS,
+                           SDL_PenTouchEventsChanged, NULL);
+
     SDL_RemoveAllPenDevices(NULL, NULL);
     SDL_DestroyRWLock(pen_device_rwlock);
     pen_device_rwlock = NULL;
@@ -228,7 +262,6 @@
 
     SDL_LockRWLockForWriting(pen_device_rwlock);
 
-    bool first_device = false;
     SDL_Pen *pen = NULL;
     void *ptr = SDL_realloc(pen_devices, (pen_device_count + 1) * sizeof (*pen));
     if (ptr) {
@@ -237,8 +270,6 @@
         pen = &pen_devices[pen_device_count];
         pen_device_count++;
 
-        first_device = (pen_device_count == 1);
-
         SDL_zerop(pen);
         pen->instance_id = result;
         pen->name = namecpy;
@@ -254,13 +285,7 @@
         SDL_free(namecpy);
     }
 
-    if (first_device) {
-        SDL_Mouse *mouse = SDL_GetMouse();
-        if (mouse->pen_touch_events && !mouse->added_pen_touch_device) {
-            SDL_AddTouch(SDL_PEN_TOUCHID, SDL_TOUCH_DEVICE_DIRECT, "pen_input");
-            mouse->added_pen_touch_device = true;
-        }
-    }
+    UpdateTouchEmulationDevicePresence();
 
     if (result && in_proximity) {
         SDL_SendPenProximity(timestamp, result, window, true, true);
@@ -278,7 +303,6 @@
     SDL_SendPenProximity(timestamp, instance_id, window, false, true);  // bye bye
 
     SDL_LockRWLockForWriting(pen_device_rwlock);
-    bool last_device = false;
     SDL_Pen *pen = FindPenByInstanceId(instance_id);
     if (pen) {
         SDL_free(pen->name);
@@ -300,18 +324,11 @@
         } else {
             SDL_free(pen_devices);
             pen_devices = NULL;
-            last_device = true;
         }
     }
     SDL_UnlockRWLock(pen_device_rwlock);
 
-    if (last_device) {
-        SDL_Mouse *mouse = SDL_GetMouse();
-        if (mouse->added_pen_touch_device) {
-            SDL_DelTouch(SDL_PEN_TOUCHID);
-            mouse->added_pen_touch_device = false;
-        }
-    }
+    UpdateTouchEmulationDevicePresence();
 }
 
 // This presumably is happening during video quit, so we don't send PROXIMITY_OUT events here.