Quellcode durchsuchen

Implement SDL_GetPenDeviceType() for Android

Susko3 vor 5 Monaten
Ursprung
Commit
e2bbbdc515

+ 5 - 3
android-project/app/src/main/java/org/libsdl/app/SDLActivity.java

@@ -229,9 +229,11 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
     private static SDLFileDialogState mFileDialogState = null;
     private static SDLFileDialogState mFileDialogState = null;
     protected static boolean mDispatchingKeyEvent = false;
     protected static boolean mDispatchingKeyEvent = false;
 
 
-    protected static SDLGenericMotionListener_API14 getMotionListener() {
+    public static SDLGenericMotionListener_API14 getMotionListener() {
         if (mMotionListener == null) {
         if (mMotionListener == null) {
-            if (Build.VERSION.SDK_INT >= 26 /* Android 8.0 (O) */) {
+            if (Build.VERSION.SDK_INT >= 29 /* Android 10 (Q) */) {
+                mMotionListener = new SDLGenericMotionListener_API29();
+            } else if (Build.VERSION.SDK_INT >= 26 /* Android 8.0 (O) */) {
                 mMotionListener = new SDLGenericMotionListener_API26();
                 mMotionListener = new SDLGenericMotionListener_API26();
             } else if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
             } else if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
                 mMotionListener = new SDLGenericMotionListener_API24();
                 mMotionListener = new SDLGenericMotionListener_API24();
@@ -1063,7 +1065,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
     public static native void onNativeTouch(int touchDevId, int pointerFingerId,
     public static native void onNativeTouch(int touchDevId, int pointerFingerId,
                                             int action, float x,
                                             int action, float x,
                                             float y, float p);
                                             float y, float p);
-    public static native void onNativePen(int penId, int button, int action, float x, float y, float p);
+    public static native void onNativePen(int penId, int device_type, int button, int action, float x, float y, float p);
     public static native void onNativeAccel(float x, float y, float z);
     public static native void onNativeAccel(float x, float y, float z);
     public static native void onNativeClipboardChanged();
     public static native void onNativeClipboardChanged();
     public static native void onNativeSurfaceCreated();
     public static native void onNativeSurfaceCreated();

+ 20 - 1
android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java

@@ -646,6 +646,10 @@ class SDLHapticHandler {
 }
 }
 
 
 class SDLGenericMotionListener_API14 implements View.OnGenericMotionListener {
 class SDLGenericMotionListener_API14 implements View.OnGenericMotionListener {
+    protected static final int SDL_PEN_DEVICE_TYPE_UNKNOWN = 0;
+    protected static final int SDL_PEN_DEVICE_TYPE_DIRECT = 1;
+    protected static final int SDL_PEN_DEVICE_TYPE_INDIRECT = 2;
+
     // Generic Motion (mouse hover, joystick...) events go here
     // Generic Motion (mouse hover, joystick...) events go here
     @Override
     @Override
     public boolean onGenericMotion(View v, MotionEvent event) {
     public boolean onGenericMotion(View v, MotionEvent event) {
@@ -697,7 +701,7 @@ class SDLGenericMotionListener_API14 implements View.OnGenericMotionListener {
                         // BUTTON_STYLUS_PRIMARY is 2^5, so shift by 4, and apply SDL_PEN_INPUT_DOWN/SDL_PEN_INPUT_ERASER_TIP
                         // BUTTON_STYLUS_PRIMARY is 2^5, so shift by 4, and apply SDL_PEN_INPUT_DOWN/SDL_PEN_INPUT_ERASER_TIP
                         int buttons = (event.getButtonState() >> 4) | (1 << (toolType == MotionEvent.TOOL_TYPE_STYLUS ? 0 : 30));
                         int buttons = (event.getButtonState() >> 4) | (1 << (toolType == MotionEvent.TOOL_TYPE_STYLUS ? 0 : 30));
 
 
-                        SDLActivity.onNativePen(event.getPointerId(i), buttons, action, x, y, p);
+                        SDLActivity.onNativePen(event.getPointerId(i), getPenDeviceType(event.getDevice()), buttons, action, x, y, p);
                         consumed = true;
                         consumed = true;
                         break;
                         break;
                 }
                 }
@@ -735,6 +739,9 @@ class SDLGenericMotionListener_API14 implements View.OnGenericMotionListener {
         return event.getY(pointerIndex);
         return event.getY(pointerIndex);
     }
     }
 
 
+    int getPenDeviceType(InputDevice penDevice) {
+        return SDL_PEN_DEVICE_TYPE_UNKNOWN;
+    }
 }
 }
 
 
 class SDLGenericMotionListener_API24 extends SDLGenericMotionListener_API14 {
 class SDLGenericMotionListener_API24 extends SDLGenericMotionListener_API14 {
@@ -856,3 +863,15 @@ class SDLGenericMotionListener_API26 extends SDLGenericMotionListener_API24 {
         return event.getY(pointerIndex);
         return event.getY(pointerIndex);
     }
     }
 }
 }
+
+class SDLGenericMotionListener_API29 extends SDLGenericMotionListener_API26 {
+    @Override
+    int getPenDeviceType(InputDevice penDevice)
+    {
+        if (penDevice == null) {
+            return SDL_PEN_DEVICE_TYPE_UNKNOWN;
+        }
+
+        return penDevice.isExternal() ? SDL_PEN_DEVICE_TYPE_INDIRECT : SDL_PEN_DEVICE_TYPE_DIRECT;
+    }
+}

+ 1 - 1
android-project/app/src/main/java/org/libsdl/app/SDLSurface.java

@@ -281,7 +281,7 @@ public class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
                 // BUTTON_STYLUS_PRIMARY is 2^5, so shift by 4, and apply SDL_PEN_INPUT_DOWN/SDL_PEN_INPUT_ERASER_TIP
                 // BUTTON_STYLUS_PRIMARY is 2^5, so shift by 4, and apply SDL_PEN_INPUT_DOWN/SDL_PEN_INPUT_ERASER_TIP
                 int buttonState = (event.getButtonState() >> 4) | (1 << (toolType == MotionEvent.TOOL_TYPE_STYLUS ? 0 : 30));
                 int buttonState = (event.getButtonState() >> 4) | (1 << (toolType == MotionEvent.TOOL_TYPE_STYLUS ? 0 : 30));
 
 
-                SDLActivity.onNativePen(pointerId, buttonState, action, x, y, p);
+                SDLActivity.onNativePen(pointerId, SDLActivity.getMotionListener().getPenDeviceType(event.getDevice()), buttonState, action, x, y, p);
             } else { // MotionEvent.TOOL_TYPE_FINGER or MotionEvent.TOOL_TYPE_UNKNOWN
             } else { // MotionEvent.TOOL_TYPE_FINGER or MotionEvent.TOOL_TYPE_UNKNOWN
                 pointerId = event.getPointerId(i);
                 pointerId = event.getPointerId(i);
                 x = getNormalizedX(event.getX(i));
                 x = getNormalizedX(event.getX(i));

+ 27 - 1
include/SDL3/SDL_pen.h

@@ -52,6 +52,7 @@
 #include <SDL3/SDL_mouse.h>
 #include <SDL3/SDL_mouse.h>
 #include <SDL3/SDL_touch.h>
 #include <SDL3/SDL_touch.h>
 
 
+#include <SDL3/SDL_begin_code.h>
 /* Set up for C function definitions, even when using C++ */
 /* Set up for C function definitions, even when using C++ */
 #ifdef __cplusplus
 #ifdef __cplusplus
 extern "C" {
 extern "C" {
@@ -84,7 +85,6 @@ typedef Uint32 SDL_PenID;
  */
  */
 #define SDL_PEN_TOUCHID ((SDL_TouchID)-2)
 #define SDL_PEN_TOUCHID ((SDL_TouchID)-2)
 
 
-
 /**
 /**
  * Pen input flags, as reported by various pen events' `pen_state` field.
  * Pen input flags, as reported by various pen events' `pen_state` field.
  *
  *
@@ -127,10 +127,36 @@ typedef enum SDL_PenAxis
     SDL_PEN_AXIS_COUNT       /**< Total known pen axis types in this version of SDL. This number may grow in future releases! */
     SDL_PEN_AXIS_COUNT       /**< Total known pen axis types in this version of SDL. This number may grow in future releases! */
 } SDL_PenAxis;
 } SDL_PenAxis;
 
 
+/**
+ * An enum that describes the type of a pen device.
+ *
+ * \since This enum is available since SDL 3.4.0.
+ */
+typedef enum SDL_PenDeviceType
+{
+    SDL_PEN_DEVICE_TYPE_INVALID = -1,
+    SDL_PEN_DEVICE_TYPE_UNKNOWN,
+    SDL_PEN_DEVICE_TYPE_DIRECT,
+    SDL_PEN_DEVICE_TYPE_INDIRECT
+} SDL_PenDeviceType;
+
+/**
+ * Get the device type of the given pen.
+ *
+ * \param instance_id the pen instance ID.
+ * \returns the device type of the given pen, or SDL_PEN_DEVICE_TYPE_INVALID on failure; call SDL_GetError() for more information.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.4.0.
+ */
+extern SDL_DECLSPEC SDL_PenDeviceType SDLCALL SDL_GetPenDeviceType(SDL_PenID instance_id);
+
 /* Ends C function definitions when using C++ */
 /* Ends C function definitions when using C++ */
 #ifdef __cplusplus
 #ifdef __cplusplus
 }
 }
 #endif
 #endif
+#include <SDL3/SDL_close_code.h>
 
 
 #endif /* SDL_pen_h_ */
 #endif /* SDL_pen_h_ */
 
 

+ 4 - 4
src/core/android/SDL_android.c

@@ -137,7 +137,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeMouse)(
 
 
 JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativePen)(
 JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativePen)(
     JNIEnv *env, jclass jcls,
     JNIEnv *env, jclass jcls,
-    jint pen_id_in, jint button, jint action, jfloat x, jfloat y, jfloat p);
+    jint pen_id_in, jint device_type, jint button, jint action, jfloat x, jfloat y, jfloat p);
 
 
 JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeAccel)(
 JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeAccel)(
     JNIEnv *env, jclass jcls,
     JNIEnv *env, jclass jcls,
@@ -235,7 +235,7 @@ static JNINativeMethod SDLActivity_tab[] = {
     { "onNativePinchUpdate", "(F)V", SDL_JAVA_INTERFACE(onNativePinchUpdate) },
     { "onNativePinchUpdate", "(F)V", SDL_JAVA_INTERFACE(onNativePinchUpdate) },
     { "onNativePinchEnd", "()V", SDL_JAVA_INTERFACE(onNativePinchEnd) },
     { "onNativePinchEnd", "()V", SDL_JAVA_INTERFACE(onNativePinchEnd) },
     { "onNativeMouse", "(IIFFZ)V", SDL_JAVA_INTERFACE(onNativeMouse) },
     { "onNativeMouse", "(IIFFZ)V", SDL_JAVA_INTERFACE(onNativeMouse) },
-    { "onNativePen", "(IIIFFF)V", SDL_JAVA_INTERFACE(onNativePen) },
+    { "onNativePen", "(IIIIFFF)V", SDL_JAVA_INTERFACE(onNativePen) },
     { "onNativeAccel", "(FFF)V", SDL_JAVA_INTERFACE(onNativeAccel) },
     { "onNativeAccel", "(FFF)V", SDL_JAVA_INTERFACE(onNativeAccel) },
     { "onNativeClipboardChanged", "()V", SDL_JAVA_INTERFACE(onNativeClipboardChanged) },
     { "onNativeClipboardChanged", "()V", SDL_JAVA_INTERFACE(onNativeClipboardChanged) },
     { "nativeLowMemory", "()V", SDL_JAVA_INTERFACE(nativeLowMemory) },
     { "nativeLowMemory", "()V", SDL_JAVA_INTERFACE(nativeLowMemory) },
@@ -1431,11 +1431,11 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeMouse)(
 // Pen
 // Pen
 JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativePen)(
 JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativePen)(
     JNIEnv *env, jclass jcls,
     JNIEnv *env, jclass jcls,
-    jint pen_id_in, jint button, jint action, jfloat x, jfloat y, jfloat p)
+    jint pen_id_in, jint device_type, jint button, jint action, jfloat x, jfloat y, jfloat p)
 {
 {
     SDL_LockMutex(Android_ActivityMutex);
     SDL_LockMutex(Android_ActivityMutex);
 
 
-    Android_OnPen(Android_Window, pen_id_in, button, action, x, y, p);
+    Android_OnPen(Android_Window, pen_id_in, device_type, button, action, x, y, p);
 
 
     SDL_UnlockMutex(Android_ActivityMutex);
     SDL_UnlockMutex(Android_ActivityMutex);
 }
 }

+ 1 - 0
src/dynapi/SDL_dynapi.sym

@@ -1265,6 +1265,7 @@ SDL3_0.0.0 {
     SDL_SavePNG_IO;
     SDL_SavePNG_IO;
     SDL_SavePNG;
     SDL_SavePNG;
     SDL_GetSystemPageSize;
     SDL_GetSystemPageSize;
+    SDL_GetPenDeviceType;
     # extra symbols go here (don't modify this line)
     # extra symbols go here (don't modify this line)
   local: *;
   local: *;
 };
 };

+ 1 - 0
src/dynapi/SDL_dynapi_overrides.h

@@ -1291,3 +1291,4 @@
 #define SDL_SavePNG_IO SDL_SavePNG_IO_REAL
 #define SDL_SavePNG_IO SDL_SavePNG_IO_REAL
 #define SDL_SavePNG SDL_SavePNG_REAL
 #define SDL_SavePNG SDL_SavePNG_REAL
 #define SDL_GetSystemPageSize SDL_GetSystemPageSize_REAL
 #define SDL_GetSystemPageSize SDL_GetSystemPageSize_REAL
+#define SDL_GetPenDeviceType SDL_GetPenDeviceType_REAL

+ 1 - 0
src/dynapi/SDL_dynapi_procs.h

@@ -1299,3 +1299,4 @@ SDL_DYNAPI_PROC(SDL_Surface*,SDL_LoadPNG,(const char *a),(a),return)
 SDL_DYNAPI_PROC(bool,SDL_SavePNG_IO,(SDL_Surface *a,SDL_IOStream *b,bool c),(a,b,c),return)
 SDL_DYNAPI_PROC(bool,SDL_SavePNG_IO,(SDL_Surface *a,SDL_IOStream *b,bool c),(a,b,c),return)
 SDL_DYNAPI_PROC(bool,SDL_SavePNG,(SDL_Surface *a,const char *b),(a,b),return)
 SDL_DYNAPI_PROC(bool,SDL_SavePNG,(SDL_Surface *a,const char *b),(a,b),return)
 SDL_DYNAPI_PROC(int,SDL_GetSystemPageSize,(void),(),return)
 SDL_DYNAPI_PROC(int,SDL_GetSystemPageSize,(void),(),return)
+SDL_DYNAPI_PROC(SDL_PenDeviceType,SDL_GetPenDeviceType,(SDL_PenID a),(a),return)

+ 9 - 0
src/events/SDL_pen.c

@@ -199,6 +199,15 @@ SDL_PenInputFlags SDL_GetPenStatus(SDL_PenID instance_id, float *axes, int num_a
     return result;
     return result;
 }
 }
 
 
+SDL_PenDeviceType SDL_GetPenDeviceType(SDL_PenID instance_id)
+{
+    SDL_LockRWLockForReading(pen_device_rwlock);
+    const SDL_Pen *pen = FindPenByInstanceId(instance_id);
+    const SDL_PenDeviceType result = pen ? pen->info.device_type : SDL_PEN_DEVICE_TYPE_INVALID;
+    SDL_UnlockRWLock(pen_device_rwlock);
+    return result;
+}
+
 SDL_PenCapabilityFlags SDL_GetPenCapabilityFromAxis(SDL_PenAxis axis)
 SDL_PenCapabilityFlags SDL_GetPenCapabilityFromAxis(SDL_PenAxis axis)
 {
 {
     // the initial capability bits happen to match up, but as
     // the initial capability bits happen to match up, but as

+ 3 - 0
src/events/SDL_pen_c.h

@@ -36,6 +36,8 @@ typedef Uint32 SDL_PenCapabilityFlags;
 #define SDL_PEN_CAPABILITY_TANGENTIAL_PRESSURE (1u << 6)  /**< Provides barrel pressure on SDL_PEN_AXIS_TANGENTIAL_PRESSURE. */
 #define SDL_PEN_CAPABILITY_TANGENTIAL_PRESSURE (1u << 6)  /**< Provides barrel pressure on SDL_PEN_AXIS_TANGENTIAL_PRESSURE. */
 #define SDL_PEN_CAPABILITY_ERASER    (1u << 7)  /**< Pen also has an eraser tip. */
 #define SDL_PEN_CAPABILITY_ERASER    (1u << 7)  /**< Pen also has an eraser tip. */
 
 
+// Rename before making this public as it clashes with SDL_PenDeviceType.
+// Prior art in Android calls this "tool type".
 typedef enum SDL_PenSubtype
 typedef enum SDL_PenSubtype
 {
 {
     SDL_PEN_TYPE_UNKNOWN,   /**< Unknown pen device */
     SDL_PEN_TYPE_UNKNOWN,   /**< Unknown pen device */
@@ -53,6 +55,7 @@ typedef struct SDL_PenInfo
     Uint32 wacom_id;   /**< For Wacom devices: wacom tool type ID, otherwise 0 (useful e.g. with libwacom) */
     Uint32 wacom_id;   /**< For Wacom devices: wacom tool type ID, otherwise 0 (useful e.g. with libwacom) */
     int num_buttons; /**< Number of pen buttons (not counting the pen tip), or -1 if unknown. */
     int num_buttons; /**< Number of pen buttons (not counting the pen tip), or -1 if unknown. */
     SDL_PenSubtype subtype;  /**< type of pen device */
     SDL_PenSubtype subtype;  /**< type of pen device */
+    SDL_PenDeviceType device_type;
 } SDL_PenInfo;
 } SDL_PenInfo;
 
 
 // Backend calls this when a new pen device is hotplugged, plus once for each pen already connected at startup.
 // Backend calls this when a new pen device is hotplugged, plus once for each pen already connected at startup.

+ 2 - 1
src/video/android/SDL_androidpen.c

@@ -33,7 +33,7 @@
 #define ACTION_POINTER_UP   6
 #define ACTION_POINTER_UP   6
 #define ACTION_HOVER_EXIT   10
 #define ACTION_HOVER_EXIT   10
 
 
-void Android_OnPen(SDL_Window *window, int pen_id_in, int button, int action, float x, float y, float p)
+void Android_OnPen(SDL_Window *window, int pen_id_in, SDL_PenDeviceType device_type, int button, int action, float x, float y, float p)
 {
 {
     if (!window) {
     if (!window) {
         return;
         return;
@@ -50,6 +50,7 @@ void Android_OnPen(SDL_Window *window, int pen_id_in, int button, int action, fl
         peninfo.capabilities = SDL_PEN_CAPABILITY_PRESSURE | SDL_PEN_CAPABILITY_ERASER;
         peninfo.capabilities = SDL_PEN_CAPABILITY_PRESSURE | SDL_PEN_CAPABILITY_ERASER;
         peninfo.num_buttons = 2;
         peninfo.num_buttons = 2;
         peninfo.subtype = SDL_PEN_TYPE_PEN;
         peninfo.subtype = SDL_PEN_TYPE_PEN;
+        peninfo.device_type = device_type;
         pen = SDL_AddPenDevice(0, NULL, &peninfo, (void *) (size_t) pen_id_in);
         pen = SDL_AddPenDevice(0, NULL, &peninfo, (void *) (size_t) pen_id_in);
         if (!pen) {
         if (!pen) {
             SDL_Log("error: can't add a pen device %d", pen_id_in);
             SDL_Log("error: can't add a pen device %d", pen_id_in);

+ 1 - 1
src/video/android/SDL_androidpen.h

@@ -22,4 +22,4 @@
 
 
 #include "SDL_androidvideo.h"
 #include "SDL_androidvideo.h"
 
 
-extern void Android_OnPen(SDL_Window *window, int pen_id_in, int button, int action, float x, float y, float p);
+extern void Android_OnPen(SDL_Window *window, int pen_id_in, SDL_PenDeviceType device_type, int button, int action, float x, float y, float p);