From 9194d199e770e6dba49568043370933a21cbc6e1 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Thu, 5 Feb 2026 09:08:45 -0800
Subject: [PATCH] Added support for the third stylus button on Android
(cherry picked from commit cd7fc90c874b53cc3054553367fa2dffb0ce2bd1)
---
.../java/org/libsdl/app/SDLControllerManager.java | 3 +++
.../app/src/main/java/org/libsdl/app/SDLSurface.java | 3 +++
src/video/android/SDL_androidpen.c | 12 ++++++------
3 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java b/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java
index 9a5a9c3f51187..f2de88af4bc8c 100644
--- a/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java
+++ b/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java
@@ -755,6 +755,9 @@ 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));
+ if ((event.getButtonState() & MotionEvent.BUTTON_TERTIARY) != 0) {
+ buttons |= 0x08;
+ }
SDLActivity.onNativePen(event.getPointerId(i), getPenDeviceType(event.getDevice()), buttons, action, x, y, p);
consumed = true;
diff --git a/android-project/app/src/main/java/org/libsdl/app/SDLSurface.java b/android-project/app/src/main/java/org/libsdl/app/SDLSurface.java
index 38f9d4f8ee513..1579b7334539a 100644
--- a/android-project/app/src/main/java/org/libsdl/app/SDLSurface.java
+++ b/android-project/app/src/main/java/org/libsdl/app/SDLSurface.java
@@ -280,6 +280,9 @@ 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));
+ if ((event.getButtonState() & MotionEvent.BUTTON_TERTIARY) != 0) {
+ buttonState |= 0x08;
+ }
SDLActivity.onNativePen(pointerId, SDLActivity.getMotionListener().getPenDeviceType(event.getDevice()), buttonState, action, x, y, p);
} else { // MotionEvent.TOOL_TYPE_FINGER or MotionEvent.TOOL_TYPE_UNKNOWN
diff --git a/src/video/android/SDL_androidpen.c b/src/video/android/SDL_androidpen.c
index 7ce2acbea4c90..e47d1d6ab2b9c 100644
--- a/src/video/android/SDL_androidpen.c
+++ b/src/video/android/SDL_androidpen.c
@@ -66,12 +66,12 @@ void Android_OnPen(SDL_Window *window, int pen_id_in, SDL_PenDeviceType device_t
SDL_PenInputFlags current = SDL_GetPenStatus(pen, NULL, 0);
int diff = current ^ button;
if (diff != 0) {
- // Android only exposes BUTTON_STYLUS_PRIMARY and BUTTON_STYLUS_SECONDARY
- if (diff & SDL_PEN_INPUT_BUTTON_1)
- SDL_SendPenButton(0, pen, window, 1, (button & SDL_PEN_INPUT_BUTTON_1) != 0);
-
- if (diff & SDL_PEN_INPUT_BUTTON_2)
- SDL_SendPenButton(0, pen, window, 2, (button & SDL_PEN_INPUT_BUTTON_2) != 0);
+ for (Uint8 i = 1; i <= 5; ++i) {
+ Uint8 mask = (1 << i);
+ if (diff & mask) {
+ SDL_SendPenButton(0, pen, window, i, (button & mask) != 0);
+ }
+ }
}
// button contains DOWN/ERASER_TIP on DOWN/UP regardless of pressed state, use action to distinguish