SDL: X11 pen detection: fix misclassification due to improper init

From 1b284cd4153d967f17cad9535cf00c153dd62570 Mon Sep 17 00:00:00 2001
From: Christoph Reichenbach <[EMAIL REDACTED]>
Date: Sun, 26 Nov 2023 08:47:32 +0000
Subject: [PATCH] X11 pen detection: fix misclassification due to improper init

xinput2_device_is_pen() was testing against default-zero values
in the X11 Atom cache on at least the first round of
detections, leading to imprecise detection.

The patch fixes two aspects of initialisation:

1. Ensure that the selector cache is always initialised in
xinput2_device_is_pen().

2. Ensure that all X11 Atoms used in SDL_x11pen.c are instantiated if
missing. This ensures that they are never None and avoids potential
failures to detect hot-plugged tablet devices.

Acknowledgements: @tilman3 for narrowing down the issue and an
initial fix
---
 src/video/x11/SDL_x11pen.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/src/video/x11/SDL_x11pen.c b/src/video/x11/SDL_x11pen.c
index 94b4a5c1b94c..6d0dbca4ec07 100644
--- a/src/video/x11/SDL_x11pen.c
+++ b/src/video/x11/SDL_x11pen.c
@@ -114,9 +114,9 @@ static void pen_atoms_ensure_initialized(SDL_VideoDevice *_this)
     pen_atoms.device_product_id = X11_XInternAtom(data->display, "Device Product ID", False);
     pen_atoms.wacom_serial_ids = X11_XInternAtom(data->display, "Wacom Serial IDs", False);
     pen_atoms.wacom_tool_type = X11_XInternAtom(data->display, "Wacom Tool Type", False);
-    pen_atoms.abs_pressure = X11_XInternAtom(data->display, "Abs Pressure", True);
-    pen_atoms.abs_tilt_x = X11_XInternAtom(data->display, "Abs Tilt X", True);
-    pen_atoms.abs_tilt_y = X11_XInternAtom(data->display, "Abs Tilt Y", True);
+    pen_atoms.abs_pressure = X11_XInternAtom(data->display, "Abs Pressure", False);
+    pen_atoms.abs_tilt_x = X11_XInternAtom(data->display, "Abs Tilt X", False);
+    pen_atoms.abs_tilt_y = X11_XInternAtom(data->display, "Abs Tilt Y", False);
 
     pen_atoms.initialized = 1;
 }
@@ -390,9 +390,12 @@ static void xinput2_vendor_peninfo(SDL_VideoDevice *_this, const XIDeviceInfo *d
 }
 
 /* Does this device have a valuator for pressure sensitivity? */
-static SDL_bool xinput2_device_is_pen(const XIDeviceInfo *dev)
+static SDL_bool xinput2_device_is_pen(SDL_VideoDevice *_this, const XIDeviceInfo *dev)
 {
     int classct;
+
+    pen_atoms_ensure_initialized(_this);
+
     for (classct = 0; classct < dev->num_classes; ++classct) {
         const XIAnyClassInfo *classinfo = dev->classes[classct];
 
@@ -445,8 +448,8 @@ void X11_InitPen(SDL_VideoDevice *_this)
         int old_num_pens_known = pen_map.num_pens_known;
         int k;
 
-        /* Only track physical devices that are enabled */
-        if (dev->use != XISlavePointer || dev->enabled == 0 || !xinput2_device_is_pen(dev)) {
+        /* Only track physical devices that are enabled and look like pens */
+        if (dev->use != XISlavePointer || dev->enabled == 0 || !xinput2_device_is_pen(_this, dev)) {
             continue;
         }