mirror of
https://github.com/etlegacy/etlegacy-android.git
synced 2025-04-12 20:20:47 +00:00
sdl: update up to 2.0.14
This commit is contained in:
parent
abfe805e92
commit
33de542dad
10 changed files with 378 additions and 354 deletions
|
@ -353,9 +353,18 @@ public class HIDDeviceManager {
|
|||
|
||||
private void connectHIDDeviceUSB(UsbDevice usbDevice) {
|
||||
synchronized (this) {
|
||||
int interface_mask = 0;
|
||||
for (int interface_index = 0; interface_index < usbDevice.getInterfaceCount(); interface_index++) {
|
||||
UsbInterface usbInterface = usbDevice.getInterface(interface_index);
|
||||
if (isHIDDeviceInterface(usbDevice, usbInterface)) {
|
||||
// Check to see if we've already added this interface
|
||||
// This happens with the Xbox Series X controller which has a duplicate interface 0, which is inactive
|
||||
int interface_id = usbInterface.getId();
|
||||
if ((interface_mask & (1 << interface_id)) != 0) {
|
||||
continue;
|
||||
}
|
||||
interface_mask |= (1 << interface_id);
|
||||
|
||||
HIDDeviceUSB device = new HIDDeviceUSB(this, usbDevice, interface_index);
|
||||
int id = device.getId();
|
||||
mDevicesById.put(id, device);
|
||||
|
|
|
@ -53,7 +53,12 @@ class HIDDeviceUSB implements HIDDevice {
|
|||
public String getSerialNumber() {
|
||||
String result = null;
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
result = mDevice.getSerialNumber();
|
||||
try {
|
||||
result = mDevice.getSerialNumber();
|
||||
}
|
||||
catch (SecurityException exception) {
|
||||
//Log.w(TAG, "App permissions mean we cannot get serial number for device " + getDeviceName() + " message: " + exception.getMessage());
|
||||
}
|
||||
}
|
||||
if (result == null) {
|
||||
result = "";
|
||||
|
|
|
@ -2,7 +2,8 @@ package org.libsdl.app;
|
|||
|
||||
import android.content.Context;
|
||||
|
||||
import java.lang.reflect.*;
|
||||
import java.lang.Class;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
SDL library initialization
|
||||
|
@ -51,16 +52,16 @@ public class SDL {
|
|||
// To use ReLinker, just add it as a dependency. For more information, see
|
||||
// https://github.com/KeepSafe/ReLinker for ReLinker's repository.
|
||||
//
|
||||
Class relinkClass = mContext.getClassLoader().loadClass("com.getkeepsafe.relinker.ReLinker");
|
||||
Class relinkListenerClass = mContext.getClassLoader().loadClass("com.getkeepsafe.relinker.ReLinker$LoadListener");
|
||||
Class contextClass = mContext.getClassLoader().loadClass("android.content.Context");
|
||||
Class stringClass = mContext.getClassLoader().loadClass("java.lang.String");
|
||||
Class<?> relinkClass = mContext.getClassLoader().loadClass("com.getkeepsafe.relinker.ReLinker");
|
||||
Class<?> relinkListenerClass = mContext.getClassLoader().loadClass("com.getkeepsafe.relinker.ReLinker$LoadListener");
|
||||
Class<?> contextClass = mContext.getClassLoader().loadClass("android.content.Context");
|
||||
Class<?> stringClass = mContext.getClassLoader().loadClass("java.lang.String");
|
||||
|
||||
// Get a 'force' instance of the ReLinker, so we can ensure libraries are reinstalled if
|
||||
// they've changed during updates.
|
||||
Method forceMethod = relinkClass.getDeclaredMethod("force");
|
||||
Object relinkInstance = forceMethod.invoke(null);
|
||||
Class relinkInstanceClass = relinkInstance.getClass();
|
||||
Class<?> relinkInstanceClass = relinkInstance.getClass();
|
||||
|
||||
// Actually load the library!
|
||||
Method loadMethod = relinkInstanceClass.getDeclaredMethod("loadLibrary", contextClass, stringClass, stringClass, relinkListenerClass);
|
||||
|
@ -77,7 +78,7 @@ public class SDL {
|
|||
catch (final SecurityException se) {
|
||||
throw se;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected static Context mContext;
|
||||
|
|
|
@ -1,35 +1,61 @@
|
|||
package org.libsdl.app;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Hashtable;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.Math;
|
||||
|
||||
import android.app.*;
|
||||
import android.content.*;
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.app.UiModeManager;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.ClipData;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.hardware.Sensor;
|
||||
import android.hardware.SensorEvent;
|
||||
import android.hardware.SensorEventListener;
|
||||
import android.hardware.SensorManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.text.InputType;
|
||||
import android.view.*;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
import android.view.Display;
|
||||
import android.view.Gravity;
|
||||
import android.view.InputDevice;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.PointerIcon;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.view.inputmethod.BaseInputConnection;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.view.inputmethod.InputConnection;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.Button;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
import android.os.*;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
import android.graphics.*;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.hardware.*;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
|
||||
import java.util.Hashtable;
|
||||
import java.util.Locale;
|
||||
|
||||
|
||||
/**
|
||||
SDL Activity
|
||||
|
@ -41,7 +67,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
|||
public static final boolean mHasMultiWindow = (Build.VERSION.SDK_INT >= 24);
|
||||
|
||||
// Cursor types
|
||||
private static final int SDL_SYSTEM_CURSOR_NONE = -1;
|
||||
// private static final int SDL_SYSTEM_CURSOR_NONE = -1;
|
||||
private static final int SDL_SYSTEM_CURSOR_ARROW = 0;
|
||||
private static final int SDL_SYSTEM_CURSOR_IBEAM = 1;
|
||||
private static final int SDL_SYSTEM_CURSOR_WAIT = 2;
|
||||
|
@ -62,6 +88,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
|||
protected static final int SDL_ORIENTATION_PORTRAIT_FLIPPED = 4;
|
||||
|
||||
protected static int mCurrentOrientation;
|
||||
protected static Locale mCurrentLocale;
|
||||
|
||||
// Handle the state of the native layer
|
||||
public enum NativeState {
|
||||
|
@ -72,7 +99,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
|||
public static NativeState mCurrentNativeState;
|
||||
|
||||
/** If shared libraries (e.g. SDL or the native application) could not be loaded. */
|
||||
public static boolean mBrokenLibraries;
|
||||
public static boolean mBrokenLibraries = true;
|
||||
|
||||
// Main components
|
||||
protected static SDLActivity mSingleton;
|
||||
|
@ -93,8 +120,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
|||
if (mMotionListener == null) {
|
||||
if (Build.VERSION.SDK_INT >= 26) {
|
||||
mMotionListener = new SDLGenericMotionListener_API26();
|
||||
} else
|
||||
if (Build.VERSION.SDK_INT >= 24) {
|
||||
} else if (Build.VERSION.SDK_INT >= 24) {
|
||||
mMotionListener = new SDLGenericMotionListener_API24();
|
||||
} else {
|
||||
mMotionListener = new SDLGenericMotionListener_API12();
|
||||
|
@ -175,7 +201,6 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
|||
mCursors = new Hashtable<Integer, PointerIcon>();
|
||||
mLastCursorID = 0;
|
||||
mSDLThread = null;
|
||||
mBrokenLibraries = false;
|
||||
mIsResumedCalled = false;
|
||||
mHasFocus = true;
|
||||
mNextNativeState = NativeState.INIT;
|
||||
|
@ -200,6 +225,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
|||
String errorMsgBrokenLib = "";
|
||||
try {
|
||||
loadLibraries();
|
||||
mBrokenLibraries = false; /* success */
|
||||
} catch(UnsatisfiedLinkError e) {
|
||||
System.err.println(e.getMessage());
|
||||
mBrokenLibraries = true;
|
||||
|
@ -243,7 +269,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
|||
mSingleton = this;
|
||||
SDL.setContext(this);
|
||||
|
||||
mClipboardHandler = new SDLClipboardHandler_API11();
|
||||
mClipboardHandler = new SDLClipboardHandler();
|
||||
|
||||
mHIDDeviceManager = HIDDeviceManager.acquire(this);
|
||||
|
||||
|
@ -258,6 +284,15 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
|||
// Only record current orientation
|
||||
SDLActivity.onNativeOrientationChanged(mCurrentOrientation);
|
||||
|
||||
try {
|
||||
if (Build.VERSION.SDK_INT < 24) {
|
||||
mCurrentLocale = getContext().getResources().getConfiguration().locale;
|
||||
} else {
|
||||
mCurrentLocale = getContext().getResources().getConfiguration().getLocales().get(0);
|
||||
}
|
||||
} catch(Exception ignored) {
|
||||
}
|
||||
|
||||
setContentView(mLayout);
|
||||
|
||||
setWindowStyle(false);
|
||||
|
@ -407,6 +442,21 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
|||
SDLActivity.nativeLowMemory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
Log.v(TAG, "onConfigurationChanged()");
|
||||
super.onConfigurationChanged(newConfig);
|
||||
|
||||
if (SDLActivity.mBrokenLibraries) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mCurrentLocale == null || !mCurrentLocale.equals(newConfig.locale)) {
|
||||
mCurrentLocale = newConfig.locale;
|
||||
SDLActivity.onNativeLocaleChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
Log.v(TAG, "onDestroy()");
|
||||
|
@ -540,11 +590,10 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
|||
mSDLThread.start();
|
||||
|
||||
// No nativeResume(), don't signal Android_ResumeSem
|
||||
mSurface.handleResume();
|
||||
} else {
|
||||
nativeResume();
|
||||
mSurface.handleResume();
|
||||
}
|
||||
mSurface.handleResume();
|
||||
|
||||
mCurrentNativeState = mNextNativeState;
|
||||
}
|
||||
|
@ -596,34 +645,32 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
|||
}
|
||||
break;
|
||||
case COMMAND_CHANGE_WINDOW_STYLE:
|
||||
if (Build.VERSION.SDK_INT < 19) {
|
||||
// This version of Android doesn't support the immersive fullscreen mode
|
||||
break;
|
||||
}
|
||||
if (context instanceof Activity) {
|
||||
Window window = ((Activity) context).getWindow();
|
||||
if (window != null) {
|
||||
if ((msg.obj instanceof Integer) && (((Integer) msg.obj).intValue() != 0)) {
|
||||
int flags = View.SYSTEM_UI_FLAG_FULLSCREEN |
|
||||
if (Build.VERSION.SDK_INT >= 19) {
|
||||
if (context instanceof Activity) {
|
||||
Window window = ((Activity) context).getWindow();
|
||||
if (window != null) {
|
||||
if ((msg.obj instanceof Integer) && ((Integer) msg.obj != 0)) {
|
||||
int flags = View.SYSTEM_UI_FLAG_FULLSCREEN |
|
||||
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
|
||||
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY |
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.INVISIBLE;
|
||||
window.getDecorView().setSystemUiVisibility(flags);
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
window.clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
|
||||
SDLActivity.mFullscreenModeActive = true;
|
||||
} else {
|
||||
int flags = View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_VISIBLE;
|
||||
window.getDecorView().setSystemUiVisibility(flags);
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
|
||||
window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
SDLActivity.mFullscreenModeActive = false;
|
||||
window.getDecorView().setSystemUiVisibility(flags);
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
window.clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
|
||||
SDLActivity.mFullscreenModeActive = true;
|
||||
} else {
|
||||
int flags = View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_VISIBLE;
|
||||
window.getDecorView().setSystemUiVisibility(flags);
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
|
||||
window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
SDLActivity.mFullscreenModeActive = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Log.e(TAG, "error handling message, getContext() returned no Activity");
|
||||
}
|
||||
} else {
|
||||
Log.e(TAG, "error handling message, getContext() returned no Activity");
|
||||
}
|
||||
break;
|
||||
case COMMAND_TEXTEDIT_HIDE:
|
||||
|
@ -646,7 +693,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
|||
if (context instanceof Activity) {
|
||||
Window window = ((Activity) context).getWindow();
|
||||
if (window != null) {
|
||||
if ((msg.obj instanceof Integer) && (((Integer) msg.obj).intValue() != 0)) {
|
||||
if ((msg.obj instanceof Integer) && ((Integer) msg.obj != 0)) {
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
} else {
|
||||
window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
|
@ -699,53 +746,53 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
|||
msg.obj = data;
|
||||
boolean result = commandHandler.sendMessage(msg);
|
||||
|
||||
if ((Build.VERSION.SDK_INT >= 19) && (command == COMMAND_CHANGE_WINDOW_STYLE)) {
|
||||
// Ensure we don't return until the resize has actually happened,
|
||||
// or 500ms have passed.
|
||||
if (Build.VERSION.SDK_INT >= 19) {
|
||||
if (command == COMMAND_CHANGE_WINDOW_STYLE) {
|
||||
// Ensure we don't return until the resize has actually happened,
|
||||
// or 500ms have passed.
|
||||
|
||||
boolean bShouldWait = false;
|
||||
boolean bShouldWait = false;
|
||||
|
||||
if (data instanceof Integer) {
|
||||
// Let's figure out if we're already laid out fullscreen or not.
|
||||
Display display = ((WindowManager)getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
|
||||
android.util.DisplayMetrics realMetrics = new android.util.DisplayMetrics();
|
||||
display.getRealMetrics( realMetrics );
|
||||
if (data instanceof Integer) {
|
||||
// Let's figure out if we're already laid out fullscreen or not.
|
||||
Display display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
|
||||
DisplayMetrics realMetrics = new DisplayMetrics();
|
||||
display.getRealMetrics(realMetrics);
|
||||
|
||||
boolean bFullscreenLayout = ((realMetrics.widthPixels == mSurface.getWidth()) &&
|
||||
(realMetrics.heightPixels == mSurface.getHeight()));
|
||||
boolean bFullscreenLayout = ((realMetrics.widthPixels == mSurface.getWidth()) &&
|
||||
(realMetrics.heightPixels == mSurface.getHeight()));
|
||||
|
||||
if (((Integer)data).intValue() == 1) {
|
||||
// If we aren't laid out fullscreen or actively in fullscreen mode already, we're going
|
||||
// to change size and should wait for surfaceChanged() before we return, so the size
|
||||
// is right back in native code. If we're already laid out fullscreen, though, we're
|
||||
// not going to change size even if we change decor modes, so we shouldn't wait for
|
||||
// surfaceChanged() -- which may not even happen -- and should return immediately.
|
||||
bShouldWait = !bFullscreenLayout;
|
||||
}
|
||||
else {
|
||||
// If we're laid out fullscreen (even if the status bar and nav bar are present),
|
||||
// or are actively in fullscreen, we're going to change size and should wait for
|
||||
// surfaceChanged before we return, so the size is right back in native code.
|
||||
bShouldWait = bFullscreenLayout;
|
||||
}
|
||||
}
|
||||
|
||||
if (bShouldWait && (SDLActivity.getContext() != null)) {
|
||||
// We'll wait for the surfaceChanged() method, which will notify us
|
||||
// when called. That way, we know our current size is really the
|
||||
// size we need, instead of grabbing a size that's still got
|
||||
// the navigation and/or status bars before they're hidden.
|
||||
//
|
||||
// We'll wait for up to half a second, because some devices
|
||||
// take a surprisingly long time for the surface resize, but
|
||||
// then we'll just give up and return.
|
||||
//
|
||||
synchronized(SDLActivity.getContext()) {
|
||||
try {
|
||||
SDLActivity.getContext().wait(500);
|
||||
if ((Integer) data == 1) {
|
||||
// If we aren't laid out fullscreen or actively in fullscreen mode already, we're going
|
||||
// to change size and should wait for surfaceChanged() before we return, so the size
|
||||
// is right back in native code. If we're already laid out fullscreen, though, we're
|
||||
// not going to change size even if we change decor modes, so we shouldn't wait for
|
||||
// surfaceChanged() -- which may not even happen -- and should return immediately.
|
||||
bShouldWait = !bFullscreenLayout;
|
||||
} else {
|
||||
// If we're laid out fullscreen (even if the status bar and nav bar are present),
|
||||
// or are actively in fullscreen, we're going to change size and should wait for
|
||||
// surfaceChanged before we return, so the size is right back in native code.
|
||||
bShouldWait = bFullscreenLayout;
|
||||
}
|
||||
catch (InterruptedException ie) {
|
||||
ie.printStackTrace();
|
||||
}
|
||||
|
||||
if (bShouldWait && (SDLActivity.getContext() != null)) {
|
||||
// We'll wait for the surfaceChanged() method, which will notify us
|
||||
// when called. That way, we know our current size is really the
|
||||
// size we need, instead of grabbing a size that's still got
|
||||
// the navigation and/or status bars before they're hidden.
|
||||
//
|
||||
// We'll wait for up to half a second, because some devices
|
||||
// take a surprisingly long time for the surface resize, but
|
||||
// then we'll just give up and return.
|
||||
//
|
||||
synchronized (SDLActivity.getContext()) {
|
||||
try {
|
||||
SDLActivity.getContext().wait(500);
|
||||
} catch (InterruptedException ie) {
|
||||
ie.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -784,6 +831,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
|||
public static native void onNativeOrientationChanged(int orientation);
|
||||
public static native void nativeAddTouch(int touchId, String name);
|
||||
public static native void nativePermissionResult(int requestCode, boolean result);
|
||||
public static native void onNativeLocaleChanged();
|
||||
|
||||
/**
|
||||
* This method is called by SDL using JNI.
|
||||
|
@ -838,9 +886,9 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
|||
orientation_portrait = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
|
||||
}
|
||||
|
||||
boolean is_landscape_allowed = (orientation_landscape == -1 ? false : true);
|
||||
boolean is_portrait_allowed = (orientation_portrait == -1 ? false : true);
|
||||
int req = -1; /* Requested orientation */
|
||||
boolean is_landscape_allowed = (orientation_landscape != -1);
|
||||
boolean is_portrait_allowed = (orientation_portrait != -1);
|
||||
int req; /* Requested orientation */
|
||||
|
||||
/* No valid hint, nothing is explicitly allowed */
|
||||
if (!is_portrait_allowed && !is_landscape_allowed) {
|
||||
|
@ -872,7 +920,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
|||
}
|
||||
}
|
||||
|
||||
Log.v("SDL", "setOrientation() requestedOrientation=" + req + " width=" + w +" height="+ h +" resizable=" + resizable + " hint=" + hint);
|
||||
Log.v(TAG, "setOrientation() requestedOrientation=" + req + " width=" + w +" height="+ h +" resizable=" + resizable + " hint=" + hint);
|
||||
mSingleton.setRequestedOrientation(req);
|
||||
}
|
||||
|
||||
|
@ -976,7 +1024,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
|||
if (mSingleton == null) {
|
||||
return false;
|
||||
}
|
||||
return mSingleton.sendCommand(command, Integer.valueOf(param));
|
||||
return mSingleton.sendCommand(command, param);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1000,30 +1048,30 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
|||
if (Build.MANUFACTURER.equals("Amlogic") && Build.MODEL.equals("X96-W")) {
|
||||
return true;
|
||||
}
|
||||
if (Build.MANUFACTURER.equals("Amlogic") && Build.MODEL.startsWith("TV")) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return Build.MANUFACTURER.equals("Amlogic") && Build.MODEL.startsWith("TV");
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called by SDL using JNI.
|
||||
*/
|
||||
public static boolean isTablet() {
|
||||
public static double getDiagonal()
|
||||
{
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
Activity activity = (Activity)getContext();
|
||||
if (activity == null) {
|
||||
return false;
|
||||
return 0.0;
|
||||
}
|
||||
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
|
||||
|
||||
double dWidthInches = metrics.widthPixels / (double)metrics.xdpi;
|
||||
double dHeightInches = metrics.heightPixels / (double)metrics.ydpi;
|
||||
|
||||
double dDiagonal = Math.sqrt((dWidthInches * dWidthInches) + (dHeightInches * dHeightInches));
|
||||
return Math.sqrt((dWidthInches * dWidthInches) + (dHeightInches * dHeightInches));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called by SDL using JNI.
|
||||
*/
|
||||
public static boolean isTablet() {
|
||||
// If our diagonal size is seven inches or greater, we consider ourselves a tablet.
|
||||
return (dDiagonal >= 7.0);
|
||||
return (getDiagonal() >= 7.0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1045,7 +1093,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
|||
}
|
||||
try {
|
||||
final Configuration config = getContext().getResources().getConfiguration();
|
||||
final Class configClass = config.getClass();
|
||||
final Class<?> configClass = config.getClass();
|
||||
return configClass.getField("SEM_DESKTOP_MODE_ENABLED").getInt(configClass)
|
||||
== configClass.getField("semDesktopModeEnabled").getInt(config);
|
||||
} catch(Exception ignored) {
|
||||
|
@ -1065,6 +1113,10 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
|||
*/
|
||||
public static boolean getManifestEnvironmentVariables() {
|
||||
try {
|
||||
if (getContext() == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ApplicationInfo applicationInfo = getContext().getPackageManager().getApplicationInfo(getContext().getPackageName(), PackageManager.GET_META_DATA);
|
||||
Bundle bundle = applicationInfo.metaData;
|
||||
if (bundle == null) {
|
||||
|
@ -1082,7 +1134,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
|||
/* environment variables set! */
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
Log.v("SDL", "exception " + e.toString());
|
||||
Log.v(TAG, "exception " + e.toString());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -1090,7 +1142,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
|||
// This method is called by SDLControllerManager's API 26 Generic Motion Handler.
|
||||
public static View getContentView()
|
||||
{
|
||||
return mSingleton.mLayout;
|
||||
return mLayout;
|
||||
}
|
||||
|
||||
static class ShowTextInputTask implements Runnable {
|
||||
|
@ -1175,7 +1227,6 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
|||
*/
|
||||
public static void setSurfaceViewFormat(int format) {
|
||||
mSingleton.sendCommand(COMMAND_CHANGE_SURFACEVIEW_FORMAT, format);
|
||||
return;
|
||||
}
|
||||
|
||||
// Input
|
||||
|
@ -1186,92 +1237,19 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
|||
public static void initTouch() {
|
||||
int[] ids = InputDevice.getDeviceIds();
|
||||
|
||||
for (int i = 0; i < ids.length; ++i) {
|
||||
InputDevice device = InputDevice.getDevice(ids[i]);
|
||||
for (int id : ids) {
|
||||
InputDevice device = InputDevice.getDevice(id);
|
||||
if (device != null && (device.getSources() & InputDevice.SOURCE_TOUCHSCREEN) != 0) {
|
||||
nativeAddTouch(device.getId(), device.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// APK expansion files support
|
||||
|
||||
/** com.android.vending.expansion.zipfile.ZipResourceFile object or null. */
|
||||
private static Object expansionFile;
|
||||
|
||||
/** com.android.vending.expansion.zipfile.ZipResourceFile's getInputStream() or null. */
|
||||
private static Method expansionFileMethod;
|
||||
|
||||
/**
|
||||
* This method is called by SDL using JNI.
|
||||
* @return an InputStream on success or null if no expansion file was used.
|
||||
* @throws IOException on errors. Message is set for the SDL error message.
|
||||
*/
|
||||
public static InputStream openAPKExpansionInputStream(String fileName) throws IOException {
|
||||
// Get a ZipResourceFile representing a merger of both the main and patch files
|
||||
if (expansionFile == null) {
|
||||
String mainHint = nativeGetHint("SDL_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION");
|
||||
if (mainHint == null) {
|
||||
return null; // no expansion use if no main version was set
|
||||
}
|
||||
String patchHint = nativeGetHint("SDL_ANDROID_APK_EXPANSION_PATCH_FILE_VERSION");
|
||||
if (patchHint == null) {
|
||||
return null; // no expansion use if no patch version was set
|
||||
}
|
||||
|
||||
Integer mainVersion;
|
||||
Integer patchVersion;
|
||||
try {
|
||||
mainVersion = Integer.valueOf(mainHint);
|
||||
patchVersion = Integer.valueOf(patchHint);
|
||||
} catch (NumberFormatException ex) {
|
||||
ex.printStackTrace();
|
||||
throw new IOException("No valid file versions set for APK expansion files", ex);
|
||||
}
|
||||
|
||||
try {
|
||||
// To avoid direct dependency on Google APK expansion library that is
|
||||
// not a part of Android SDK we access it using reflection
|
||||
expansionFile = Class.forName("com.android.vending.expansion.zipfile.APKExpansionSupport")
|
||||
.getMethod("getAPKExpansionZipFile", Context.class, int.class, int.class)
|
||||
.invoke(null, SDL.getContext(), mainVersion, patchVersion);
|
||||
|
||||
expansionFileMethod = expansionFile.getClass()
|
||||
.getMethod("getInputStream", String.class);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
expansionFile = null;
|
||||
expansionFileMethod = null;
|
||||
throw new IOException("Could not access APK expansion support library", ex);
|
||||
}
|
||||
}
|
||||
|
||||
// Get an input stream for a known file inside the expansion file ZIPs
|
||||
InputStream fileStream;
|
||||
try {
|
||||
fileStream = (InputStream)expansionFileMethod.invoke(expansionFile, fileName);
|
||||
} catch (Exception ex) {
|
||||
// calling "getInputStream" failed
|
||||
ex.printStackTrace();
|
||||
throw new IOException("Could not open stream from APK expansion file", ex);
|
||||
}
|
||||
|
||||
if (fileStream == null) {
|
||||
// calling "getInputStream" was successful but null was returned
|
||||
throw new IOException("Could not find path in APK expansion file");
|
||||
}
|
||||
|
||||
return fileStream;
|
||||
}
|
||||
|
||||
// Messagebox
|
||||
|
||||
/** Result of current messagebox. Also used for blocking the calling thread. */
|
||||
protected final int[] messageboxSelection = new int[1];
|
||||
|
||||
/** Id of current dialog. */
|
||||
protected int dialogs = 0;
|
||||
|
||||
/**
|
||||
* This method is called by SDL using JNI.
|
||||
* Shows the messagebox from UI thread and block calling thread.
|
||||
|
@ -1315,7 +1293,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
|||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
showDialog(dialogs++, args);
|
||||
messageboxCreateAndShow(args);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1335,8 +1313,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
|||
return messageboxSelection[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Dialog onCreateDialog(int ignore, Bundle args) {
|
||||
protected void messageboxCreateAndShow(Bundle args) {
|
||||
|
||||
// TODO set values from "flags" to messagebox dialog
|
||||
|
||||
|
@ -1365,7 +1342,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
|||
|
||||
// create dialog with title and a listener to wake up calling thread
|
||||
|
||||
final Dialog dialog = new Dialog(this);
|
||||
final AlertDialog dialog = new AlertDialog.Builder(this).create();
|
||||
dialog.setTitle(args.getString("title"));
|
||||
dialog.setCancelable(false);
|
||||
dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
|
||||
|
@ -1451,7 +1428,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
|||
|
||||
// add content to dialog and return
|
||||
|
||||
dialog.setContentView(content);
|
||||
dialog.setView(content);
|
||||
dialog.setOnKeyListener(new Dialog.OnKeyListener() {
|
||||
@Override
|
||||
public boolean onKey(DialogInterface d, int keyCode, KeyEvent event) {
|
||||
|
@ -1466,20 +1443,22 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
|||
}
|
||||
});
|
||||
|
||||
return dialog;
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
private final Runnable rehideSystemUi = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
int flags = View.SYSTEM_UI_FLAG_FULLSCREEN |
|
||||
if (Build.VERSION.SDK_INT >= 19) {
|
||||
int flags = View.SYSTEM_UI_FLAG_FULLSCREEN |
|
||||
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
|
||||
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY |
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.INVISIBLE;
|
||||
|
||||
SDLActivity.this.getWindow().getDecorView().setSystemUiVisibility(flags);
|
||||
SDLActivity.this.getWindow().getDecorView().setSystemUiVisibility(flags);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1624,11 +1603,32 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
|||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
|
||||
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
nativePermissionResult(requestCode, true);
|
||||
} else {
|
||||
nativePermissionResult(requestCode, false);
|
||||
boolean result = (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED);
|
||||
nativePermissionResult(requestCode, result);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called by SDL using JNI.
|
||||
*/
|
||||
public static int openURL(String url)
|
||||
{
|
||||
try {
|
||||
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||
i.setData(Uri.parse(url));
|
||||
|
||||
int flags = Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
flags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
|
||||
} else {
|
||||
flags |= Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET;
|
||||
}
|
||||
i.addFlags(flags);
|
||||
|
||||
mSingleton.startActivity(i);
|
||||
} catch (Exception ex) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1655,13 +1655,12 @@ class SDLMain implements Runnable {
|
|||
|
||||
Log.v("SDL", "Finished main function");
|
||||
|
||||
if (SDLActivity.mSingleton == null || SDLActivity.mSingleton.isFinishing()) {
|
||||
// Activity is already being destroyed
|
||||
} else {
|
||||
if (SDLActivity.mSingleton != null && !SDLActivity.mSingleton.isFinishing()) {
|
||||
// Let's finish the Activity
|
||||
SDLActivity.mSDLThread = null;
|
||||
SDLActivity.mSingleton.finish();
|
||||
}
|
||||
} // else: Activity is already being destroyed
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1786,13 +1785,13 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
|
|||
try
|
||||
{
|
||||
if (Build.VERSION.SDK_INT >= 17) {
|
||||
android.util.DisplayMetrics realMetrics = new android.util.DisplayMetrics();
|
||||
DisplayMetrics realMetrics = new DisplayMetrics();
|
||||
mDisplay.getRealMetrics( realMetrics );
|
||||
nDeviceWidth = realMetrics.widthPixels;
|
||||
nDeviceHeight = realMetrics.heightPixels;
|
||||
}
|
||||
} catch(Exception ignored) {
|
||||
}
|
||||
catch ( java.lang.Throwable throwable ) {}
|
||||
|
||||
synchronized(SDLActivity.getContext()) {
|
||||
// In case we're waiting on a size change after going fullscreen, send a notification.
|
||||
|
@ -1809,12 +1808,7 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
|
|||
boolean skip = false;
|
||||
int requestedOrientation = SDLActivity.mSingleton.getRequestedOrientation();
|
||||
|
||||
if (requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)
|
||||
{
|
||||
// Accept any
|
||||
}
|
||||
else if (requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT || requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT)
|
||||
{
|
||||
if (requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT || requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT) {
|
||||
if (mWidth > mHeight) {
|
||||
skip = true;
|
||||
}
|
||||
|
@ -1868,6 +1862,19 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
|
|||
int deviceId = event.getDeviceId();
|
||||
int source = event.getSource();
|
||||
|
||||
if (source == InputDevice.SOURCE_UNKNOWN) {
|
||||
InputDevice device = InputDevice.getDevice(deviceId);
|
||||
if (device != null) {
|
||||
source = device.getSources();
|
||||
}
|
||||
}
|
||||
|
||||
// if (event.getAction() == KeyEvent.ACTION_DOWN) {
|
||||
// Log.v("SDL", "key down: " + keyCode + ", deviceId = " + deviceId + ", source = " + source);
|
||||
// } else if (event.getAction() == KeyEvent.ACTION_UP) {
|
||||
// Log.v("SDL", "key up: " + keyCode + ", deviceId = " + deviceId + ", source = " + source);
|
||||
// }
|
||||
|
||||
// Dispatch the different events depending on where they come from
|
||||
// Some SOURCE_JOYSTICK, SOURCE_DPAD or SOURCE_GAMEPAD are also SOURCE_KEYBOARD
|
||||
// So, we try to process them as JOYSTICK/DPAD/GAMEPAD events first, if that fails we try them as KEYBOARD
|
||||
|
@ -1888,24 +1895,14 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
|
|||
}
|
||||
}
|
||||
|
||||
if (source == InputDevice.SOURCE_UNKNOWN) {
|
||||
InputDevice device = InputDevice.getDevice(deviceId);
|
||||
if (device != null) {
|
||||
source = device.getSources();
|
||||
}
|
||||
}
|
||||
|
||||
if ((source & InputDevice.SOURCE_KEYBOARD) != 0) {
|
||||
if (event.getAction() == KeyEvent.ACTION_DOWN) {
|
||||
//Log.v("SDL", "key down: " + keyCode);
|
||||
if (SDLActivity.isTextInputEvent(event)) {
|
||||
SDLInputConnection.nativeCommitText(String.valueOf((char) event.getUnicodeChar()), 1);
|
||||
}
|
||||
SDLActivity.onNativeKeyDown(keyCode);
|
||||
return true;
|
||||
}
|
||||
else if (event.getAction() == KeyEvent.ACTION_UP) {
|
||||
//Log.v("SDL", "key up: " + keyCode);
|
||||
} else if (event.getAction() == KeyEvent.ACTION_UP) {
|
||||
SDLActivity.onNativeKeyUp(keyCode);
|
||||
return true;
|
||||
}
|
||||
|
@ -1932,22 +1929,34 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
|
|||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
/* Ref: http://developer.android.com/training/gestures/multi.html */
|
||||
final int touchDevId = event.getDeviceId();
|
||||
int touchDevId = event.getDeviceId();
|
||||
final int pointerCount = event.getPointerCount();
|
||||
int action = event.getActionMasked();
|
||||
int pointerFingerId;
|
||||
int mouseButton;
|
||||
int i = -1;
|
||||
float x,y,p;
|
||||
|
||||
/*
|
||||
* Prevent id to be -1, since it's used in SDL internal for synthetic events
|
||||
* Appears when using Android emulator, eg:
|
||||
* adb shell input mouse tap 100 100
|
||||
* adb shell input touchscreen tap 100 100
|
||||
*/
|
||||
if (touchDevId < 0) {
|
||||
touchDevId -= 1;
|
||||
}
|
||||
|
||||
// 12290 = Samsung DeX mode desktop mouse
|
||||
// 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)) {
|
||||
int mouseButton = 1;
|
||||
try {
|
||||
mouseButton = (Integer) event.getClass().getMethod("getButtonState").invoke(event);
|
||||
} catch(Exception e) {
|
||||
mouseButton = 1; // oh well.
|
||||
Object object = event.getClass().getMethod("getButtonState").invoke(event);
|
||||
if (object != null) {
|
||||
mouseButton = (Integer) object;
|
||||
}
|
||||
} catch(Exception ignored) {
|
||||
}
|
||||
|
||||
// We need to check if we're in relative mouse mode and get the axis offset rather than the x/y values
|
||||
|
@ -1978,6 +1987,7 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
|
|||
case MotionEvent.ACTION_DOWN:
|
||||
// Primary pointer up/down, the index is always zero
|
||||
i = 0;
|
||||
/* fallthrough */
|
||||
case MotionEvent.ACTION_POINTER_UP:
|
||||
case MotionEvent.ACTION_POINTER_DOWN:
|
||||
// Non primary pointer up/down
|
||||
|
@ -2044,7 +2054,7 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
|
|||
|
||||
// Since we may have an orientation set, we won't receive onConfigurationChanged events.
|
||||
// We thus should check here.
|
||||
int newOrientation = SDLActivity.SDL_ORIENTATION_UNKNOWN;
|
||||
int newOrientation;
|
||||
|
||||
float x, y;
|
||||
switch (mDisplay.getRotation()) {
|
||||
|
@ -2063,6 +2073,7 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
|
|||
y = -event.values[1];
|
||||
newOrientation = SDLActivity.SDL_ORIENTATION_PORTRAIT_FLIPPED;
|
||||
break;
|
||||
case Surface.ROTATION_0:
|
||||
default:
|
||||
x = event.values[0];
|
||||
y = event.values[1];
|
||||
|
@ -2109,8 +2120,7 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
|
|||
// Change our action value to what SDL's code expects.
|
||||
if (action == MotionEvent.ACTION_BUTTON_PRESS) {
|
||||
action = MotionEvent.ACTION_DOWN;
|
||||
}
|
||||
else if (action == MotionEvent.ACTION_BUTTON_RELEASE) {
|
||||
} else { /* MotionEvent.ACTION_BUTTON_RELEASE */
|
||||
action = MotionEvent.ACTION_UP;
|
||||
}
|
||||
|
||||
|
@ -2275,45 +2285,38 @@ class SDLInputConnection extends BaseInputConnection {
|
|||
}
|
||||
}
|
||||
|
||||
interface SDLClipboardHandler {
|
||||
class SDLClipboardHandler implements
|
||||
ClipboardManager.OnPrimaryClipChangedListener {
|
||||
|
||||
public boolean clipboardHasText();
|
||||
public String clipboardGetText();
|
||||
public void clipboardSetText(String string);
|
||||
protected ClipboardManager mClipMgr;
|
||||
|
||||
}
|
||||
|
||||
|
||||
class SDLClipboardHandler_API11 implements
|
||||
SDLClipboardHandler,
|
||||
android.content.ClipboardManager.OnPrimaryClipChangedListener {
|
||||
|
||||
protected android.content.ClipboardManager mClipMgr;
|
||||
|
||||
SDLClipboardHandler_API11() {
|
||||
mClipMgr = (android.content.ClipboardManager) SDL.getContext().getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
SDLClipboardHandler() {
|
||||
mClipMgr = (ClipboardManager) SDL.getContext().getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
mClipMgr.addPrimaryClipChangedListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean clipboardHasText() {
|
||||
return mClipMgr.hasText();
|
||||
return mClipMgr.hasPrimaryClip();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String clipboardGetText() {
|
||||
CharSequence text;
|
||||
text = mClipMgr.getText();
|
||||
if (text != null) {
|
||||
return text.toString();
|
||||
ClipData clip = mClipMgr.getPrimaryClip();
|
||||
if (clip != null) {
|
||||
ClipData.Item item = clip.getItemAt(0);
|
||||
if (item != null) {
|
||||
CharSequence text = item.getText();
|
||||
if (text != null) {
|
||||
return text.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clipboardSetText(String string) {
|
||||
mClipMgr.removePrimaryClipChangedListener(this);
|
||||
mClipMgr.setText(string);
|
||||
ClipData clip = ClipData.newPlainText(null, string);
|
||||
mClipMgr.setPrimaryClip(clip);
|
||||
mClipMgr.addPrimaryClipChangedListener(this);
|
||||
}
|
||||
|
||||
|
@ -2321,6 +2324,5 @@ class SDLClipboardHandler_API11 implements
|
|||
public void onPrimaryClipChanged() {
|
||||
SDLActivity.onNativeClipboardChanged();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
package org.libsdl.app;
|
||||
|
||||
import android.media.*;
|
||||
import android.media.AudioFormat;
|
||||
import android.media.AudioManager;
|
||||
import android.media.AudioRecord;
|
||||
import android.media.AudioTrack;
|
||||
import android.media.MediaRecorder;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
|
||||
|
@ -199,7 +203,6 @@ public class SDLAudioManager
|
|||
results[0] = mAudioRecord.getSampleRate();
|
||||
results[1] = mAudioRecord.getAudioFormat();
|
||||
results[2] = mAudioRecord.getChannelCount();
|
||||
results[3] = desiredFrames;
|
||||
|
||||
} else {
|
||||
if (mAudioTrack == null) {
|
||||
|
@ -223,8 +226,8 @@ public class SDLAudioManager
|
|||
results[0] = mAudioTrack.getSampleRate();
|
||||
results[1] = mAudioTrack.getAudioFormat();
|
||||
results[2] = mAudioTrack.getChannelCount();
|
||||
results[3] = desiredFrames;
|
||||
}
|
||||
results[3] = desiredFrames;
|
||||
|
||||
Log.v(TAG, "Opening " + (isCapture ? "capture" : "playback") + ", got " + results[3] + " frames of " + results[2] + " channel " + getAudioFormatString(results[1]) + " audio at " + results[0] + " Hz");
|
||||
|
||||
|
|
|
@ -6,9 +6,14 @@ import java.util.Comparator;
|
|||
import java.util.List;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.*;
|
||||
import android.view.*;
|
||||
import android.os.Build;
|
||||
import android.os.VibrationEffect;
|
||||
import android.os.Vibrator;
|
||||
import android.util.Log;
|
||||
import android.view.InputDevice;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
||||
|
||||
public class SDLControllerManager
|
||||
|
@ -98,7 +103,7 @@ public class SDLControllerManager
|
|||
int sources = device.getSources();
|
||||
|
||||
/* This is called for every button press, so let's not spam the logs */
|
||||
/**
|
||||
/*
|
||||
if ((sources & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
|
||||
Log.v(TAG, "Input device " + device.getName() + " has class joystick.");
|
||||
}
|
||||
|
@ -108,7 +113,7 @@ public class SDLControllerManager
|
|||
if ((sources & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD) {
|
||||
Log.v(TAG, "Input device " + device.getName() + " is a gamepad.");
|
||||
}
|
||||
**/
|
||||
*/
|
||||
|
||||
return ((sources & InputDevice.SOURCE_CLASS_JOYSTICK) != 0 ||
|
||||
((sources & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD) ||
|
||||
|
@ -167,7 +172,7 @@ class SDLJoystickHandler_API16 extends SDLJoystickHandler {
|
|||
}
|
||||
}
|
||||
|
||||
private ArrayList<SDLJoystick> mJoysticks;
|
||||
private final ArrayList<SDLJoystick> mJoysticks;
|
||||
|
||||
public SDLJoystickHandler_API16() {
|
||||
|
||||
|
@ -177,13 +182,14 @@ class SDLJoystickHandler_API16 extends SDLJoystickHandler {
|
|||
@Override
|
||||
public void pollInputDevices() {
|
||||
int[] deviceIds = InputDevice.getDeviceIds();
|
||||
for(int i=0; i < deviceIds.length; ++i) {
|
||||
SDLJoystick joystick = getJoystick(deviceIds[i]);
|
||||
if (joystick == null) {
|
||||
joystick = new SDLJoystick();
|
||||
InputDevice joystickDevice = InputDevice.getDevice(deviceIds[i]);
|
||||
if (SDLControllerManager.isDeviceSDLJoystick(deviceIds[i])) {
|
||||
joystick.device_id = deviceIds[i];
|
||||
|
||||
for (int device_id : deviceIds) {
|
||||
if (SDLControllerManager.isDeviceSDLJoystick(device_id)) {
|
||||
SDLJoystick joystick = getJoystick(device_id);
|
||||
if (joystick == null) {
|
||||
InputDevice joystickDevice = InputDevice.getDevice(device_id);
|
||||
joystick = new SDLJoystick();
|
||||
joystick.device_id = device_id;
|
||||
joystick.name = joystickDevice.getName();
|
||||
joystick.desc = getJoystickDescriptor(joystickDevice);
|
||||
joystick.axes = new ArrayList<InputDevice.MotionRange>();
|
||||
|
@ -191,53 +197,57 @@ class SDLJoystickHandler_API16 extends SDLJoystickHandler {
|
|||
|
||||
List<InputDevice.MotionRange> ranges = joystickDevice.getMotionRanges();
|
||||
Collections.sort(ranges, new RangeComparator());
|
||||
for (InputDevice.MotionRange range : ranges ) {
|
||||
for (InputDevice.MotionRange range : ranges) {
|
||||
if ((range.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
|
||||
if (range.getAxis() == MotionEvent.AXIS_HAT_X ||
|
||||
range.getAxis() == MotionEvent.AXIS_HAT_Y) {
|
||||
if (range.getAxis() == MotionEvent.AXIS_HAT_X || range.getAxis() == MotionEvent.AXIS_HAT_Y) {
|
||||
joystick.hats.add(range);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
joystick.axes.add(range);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mJoysticks.add(joystick);
|
||||
SDLControllerManager.nativeAddJoystick(joystick.device_id, joystick.name, joystick.desc, getVendorId(joystickDevice), getProductId(joystickDevice), false, getButtonMask(joystickDevice), joystick.axes.size(), joystick.hats.size()/2, 0);
|
||||
SDLControllerManager.nativeAddJoystick(joystick.device_id, joystick.name, joystick.desc,
|
||||
getVendorId(joystickDevice), getProductId(joystickDevice), false,
|
||||
getButtonMask(joystickDevice), joystick.axes.size(), joystick.hats.size()/2, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check removed devices */
|
||||
ArrayList<Integer> removedDevices = new ArrayList<Integer>();
|
||||
for(int i=0; i < mJoysticks.size(); i++) {
|
||||
int device_id = mJoysticks.get(i).device_id;
|
||||
int j;
|
||||
for (j=0; j < deviceIds.length; j++) {
|
||||
if (device_id == deviceIds[j]) break;
|
||||
ArrayList<Integer> removedDevices = null;
|
||||
for (SDLJoystick joystick : mJoysticks) {
|
||||
int device_id = joystick.device_id;
|
||||
int i;
|
||||
for (i = 0; i < deviceIds.length; i++) {
|
||||
if (device_id == deviceIds[i]) break;
|
||||
}
|
||||
if (j == deviceIds.length) {
|
||||
removedDevices.add(Integer.valueOf(device_id));
|
||||
if (i == deviceIds.length) {
|
||||
if (removedDevices == null) {
|
||||
removedDevices = new ArrayList<Integer>();
|
||||
}
|
||||
removedDevices.add(device_id);
|
||||
}
|
||||
}
|
||||
|
||||
for(int i=0; i < removedDevices.size(); i++) {
|
||||
int device_id = removedDevices.get(i).intValue();
|
||||
SDLControllerManager.nativeRemoveJoystick(device_id);
|
||||
for (int j=0; j < mJoysticks.size(); j++) {
|
||||
if (mJoysticks.get(j).device_id == device_id) {
|
||||
mJoysticks.remove(j);
|
||||
break;
|
||||
if (removedDevices != null) {
|
||||
for (int device_id : removedDevices) {
|
||||
SDLControllerManager.nativeRemoveJoystick(device_id);
|
||||
for (int i = 0; i < mJoysticks.size(); i++) {
|
||||
if (mJoysticks.get(i).device_id == device_id) {
|
||||
mJoysticks.remove(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected SDLJoystick getJoystick(int device_id) {
|
||||
for(int i=0; i < mJoysticks.size(); i++) {
|
||||
if (mJoysticks.get(i).device_id == device_id) {
|
||||
return mJoysticks.get(i);
|
||||
for (SDLJoystick joystick : mJoysticks) {
|
||||
if (joystick.device_id == device_id) {
|
||||
return joystick;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
@ -248,25 +258,21 @@ class SDLJoystickHandler_API16 extends SDLJoystickHandler {
|
|||
if ((event.getSource() & InputDevice.SOURCE_JOYSTICK) != 0) {
|
||||
int actionPointerIndex = event.getActionIndex();
|
||||
int action = event.getActionMasked();
|
||||
switch(action) {
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
SDLJoystick joystick = getJoystick(event.getDeviceId());
|
||||
if ( joystick != null ) {
|
||||
for (int i = 0; i < joystick.axes.size(); i++) {
|
||||
InputDevice.MotionRange range = joystick.axes.get(i);
|
||||
/* Normalize the value to -1...1 */
|
||||
float value = ( event.getAxisValue( range.getAxis(), actionPointerIndex) - range.getMin() ) / range.getRange() * 2.0f - 1.0f;
|
||||
SDLControllerManager.onNativeJoy(joystick.device_id, i, value );
|
||||
}
|
||||
for (int i = 0; i < joystick.hats.size(); i+=2) {
|
||||
int hatX = Math.round(event.getAxisValue( joystick.hats.get(i).getAxis(), actionPointerIndex ) );
|
||||
int hatY = Math.round(event.getAxisValue( joystick.hats.get(i+1).getAxis(), actionPointerIndex ) );
|
||||
SDLControllerManager.onNativeHat(joystick.device_id, i/2, hatX, hatY );
|
||||
}
|
||||
if (action == MotionEvent.ACTION_MOVE) {
|
||||
SDLJoystick joystick = getJoystick(event.getDeviceId());
|
||||
if (joystick != null) {
|
||||
for (int i = 0; i < joystick.axes.size(); i++) {
|
||||
InputDevice.MotionRange range = joystick.axes.get(i);
|
||||
/* Normalize the value to -1...1 */
|
||||
float value = (event.getAxisValue(range.getAxis(), actionPointerIndex) - range.getMin()) / range.getRange() * 2.0f - 1.0f;
|
||||
SDLControllerManager.onNativeJoy(joystick.device_id, i, value);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
for (int i = 0; i < joystick.hats.size() / 2; i++) {
|
||||
int hatX = Math.round(event.getAxisValue(joystick.hats.get(2 * i).getAxis(), actionPointerIndex));
|
||||
int hatY = Math.round(event.getAxisValue(joystick.hats.get(2 * i + 1).getAxis(), actionPointerIndex));
|
||||
SDLControllerManager.onNativeHat(joystick.device_id, i, hatX, hatY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -432,13 +438,13 @@ class SDLHapticHandler_API26 extends SDLHapticHandler {
|
|||
|
||||
class SDLHapticHandler {
|
||||
|
||||
class SDLHaptic {
|
||||
static class SDLHaptic {
|
||||
public int device_id;
|
||||
public String name;
|
||||
public Vibrator vib;
|
||||
}
|
||||
|
||||
private ArrayList<SDLHaptic> mHaptics;
|
||||
private final ArrayList<SDLHaptic> mHaptics;
|
||||
|
||||
public SDLHapticHandler() {
|
||||
mHaptics = new ArrayList<SDLHaptic>();
|
||||
|
@ -504,37 +510,41 @@ class SDLHapticHandler {
|
|||
}
|
||||
|
||||
/* Check removed devices */
|
||||
ArrayList<Integer> removedDevices = new ArrayList<Integer>();
|
||||
for(int i=0; i < mHaptics.size(); i++) {
|
||||
int device_id = mHaptics.get(i).device_id;
|
||||
int j;
|
||||
for (j=0; j < deviceIds.length; j++) {
|
||||
if (device_id == deviceIds[j]) break;
|
||||
ArrayList<Integer> removedDevices = null;
|
||||
for (SDLHaptic haptic : mHaptics) {
|
||||
int device_id = haptic.device_id;
|
||||
int i;
|
||||
for (i = 0; i < deviceIds.length; i++) {
|
||||
if (device_id == deviceIds[i]) break;
|
||||
}
|
||||
|
||||
if (device_id == deviceId_VIBRATOR_SERVICE && hasVibratorService) {
|
||||
// don't remove the vibrator if it is still present
|
||||
} else if (j == deviceIds.length) {
|
||||
removedDevices.add(device_id);
|
||||
}
|
||||
if (device_id != deviceId_VIBRATOR_SERVICE || !hasVibratorService) {
|
||||
if (i == deviceIds.length) {
|
||||
if (removedDevices == null) {
|
||||
removedDevices = new ArrayList<Integer>();
|
||||
}
|
||||
removedDevices.add(device_id);
|
||||
}
|
||||
} // else: don't remove the vibrator if it is still present
|
||||
}
|
||||
|
||||
for(int i=0; i < removedDevices.size(); i++) {
|
||||
int device_id = removedDevices.get(i);
|
||||
SDLControllerManager.nativeRemoveHaptic(device_id);
|
||||
for (int j=0; j < mHaptics.size(); j++) {
|
||||
if (mHaptics.get(j).device_id == device_id) {
|
||||
mHaptics.remove(j);
|
||||
break;
|
||||
if (removedDevices != null) {
|
||||
for (int device_id : removedDevices) {
|
||||
SDLControllerManager.nativeRemoveHaptic(device_id);
|
||||
for (int i = 0; i < mHaptics.size(); i++) {
|
||||
if (mHaptics.get(i).device_id == device_id) {
|
||||
mHaptics.remove(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected SDLHaptic getHaptic(int device_id) {
|
||||
for(int i=0; i < mHaptics.size(); i++) {
|
||||
if (mHaptics.get(i).device_id == device_id) {
|
||||
return mHaptics.get(i);
|
||||
for (SDLHaptic haptic : mHaptics) {
|
||||
if (haptic.device_id == device_id) {
|
||||
return haptic;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
@ -655,8 +665,7 @@ class SDLGenericMotionListener_API24 extends SDLGenericMotionListener_API12 {
|
|||
public float getEventX(MotionEvent event) {
|
||||
if (mRelativeModeEnabled) {
|
||||
return event.getAxisValue(MotionEvent.AXIS_RELATIVE_X);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return event.getX(0);
|
||||
}
|
||||
}
|
||||
|
@ -665,14 +674,12 @@ class SDLGenericMotionListener_API24 extends SDLGenericMotionListener_API12 {
|
|||
public float getEventY(MotionEvent event) {
|
||||
if (mRelativeModeEnabled) {
|
||||
return event.getAxisValue(MotionEvent.AXIS_RELATIVE_Y);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return event.getY(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class SDLGenericMotionListener_API26 extends SDLGenericMotionListener_API24 {
|
||||
// Generic Motion (mouse hover, joystick...) events go here
|
||||
private boolean mRelativeModeEnabled;
|
||||
|
@ -753,15 +760,12 @@ class SDLGenericMotionListener_API26 extends SDLGenericMotionListener_API24 {
|
|||
if (!SDLActivity.isDeXMode() || (Build.VERSION.SDK_INT >= 27)) {
|
||||
if (enabled) {
|
||||
SDLActivity.getContentView().requestPointerCapture();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
SDLActivity.getContentView().releasePointerCapture();
|
||||
}
|
||||
mRelativeModeEnabled = enabled;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in a new issue