Skip to content

Commit dfc2590

Browse files
committed
update sdl android wrapper
1 parent 0b434b6 commit dfc2590

5 files changed

Lines changed: 104 additions & 29 deletions

File tree

android-project/app/src/main/java/org/libsdl/app/HIDDeviceManager.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ private boolean isXbox360Controller(UsbDevice usbDevice, UsbInterface usbInterfa
256256
0x24c6, // PowerA
257257
0x2c22, // Qanba
258258
0x2dc8, // 8BitDo
259+
0x37d7, // Flydigi
259260
0x9886, // ASTRO Gaming
260261
};
261262

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

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@
6060
public class SDLActivity extends Activity implements View.OnSystemUiVisibilityChangeListener {
6161
private static final String TAG = "SDL";
6262
private static final int SDL_MAJOR_VERSION = 3;
63-
private static final int SDL_MINOR_VERSION = 3;
64-
private static final int SDL_MICRO_VERSION = 3;
63+
private static final int SDL_MINOR_VERSION = 4;
64+
private static final int SDL_MICRO_VERSION = 8;
6565
/*
6666
// Display InputType.SOURCE/CLASS of events and devices
6767
//
@@ -570,7 +570,7 @@ protected void onStart() {
570570
public static int getNaturalOrientation() {
571571
int result = SDL_ORIENTATION_UNKNOWN;
572572

573-
Activity activity = (Activity)getContext();
573+
Activity activity = getContext();
574574
if (activity != null) {
575575
Configuration config = activity.getResources().getConfiguration();
576576
Display display = activity.getWindowManager().getDefaultDisplay();
@@ -590,7 +590,7 @@ public static int getNaturalOrientation() {
590590
public static int getCurrentRotation() {
591591
int result = 0;
592592

593-
Activity activity = (Activity)getContext();
593+
Activity activity = getContext();
594594
if (activity != null) {
595595
Display display = activity.getWindowManager().getDefaultDisplay();
596596
switch (display.getRotation()) {
@@ -1270,10 +1270,10 @@ public static boolean isAndroidTV() {
12701270
if (Build.MANUFACTURER.equals("MINIX") && Build.MODEL.equals("NEO-U1")) {
12711271
return true;
12721272
}
1273-
if (Build.MANUFACTURER.equals("Amlogic") && Build.MODEL.equals("X96-W")) {
1274-
return true;
1275-
}
1276-
if (Build.MANUFACTURER.equals("Amlogic") && Build.MODEL.startsWith("TV")) {
1273+
if (Build.MANUFACTURER.equals("Amlogic") &&
1274+
(Build.MODEL.startsWith("TV") ||
1275+
Build.MODEL.equals("X96-W") ||
1276+
Build.MODEL.equals("A95X-R1"))) {
12771277
return true;
12781278
}
12791279
return false;
@@ -1292,7 +1292,7 @@ public static boolean isVRHeadset() {
12921292
public static double getDiagonal()
12931293
{
12941294
DisplayMetrics metrics = new DisplayMetrics();
1295-
Activity activity = (Activity)getContext();
1295+
Activity activity = getContext();
12961296
if (activity == null) {
12971297
return 0.0;
12981298
}
@@ -1940,7 +1940,7 @@ public static void requestPermission(String permission, int requestCode) {
19401940
return;
19411941
}
19421942

1943-
Activity activity = (Activity)getContext();
1943+
Activity activity = getContext();
19441944
if (activity.checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
19451945
activity.requestPermissions(new String[]{permission}, requestCode);
19461946
} else {

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

Lines changed: 66 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66
import java.util.List;
77

88
import android.content.Context;
9+
import android.hardware.lights.Light;
10+
import android.hardware.lights.LightsRequest;
11+
import android.hardware.lights.LightsManager;
12+
import android.hardware.lights.LightState;
13+
import android.graphics.Color;
914
import android.os.Build;
1015
import android.os.VibrationEffect;
1116
import android.os.Vibrator;
@@ -25,7 +30,7 @@ public class SDLControllerManager
2530
static native void nativeAddJoystick(int device_id, String name, String desc,
2631
int vendor_id, int product_id,
2732
int button_mask,
28-
int naxes, int axis_mask, int nhats, boolean can_rumble);
33+
int naxes, int axis_mask, int nhats, boolean can_rumble, boolean has_rgb_led);
2934
static native void nativeRemoveJoystick(int device_id);
3035
static native void nativeAddHaptic(int device_id, String name);
3136
static native void nativeRemoveHaptic(int device_id);
@@ -69,6 +74,13 @@ static void pollInputDevices() {
6974
mJoystickHandler.pollInputDevices();
7075
}
7176

77+
/**
78+
* This method is called by SDL using JNI.
79+
*/
80+
static void joystickSetLED(int device_id, int red, int green, int blue) {
81+
mJoystickHandler.setLED(device_id, red, green, blue);
82+
}
83+
7284
/**
7385
* This method is called by SDL using JNI.
7486
*/
@@ -139,6 +151,8 @@ static class SDLJoystick {
139151
String desc;
140152
ArrayList<InputDevice.MotionRange> axes;
141153
ArrayList<InputDevice.MotionRange> hats;
154+
ArrayList<Light> lights;
155+
LightsManager.LightsSession lightsSession;
142156
}
143157
static class RangeComparator implements Comparator<InputDevice.MotionRange> {
144158
@Override
@@ -197,7 +211,7 @@ public int compare(InputDevice.MotionRange arg0, InputDevice.MotionRange arg1) {
197211
/**
198212
* Handles adding and removing of input devices.
199213
*/
200-
void pollInputDevices() {
214+
synchronized void pollInputDevices() {
201215
int[] deviceIds = InputDevice.getDeviceIds();
202216

203217
for (int device_id : deviceIds) {
@@ -211,6 +225,7 @@ void pollInputDevices() {
211225
joystick.desc = getJoystickDescriptor(joystickDevice);
212226
joystick.axes = new ArrayList<InputDevice.MotionRange>();
213227
joystick.hats = new ArrayList<InputDevice.MotionRange>();
228+
joystick.lights = new ArrayList<Light>();
214229

215230
List<InputDevice.MotionRange> ranges = joystickDevice.getMotionRanges();
216231
Collections.sort(ranges, new RangeComparator());
@@ -225,18 +240,30 @@ void pollInputDevices() {
225240
}
226241

227242
boolean can_rumble = false;
243+
boolean has_rgb_led = false;
228244
if (Build.VERSION.SDK_INT >= 31 /* Android 12.0 (S) */) {
229-
VibratorManager manager = joystickDevice.getVibratorManager();
230-
int[] vibrators = manager.getVibratorIds();
245+
VibratorManager vibratorManager = joystickDevice.getVibratorManager();
246+
int[] vibrators = vibratorManager.getVibratorIds();
231247
if (vibrators.length > 0) {
232248
can_rumble = true;
233249
}
250+
LightsManager lightsManager = joystickDevice.getLightsManager();
251+
List<Light> lights = lightsManager.getLights();
252+
for (Light light : lights) {
253+
if (light.hasRgbControl()) {
254+
joystick.lights.add(light);
255+
}
256+
}
257+
if (!joystick.lights.isEmpty()) {
258+
joystick.lightsSession = lightsManager.openSession();
259+
has_rgb_led = true;
260+
}
234261
}
235262

236263
mJoysticks.add(joystick);
237264
SDLControllerManager.nativeAddJoystick(joystick.device_id, joystick.name, joystick.desc,
238265
getVendorId(joystickDevice), getProductId(joystickDevice),
239-
getButtonMask(joystickDevice), joystick.axes.size(), getAxisMask(joystick.axes), joystick.hats.size()/2, can_rumble);
266+
getButtonMask(joystickDevice), joystick.axes.size(), getAxisMask(joystick.axes), joystick.hats.size()/2, can_rumble, has_rgb_led);
240267
}
241268
}
242269
}
@@ -262,6 +289,16 @@ void pollInputDevices() {
262289
SDLControllerManager.nativeRemoveJoystick(device_id);
263290
for (int i = 0; i < mJoysticks.size(); i++) {
264291
if (mJoysticks.get(i).device_id == device_id) {
292+
if (Build.VERSION.SDK_INT >= 31 /* Android 12.0 (S) */) {
293+
if (mJoysticks.get(i).lightsSession != null) {
294+
try {
295+
mJoysticks.get(i).lightsSession.close();
296+
} catch (Exception e) {
297+
// Session may already be unregistered when device disconnects
298+
}
299+
mJoysticks.get(i).lightsSession = null;
300+
}
301+
}
265302
mJoysticks.remove(i);
266303
break;
267304
}
@@ -270,7 +307,7 @@ void pollInputDevices() {
270307
}
271308
}
272309

273-
protected SDLJoystick getJoystick(int device_id) {
310+
synchronized protected SDLJoystick getJoystick(int device_id) {
274311
for (SDLJoystick joystick : mJoysticks) {
275312
if (joystick.device_id == device_id) {
276313
return joystick;
@@ -453,6 +490,24 @@ int getButtonMask(InputDevice joystickDevice) {
453490
}
454491
return button_mask;
455492
}
493+
494+
void setLED(int device_id, int red, int green, int blue) {
495+
if (Build.VERSION.SDK_INT < 31 /* Android 12.0 (S) */) {
496+
return;
497+
}
498+
SDLJoystick joystick = getJoystick(device_id);
499+
if (joystick == null || joystick.lights.isEmpty()) {
500+
return;
501+
}
502+
LightsRequest.Builder lightsRequest = new LightsRequest.Builder();
503+
LightState lightState = new LightState.Builder().setColor(Color.rgb(red, green, blue)).build();
504+
for (Light light : joystick.lights) {
505+
if (light.hasRgbControl()) {
506+
lightsRequest.addLight(light, lightState);
507+
}
508+
}
509+
joystick.lightsSession.requestLights(lightsRequest.build());
510+
}
456511
}
457512

458513
class SDLHapticHandler_API31 extends SDLHapticHandler {
@@ -587,7 +642,7 @@ void stop(int device_id) {
587642
}
588643
}
589644

590-
void pollHapticDevices() {
645+
synchronized void pollHapticDevices() {
591646

592647
final int deviceId_VIBRATOR_SERVICE = 999999;
593648
boolean hasVibratorService = false;
@@ -635,7 +690,7 @@ void pollHapticDevices() {
635690
}
636691
}
637692

638-
protected SDLHaptic getHaptic(int device_id) {
693+
synchronized protected SDLHaptic getHaptic(int device_id) {
639694
for (SDLHaptic haptic : mHaptics) {
640695
if (haptic.device_id == device_id) {
641696
return haptic;
@@ -700,6 +755,9 @@ public boolean onGenericMotion(View v, MotionEvent event) {
700755

701756
// BUTTON_STYLUS_PRIMARY is 2^5, so shift by 4, and apply SDL_PEN_INPUT_DOWN/SDL_PEN_INPUT_ERASER_TIP
702757
int buttons = (event.getButtonState() >> 4) | (1 << (toolType == MotionEvent.TOOL_TYPE_STYLUS ? 0 : 30));
758+
if ((event.getButtonState() & MotionEvent.BUTTON_TERTIARY) != 0) {
759+
buttons |= 0x08;
760+
}
703761

704762
SDLActivity.onNativePen(event.getPointerId(i), getPenDeviceType(event.getDevice()), buttons, action, x, y, p);
705763
consumed = true;

android-project/app/src/main/java/org/libsdl/app/SDLInputConnection.java

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -65,17 +65,15 @@ public boolean setComposingText(CharSequence text, int newCursorPosition) {
6565

6666
@Override
6767
public boolean deleteSurroundingText(int beforeLength, int afterLength) {
68-
if (Build.VERSION.SDK_INT <= 29 /* Android 10.0 (Q) */) {
69-
// Workaround to capture backspace key. Ref: http://stackoverflow.com/questions>/14560344/android-backspace-in-webview-baseinputconnection
70-
// and https://bugzilla.libsdl.org/show_bug.cgi?id=2265
71-
if (beforeLength > 0 && afterLength == 0) {
72-
// backspace(s)
73-
while (beforeLength-- > 0) {
74-
nativeGenerateScancodeForUnichar('\b');
75-
}
76-
return true;
77-
}
78-
}
68+
// Workaround to capture backspace key. Ref: http://stackoverflow.com/questions>/14560344/android-backspace-in-webview-baseinputconnection
69+
// and https://bugzilla.libsdl.org/show_bug.cgi?id=2265
70+
if (beforeLength > 0 && afterLength == 0) {
71+
// backspace(s)
72+
while (beforeLength-- > 0) {
73+
nativeGenerateScancodeForUnichar('\b');
74+
}
75+
return true;
76+
}
7977

8078
if (!super.deleteSurroundingText(beforeLength, afterLength)) {
8179
return false;

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ public class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
4545
// Is SurfaceView ready for rendering
4646
protected boolean mIsSurfaceReady;
4747

48+
// Is on-screen keyboard visible
49+
protected boolean mKeyboardVisible;
50+
4851
// Pinch events
4952
private final ScaleGestureDetector scaleGestureDetector;
5053

@@ -208,6 +211,18 @@ public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {
208211
WindowInsets.Type.displayCutout());
209212

210213
SDLActivity.onNativeInsetsChanged(combined.left, combined.right, combined.top, combined.bottom);
214+
215+
if (insets.isVisible(WindowInsets.Type.ime())) {
216+
if (!mKeyboardVisible) {
217+
mKeyboardVisible = true;
218+
SDLActivity.onNativeScreenKeyboardShown();
219+
}
220+
} else {
221+
if (mKeyboardVisible) {
222+
mKeyboardVisible = false;
223+
SDLActivity.onNativeScreenKeyboardHidden();
224+
}
225+
}
211226
}
212227

213228
// Pass these to any child views in case they need them
@@ -280,6 +295,9 @@ public boolean onTouch(View v, MotionEvent event) {
280295

281296
// BUTTON_STYLUS_PRIMARY is 2^5, so shift by 4, and apply SDL_PEN_INPUT_DOWN/SDL_PEN_INPUT_ERASER_TIP
282297
int buttonState = (event.getButtonState() >> 4) | (1 << (toolType == MotionEvent.TOOL_TYPE_STYLUS ? 0 : 30));
298+
if ((event.getButtonState() & MotionEvent.BUTTON_TERTIARY) != 0) {
299+
buttonState |= 0x08;
300+
}
283301

284302
SDLActivity.onNativePen(pointerId, SDLActivity.getMotionListener().getPenDeviceType(event.getDevice()), buttonState, action, x, y, p);
285303
} else { // MotionEvent.TOOL_TYPE_FINGER or MotionEvent.TOOL_TYPE_UNKNOWN

0 commit comments

Comments
 (0)