diff --git a/NOTICE.md b/NOTICE.md index 44e2b783b..2b772acf9 100644 --- a/NOTICE.md +++ b/NOTICE.md @@ -46,7 +46,7 @@ This product bundles pixman 0.32.8, which is available under an This product bundles libpng 1.6.12, which is available under a "zlib" (BSD-style) license. For details, see [project/lib/png/](project/lib). -This product bundles SDL 2.0.9, which is available under a +This product bundles SDL revision 24883e864f7e, which is available under a "zlib" (BSD-style) license. For details, see [project/lib/sdl/](project/lib). This product bundles tinyfiledialogs 2.9.3, which is available under a diff --git a/project/lib/sdl b/project/lib/sdl index 7c3c7f010..2f6ec995f 160000 --- a/project/lib/sdl +++ b/project/lib/sdl @@ -1 +1 @@ -Subproject commit 7c3c7f0107e4b82e7e261c60ce3f8f4cf2ea889c +Subproject commit 2f6ec995f50b45912e1de9021bde261ddc639871 diff --git a/templates/android/template/app/src/main/java/org/libsdl/app/HIDDeviceBLESteamController.java b/templates/android/template/app/src/main/java/org/libsdl/app/HIDDeviceBLESteamController.java index 4cf114a29..51538faed 100644 --- a/templates/android/template/app/src/main/java/org/libsdl/app/HIDDeviceBLESteamController.java +++ b/templates/android/template/app/src/main/java/org/libsdl/app/HIDDeviceBLESteamController.java @@ -12,12 +12,11 @@ import android.bluetooth.BluetoothGattService; import android.os.Handler; import android.os.Looper; import android.util.Log; +import android.os.*; //import com.android.internal.util.HexDump; import java.lang.Runnable; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.util.Arrays; import java.util.LinkedList; import java.util.UUID; @@ -186,10 +185,13 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe // Because on Chromebooks we show up as a dual-mode device, it will attempt to connect TRANSPORT_AUTO, which will use TRANSPORT_BREDR instead // of TRANSPORT_LE. Let's force ourselves to connect low energy. private BluetoothGatt connectGatt(boolean managed) { - try { - Method m = mDevice.getClass().getDeclaredMethod("connectGatt", Context.class, boolean.class, BluetoothGattCallback.class, int.class); - return (BluetoothGatt) m.invoke(mDevice, mManager.getContext(), managed, this, TRANSPORT_LE); - } catch (Exception e) { + if (Build.VERSION.SDK_INT >= 23) { + try { + return mDevice.connectGatt(mManager.getContext(), managed, this, TRANSPORT_LE); + } catch (Exception e) { + return mDevice.connectGatt(mManager.getContext(), managed, this); + } + } else { return mDevice.connectGatt(mManager.getContext(), managed, this); } } diff --git a/templates/android/template/app/src/main/java/org/libsdl/app/HIDDeviceManager.java b/templates/android/template/app/src/main/java/org/libsdl/app/HIDDeviceManager.java index db9400f6d..241775d46 100644 --- a/templates/android/template/app/src/main/java/org/libsdl/app/HIDDeviceManager.java +++ b/templates/android/template/app/src/main/java/org/libsdl/app/HIDDeviceManager.java @@ -411,7 +411,7 @@ public class HIDDeviceManager { if (mIsChromebook) { mHandler = new Handler(Looper.getMainLooper()); - mLastBluetoothDevices = new ArrayList<>(); + mLastBluetoothDevices = new ArrayList(); // final HIDDeviceManager finalThis = this; // mHandler.postDelayed(new Runnable() { @@ -439,8 +439,8 @@ public class HIDDeviceManager { return; } - ArrayList disconnected = new ArrayList<>(); - ArrayList connected = new ArrayList<>(); + ArrayList disconnected = new ArrayList(); + ArrayList connected = new ArrayList(); List currentConnected = mBluetoothManager.getConnectedDevices(BluetoothProfile.GATT); diff --git a/templates/android/template/app/src/main/java/org/libsdl/app/SDLActivity.java b/templates/android/template/app/src/main/java/org/libsdl/app/SDLActivity.java index 4d056d82b..163a36af1 100644 --- a/templates/android/template/app/src/main/java/org/libsdl/app/SDLActivity.java +++ b/templates/android/template/app/src/main/java/org/libsdl/app/SDLActivity.java @@ -37,7 +37,8 @@ import android.content.pm.ApplicationInfo; public class SDLActivity extends Activity implements View.OnSystemUiVisibilityChangeListener { private static final String TAG = "SDL"; - public static boolean mIsResumedCalled, mIsSurfaceReady, mHasFocus; + public static boolean mIsResumedCalled, mHasFocus; + public static final boolean mHasMultiWindow = (Build.VERSION.SDK_INT >= 24); // Cursor types private static final int SDL_SYSTEM_CURSOR_NONE = -1; @@ -70,15 +71,9 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh public static NativeState mNextNativeState; public static NativeState mCurrentNativeState; - public static boolean mExitCalledFromJava; - /** If shared libraries (e.g. SDL or the native application) could not be loaded. */ public static boolean mBrokenLibraries; - // If we want to separate mouse and touch events. - // This is only toggled in native code when a hint is set! - public static boolean mSeparateMouseAndTouch; - // Main components protected static SDLActivity mSingleton; protected static SDLSurface mSurface; @@ -86,7 +81,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh protected static boolean mScreenKeyboardShown; protected static ViewGroup mLayout; protected static SDLClipboardHandler mClipboardHandler; - protected static Hashtable mCursors; + protected static Hashtable mCursors; protected static int mLastCursorID; protected static SDLGenericMotionListener_API12 mMotionListener; protected static HIDDeviceManager mHIDDeviceManager; @@ -142,6 +137,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh */ protected String[] getLibraries() { return new String[] { + //"hidapi", "SDL2", // "SDL2_image", // "SDL2_mixer", @@ -176,13 +172,11 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh mTextEdit = null; mLayout = null; mClipboardHandler = null; - mCursors = new Hashtable(); + mCursors = new Hashtable(); mLastCursorID = 0; mSDLThread = null; - mExitCalledFromJava = false; mBrokenLibraries = false; mIsResumedCalled = false; - mIsSurfaceReady = false; mHasFocus = true; mNextNativeState = NativeState.INIT; mCurrentNativeState = NativeState.INIT; @@ -196,6 +190,12 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh Log.v(TAG, "onCreate()"); super.onCreate(savedInstanceState); + try { + Thread.currentThread().setName("SDLActivity"); + } catch (Exception e) { + Log.v(TAG, "modify thread properties failed " + e.toString()); + } + // Load shared libraries String errorMsgBrokenLib = ""; try { @@ -243,12 +243,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh mSingleton = this; SDL.setContext(this); - if (Build.VERSION.SDK_INT >= 11) { - mClipboardHandler = new SDLClipboardHandler_API11(); - } else { - /* Before API 11, no clipboard notification (eg no SDL_CLIPBOARDUPDATE) */ - mClipboardHandler = new SDLClipboardHandler_Old(); - } + mClipboardHandler = new SDLClipboardHandler_API11(); // TODO: Enable HIDDeviceManager? // mHIDDeviceManager = HIDDeviceManager.acquire(this); @@ -261,6 +256,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh // Get our current screen orientation and pass it down. mCurrentOrientation = SDLActivity.getCurrentOrientation(); + // Only record current orientation SDLActivity.onNativeOrientationChanged(mCurrentOrientation); setContentView(mLayout); @@ -280,16 +276,12 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh } } - // Events - @Override - protected void onPause() { - Log.v(TAG, "onPause()"); - super.onPause(); + protected void pauseNativeThread() { mNextNativeState = NativeState.PAUSED; mIsResumedCalled = false; if (SDLActivity.mBrokenLibraries) { - return; + return; } if (mHIDDeviceManager != null) { @@ -299,10 +291,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh SDLActivity.handleNativeState(); } - @Override - protected void onResume() { - Log.v(TAG, "onResume()"); - super.onResume(); + protected void resumeNativeThread() { mNextNativeState = NativeState.RESUMED; mIsResumedCalled = true; @@ -317,6 +306,43 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh SDLActivity.handleNativeState(); } + // Events + @Override + protected void onPause() { + Log.v(TAG, "onPause()"); + super.onPause(); + if (!mHasMultiWindow) { + pauseNativeThread(); + } + } + + @Override + protected void onResume() { + Log.v(TAG, "onResume()"); + super.onResume(); + if (!mHasMultiWindow) { + resumeNativeThread(); + } + } + + @Override + protected void onStop() { + Log.v(TAG, "onStop()"); + super.onStop(); + if (mHasMultiWindow) { + pauseNativeThread(); + } + } + + @Override + protected void onStart() { + Log.v(TAG, "onStart()"); + super.onStart(); + if (mHasMultiWindow) { + resumeNativeThread(); + } + } + public static int getCurrentOrientation() { final Context context = SDLActivity.getContext(); final Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); @@ -353,15 +379,21 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh return; } - SDLActivity.mHasFocus = hasFocus; + mHasFocus = hasFocus; if (hasFocus) { mNextNativeState = NativeState.RESUMED; SDLActivity.getMotionListener().reclaimRelativeMouseModeIfNeeded(); - } else { - mNextNativeState = NativeState.PAUSED; - } - SDLActivity.handleNativeState(); + SDLActivity.handleNativeState(); + nativeFocusChanged(true); + + } else { + nativeFocusChanged(false); + if (!mHasMultiWindow) { + mNextNativeState = NativeState.PAUSED; + SDLActivity.handleNativeState(); + } + } } @Override @@ -387,34 +419,25 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh if (SDLActivity.mBrokenLibraries) { super.onDestroy(); - // Reset everything in case the user re opens the app - SDLActivity.initialize(); return; } - mNextNativeState = NativeState.PAUSED; - SDLActivity.handleNativeState(); - - // Send a quit message to the application - SDLActivity.mExitCalledFromJava = true; - SDLActivity.nativeQuit(); - - // Now wait for the SDL thread to quit if (SDLActivity.mSDLThread != null) { + + // Send Quit event to "SDLThread" thread + SDLActivity.nativeSendQuit(); + + // Wait for "SDLThread" thread to end try { SDLActivity.mSDLThread.join(); } catch(Exception e) { - Log.v(TAG, "Problem stopping thread: " + e); + Log.v(TAG, "Problem stopping SDLThread: " + e); } - SDLActivity.mSDLThread = null; - - //Log.v(TAG, "Finished waiting for SDL thread"); } - super.onDestroy(); + SDLActivity.nativeQuit(); - // Reset everything in case the user re opens the app - SDLActivity.initialize(); + super.onDestroy(); } @Override @@ -491,16 +514,19 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh // Try a transition to paused state if (mNextNativeState == NativeState.PAUSED) { - nativePause(); - if (mSurface != null) + if (mSDLThread != null) { + nativePause(); + } + if (mSurface != null) { mSurface.handlePause(); + } mCurrentNativeState = mNextNativeState; return; } // Try a transition to resumed state if (mNextNativeState == NativeState.RESUMED) { - if (mIsSurfaceReady && mHasFocus && mIsResumedCalled) { + if (mSurface.mIsSurfaceReady && mHasFocus && mIsResumedCalled) { if (mSDLThread == null) { // This is the entry point to the C app. // Start up the C app thread and enable sensor input for the first time @@ -509,28 +535,24 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh mSDLThread = new Thread(new SDLMain(), "SDLThread"); mSurface.enableSensor(Sensor.TYPE_ACCELEROMETER, true); mSDLThread.start(); + + // No nativeResume(), don't signal Android_ResumeSem + mSurface.handleResume(); + } else { + nativeResume(); + mSurface.handleResume(); } - nativeResume(); - mSurface.handleResume(); mCurrentNativeState = mNextNativeState; } } } - /* The native thread has finished */ - public static void handleNativeExit() { - SDLActivity.mSDLThread = null; - if (mSingleton != null) { - mSingleton.finish(); - } - } - - // Messages from the SDLMain thread static final int COMMAND_CHANGE_TITLE = 1; static final int COMMAND_CHANGE_WINDOW_STYLE = 2; static final int COMMAND_TEXTEDIT_HIDE = 3; + static final int COMMAND_CHANGE_SURFACEVIEW_FORMAT = 4; static final int COMMAND_SET_KEEP_SCREEN_ON = 5; protected static final int COMMAND_USER = 0x8000; @@ -628,6 +650,32 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh } break; } + case COMMAND_CHANGE_SURFACEVIEW_FORMAT: + { + int format = (Integer) msg.obj; + int pf; + + if (SDLActivity.mSurface == null) { + return; + } + + SurfaceHolder holder = SDLActivity.mSurface.getHolder(); + if (holder == null) { + return; + } + + if (format == 1) { + pf = PixelFormat.RGBA_8888; + } else if (format == 2) { + pf = PixelFormat.RGBX_8888; + } else { + pf = PixelFormat.RGB_565; + } + + holder.setFormat(pf); + + break; + } default: if ((context instanceof SDLActivity) && !((SDLActivity) context).onUnhandledMessage(msg.arg1, msg.obj)) { Log.e(TAG, "error handling message, command is " + msg.arg1); @@ -705,11 +753,14 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh public static native int nativeSetupJNI(); public static native int nativeRunMain(String library, String function, Object arguments); public static native void nativeLowMemory(); + public static native void nativeSendQuit(); public static native void nativeQuit(); public static native void nativePause(); public static native void nativeResume(); + public static native void nativeFocusChanged(boolean hasFocus); public static native void onNativeDropFile(String filename); - public static native void onNativeResize(int surfaceWidth, int surfaceHeight, int deviceWidth, int deviceHeight, int format, float rate); + public static native void nativeSetScreenResolution(int surfaceWidth, int surfaceHeight, int deviceWidth, int deviceHeight, int format, float rate); + public static native void onNativeResize(); public static native void onNativeKeyDown(int keycode); public static native void onNativeKeyUp(int keycode); public static native void onNativeKeyboardFocusLost(); @@ -719,11 +770,13 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh 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(); public static native void onNativeSurfaceChanged(); public static native void onNativeSurfaceDestroyed(); public static native String nativeGetHint(String name); public static native void nativeSetenv(String name, String value); public static native void onNativeOrientationChanged(int orientation); + public static native void nativeAddTouch(int touchId, String name); /** * This method is called by SDL using JNI. @@ -1014,10 +1067,8 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh public static boolean isTextInputEvent(KeyEvent event) { // Key pressed with Ctrl should be sent as SDL_KEYDOWN/SDL_KEYUP and not SDL_TEXTINPUT - if (Build.VERSION.SDK_INT >= 11) { - if (event.isCtrlPressed()) { - return false; - } + if (event.isCtrlPressed()) { + return false; } return event.isPrintingKey() || event.getKeyCode() == KeyEvent.KEYCODE_SPACE; @@ -1033,23 +1084,28 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh return SDLActivity.mSurface.getNativeSurface(); } + /** + * This method is called by SDL using JNI. + */ + public static void setSurfaceViewFormat(int format) { + mSingleton.sendCommand(COMMAND_CHANGE_SURFACEVIEW_FORMAT, format); + return; + } + // Input /** * This method is called by SDL using JNI. - * @return an array which may be empty but is never null. */ - public static int[] inputGetInputDeviceIds(int sources) { + public static void initTouch() { int[] ids = InputDevice.getDeviceIds(); - int[] filtered = new int[ids.length]; - int used = 0; + for (int i = 0; i < ids.length; ++i) { InputDevice device = InputDevice.getDevice(ids[i]); - if ((device != null) && ((device.getSources() & sources) != 0)) { - filtered[used++] = device.getId(); + if (device != null && (device.getSources() & InputDevice.SOURCE_TOUCHSCREEN) != 0) { + nativeAddTouch(device.getId(), device.getName()); } } - return Arrays.copyOf(filtered, used); } // APK expansion files support @@ -1380,13 +1436,14 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh public static int createCustomCursor(int[] colors, int width, int height, int hotSpotX, int hotSpotY) { Bitmap bitmap = Bitmap.createBitmap(colors, width, height, Bitmap.Config.ARGB_8888); ++mLastCursorID; - // This requires API 24, so use reflection to implement this - try { - Class PointerIconClass = Class.forName("android.view.PointerIcon"); - Class[] arg_types = new Class[] { Bitmap.class, float.class, float.class }; - Method create = PointerIconClass.getMethod("create", arg_types); - mCursors.put(mLastCursorID, create.invoke(null, bitmap, hotSpotX, hotSpotY)); - } catch (Exception e) { + + if (Build.VERSION.SDK_INT >= 24) { + try { + mCursors.put(mLastCursorID, PointerIcon.create(bitmap, hotSpotX, hotSpotY)); + } catch (Exception e) { + return 0; + } + } else { return 0; } return mLastCursorID; @@ -1396,12 +1453,14 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh * This method is called by SDL using JNI. */ public static boolean setCustomCursor(int cursorID) { - // This requires API 24, so use reflection to implement this - try { - Class PointerIconClass = Class.forName("android.view.PointerIcon"); - Method setPointerIcon = SDLSurface.class.getMethod("setPointerIcon", PointerIconClass); - setPointerIcon.invoke(mSurface, mCursors.get(cursorID)); - } catch (Exception e) { + + if (Build.VERSION.SDK_INT >= 24) { + try { + mSurface.setPointerIcon(mCursors.get(cursorID)); + } catch (Exception e) { + return false; + } + } else { return false; } return true; @@ -1450,15 +1509,12 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh cursor_type = 1002; //PointerIcon.TYPE_HAND; break; } - // This requires API 24, so use reflection to implement this - try { - Class PointerIconClass = Class.forName("android.view.PointerIcon"); - Class[] arg_types = new Class[] { Context.class, int.class }; - Method getSystemIcon = PointerIconClass.getMethod("getSystemIcon", arg_types); - Method setPointerIcon = SDLSurface.class.getMethod("setPointerIcon", PointerIconClass); - setPointerIcon.invoke(mSurface, getSystemIcon.invoke(null, SDL.getContext(), cursor_type)); - } catch (Exception e) { - return false; + if (Build.VERSION.SDK_INT >= 24) { + try { + mSurface.setPointerIcon(PointerIcon.getSystemIcon(SDL.getContext(), cursor_type)); + } catch (Exception e) { + return false; + } } return true; } @@ -1475,14 +1531,24 @@ class SDLMain implements Runnable { String function = SDLActivity.mSingleton.getMainFunction(); String[] arguments = SDLActivity.mSingleton.getArguments(); + try { + android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_DISPLAY); + } catch (Exception e) { + Log.v("SDL", "modify thread properties failed " + e.toString()); + } + Log.v("SDL", "Running main function " + function + " from library " + library); + SDLActivity.nativeRunMain(library, function, arguments); Log.v("SDL", "Finished main function"); - // Native thread has finished, let's finish the Activity - if (!SDLActivity.mExitCalledFromJava) { - SDLActivity.handleNativeExit(); + if (SDLActivity.mSingleton.isFinishing()) { + // Activity is already being destroyed + } else { + // Let's finish the Activity + SDLActivity.mSDLThread = null; + SDLActivity.mSingleton.finish(); } } } @@ -1498,11 +1564,14 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, View.OnKeyListener, View.OnTouchListener, SensorEventListener { // Sensors - protected static SensorManager mSensorManager; - protected static Display mDisplay; + protected SensorManager mSensorManager; + protected Display mDisplay; // Keep track of the surface size to normalize touch events - protected static float mWidth, mHeight; + protected float mWidth, mHeight; + + // Is SurfaceView ready for rendering + public boolean mIsSurfaceReady; // Startup public SDLSurface(Context context) { @@ -1518,13 +1587,13 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, mDisplay = ((WindowManager)context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE); - if (Build.VERSION.SDK_INT >= 12) { - setOnGenericMotionListener(SDLActivity.getMotionListener()); - } + setOnGenericMotionListener(SDLActivity.getMotionListener()); // Some arbitrary defaults to avoid a potential division by zero mWidth = 1.0f; mHeight = 1.0f; + + mIsSurfaceReady = false; } public void handlePause() { @@ -1548,7 +1617,7 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, @Override public void surfaceCreated(SurfaceHolder holder) { Log.v("SDL", "surfaceCreated()"); - holder.setType(SurfaceHolder.SURFACE_TYPE_GPU); + SDLActivity.onNativeSurfaceCreated(); } // Called when we lose the surface @@ -1560,7 +1629,7 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, SDLActivity.mNextNativeState = SDLActivity.NativeState.PAUSED; SDLActivity.handleNativeState(); - SDLActivity.mIsSurfaceReady = false; + mIsSurfaceReady = false; SDLActivity.onNativeSurfaceDestroyed(); } @@ -1576,23 +1645,6 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, int sdlFormat = 0x15151002; // SDL_PIXELFORMAT_RGB565 by default switch (format) { - case PixelFormat.A_8: - Log.v("SDL", "pixel format A_8"); - break; - case PixelFormat.LA_88: - Log.v("SDL", "pixel format LA_88"); - break; - case PixelFormat.L_8: - Log.v("SDL", "pixel format L_8"); - break; - case PixelFormat.RGBA_4444: - Log.v("SDL", "pixel format RGBA_4444"); - sdlFormat = 0x15421002; // SDL_PIXELFORMAT_RGBA4444 - break; - case PixelFormat.RGBA_5551: - Log.v("SDL", "pixel format RGBA_5551"); - sdlFormat = 0x15441002; // SDL_PIXELFORMAT_RGBA5551 - break; case PixelFormat.RGBA_8888: Log.v("SDL", "pixel format RGBA_8888"); sdlFormat = 0x16462004; // SDL_PIXELFORMAT_RGBA8888 @@ -1601,10 +1653,6 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, Log.v("SDL", "pixel format RGBX_8888"); sdlFormat = 0x16261804; // SDL_PIXELFORMAT_RGBX8888 break; - case PixelFormat.RGB_332: - Log.v("SDL", "pixel format RGB_332"); - sdlFormat = 0x14110801; // SDL_PIXELFORMAT_RGB332 - break; case PixelFormat.RGB_565: Log.v("SDL", "pixel format RGB_565"); sdlFormat = 0x15151002; // SDL_PIXELFORMAT_RGB565 @@ -1641,7 +1689,8 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, Log.v("SDL", "Window size: " + width + "x" + height); Log.v("SDL", "Device size: " + nDeviceWidth + "x" + nDeviceHeight); - SDLActivity.onNativeResize(width, height, nDeviceWidth, nDeviceHeight, sdlFormat, mDisplay.getRefreshRate()); + SDLActivity.nativeSetScreenResolution(width, height, nDeviceWidth, nDeviceHeight, sdlFormat, mDisplay.getRefreshRate()); + SDLActivity.onNativeResize(); boolean skip = false; int requestedOrientation = SDLActivity.mSingleton.getRequestedOrientation(); @@ -1674,16 +1723,17 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, if (skip) { Log.v("SDL", "Skip .. Surface is not ready."); - SDLActivity.mIsSurfaceReady = false; + mIsSurfaceReady = false; return; } - /* Surface is ready */ - SDLActivity.mIsSurfaceReady = true; - /* If the surface has been previously destroyed by onNativeSurfaceDestroyed, recreate it here */ SDLActivity.onNativeSurfaceChanged(); + /* Surface is ready */ + mIsSurfaceReady = true; + + SDLActivity.mNextNativeState = SDLActivity.NativeState.RESUMED; SDLActivity.handleNativeState(); } @@ -1755,17 +1805,14 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, int i = -1; float x,y,p; - // !!! FIXME: dump this SDK check after 2.0.4 ships and require API14. // 12290 = Samsung DeX mode desktop mouse - if ((event.getSource() == InputDevice.SOURCE_MOUSE || event.getSource() == 12290) && SDLActivity.mSeparateMouseAndTouch) { - if (Build.VERSION.SDK_INT < 14) { - mouseButton = 1; // all mouse buttons are the left button - } else { - try { - mouseButton = (Integer) event.getClass().getMethod("getButtonState").invoke(event); - } catch(Exception e) { - mouseButton = 1; // oh well. - } + // 12290 = 0x3002 = 0x2002 | 0x1002 = SOURCE_MOUSE | SOURCE_TOUCHSCREEN + // 0x2 = SOURCE_CLASS_POINTER + if (event.getSource() == InputDevice.SOURCE_MOUSE || event.getSource() == (InputDevice.SOURCE_MOUSE | InputDevice.SOURCE_TOUCHSCREEN)) { + try { + mouseButton = (Integer) event.getClass().getMethod("getButtonState").invoke(event); + } catch(Exception e) { + mouseButton = 1; // oh well. } // We need to check if we're in relative mouse mode and get the axis offset rather than the x/y values @@ -1835,9 +1882,9 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, } } - try { - Thread.sleep((Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO) ? 16 : 1); - } catch (InterruptedException e) {} + //try { + // Thread.sleep((Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO) ? 16 : 1); + //} catch (InterruptedException e) {} return true; } @@ -2147,33 +2194,3 @@ class SDLClipboardHandler_API11 implements } -class SDLClipboardHandler_Old implements - SDLClipboardHandler { - - protected android.text.ClipboardManager mClipMgrOld; - - SDLClipboardHandler_Old() { - mClipMgrOld = (android.text.ClipboardManager) SDL.getContext().getSystemService(Context.CLIPBOARD_SERVICE); - } - - @Override - public boolean clipboardHasText() { - return mClipMgrOld.hasText(); - } - - @Override - public String clipboardGetText() { - CharSequence text; - text = mClipMgrOld.getText(); - if (text != null) { - return text.toString(); - } - return null; - } - - @Override - public void clipboardSetText(String string) { - mClipMgrOld.setText(string); - } -} - diff --git a/templates/android/template/app/src/main/java/org/libsdl/app/SDLAudioManager.java b/templates/android/template/app/src/main/java/org/libsdl/app/SDLAudioManager.java index bed0eb5c3..0714419c2 100644 --- a/templates/android/template/app/src/main/java/org/libsdl/app/SDLAudioManager.java +++ b/templates/android/template/app/src/main/java/org/libsdl/app/SDLAudioManager.java @@ -73,7 +73,7 @@ public class SDLAudioManager sampleSize = 2; break; } - + if (isCapture) { switch (desiredChannels) { case 1: @@ -298,7 +298,7 @@ public class SDLAudioManager Log.e(TAG, "Attempted to make audio call with uninitialized audio!"); return; } - + for (int i = 0; i < buffer.length; ) { int result = mAudioTrack.write(buffer, i, buffer.length - i); if (result > 0) { @@ -364,5 +364,24 @@ public class SDLAudioManager } } + /** This method is called by SDL using JNI. */ + public static void audioSetThreadPriority(boolean iscapture, int device_id) { + try { + + /* Set thread name */ + if (iscapture) { + Thread.currentThread().setName("SDLAudioC" + device_id); + } else { + Thread.currentThread().setName("SDLAudioP" + device_id); + } + + /* Set thread priority */ + android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_AUDIO); + + } catch (Exception e) { + Log.v(TAG, "modify thread properties failed " + e.toString()); + } + } + public static native int nativeSetupJNI(); } diff --git a/templates/android/template/app/src/main/java/org/libsdl/app/SDLControllerManager.java b/templates/android/template/app/src/main/java/org/libsdl/app/SDLControllerManager.java index 6c5623d27..a81e97bee 100644 --- a/templates/android/template/app/src/main/java/org/libsdl/app/SDLControllerManager.java +++ b/templates/android/template/app/src/main/java/org/libsdl/app/SDLControllerManager.java @@ -39,12 +39,8 @@ public class SDLControllerManager if (mJoystickHandler == null) { if (Build.VERSION.SDK_INT >= 19) { mJoystickHandler = new SDLJoystickHandler_API19(); - } else if (Build.VERSION.SDK_INT >= 16) { - mJoystickHandler = new SDLJoystickHandler_API16(); - } else if (Build.VERSION.SDK_INT >= 12) { - mJoystickHandler = new SDLJoystickHandler_API12(); } else { - mJoystickHandler = new SDLJoystickHandler(); + mJoystickHandler = new SDLJoystickHandler_API16(); } } @@ -103,8 +99,8 @@ public class SDLControllerManager /* This is called for every button press, so let's not spam the logs */ /** - if ((sources & InputDevice.SOURCE_CLASS_JOYSTICK) == InputDevice.SOURCE_CLASS_JOYSTICK) { - Log.v(TAG, "Input device " + device.getName() + " is a joystick."); + if ((sources & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) { + Log.v(TAG, "Input device " + device.getName() + " has class joystick."); } if ((sources & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD) { Log.v(TAG, "Input device " + device.getName() + " is a dpad."); @@ -114,7 +110,7 @@ public class SDLControllerManager } **/ - return (((sources & InputDevice.SOURCE_CLASS_JOYSTICK) == InputDevice.SOURCE_CLASS_JOYSTICK) || + return ((sources & InputDevice.SOURCE_CLASS_JOYSTICK) != 0 || ((sources & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD) || ((sources & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD) ); @@ -122,7 +118,6 @@ public class SDLControllerManager } -/* A null joystick handler for API level < 12 devices (the accelerometer is handled separately) */ class SDLJoystickHandler { /** @@ -142,7 +137,7 @@ class SDLJoystickHandler { } /* Actual joystick functionality available for API >= 12 devices */ -class SDLJoystickHandler_API12 extends SDLJoystickHandler { +class SDLJoystickHandler_API16 extends SDLJoystickHandler { static class SDLJoystick { public int device_id; @@ -174,7 +169,7 @@ class SDLJoystickHandler_API12 extends SDLJoystickHandler { private ArrayList mJoysticks; - public SDLJoystickHandler_API12() { + public SDLJoystickHandler_API16() { mJoysticks = new ArrayList(); } @@ -278,6 +273,12 @@ class SDLJoystickHandler_API12 extends SDLJoystickHandler { } public String getJoystickDescriptor(InputDevice joystickDevice) { + String desc = joystickDevice.getDescriptor(); + + if (desc != null && !desc.isEmpty()) { + return desc; + } + return joystickDevice.getName(); } public int getProductId(InputDevice joystickDevice) { @@ -291,20 +292,6 @@ class SDLJoystickHandler_API12 extends SDLJoystickHandler { } } -class SDLJoystickHandler_API16 extends SDLJoystickHandler_API12 { - - @Override - public String getJoystickDescriptor(InputDevice joystickDevice) { - String desc = joystickDevice.getDescriptor(); - - if (desc != null && !desc.isEmpty()) { - return desc; - } - - return super.getJoystickDescriptor(joystickDevice); - } -} - class SDLJoystickHandler_API19 extends SDLJoystickHandler_API16 { @Override @@ -482,21 +469,18 @@ class SDLHapticHandler { // so the first controller seen by SDL matches what the receiver // considers to be the first controller - if (Build.VERSION.SDK_INT >= 16) - { - for (int i = deviceIds.length - 1; i > -1; i--) { - SDLHaptic haptic = getHaptic(deviceIds[i]); - if (haptic == null) { - InputDevice device = InputDevice.getDevice(deviceIds[i]); - Vibrator vib = device.getVibrator(); - if (vib.hasVibrator()) { - haptic = new SDLHaptic(); - haptic.device_id = deviceIds[i]; - haptic.name = device.getName(); - haptic.vib = vib; - mHaptics.add(haptic); - SDLControllerManager.nativeAddHaptic(haptic.device_id, haptic.name); - } + for (int i = deviceIds.length - 1; i > -1; i--) { + SDLHaptic haptic = getHaptic(deviceIds[i]); + if (haptic == null) { + InputDevice device = InputDevice.getDevice(deviceIds[i]); + Vibrator vib = device.getVibrator(); + if (vib.hasVibrator()) { + haptic = new SDLHaptic(); + haptic.device_id = deviceIds[i]; + haptic.name = device.getName(); + haptic.vib = vib; + mHaptics.add(haptic); + SDLControllerManager.nativeAddHaptic(haptic.device_id, haptic.name); } } } @@ -504,11 +488,7 @@ class SDLHapticHandler { /* Check VIBRATOR_SERVICE */ Vibrator vib = (Vibrator) SDL.getContext().getSystemService(Context.VIBRATOR_SERVICE); if (vib != null) { - if (Build.VERSION.SDK_INT >= 11) { - hasVibratorService = vib.hasVibrator(); - } else { - hasVibratorService = true; - } + hasVibratorService = vib.hasVibrator(); if (hasVibratorService) { SDLHaptic haptic = getHaptic(deviceId_VIBRATOR_SERVICE); @@ -575,9 +555,6 @@ class SDLGenericMotionListener_API12 implements View.OnGenericMotionListener { return SDLControllerManager.handleJoystickMotionEvent(event); case InputDevice.SOURCE_MOUSE: - if (!SDLActivity.mSeparateMouseAndTouch) { - break; - } action = event.getActionMasked(); switch (action) { case MotionEvent.ACTION_SCROLL: @@ -640,51 +617,22 @@ class SDLGenericMotionListener_API24 extends SDLGenericMotionListener_API12 { @Override public boolean onGenericMotion(View v, MotionEvent event) { - float x, y; - int action; - switch ( event.getSource() ) { - case InputDevice.SOURCE_JOYSTICK: - case InputDevice.SOURCE_GAMEPAD: - case InputDevice.SOURCE_DPAD: - return SDLControllerManager.handleJoystickMotionEvent(event); - - case InputDevice.SOURCE_MOUSE: - if (!SDLActivity.mSeparateMouseAndTouch) { - break; + // Handle relative mouse mode + if (mRelativeModeEnabled) { + if (event.getSource() == InputDevice.SOURCE_MOUSE) { + int action = event.getActionMasked(); + if (action == MotionEvent.ACTION_HOVER_MOVE) { + float x = event.getAxisValue(MotionEvent.AXIS_RELATIVE_X); + float y = event.getAxisValue(MotionEvent.AXIS_RELATIVE_Y); + SDLActivity.onNativeMouse(0, action, x, y, true); + return true; } - action = event.getActionMasked(); - switch (action) { - case MotionEvent.ACTION_SCROLL: - x = event.getAxisValue(MotionEvent.AXIS_HSCROLL, 0); - y = event.getAxisValue(MotionEvent.AXIS_VSCROLL, 0); - SDLActivity.onNativeMouse(0, action, x, y, false); - return true; - - case MotionEvent.ACTION_HOVER_MOVE: - if (mRelativeModeEnabled) { - x = event.getAxisValue(MotionEvent.AXIS_RELATIVE_X); - y = event.getAxisValue(MotionEvent.AXIS_RELATIVE_Y); - } - else { - x = event.getX(0); - y = event.getY(0); - } - - SDLActivity.onNativeMouse(0, action, x, y, mRelativeModeEnabled); - return true; - - default: - break; - } - break; - - default: - break; + } } - // Event was not managed - return false; + // Event was not managed, call SDLGenericMotionListener_API12 method + return super.onGenericMotion(v, event); } @Override @@ -741,11 +689,8 @@ class SDLGenericMotionListener_API26 extends SDLGenericMotionListener_API24 { return SDLControllerManager.handleJoystickMotionEvent(event); case InputDevice.SOURCE_MOUSE: - case 12290: // DeX desktop mouse cursor is a separate non-standard input type. - if (!SDLActivity.mSeparateMouseAndTouch) { - break; - } - + // DeX desktop mouse cursor is a separate non-standard input type. + case InputDevice.SOURCE_MOUSE | InputDevice.SOURCE_TOUCHSCREEN: action = event.getActionMasked(); switch (action) { case MotionEvent.ACTION_SCROLL: @@ -766,9 +711,6 @@ class SDLGenericMotionListener_API26 extends SDLGenericMotionListener_API24 { break; case InputDevice.SOURCE_MOUSE_RELATIVE: - if (!SDLActivity.mSeparateMouseAndTouch) { - break; - } action = event.getActionMasked(); switch (action) { case MotionEvent.ACTION_SCROLL: @@ -843,4 +785,4 @@ class SDLGenericMotionListener_API26 extends SDLGenericMotionListener_API24 { // Relative mouse in capture mode will only have relative for X/Y return event.getY(0); } -} \ No newline at end of file +}