Skip to content

Implement SDL_GetPenDeviceType() for Android #13264

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -234,9 +234,11 @@ public enum NativeState {
private static SDLFileDialogState mFileDialogState = null;
protected static boolean mDispatchingKeyEvent = false;

protected static SDLGenericMotionListener_API14 getMotionListener() {
public static SDLGenericMotionListener_API14 getMotionListener() {
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();
} else if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
mMotionListener = new SDLGenericMotionListener_API24();
Expand Down Expand Up @@ -1072,7 +1074,7 @@ protected boolean sendCommand(int command, Object data) {
public static native void onNativeTouch(int touchDevId, int pointerFingerId,
int action, float x,
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 onNativeClipboardChanged();
public static native void onNativeSurfaceCreated();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,10 @@ protected SDLHaptic getHaptic(int device_id) {
}

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
@Override
public boolean onGenericMotion(View v, MotionEvent event) {
Expand Down Expand Up @@ -714,7 +718,7 @@ public boolean onGenericMotion(View v, MotionEvent event) {
// 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));

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;
break;
}
Expand Down Expand Up @@ -752,6 +756,9 @@ float getEventY(MotionEvent event, int pointerIndex) {
return event.getY(pointerIndex);
}

int getPenDeviceType(InputDevice penDevice) {
return SDL_PEN_DEVICE_TYPE_UNKNOWN;
}
}

class SDLGenericMotionListener_API24 extends SDLGenericMotionListener_API14 {
Expand Down Expand Up @@ -847,3 +854,15 @@ float getEventY(MotionEvent event, int 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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ public boolean onTouch(View v, MotionEvent event) {
// 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));

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
pointerId = event.getPointerId(i);
x = getNormalizedX(event.getX(i));
Expand Down
28 changes: 27 additions & 1 deletion include/SDL3/SDL_pen.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include <SDL3/SDL_mouse.h>
#include <SDL3/SDL_touch.h>

#include <SDL3/SDL_begin_code.h>
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -75,7 +76,6 @@ typedef Uint32 SDL_PenID;
*/
#define SDL_PEN_TOUCHID ((SDL_TouchID)-2)


/**
* Pen input flags, as reported by various pen events' `pen_state` field.
*
Expand Down Expand Up @@ -118,10 +118,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_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++ */
#ifdef __cplusplus
}
#endif
#include <SDL3/SDL_close_code.h>

#endif /* SDL_pen_h_ */

8 changes: 4 additions & 4 deletions src/core/android/SDL_android.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeMouse)(

JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativePen)(
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)(
JNIEnv *env, jclass jcls,
Expand Down Expand Up @@ -214,7 +214,7 @@ static JNINativeMethod SDLActivity_tab[] = {
{ "onNativeKeyboardFocusLost", "()V", SDL_JAVA_INTERFACE(onNativeKeyboardFocusLost) },
{ "onNativeTouch", "(IIIFFF)V", SDL_JAVA_INTERFACE(onNativeTouch) },
{ "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) },
{ "onNativeClipboardChanged", "()V", SDL_JAVA_INTERFACE(onNativeClipboardChanged) },
{ "nativeLowMemory", "()V", SDL_JAVA_INTERFACE(nativeLowMemory) },
Expand Down Expand Up @@ -1361,11 +1361,11 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeMouse)(
// Pen
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativePen)(
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);

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);
}
Expand Down
1 change: 1 addition & 0 deletions src/dynapi/SDL_dynapi.sym
Original file line number Diff line number Diff line change
Expand Up @@ -1254,6 +1254,7 @@ SDL3_0.0.0 {
SDL_SetAudioIterationCallbacks;
SDL_GetEventDescription;
SDL_PutAudioStreamDataNoCopy;
SDL_GetPenDeviceType;
# extra symbols go here (don't modify this line)
local: *;
};
1 change: 1 addition & 0 deletions src/dynapi/SDL_dynapi_overrides.h
Original file line number Diff line number Diff line change
Expand Up @@ -1279,3 +1279,4 @@
#define SDL_SetAudioIterationCallbacks SDL_SetAudioIterationCallbacks_REAL
#define SDL_GetEventDescription SDL_GetEventDescription_REAL
#define SDL_PutAudioStreamDataNoCopy SDL_PutAudioStreamDataNoCopy_REAL
#define SDL_GetPenDeviceType SDL_GetPenDeviceType_REAL
1 change: 1 addition & 0 deletions src/dynapi/SDL_dynapi_procs.h
Original file line number Diff line number Diff line change
Expand Up @@ -1287,3 +1287,4 @@ SDL_DYNAPI_PROC(bool,SDL_PutAudioStreamPlanarData,(SDL_AudioStream *a,const void
SDL_DYNAPI_PROC(bool,SDL_SetAudioIterationCallbacks,(SDL_AudioDeviceID a,SDL_AudioIterationCallback b,SDL_AudioIterationCallback c,void *d),(a,b,c,d),return)
SDL_DYNAPI_PROC(int,SDL_GetEventDescription,(const SDL_Event *a,char *b,int c),(a,b,c),return)
SDL_DYNAPI_PROC(bool,SDL_PutAudioStreamDataNoCopy,(SDL_AudioStream *a,const void *b,int c,SDL_AudioStreamDataCompleteCallback d,void *e),(a,b,c,d,e),return)
SDL_DYNAPI_PROC(SDL_PenDeviceType,SDL_GetPenDeviceType,(SDL_PenID a),(a),return)
9 changes: 9 additions & 0 deletions src/events/SDL_pen.c
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,15 @@ SDL_PenInputFlags SDL_GetPenStatus(SDL_PenID instance_id, float *axes, int num_a
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)
{
// the initial capability bits happen to match up, but as
Expand Down
3 changes: 3 additions & 0 deletions src/events/SDL_pen_c.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_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
{
SDL_PEN_TYPE_UNKNOWN, /**< Unknown pen device */
Expand All @@ -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) */
int num_buttons; /**< Number of pen buttons (not counting the pen tip), or -1 if unknown. */
SDL_PenSubtype subtype; /**< type of pen device */
SDL_PenDeviceType device_type;
} SDL_PenInfo;

// Backend calls this when a new pen device is hotplugged, plus once for each pen already connected at startup.
Expand Down
3 changes: 2 additions & 1 deletion src/video/android/SDL_androidpen.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
#define ACTION_POINTER_UP 6
#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) {
return;
Expand All @@ -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.num_buttons = 2;
peninfo.subtype = SDL_PEN_TYPE_PEN;
peninfo.device_type = device_type;
pen = SDL_AddPenDevice(0, NULL, &peninfo, (void *) (size_t) pen_id_in);
if (!pen) {
SDL_Log("error: can't add a pen device %d", pen_id_in);
Expand Down
2 changes: 1 addition & 1 deletion src/video/android/SDL_androidpen.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@

#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);
Loading