Refactor XashActivity, fix crash in XashService, add compat wrappers
This commit is contained in:
parent
ac0e9b633d
commit
8602bd4e9e
5 changed files with 747 additions and 689 deletions
|
@ -59,6 +59,12 @@ public class LauncherActivity extends Activity
|
||||||
}
|
}
|
||||||
|
|
||||||
setContentView(R.layout.activity_launcher);
|
setContentView(R.layout.activity_launcher);
|
||||||
|
|
||||||
|
if( sdk > 17 )
|
||||||
|
{
|
||||||
|
ImageView icon = (ImageView) findViewById(R.id.launcherIcon);
|
||||||
|
icon.setImageDrawable(getResources().getDrawable(R.mipmap.ic_launcher));
|
||||||
|
}
|
||||||
|
|
||||||
TabHost tabHost = (TabHost) findViewById(R.id.tabhost);
|
TabHost tabHost = (TabHost) findViewById(R.id.tabhost);
|
||||||
|
|
||||||
|
@ -264,12 +270,11 @@ public class LauncherActivity extends Activity
|
||||||
hideRodirSettings( !useRoDir.isChecked() );
|
hideRodirSettings( !useRoDir.isChecked() );
|
||||||
updateResolutionResult();
|
updateResolutionResult();
|
||||||
toggleResolutionFields();
|
toggleResolutionFields();
|
||||||
FWGSLib.applyPermissions( this, new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE }, REQUEST_PERMISSIONS );
|
FWGSLib.cmp.applyPermissions( this, new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE }, REQUEST_PERMISSIONS );
|
||||||
if( !mPref.getBoolean("successfulRun",false) )
|
if( !mPref.getBoolean("successfulRun",false) )
|
||||||
showFirstRun();
|
showFirstRun();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRequestPermissionsResult( int requestCode, String[] permissions, int[] grantResults )
|
public void onRequestPermissionsResult( int requestCode, String[] permissions, int[] grantResults )
|
||||||
{
|
{
|
||||||
if( requestCode == REQUEST_PERMISSIONS )
|
if( requestCode == REQUEST_PERMISSIONS )
|
||||||
|
@ -434,6 +439,12 @@ public class LauncherActivity extends Activity
|
||||||
dialog.setContentView(R.layout.about);
|
dialog.setContentView(R.layout.about);
|
||||||
dialog.setCancelable(true);
|
dialog.setCancelable(true);
|
||||||
dialog.show();
|
dialog.show();
|
||||||
|
if( sdk > 17 )
|
||||||
|
{
|
||||||
|
ImageView icon = (ImageView) dialog.findViewById(R.id.aboutIcon);
|
||||||
|
icon.setImageDrawable(getResources().getDrawable(R.mipmap.ic_launcher));
|
||||||
|
}
|
||||||
|
|
||||||
TextView tView6 = (TextView) dialog.findViewById(R.id.textView6);
|
TextView tView6 = (TextView) dialog.findViewById(R.id.textView6);
|
||||||
tView6.setMovementMethod(LinkMovementMethod.getInstance());
|
tView6.setMovementMethod(LinkMovementMethod.getInstance());
|
||||||
((Button)dialog.findViewById( R.id.button_about_ok )).setOnClickListener(new View.OnClickListener(){
|
((Button)dialog.findViewById( R.id.button_about_ok )).setOnClickListener(new View.OnClickListener(){
|
||||||
|
|
|
@ -32,7 +32,7 @@ import java.security.MessageDigest;
|
||||||
|
|
||||||
import su.xash.engine.R;
|
import su.xash.engine.R;
|
||||||
import su.xash.engine.XashConfig;
|
import su.xash.engine.XashConfig;
|
||||||
import su.xash.engine.JoystickHandler;
|
import su.xash.engine.XashInput;
|
||||||
import android.provider.Settings.Secure;
|
import android.provider.Settings.Secure;
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
|
|
||||||
|
@ -57,8 +57,7 @@ public class XashActivity extends Activity {
|
||||||
public static final int sdk = Integer.valueOf( Build.VERSION.SDK );
|
public static final int sdk = Integer.valueOf( Build.VERSION.SDK );
|
||||||
public static final String TAG = "XASH3D:XashActivity";
|
public static final String TAG = "XASH3D:XashActivity";
|
||||||
public static int mPixelFormat;
|
public static int mPixelFormat;
|
||||||
public static JoystickHandler handler;
|
public static XashInput.JoystickHandler handler;
|
||||||
public static ImmersiveMode mImmersiveMode;
|
|
||||||
public static boolean keyboardVisible = false;
|
public static boolean keyboardVisible = false;
|
||||||
public static boolean mEngineReady = false;
|
public static boolean mEngineReady = false;
|
||||||
public static boolean mEnginePaused = false;
|
public static boolean mEnginePaused = false;
|
||||||
|
@ -110,6 +109,7 @@ public class XashActivity extends Activity {
|
||||||
{
|
{
|
||||||
Log.v( TAG, "onCreate()" );
|
Log.v( TAG, "onCreate()" );
|
||||||
super.onCreate( savedInstanceState );
|
super.onCreate( savedInstanceState );
|
||||||
|
|
||||||
mEngineReady = false;
|
mEngineReady = false;
|
||||||
|
|
||||||
if( sdk >= 8 && CertCheck.dumbAntiPDALifeCheck( this ) )
|
if( sdk >= 8 && CertCheck.dumbAntiPDALifeCheck( this ) )
|
||||||
|
@ -137,7 +137,7 @@ public class XashActivity extends Activity {
|
||||||
mUseRoDir = mPref.getBoolean("use_rodir", false);
|
mUseRoDir = mPref.getBoolean("use_rodir", false);
|
||||||
mWriteDir = mPref.getString("writedir", FWGSLib.getExternalFilesDir( this ));
|
mWriteDir = mPref.getString("writedir", FWGSLib.getExternalFilesDir( this ));
|
||||||
|
|
||||||
FWGSLib.applyPermissions( this, new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE }, REQUEST_PERMISSIONS );
|
FWGSLib.cmp.applyPermissions( this, new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE }, REQUEST_PERMISSIONS );
|
||||||
|
|
||||||
// just in case
|
// just in case
|
||||||
if( mWriteDir.length() == 0 )
|
if( mWriteDir.length() == 0 )
|
||||||
|
@ -161,8 +161,7 @@ public class XashActivity extends Activity {
|
||||||
checkWritePermission( basedir );
|
checkWritePermission( basedir );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRequestPermissionsResult( int requestCode, String[] permissions, int[] grantResults )
|
public void onRequestPermissionsResult( int requestCode, String[] permissions, int[] grantResults )
|
||||||
{
|
{
|
||||||
if( requestCode == REQUEST_PERMISSIONS )
|
if( requestCode == REQUEST_PERMISSIONS )
|
||||||
|
@ -294,10 +293,7 @@ public class XashActivity extends Activity {
|
||||||
|
|
||||||
super.onWindowFocusChanged( hasFocus );
|
super.onWindowFocusChanged( hasFocus );
|
||||||
|
|
||||||
if( mImmersiveMode != null )
|
FWGSLib.cmp.applyImmersiveMode(keyboardVisible, mDecorView);
|
||||||
{
|
|
||||||
mImmersiveMode.apply();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setFolderAsk( Context ctx, Boolean b )
|
public static void setFolderAsk( Context ctx, Boolean b )
|
||||||
|
@ -430,14 +426,7 @@ public class XashActivity extends Activity {
|
||||||
|
|
||||||
SurfaceHolder holder = mSurface.getHolder();
|
SurfaceHolder holder = mSurface.getHolder();
|
||||||
holder.setType( SurfaceHolder.SURFACE_TYPE_GPU );
|
holder.setType( SurfaceHolder.SURFACE_TYPE_GPU );
|
||||||
|
handler = XashInput.getJoystickHandler();
|
||||||
if( sdk >= 14 )
|
|
||||||
handler = new JoystickHandler_v14();
|
|
||||||
else if( sdk >= 12 )
|
|
||||||
handler = new JoystickHandler_v12();
|
|
||||||
else
|
|
||||||
handler = new JoystickHandler();
|
|
||||||
handler.init();
|
|
||||||
|
|
||||||
mVibrator = ( Vibrator )getSystemService( Context.VIBRATOR_SERVICE );
|
mVibrator = ( Vibrator )getSystemService( Context.VIBRATOR_SERVICE );
|
||||||
mHasVibrator = handler.hasVibrator() && (mVibrator != null);
|
mHasVibrator = handler.hasVibrator() && (mVibrator != null);
|
||||||
|
@ -446,14 +435,8 @@ public class XashActivity extends Activity {
|
||||||
mUseVolume = mPref.getBoolean( "usevolume", false );
|
mUseVolume = mPref.getBoolean( "usevolume", false );
|
||||||
if( mPref.getBoolean( "enableResizeWorkaround", true ) )
|
if( mPref.getBoolean( "enableResizeWorkaround", true ) )
|
||||||
AndroidBug5497Workaround.assistActivity( this );
|
AndroidBug5497Workaround.assistActivity( this );
|
||||||
|
if( XashActivity.mPref.getBoolean( "immersive_mode", false ) )
|
||||||
// Immersive Mode is available only at >KitKat
|
mDecorView = getWindow().getDecorView();
|
||||||
Boolean enableImmersive = ( sdk >= 19 ) && ( mPref.getBoolean( "immersive_mode", true ) );
|
|
||||||
if( enableImmersive )
|
|
||||||
mImmersiveMode = new ImmersiveMode_v19();
|
|
||||||
else mImmersiveMode = new ImmersiveMode();
|
|
||||||
|
|
||||||
mDecorView = getWindow().getDecorView();
|
|
||||||
|
|
||||||
if( mPref.getBoolean( "resolution_fixed", false ) )
|
if( mPref.getBoolean( "resolution_fixed", false ) )
|
||||||
{
|
{
|
||||||
|
@ -480,11 +463,7 @@ public class XashActivity extends Activity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
FWGSLib.cmp.startForegroundService( this, new Intent( getBaseContext(), XashService.class ) );
|
||||||
if( sdk >= Build.VERSION_CODES.O )
|
|
||||||
startForegroundService( new Intent( getBaseContext(), XashService.class ) );
|
|
||||||
else if( sdk >= 5 )
|
|
||||||
startService( new Intent( getBaseContext(), XashService.class ) );
|
|
||||||
|
|
||||||
mEngineReady = true;
|
mEngineReady = true;
|
||||||
}
|
}
|
||||||
|
@ -494,18 +473,7 @@ public class XashActivity extends Activity {
|
||||||
{
|
{
|
||||||
Intent intent = getIntent();
|
Intent intent = getIntent();
|
||||||
|
|
||||||
String enginedir;
|
String enginedir = FWGSLib.cmp.getNativeLibDir(this);
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ApplicationInfo ai = FWGSLib.getApplicationInfo(this, null, 0);
|
|
||||||
enginedir = ai.nativeLibraryDir;
|
|
||||||
}
|
|
||||||
catch(Exception e)
|
|
||||||
{
|
|
||||||
e.printStackTrace();
|
|
||||||
enginedir = getFilesDir().getParentFile().getPath() + "/lib";
|
|
||||||
}
|
|
||||||
|
|
||||||
String argv = FWGSLib.getStringExtraFromIntent( intent, "argv", mPref.getString( "argv", "-dev 3 -log" ) );
|
String argv = FWGSLib.getStringExtraFromIntent( intent, "argv", mPref.getString( "argv", "-dev 3 -log" ) );
|
||||||
String gamelibdir = FWGSLib.getStringExtraFromIntent( intent, "gamelibdir", enginedir );
|
String gamelibdir = FWGSLib.getStringExtraFromIntent( intent, "gamelibdir", enginedir );
|
||||||
|
@ -920,16 +888,14 @@ public class XashActivity extends Activity {
|
||||||
|
|
||||||
imm.showSoftInput( mTextEdit, 0 );
|
imm.showSoftInput( mTextEdit, 0 );
|
||||||
keyboardVisible = true;
|
keyboardVisible = true;
|
||||||
if( XashActivity.mImmersiveMode != null )
|
FWGSLib.cmp.applyImmersiveMode( keyboardVisible, mDecorView );
|
||||||
XashActivity.mImmersiveMode.apply();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mTextEdit.setVisibility( View.GONE );
|
mTextEdit.setVisibility( View.GONE );
|
||||||
imm.hideSoftInputFromWindow( mTextEdit.getWindowToken(), 0 );
|
imm.hideSoftInputFromWindow( mTextEdit.getWindowToken(), 0 );
|
||||||
keyboardVisible = false;
|
keyboardVisible = false;
|
||||||
if( XashActivity.mImmersiveMode != null )
|
FWGSLib.cmp.applyImmersiveMode( keyboardVisible, mDecorView );
|
||||||
XashActivity.mImmersiveMode.apply();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1050,18 +1016,6 @@ public class XashActivity extends Activity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Simple nativeInit() runnable
|
|
||||||
*/
|
|
||||||
class XashMain implements Runnable
|
|
||||||
{
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
XashActivity.nativeInit( XashActivity.mArgv );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
EngineSurface. This is what we draw on, so we need to know when it's created
|
EngineSurface. This is what we draw on, so we need to know when it's created
|
||||||
in order to do anything useful.
|
in order to do anything useful.
|
||||||
|
@ -1096,10 +1050,7 @@ class EngineSurface extends SurfaceView implements SurfaceHolder.Callback, View.
|
||||||
setFocusableInTouchMode( true );
|
setFocusableInTouchMode( true );
|
||||||
requestFocus();
|
requestFocus();
|
||||||
setOnKeyListener( this );
|
setOnKeyListener( this );
|
||||||
if( XashActivity.sdk >= 5 )
|
setOnTouchListener( XashInput.getTouchListener() );
|
||||||
setOnTouchListener( new EngineTouchListener_v5() );
|
|
||||||
else
|
|
||||||
setOnTouchListener( new EngineTouchListener_v1() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called when we have a valid drawing surface
|
// Called when we have a valid drawing surface
|
||||||
|
@ -1161,7 +1112,13 @@ class EngineSurface extends SurfaceView implements SurfaceHolder.Callback, View.
|
||||||
// Now start up the C app thread
|
// Now start up the C app thread
|
||||||
if( mEngThread == null )
|
if( mEngThread == null )
|
||||||
{
|
{
|
||||||
mEngThread = new Thread( new XashMain(), "EngineThread" );
|
mEngThread = new Thread( new Runnable(){
|
||||||
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
XashActivity.nativeInit( XashActivity.mArgv );
|
||||||
|
}
|
||||||
|
}, "EngineThread" );
|
||||||
mEngThread.start();
|
mEngThread.start();
|
||||||
}
|
}
|
||||||
resizing = false;
|
resizing = false;
|
||||||
|
@ -1381,214 +1338,6 @@ class EngineSurface extends SurfaceView implements SurfaceHolder.Callback, View.
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is a fake invisible editor view that receives the input and defines the
|
|
||||||
* pan&scan region
|
|
||||||
*/
|
|
||||||
class DummyEdit extends View implements View.OnKeyListener
|
|
||||||
{
|
|
||||||
InputConnection ic;
|
|
||||||
|
|
||||||
public DummyEdit( Context context )
|
|
||||||
{
|
|
||||||
super( context );
|
|
||||||
setFocusableInTouchMode( true );
|
|
||||||
setFocusable( true );
|
|
||||||
setOnKeyListener( this );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onCheckIsTextEditor()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onKey( View v, int keyCode, KeyEvent event )
|
|
||||||
{
|
|
||||||
return XashActivity.handleKey( keyCode, event );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public InputConnection onCreateInputConnection( EditorInfo outAttrs )
|
|
||||||
{
|
|
||||||
ic = new XashInputConnection( this, true );
|
|
||||||
|
|
||||||
outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_EXTRACT_UI
|
|
||||||
| 33554432 /* API 11: EditorInfo.IME_FLAG_NO_FULLSCREEN */;
|
|
||||||
|
|
||||||
return ic;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class XashInputConnection extends BaseInputConnection
|
|
||||||
{
|
|
||||||
public XashInputConnection( View targetView, boolean fullEditor )
|
|
||||||
{
|
|
||||||
super( targetView, fullEditor );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean sendKeyEvent( KeyEvent event )
|
|
||||||
{
|
|
||||||
if( XashActivity.handleKey( event.getKeyCode(), event ) )
|
|
||||||
return true;
|
|
||||||
return super.sendKeyEvent( event );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean commitText( CharSequence text, int newCursorPosition )
|
|
||||||
{
|
|
||||||
// nativeCommitText(text.toString(), newCursorPosition);
|
|
||||||
if( text.toString().equals( "\n" ) )
|
|
||||||
{
|
|
||||||
XashActivity.nativeKey( 1, KeyEvent.KEYCODE_ENTER );
|
|
||||||
XashActivity.nativeKey( 0, KeyEvent.KEYCODE_ENTER );
|
|
||||||
}
|
|
||||||
XashActivity.nativeString( text.toString() );
|
|
||||||
|
|
||||||
return super.commitText( text, newCursorPosition );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean setComposingText( CharSequence text, int newCursorPosition )
|
|
||||||
{
|
|
||||||
// a1batross:
|
|
||||||
// This method is intended to show composed text immediately
|
|
||||||
// that after will be replaced by text from "commitText" method
|
|
||||||
// Just leaving this unimplemented fixes "twice" input on T9/Swype-like keyboards
|
|
||||||
|
|
||||||
//ativeSetComposingText(text.toString(), newCursorPosition);
|
|
||||||
// XashActivity.nativeString( text.toString() );
|
|
||||||
|
|
||||||
return super.setComposingText( text, newCursorPosition );
|
|
||||||
}
|
|
||||||
|
|
||||||
public native void nativeSetComposingText( String text, int newCursorPosition );
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean deleteSurroundingText( int beforeLength, int afterLength )
|
|
||||||
{
|
|
||||||
// Workaround to capture backspace key. Ref: http://stackoverflow.com/questions/14560344/android-backspace-in-webview-baseinputconnection
|
|
||||||
// and https://bugzilla.libsdl.org/show_bug.cgi?id=2265
|
|
||||||
if( beforeLength > 0 && afterLength == 0 )
|
|
||||||
{
|
|
||||||
boolean ret = true;
|
|
||||||
// backspace(s)
|
|
||||||
while( beforeLength-- > 0 )
|
|
||||||
{
|
|
||||||
boolean ret_key = sendKeyEvent( new KeyEvent( KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL ) )
|
|
||||||
&& sendKeyEvent( new KeyEvent( KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DEL ) );
|
|
||||||
ret = ret && ret_key;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.deleteSurroundingText(beforeLength, afterLength);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
class EngineTouchListener_v1 implements View.OnTouchListener
|
|
||||||
{
|
|
||||||
// Touch events
|
|
||||||
public boolean onTouch( View v, MotionEvent event )
|
|
||||||
{
|
|
||||||
XashActivity.nativeTouch( 0, event.getAction(), event.getX(), event.getY() );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class EngineTouchListener_v5 implements View.OnTouchListener
|
|
||||||
{
|
|
||||||
float lx = 0, ly = 0;
|
|
||||||
boolean secondarypressed = false;
|
|
||||||
|
|
||||||
// Touch events
|
|
||||||
public boolean onTouch( View v, MotionEvent event )
|
|
||||||
{
|
|
||||||
//final int touchDevId = event.getDeviceId();
|
|
||||||
final int pointerCount = event.getPointerCount();
|
|
||||||
int action = event.getActionMasked();
|
|
||||||
int pointerFingerId, mouseButton, i = -1;
|
|
||||||
float x, y;
|
|
||||||
|
|
||||||
switch( action )
|
|
||||||
{
|
|
||||||
case MotionEvent.ACTION_MOVE:
|
|
||||||
if( ( !XashActivity.fMouseShown ) && ( ( XashActivity.handler.getSource( event ) & InputDevice.SOURCE_MOUSE ) == InputDevice.SOURCE_MOUSE ) )
|
|
||||||
{
|
|
||||||
x = event.getX();
|
|
||||||
y = event.getY();
|
|
||||||
|
|
||||||
XashActivity.nativeMouseMove( x - lx, y - ly );
|
|
||||||
lx = x;
|
|
||||||
ly = y;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
for( i = 0; i < pointerCount; i++ )
|
|
||||||
{
|
|
||||||
pointerFingerId = event.getPointerId( i );
|
|
||||||
x = event.getX( i ) * XashActivity.mTouchScaleX;
|
|
||||||
y = event.getY( i ) * XashActivity.mTouchScaleY;
|
|
||||||
XashActivity.nativeTouch( pointerFingerId, 2, x, y );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case MotionEvent.ACTION_UP:
|
|
||||||
case MotionEvent.ACTION_DOWN:
|
|
||||||
if( !XashActivity.fMouseShown && ( ( XashActivity.handler.getSource( event ) & InputDevice.SOURCE_MOUSE ) == InputDevice.SOURCE_MOUSE ) )
|
|
||||||
{
|
|
||||||
lx = event.getX();
|
|
||||||
ly = event.getY();
|
|
||||||
boolean down = ( action == MotionEvent.ACTION_DOWN ) || ( action == MotionEvent.ACTION_POINTER_DOWN );
|
|
||||||
int buttonState = XashActivity.handler.getButtonState( event );
|
|
||||||
if( down && ( buttonState & MotionEvent.BUTTON_SECONDARY ) != 0 )
|
|
||||||
{
|
|
||||||
XashActivity.nativeKey( 1, -243 );
|
|
||||||
secondarypressed = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if( !down && secondarypressed && ( buttonState & MotionEvent.BUTTON_SECONDARY ) == 0 )
|
|
||||||
{
|
|
||||||
secondarypressed = false;
|
|
||||||
XashActivity.nativeKey( 0, -243 );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
XashActivity.nativeKey( down ? 1 : 0, -241 );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
i = 0;
|
|
||||||
// fallthrough
|
|
||||||
case MotionEvent.ACTION_POINTER_UP:
|
|
||||||
case MotionEvent.ACTION_POINTER_DOWN:
|
|
||||||
// Non primary pointer up/down
|
|
||||||
if( i == -1 )
|
|
||||||
{
|
|
||||||
i = event.getActionIndex();
|
|
||||||
}
|
|
||||||
|
|
||||||
pointerFingerId = event.getPointerId( i );
|
|
||||||
|
|
||||||
x = event.getX( i ) * XashActivity.mTouchScaleX;
|
|
||||||
y = event.getY( i ) * XashActivity.mTouchScaleY;
|
|
||||||
if( action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_POINTER_UP )
|
|
||||||
XashActivity.nativeTouch( pointerFingerId,1, x, y );
|
|
||||||
if( action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_POINTER_DOWN )
|
|
||||||
XashActivity.nativeTouch( pointerFingerId,0, x, y );
|
|
||||||
break;
|
|
||||||
case MotionEvent.ACTION_CANCEL:
|
|
||||||
for( i = 0; i < pointerCount; i++ )
|
|
||||||
{
|
|
||||||
pointerFingerId = event.getPointerId( i );
|
|
||||||
x = event.getX( i ) * XashActivity.mTouchScaleX;
|
|
||||||
y = event.getY( i ) * XashActivity.mTouchScaleY;
|
|
||||||
XashActivity.nativeTouch( pointerFingerId, 1, x, y );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class AndroidBug5497Workaround
|
class AndroidBug5497Workaround
|
||||||
{
|
{
|
||||||
// For more information, see https://code.google.com/p/android/issues/detail?id=5497
|
// For more information, see https://code.google.com/p/android/issues/detail?id=5497
|
||||||
|
@ -1637,8 +1386,7 @@ class AndroidBug5497Workaround
|
||||||
XashActivity.keyboardVisible = false;
|
XashActivity.keyboardVisible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( XashActivity.mImmersiveMode != null )
|
FWGSLib.cmp.applyImmersiveMode( XashActivity.keyboardVisible, XashActivity.mDecorView );
|
||||||
XashActivity.mImmersiveMode.apply();
|
|
||||||
|
|
||||||
mChildOfContent.requestLayout();
|
mChildOfContent.requestLayout();
|
||||||
usableHeightPrevious = usableHeightNow;
|
usableHeightPrevious = usableHeightNow;
|
||||||
|
@ -1651,377 +1399,4 @@ class AndroidBug5497Workaround
|
||||||
mChildOfContent.getWindowVisibleDisplayFrame( r );
|
mChildOfContent.getWindowVisibleDisplayFrame( r );
|
||||||
return r.bottom - r.top;
|
return r.bottom - r.top;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ImmersiveMode
|
|
||||||
{
|
|
||||||
void apply()
|
|
||||||
{
|
|
||||||
//stub
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ImmersiveMode_v19 extends ImmersiveMode
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
void apply()
|
|
||||||
{
|
|
||||||
if( !XashActivity.keyboardVisible )
|
|
||||||
XashActivity.mDecorView.setSystemUiVisibility(
|
|
||||||
0x00000100 // View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
|
||||||
| 0x00000200 // View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
|
||||||
| 0x00000400 // View.SYSTEM_UI_FLAG_LAYOUT_FULSCREEN
|
|
||||||
| 0x00000002 // View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
|
|
||||||
| 0x00000004 // View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
|
|
||||||
| 0x00001000 // View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
|
|
||||||
);
|
|
||||||
else
|
|
||||||
XashActivity.mDecorView.setSystemUiVisibility( 0 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class JoystickHandler
|
|
||||||
{
|
|
||||||
public int getSource( KeyEvent event )
|
|
||||||
{
|
|
||||||
return InputDevice.SOURCE_UNKNOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSource( MotionEvent event )
|
|
||||||
{
|
|
||||||
return InputDevice.SOURCE_UNKNOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean handleAxis( MotionEvent event )
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isGamepadButton( int keyCode )
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String keyCodeToString( int keyCode )
|
|
||||||
{
|
|
||||||
return String.valueOf( keyCode );
|
|
||||||
}
|
|
||||||
|
|
||||||
public void init()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasVibrator()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void showMouse( boolean show )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getButtonState( MotionEvent event )
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Wrap_NVMouseExtensions
|
|
||||||
{
|
|
||||||
private static Object inputManager;
|
|
||||||
private static Method mInputManager_setCursorVisibility;
|
|
||||||
private static Method mView_setPointerIcon;
|
|
||||||
private static Class mPointerIcon;
|
|
||||||
private static Object mEmptyIcon;
|
|
||||||
public static int nMotionEvent_AXIS_RELATIVE_X = 0;
|
|
||||||
public static int nMotionEvent_AXIS_RELATIVE_Y = 0;
|
|
||||||
|
|
||||||
//**************************************************************************
|
|
||||||
static
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
mInputManager_setCursorVisibility =
|
|
||||||
Class.forName( "android.hardware.input.InputManager" ).getMethod( "setCursorVisibility", boolean.class );
|
|
||||||
|
|
||||||
inputManager = XashActivity.mSingleton.getSystemService( "input" );
|
|
||||||
}
|
|
||||||
catch( Exception ex )
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
mPointerIcon=Class.forName("android.view.PointerIcon");
|
|
||||||
mEmptyIcon = mPointerIcon.getDeclaredMethod("getSystemIcon",android.content.Context.class, int.class).invoke(null,XashActivity.mSingleton.getContext(),0);
|
|
||||||
mView_setPointerIcon = View.class.getMethod("setPointerIcon",mPointerIcon);
|
|
||||||
}
|
|
||||||
catch( Exception ex1 )
|
|
||||||
{
|
|
||||||
ex1.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* DO THE SAME FOR RELATIVEY */
|
|
||||||
}
|
|
||||||
|
|
||||||
//*************************************************************************
|
|
||||||
public static void checkAvailable() throws Exception
|
|
||||||
{
|
|
||||||
Field fieldMotionEvent_AXIS_RELATIVE_X = MotionEvent.class.getField( "AXIS_RELATIVE_X" );
|
|
||||||
nMotionEvent_AXIS_RELATIVE_X = ( Integer )fieldMotionEvent_AXIS_RELATIVE_X.get( null );
|
|
||||||
Field fieldMotionEvent_AXIS_RELATIVE_Y = MotionEvent.class.getField( "AXIS_RELATIVE_Y" );
|
|
||||||
nMotionEvent_AXIS_RELATIVE_Y = ( Integer )fieldMotionEvent_AXIS_RELATIVE_Y.get( null );
|
|
||||||
}
|
|
||||||
|
|
||||||
static void setPointerIcon( View view, boolean fVisibility )
|
|
||||||
{
|
|
||||||
Log.v("XashInput", "SET CURSOR VISIBILITY " + fVisibility + " obj " + mEmptyIcon.toString() );
|
|
||||||
try
|
|
||||||
{
|
|
||||||
mView_setPointerIcon.invoke(view,fVisibility?null:mEmptyIcon);
|
|
||||||
}
|
|
||||||
catch( Exception e)
|
|
||||||
{
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static void setGroupPointerIcon( ViewGroup parent, boolean fVisibility )
|
|
||||||
{
|
|
||||||
for( int i = parent.getChildCount() - 1; i >= 0; i-- )
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
final View child = parent.getChildAt(i);
|
|
||||||
|
|
||||||
if( child == null )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if( child instanceof ViewGroup )
|
|
||||||
{
|
|
||||||
setGroupPointerIcon((ViewGroup) child, fVisibility);
|
|
||||||
}
|
|
||||||
setPointerIcon( child, fVisibility);
|
|
||||||
|
|
||||||
}
|
|
||||||
catch( Exception ex )
|
|
||||||
{
|
|
||||||
ex.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//**************************************************************************
|
|
||||||
public static void setCursorVisibility( boolean fVisibility )
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
mInputManager_setCursorVisibility.invoke( inputManager, fVisibility );
|
|
||||||
|
|
||||||
}
|
|
||||||
catch( Exception e )
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ViewGroup rootViewGroup = (ViewGroup) XashActivity.mSingleton.getWindow().getDecorView();
|
|
||||||
setGroupPointerIcon(rootViewGroup, fVisibility);
|
|
||||||
setGroupPointerIcon((ViewGroup)XashActivity.mDecorView, fVisibility);
|
|
||||||
for (int i = 0; i < rootViewGroup.getChildCount(); i++) {
|
|
||||||
View view = rootViewGroup.getChildAt(i);
|
|
||||||
setPointerIcon(view, fVisibility);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch( Exception ex)
|
|
||||||
{
|
|
||||||
ex.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//**************************************************************************
|
|
||||||
public static int getAxisRelativeX()
|
|
||||||
{
|
|
||||||
return nMotionEvent_AXIS_RELATIVE_X;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getAxisRelativeY()
|
|
||||||
{
|
|
||||||
return nMotionEvent_AXIS_RELATIVE_Y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class JoystickHandler_v12 extends JoystickHandler
|
|
||||||
{
|
|
||||||
private static float prevSide, prevFwd, prevYaw, prevPtch, prevLT, prevRT, prevHX, prevHY;
|
|
||||||
|
|
||||||
public static boolean mNVMouseExtensions = false;
|
|
||||||
|
|
||||||
static int mouseId;
|
|
||||||
static
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Wrap_NVMouseExtensions.checkAvailable();
|
|
||||||
mNVMouseExtensions = true;
|
|
||||||
}
|
|
||||||
catch( Throwable t )
|
|
||||||
{
|
|
||||||
mNVMouseExtensions = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init()
|
|
||||||
{
|
|
||||||
XashActivity.mSurface.setOnGenericMotionListener( new MotionListener() );
|
|
||||||
Log.d( XashActivity.TAG, "mNVMouseExtensions = " + mNVMouseExtensions );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getSource( KeyEvent event )
|
|
||||||
{
|
|
||||||
return event.getSource();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getSource( MotionEvent event )
|
|
||||||
{
|
|
||||||
if( event.getDeviceId() == mouseId )
|
|
||||||
return InputDevice.SOURCE_MOUSE;
|
|
||||||
return event.getSource();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean handleAxis( MotionEvent event )
|
|
||||||
{
|
|
||||||
// how event can be from null device, Android?
|
|
||||||
final InputDevice device = event.getDevice();
|
|
||||||
if( device == null )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// maybe I need to cache this...
|
|
||||||
for( InputDevice.MotionRange range: device.getMotionRanges() )
|
|
||||||
{
|
|
||||||
// normalize in -1.0..1.0 (copied from SDL2)
|
|
||||||
final float cur = ( event.getAxisValue( range.getAxis(), event.getActionIndex() ) - range.getMin() ) / range.getRange() * 2.0f - 1.0f;
|
|
||||||
final float dead = range.getFlat(); // get axis dead zone
|
|
||||||
switch( range.getAxis() )
|
|
||||||
{
|
|
||||||
// typical axes
|
|
||||||
// move
|
|
||||||
case MotionEvent.AXIS_X:
|
|
||||||
prevSide = XashActivity.performEngineAxisEvent( cur, XashActivity.JOY_AXIS_SIDE, prevSide, dead );
|
|
||||||
break;
|
|
||||||
case MotionEvent.AXIS_Y:
|
|
||||||
prevFwd = XashActivity.performEngineAxisEvent( cur, XashActivity.JOY_AXIS_FWD, prevFwd, dead );
|
|
||||||
break;
|
|
||||||
|
|
||||||
// rotate. Invert, so by default this works as it's should
|
|
||||||
case MotionEvent.AXIS_Z:
|
|
||||||
prevPtch = XashActivity.performEngineAxisEvent( -cur, XashActivity.JOY_AXIS_PITCH, prevPtch, dead );
|
|
||||||
break;
|
|
||||||
case MotionEvent.AXIS_RZ:
|
|
||||||
prevYaw = XashActivity.performEngineAxisEvent( -cur, XashActivity.JOY_AXIS_YAW, prevYaw, dead );
|
|
||||||
break;
|
|
||||||
|
|
||||||
// trigger
|
|
||||||
case MotionEvent.AXIS_RTRIGGER:
|
|
||||||
prevLT = XashActivity.performEngineAxisEvent( cur, XashActivity.JOY_AXIS_RT, prevLT, dead );
|
|
||||||
break;
|
|
||||||
case MotionEvent.AXIS_LTRIGGER:
|
|
||||||
prevRT = XashActivity.performEngineAxisEvent( cur, XashActivity.JOY_AXIS_LT, prevRT, dead );
|
|
||||||
break;
|
|
||||||
|
|
||||||
// hats
|
|
||||||
case MotionEvent.AXIS_HAT_X:
|
|
||||||
prevHX = XashActivity.performEngineHatEvent( cur, true, prevHX );
|
|
||||||
break;
|
|
||||||
case MotionEvent.AXIS_HAT_Y:
|
|
||||||
prevHY = XashActivity.performEngineHatEvent( cur, false, prevHY );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isGamepadButton( int keyCode )
|
|
||||||
{
|
|
||||||
return KeyEvent.isGamepadButton( keyCode );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String keyCodeToString( int keyCode )
|
|
||||||
{
|
|
||||||
return KeyEvent.keyCodeToString( keyCode );
|
|
||||||
}
|
|
||||||
|
|
||||||
class MotionListener implements View.OnGenericMotionListener
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public boolean onGenericMotion( View view, MotionEvent event )
|
|
||||||
{
|
|
||||||
final int source = XashActivity.handler.getSource( event );
|
|
||||||
|
|
||||||
if( FWGSLib.FExactBitSet( source, InputDevice.SOURCE_GAMEPAD ) ||
|
|
||||||
FWGSLib.FExactBitSet( source, InputDevice.SOURCE_CLASS_JOYSTICK ) )
|
|
||||||
return XashActivity.handler.handleAxis( event );
|
|
||||||
|
|
||||||
if( mNVMouseExtensions )
|
|
||||||
{
|
|
||||||
float x = event.getAxisValue( Wrap_NVMouseExtensions.getAxisRelativeX(), 0 );
|
|
||||||
float y = event.getAxisValue( Wrap_NVMouseExtensions.getAxisRelativeY(), 0 );
|
|
||||||
if( !FWGSLib.FExactBitSet( source, InputDevice.SOURCE_MOUSE) && (x != 0 || y != 0 ))
|
|
||||||
mouseId = event.getDeviceId();
|
|
||||||
|
|
||||||
switch( event.getAction() )
|
|
||||||
{
|
|
||||||
case MotionEvent.ACTION_SCROLL:
|
|
||||||
if( event.getAxisValue( MotionEvent.AXIS_VSCROLL ) < 0.0f )
|
|
||||||
{
|
|
||||||
XashActivity.nativeKey( 1, -239 );
|
|
||||||
XashActivity.nativeKey( 0, -239 );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
XashActivity.nativeKey( 1, -240 );
|
|
||||||
XashActivity.nativeKey( 0, -240 );
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
XashActivity.nativeMouseMove( x, y );
|
|
||||||
// Log.v("XashInput", "MouseMove: " +x + " " + y );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Add it someday
|
|
||||||
// else if( (event.getSource() & InputDevice.SOURCE_CLASS_TRACKBALL) == InputDevice.SOURCE_CLASS_TRACKBALL )
|
|
||||||
// return XashActivity.handleBall( event );
|
|
||||||
//return super.onGenericMotion( view, event );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasVibrator()
|
|
||||||
{
|
|
||||||
if( XashActivity.mVibrator != null )
|
|
||||||
return XashActivity.mVibrator.hasVibrator();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void showMouse( boolean show )
|
|
||||||
{
|
|
||||||
if( mNVMouseExtensions )
|
|
||||||
Wrap_NVMouseExtensions.setCursorVisibility( show );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class JoystickHandler_v14 extends JoystickHandler_v12
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public int getButtonState( MotionEvent event )
|
|
||||||
{
|
|
||||||
return event.getButtonState();
|
|
||||||
}
|
|
||||||
}
|
|
614
android/src/su/xash/engine/XashInput.java
Normal file
614
android/src/su/xash/engine/XashInput.java
Normal file
|
@ -0,0 +1,614 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
package su.xash.engine;
|
||||||
|
import java.lang.*;
|
||||||
|
import java.lang.reflect.*;
|
||||||
|
import java.util.*;
|
||||||
|
import android.app.*;
|
||||||
|
import android.content.*;
|
||||||
|
import android.view.*;
|
||||||
|
import android.os.*;
|
||||||
|
import android.util.*;
|
||||||
|
import android.graphics.*;
|
||||||
|
import android.text.method.*;
|
||||||
|
import android.text.*;
|
||||||
|
import android.media.*;
|
||||||
|
import android.hardware.*;
|
||||||
|
import android.content.*;
|
||||||
|
import android.widget.*;
|
||||||
|
import android.content.pm.*;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.provider.*;
|
||||||
|
import android.view.inputmethod.*;
|
||||||
|
import su.xash.fwgslib.*;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class XashInput
|
||||||
|
{
|
||||||
|
public static JoystickHandler getJoystickHandler()
|
||||||
|
{
|
||||||
|
JoystickHandler handler;
|
||||||
|
|
||||||
|
if( FWGSLib.sdk >= 14 )
|
||||||
|
handler = new JoystickHandler_v14();
|
||||||
|
else if( FWGSLib.sdk >= 12 )
|
||||||
|
handler = new JoystickHandler_v12();
|
||||||
|
else
|
||||||
|
handler = new JoystickHandler();
|
||||||
|
handler.init();
|
||||||
|
return handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class JoystickHandler
|
||||||
|
{
|
||||||
|
public int getSource( KeyEvent event )
|
||||||
|
{
|
||||||
|
return InputDevice.SOURCE_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSource( MotionEvent event )
|
||||||
|
{
|
||||||
|
return InputDevice.SOURCE_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean handleAxis( MotionEvent event )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isGamepadButton( int keyCode )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String keyCodeToString( int keyCode )
|
||||||
|
{
|
||||||
|
return String.valueOf( keyCode );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasVibrator()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void showMouse( boolean show )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getButtonState( MotionEvent event )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static class JoystickHandler_v12 extends JoystickHandler
|
||||||
|
{
|
||||||
|
private static float prevSide, prevFwd, prevYaw, prevPtch, prevLT, prevRT, prevHX, prevHY;
|
||||||
|
|
||||||
|
public static boolean mNVMouseExtensions = false;
|
||||||
|
|
||||||
|
static int mouseId;
|
||||||
|
static
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Wrap_NVMouseExtensions.checkAvailable();
|
||||||
|
mNVMouseExtensions = true;
|
||||||
|
}
|
||||||
|
catch( Throwable t )
|
||||||
|
{
|
||||||
|
mNVMouseExtensions = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init()
|
||||||
|
{
|
||||||
|
XashActivity.mSurface.setOnGenericMotionListener( new MotionListener() );
|
||||||
|
Log.d( XashActivity.TAG, "mNVMouseExtensions = " + mNVMouseExtensions );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSource( KeyEvent event )
|
||||||
|
{
|
||||||
|
return event.getSource();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSource( MotionEvent event )
|
||||||
|
{
|
||||||
|
if( event.getDeviceId() == mouseId )
|
||||||
|
return InputDevice.SOURCE_MOUSE;
|
||||||
|
return event.getSource();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handleAxis( MotionEvent event )
|
||||||
|
{
|
||||||
|
// how event can be from null device, Android?
|
||||||
|
final InputDevice device = event.getDevice();
|
||||||
|
if( device == null )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// maybe I need to cache this...
|
||||||
|
for( InputDevice.MotionRange range: device.getMotionRanges() )
|
||||||
|
{
|
||||||
|
// normalize in -1.0..1.0 (copied from SDL2)
|
||||||
|
final float cur = ( event.getAxisValue( range.getAxis(), event.getActionIndex() ) - range.getMin() ) / range.getRange() * 2.0f - 1.0f;
|
||||||
|
final float dead = range.getFlat(); // get axis dead zone
|
||||||
|
switch( range.getAxis() )
|
||||||
|
{
|
||||||
|
// typical axes
|
||||||
|
// move
|
||||||
|
case MotionEvent.AXIS_X:
|
||||||
|
prevSide = XashActivity.performEngineAxisEvent( cur, XashActivity.JOY_AXIS_SIDE, prevSide, dead );
|
||||||
|
break;
|
||||||
|
case MotionEvent.AXIS_Y:
|
||||||
|
prevFwd = XashActivity.performEngineAxisEvent( cur, XashActivity.JOY_AXIS_FWD, prevFwd, dead );
|
||||||
|
break;
|
||||||
|
|
||||||
|
// rotate. Invert, so by default this works as it's should
|
||||||
|
case MotionEvent.AXIS_Z:
|
||||||
|
prevPtch = XashActivity.performEngineAxisEvent( -cur, XashActivity.JOY_AXIS_PITCH, prevPtch, dead );
|
||||||
|
break;
|
||||||
|
case MotionEvent.AXIS_RZ:
|
||||||
|
prevYaw = XashActivity.performEngineAxisEvent( -cur, XashActivity.JOY_AXIS_YAW, prevYaw, dead );
|
||||||
|
break;
|
||||||
|
|
||||||
|
// trigger
|
||||||
|
case MotionEvent.AXIS_RTRIGGER:
|
||||||
|
prevLT = XashActivity.performEngineAxisEvent( cur, XashActivity.JOY_AXIS_RT, prevLT, dead );
|
||||||
|
break;
|
||||||
|
case MotionEvent.AXIS_LTRIGGER:
|
||||||
|
prevRT = XashActivity.performEngineAxisEvent( cur, XashActivity.JOY_AXIS_LT, prevRT, dead );
|
||||||
|
break;
|
||||||
|
|
||||||
|
// hats
|
||||||
|
case MotionEvent.AXIS_HAT_X:
|
||||||
|
prevHX = XashActivity.performEngineHatEvent( cur, true, prevHX );
|
||||||
|
break;
|
||||||
|
case MotionEvent.AXIS_HAT_Y:
|
||||||
|
prevHY = XashActivity.performEngineHatEvent( cur, false, prevHY );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isGamepadButton( int keyCode )
|
||||||
|
{
|
||||||
|
return KeyEvent.isGamepadButton( keyCode );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String keyCodeToString( int keyCode )
|
||||||
|
{
|
||||||
|
return KeyEvent.keyCodeToString( keyCode );
|
||||||
|
}
|
||||||
|
|
||||||
|
class MotionListener implements View.OnGenericMotionListener
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public boolean onGenericMotion( View view, MotionEvent event )
|
||||||
|
{
|
||||||
|
final int source = XashActivity.handler.getSource( event );
|
||||||
|
|
||||||
|
if( FWGSLib.FExactBitSet( source, InputDevice.SOURCE_GAMEPAD ) ||
|
||||||
|
FWGSLib.FExactBitSet( source, InputDevice.SOURCE_CLASS_JOYSTICK ) )
|
||||||
|
return XashActivity.handler.handleAxis( event );
|
||||||
|
|
||||||
|
if( mNVMouseExtensions )
|
||||||
|
{
|
||||||
|
float x = event.getAxisValue( Wrap_NVMouseExtensions.getAxisRelativeX(), 0 );
|
||||||
|
float y = event.getAxisValue( Wrap_NVMouseExtensions.getAxisRelativeY(), 0 );
|
||||||
|
if( !FWGSLib.FExactBitSet( source, InputDevice.SOURCE_MOUSE) && (x != 0 || y != 0 ))
|
||||||
|
mouseId = event.getDeviceId();
|
||||||
|
|
||||||
|
switch( event.getAction() )
|
||||||
|
{
|
||||||
|
case MotionEvent.ACTION_SCROLL:
|
||||||
|
if( event.getAxisValue( MotionEvent.AXIS_VSCROLL ) < 0.0f )
|
||||||
|
{
|
||||||
|
XashActivity.nativeKey( 1, -239 );
|
||||||
|
XashActivity.nativeKey( 0, -239 );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
XashActivity.nativeKey( 1, -240 );
|
||||||
|
XashActivity.nativeKey( 0, -240 );
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
XashActivity.nativeMouseMove( x, y );
|
||||||
|
// Log.v("XashInput", "MouseMove: " +x + " " + y );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Add it someday
|
||||||
|
// else if( (event.getSource() & InputDevice.SOURCE_CLASS_TRACKBALL) == InputDevice.SOURCE_CLASS_TRACKBALL )
|
||||||
|
// return XashActivity.handleBall( event );
|
||||||
|
//return super.onGenericMotion( view, event );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasVibrator()
|
||||||
|
{
|
||||||
|
if( XashActivity.mVibrator != null )
|
||||||
|
return XashActivity.mVibrator.hasVibrator();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showMouse( boolean show )
|
||||||
|
{
|
||||||
|
if( mNVMouseExtensions )
|
||||||
|
Wrap_NVMouseExtensions.setCursorVisibility( show );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class JoystickHandler_v14 extends JoystickHandler_v12
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public int getButtonState( MotionEvent event )
|
||||||
|
{
|
||||||
|
return event.getButtonState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static View.OnTouchListener getTouchListener()
|
||||||
|
{
|
||||||
|
if( FWGSLib.sdk >= 5 )
|
||||||
|
return new EngineTouchListener_v5();
|
||||||
|
else
|
||||||
|
return new EngineTouchListener_v1();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class Wrap_NVMouseExtensions
|
||||||
|
{
|
||||||
|
private static Object inputManager;
|
||||||
|
private static Method mInputManager_setCursorVisibility;
|
||||||
|
private static Method mView_setPointerIcon;
|
||||||
|
private static Class mPointerIcon;
|
||||||
|
private static Object mEmptyIcon;
|
||||||
|
public static int nMotionEvent_AXIS_RELATIVE_X = 0;
|
||||||
|
public static int nMotionEvent_AXIS_RELATIVE_Y = 0;
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
static
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
mInputManager_setCursorVisibility =
|
||||||
|
Class.forName( "android.hardware.input.InputManager" ).getMethod( "setCursorVisibility", boolean.class );
|
||||||
|
|
||||||
|
inputManager = XashActivity.mSingleton.getSystemService( "input" );
|
||||||
|
}
|
||||||
|
catch( Exception ex )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
mPointerIcon=Class.forName("android.view.PointerIcon");
|
||||||
|
mEmptyIcon = mPointerIcon.getDeclaredMethod("getSystemIcon",android.content.Context.class, int.class).invoke(null,XashActivity.mSingleton.getContext(),0);
|
||||||
|
mView_setPointerIcon = View.class.getMethod("setPointerIcon",mPointerIcon);
|
||||||
|
}
|
||||||
|
catch( Exception ex1 )
|
||||||
|
{
|
||||||
|
ex1.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* DO THE SAME FOR RELATIVEY */
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
public static void checkAvailable() throws Exception
|
||||||
|
{
|
||||||
|
Field fieldMotionEvent_AXIS_RELATIVE_X = MotionEvent.class.getField( "AXIS_RELATIVE_X" );
|
||||||
|
nMotionEvent_AXIS_RELATIVE_X = ( Integer )fieldMotionEvent_AXIS_RELATIVE_X.get( null );
|
||||||
|
Field fieldMotionEvent_AXIS_RELATIVE_Y = MotionEvent.class.getField( "AXIS_RELATIVE_Y" );
|
||||||
|
nMotionEvent_AXIS_RELATIVE_Y = ( Integer )fieldMotionEvent_AXIS_RELATIVE_Y.get( null );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setPointerIcon( View view, boolean fVisibility )
|
||||||
|
{
|
||||||
|
Log.v("XashInput", "SET CURSOR VISIBILITY " + fVisibility + " obj " + mEmptyIcon.toString() );
|
||||||
|
try
|
||||||
|
{
|
||||||
|
mView_setPointerIcon.invoke(view,fVisibility?null:mEmptyIcon);
|
||||||
|
}
|
||||||
|
catch( Exception e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void setGroupPointerIcon( ViewGroup parent, boolean fVisibility )
|
||||||
|
{
|
||||||
|
for( int i = parent.getChildCount() - 1; i >= 0; i-- )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
final View child = parent.getChildAt(i);
|
||||||
|
|
||||||
|
if( child == null )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if( child instanceof ViewGroup )
|
||||||
|
{
|
||||||
|
setGroupPointerIcon((ViewGroup) child, fVisibility);
|
||||||
|
}
|
||||||
|
setPointerIcon( child, fVisibility);
|
||||||
|
|
||||||
|
}
|
||||||
|
catch( Exception ex )
|
||||||
|
{
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
public static void setCursorVisibility( boolean fVisibility )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
mInputManager_setCursorVisibility.invoke( inputManager, fVisibility );
|
||||||
|
|
||||||
|
}
|
||||||
|
catch( Exception e )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ViewGroup rootViewGroup = (ViewGroup) XashActivity.mSingleton.getWindow().getDecorView();
|
||||||
|
setGroupPointerIcon(rootViewGroup, fVisibility);
|
||||||
|
setGroupPointerIcon((ViewGroup)XashActivity.mDecorView, fVisibility);
|
||||||
|
for (int i = 0; i < rootViewGroup.getChildCount(); i++) {
|
||||||
|
View view = rootViewGroup.getChildAt(i);
|
||||||
|
setPointerIcon(view, fVisibility);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch( Exception ex)
|
||||||
|
{
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
public static int getAxisRelativeX()
|
||||||
|
{
|
||||||
|
return nMotionEvent_AXIS_RELATIVE_X;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getAxisRelativeY()
|
||||||
|
{
|
||||||
|
return nMotionEvent_AXIS_RELATIVE_Y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class EngineTouchListener_v1 implements View.OnTouchListener
|
||||||
|
{
|
||||||
|
// Touch events
|
||||||
|
public boolean onTouch( View v, MotionEvent event )
|
||||||
|
{
|
||||||
|
XashActivity.nativeTouch( 0, event.getAction(), event.getX(), event.getY() );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EngineTouchListener_v5 implements View.OnTouchListener
|
||||||
|
{
|
||||||
|
float lx = 0, ly = 0;
|
||||||
|
boolean secondarypressed = false;
|
||||||
|
|
||||||
|
// Touch events
|
||||||
|
public boolean onTouch( View v, MotionEvent event )
|
||||||
|
{
|
||||||
|
//final int touchDevId = event.getDeviceId();
|
||||||
|
final int pointerCount = event.getPointerCount();
|
||||||
|
int action = event.getActionMasked();
|
||||||
|
int pointerFingerId, mouseButton, i = -1;
|
||||||
|
float x, y;
|
||||||
|
|
||||||
|
switch( action )
|
||||||
|
{
|
||||||
|
case MotionEvent.ACTION_MOVE:
|
||||||
|
if( ( !XashActivity.fMouseShown ) && ( ( XashActivity.handler.getSource( event ) & InputDevice.SOURCE_MOUSE ) == InputDevice.SOURCE_MOUSE ) )
|
||||||
|
{
|
||||||
|
x = event.getX();
|
||||||
|
y = event.getY();
|
||||||
|
|
||||||
|
XashActivity.nativeMouseMove( x - lx, y - ly );
|
||||||
|
lx = x;
|
||||||
|
ly = y;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for( i = 0; i < pointerCount; i++ )
|
||||||
|
{
|
||||||
|
pointerFingerId = event.getPointerId( i );
|
||||||
|
x = event.getX( i ) * XashActivity.mTouchScaleX;
|
||||||
|
y = event.getY( i ) * XashActivity.mTouchScaleY;
|
||||||
|
XashActivity.nativeTouch( pointerFingerId, 2, x, y );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MotionEvent.ACTION_UP:
|
||||||
|
case MotionEvent.ACTION_DOWN:
|
||||||
|
if( !XashActivity.fMouseShown && ( ( XashActivity.handler.getSource( event ) & InputDevice.SOURCE_MOUSE ) == InputDevice.SOURCE_MOUSE ) )
|
||||||
|
{
|
||||||
|
lx = event.getX();
|
||||||
|
ly = event.getY();
|
||||||
|
boolean down = ( action == MotionEvent.ACTION_DOWN ) || ( action == MotionEvent.ACTION_POINTER_DOWN );
|
||||||
|
int buttonState = XashActivity.handler.getButtonState( event );
|
||||||
|
if( down && ( buttonState & MotionEvent.BUTTON_SECONDARY ) != 0 )
|
||||||
|
{
|
||||||
|
XashActivity.nativeKey( 1, -243 );
|
||||||
|
secondarypressed = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if( !down && secondarypressed && ( buttonState & MotionEvent.BUTTON_SECONDARY ) == 0 )
|
||||||
|
{
|
||||||
|
secondarypressed = false;
|
||||||
|
XashActivity.nativeKey( 0, -243 );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
XashActivity.nativeKey( down ? 1 : 0, -241 );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
i = 0;
|
||||||
|
// fallthrough
|
||||||
|
case MotionEvent.ACTION_POINTER_UP:
|
||||||
|
case MotionEvent.ACTION_POINTER_DOWN:
|
||||||
|
// Non primary pointer up/down
|
||||||
|
if( i == -1 )
|
||||||
|
{
|
||||||
|
i = event.getActionIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
pointerFingerId = event.getPointerId( i );
|
||||||
|
|
||||||
|
x = event.getX( i ) * XashActivity.mTouchScaleX;
|
||||||
|
y = event.getY( i ) * XashActivity.mTouchScaleY;
|
||||||
|
if( action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_POINTER_UP )
|
||||||
|
XashActivity.nativeTouch( pointerFingerId,1, x, y );
|
||||||
|
if( action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_POINTER_DOWN )
|
||||||
|
XashActivity.nativeTouch( pointerFingerId,0, x, y );
|
||||||
|
break;
|
||||||
|
case MotionEvent.ACTION_CANCEL:
|
||||||
|
for( i = 0; i < pointerCount; i++ )
|
||||||
|
{
|
||||||
|
pointerFingerId = event.getPointerId( i );
|
||||||
|
x = event.getX( i ) * XashActivity.mTouchScaleX;
|
||||||
|
y = event.getY( i ) * XashActivity.mTouchScaleY;
|
||||||
|
XashActivity.nativeTouch( pointerFingerId, 1, x, y );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* This is a fake invisible editor view that receives the input and defines the
|
||||||
|
* pan&scan region
|
||||||
|
*/
|
||||||
|
class DummyEdit extends View implements View.OnKeyListener
|
||||||
|
{
|
||||||
|
InputConnection ic;
|
||||||
|
|
||||||
|
public DummyEdit( Context context )
|
||||||
|
{
|
||||||
|
super( context );
|
||||||
|
setFocusableInTouchMode( true );
|
||||||
|
setFocusable( true );
|
||||||
|
setOnKeyListener( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCheckIsTextEditor()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onKey( View v, int keyCode, KeyEvent event )
|
||||||
|
{
|
||||||
|
return XashActivity.handleKey( keyCode, event );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputConnection onCreateInputConnection( EditorInfo outAttrs )
|
||||||
|
{
|
||||||
|
ic = new XashInputConnection( this, true );
|
||||||
|
|
||||||
|
outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_EXTRACT_UI
|
||||||
|
| 33554432 /* API 11: EditorInfo.IME_FLAG_NO_FULLSCREEN */;
|
||||||
|
|
||||||
|
return ic;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class XashInputConnection extends BaseInputConnection
|
||||||
|
{
|
||||||
|
public XashInputConnection( View targetView, boolean fullEditor )
|
||||||
|
{
|
||||||
|
super( targetView, fullEditor );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean sendKeyEvent( KeyEvent event )
|
||||||
|
{
|
||||||
|
if( XashActivity.handleKey( event.getKeyCode(), event ) )
|
||||||
|
return true;
|
||||||
|
return super.sendKeyEvent( event );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean commitText( CharSequence text, int newCursorPosition )
|
||||||
|
{
|
||||||
|
// nativeCommitText(text.toString(), newCursorPosition);
|
||||||
|
if( text.toString().equals( "\n" ) )
|
||||||
|
{
|
||||||
|
XashActivity.nativeKey( 1, KeyEvent.KEYCODE_ENTER );
|
||||||
|
XashActivity.nativeKey( 0, KeyEvent.KEYCODE_ENTER );
|
||||||
|
}
|
||||||
|
XashActivity.nativeString( text.toString() );
|
||||||
|
|
||||||
|
return super.commitText( text, newCursorPosition );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean setComposingText( CharSequence text, int newCursorPosition )
|
||||||
|
{
|
||||||
|
// a1batross:
|
||||||
|
// This method is intended to show composed text immediately
|
||||||
|
// that after will be replaced by text from "commitText" method
|
||||||
|
// Just leaving this unimplemented fixes "twice" input on T9/Swype-like keyboards
|
||||||
|
|
||||||
|
//ativeSetComposingText(text.toString(), newCursorPosition);
|
||||||
|
// XashActivity.nativeString( text.toString() );
|
||||||
|
|
||||||
|
return super.setComposingText( text, newCursorPosition );
|
||||||
|
}
|
||||||
|
|
||||||
|
public native void nativeSetComposingText( String text, int newCursorPosition );
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean deleteSurroundingText( int beforeLength, int afterLength )
|
||||||
|
{
|
||||||
|
// Workaround to capture backspace key. Ref: http://stackoverflow.com/questions/14560344/android-backspace-in-webview-baseinputconnection
|
||||||
|
// and https://bugzilla.libsdl.org/show_bug.cgi?id=2265
|
||||||
|
if( beforeLength > 0 && afterLength == 0 )
|
||||||
|
{
|
||||||
|
boolean ret = true;
|
||||||
|
// backspace(s)
|
||||||
|
while( beforeLength-- > 0 )
|
||||||
|
{
|
||||||
|
boolean ret_key = sendKeyEvent( new KeyEvent( KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL ) )
|
||||||
|
&& sendKeyEvent( new KeyEvent( KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DEL ) );
|
||||||
|
ret = ret && ret_key;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.deleteSurroundingText(beforeLength, afterLength);
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,7 +32,6 @@ import java.security.MessageDigest;
|
||||||
|
|
||||||
import su.xash.engine.R;
|
import su.xash.engine.R;
|
||||||
import su.xash.engine.XashConfig;
|
import su.xash.engine.XashConfig;
|
||||||
import su.xash.engine.JoystickHandler;
|
|
||||||
|
|
||||||
|
|
||||||
public class XashService extends Service
|
public class XashService extends Service
|
||||||
|
@ -64,9 +63,9 @@ public class XashService extends Service
|
||||||
{
|
{
|
||||||
Log.d("XashService", "Service Started");
|
Log.d("XashService", "Service Started");
|
||||||
|
|
||||||
not = XashNotification.getXashNotification(this);
|
not = XashNotification.getXashNotification();
|
||||||
|
|
||||||
startForeground(not.getId(), not.createNotification());
|
startForeground(not.getId(), not.createNotification(this));
|
||||||
|
|
||||||
return START_NOT_STICKY;
|
return START_NOT_STICKY;
|
||||||
}
|
}
|
||||||
|
@ -98,20 +97,16 @@ public class XashService extends Service
|
||||||
}
|
}
|
||||||
stopSelf();
|
stopSelf();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class XashNotification
|
public static class XashNotification
|
||||||
{
|
{
|
||||||
public Notification notification;
|
public Notification notification;
|
||||||
public final int notificationId = 100;
|
public final int notificationId = 100;
|
||||||
public Context ctx;
|
protected Context ctx;
|
||||||
|
|
||||||
public XashNotification(Context ctx)
|
|
||||||
{
|
|
||||||
this.ctx = ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Notification createNotification()
|
public Notification createNotification(Context context)
|
||||||
{
|
{
|
||||||
|
ctx = context;
|
||||||
Intent engineIntent = new Intent(ctx, XashActivity.class);
|
Intent engineIntent = new Intent(ctx, XashActivity.class);
|
||||||
engineIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
|
engineIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
|
||||||
|
|
||||||
|
@ -133,14 +128,14 @@ public class XashService extends Service
|
||||||
public void setIcon(Bitmap bmp)
|
public void setIcon(Bitmap bmp)
|
||||||
{
|
{
|
||||||
notification.contentView.setImageViewBitmap( R.id.status_image, bmp );
|
notification.contentView.setImageViewBitmap( R.id.status_image, bmp );
|
||||||
NotificationManager nm = ctx.getSystemService(NotificationManager.class);
|
NotificationManager nm = (NotificationManager)ctx.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
nm.notify( notificationId, notification );
|
nm.notify( notificationId, notification );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setText(String title)
|
public void setText(String title)
|
||||||
{
|
{
|
||||||
notification.contentView.setTextViewText( R.id.status_text, title );
|
notification.contentView.setTextViewText( R.id.status_text, title );
|
||||||
NotificationManager nm = ctx.getSystemService(NotificationManager.class);
|
NotificationManager nm = (NotificationManager)ctx.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
nm.notify( notificationId, notification );
|
nm.notify( notificationId, notification );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,28 +144,26 @@ public class XashService extends Service
|
||||||
return notificationId;
|
return notificationId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static XashNotification getXashNotification(Context ctx)
|
public static XashNotification getXashNotification()
|
||||||
{
|
{
|
||||||
if( XashActivity.sdk >= Build.VERSION_CODES.O )
|
if( XashActivity.sdk >= 26 )
|
||||||
return new XashNotification_O(ctx);
|
return new XashNotification_v26();
|
||||||
else if( XashActivity.sdk >= 21 )
|
// else if( XashActivity.sdk >= 21 )
|
||||||
return new XashNotification_v21(ctx);
|
// return new XashNotification_v21();
|
||||||
return new XashNotification(ctx);
|
else
|
||||||
|
return new XashNotification();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class XashNotification_v21 extends XashNotification
|
private static class XashNotification_v21 extends XashNotification
|
||||||
{
|
{
|
||||||
protected Notification.Builder builder;
|
protected Notification.Builder builder;
|
||||||
|
|
||||||
public XashNotification_v21(Context ctx)
|
|
||||||
{
|
|
||||||
super(ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Notification createNotification()
|
public Notification createNotification(Context context)
|
||||||
{
|
{
|
||||||
|
ctx = context;
|
||||||
Intent engineIntent = new Intent(ctx, XashActivity.class);
|
Intent engineIntent = new Intent(ctx, XashActivity.class);
|
||||||
engineIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
|
engineIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
|
||||||
|
|
||||||
|
@ -196,7 +189,7 @@ public class XashService extends Service
|
||||||
public void setIcon(Bitmap bmp)
|
public void setIcon(Bitmap bmp)
|
||||||
{
|
{
|
||||||
notification = builder.setLargeIcon(bmp).build();
|
notification = builder.setLargeIcon(bmp).build();
|
||||||
NotificationManager nm = ctx.getSystemService(NotificationManager.class);
|
NotificationManager nm = (NotificationManager)ctx.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
nm.notify( notificationId, notification );
|
nm.notify( notificationId, notification );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,25 +197,21 @@ public class XashService extends Service
|
||||||
public void setText(String str)
|
public void setText(String str)
|
||||||
{
|
{
|
||||||
notification = builder.setContentText(str).build();
|
notification = builder.setContentText(str).build();
|
||||||
NotificationManager nm = ctx.getSystemService(NotificationManager.class);
|
NotificationManager nm = (NotificationManager)ctx.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
nm.notify( notificationId, notification );
|
nm.notify( notificationId, notification );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class XashNotification_O extends XashNotification_v21
|
|
||||||
|
private static class XashNotification_v26 extends XashNotification_v21
|
||||||
{
|
{
|
||||||
private static final String CHANNEL_ID = "XashServiceChannel";
|
private static final String CHANNEL_ID = "XashServiceChannel";
|
||||||
|
|
||||||
public XashNotification_O(Context ctx)
|
|
||||||
{
|
|
||||||
super(ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createNotificationChannel()
|
private void createNotificationChannel()
|
||||||
{
|
{
|
||||||
// Create the NotificationChannel, but only on API 26+ because
|
// Create the NotificationChannel, but only on API 26+ because
|
||||||
// the NotificationChannel class is new and not in the support library
|
// the NotificationChannel class is new and not in the support library
|
||||||
if (XashActivity.sdk >= Build.VERSION_CODES.O)
|
if (XashActivity.sdk >= 26)
|
||||||
{
|
{
|
||||||
final NotificationManager nm = ctx.getSystemService(NotificationManager.class);
|
final NotificationManager nm = ctx.getSystemService(NotificationManager.class);
|
||||||
|
|
||||||
|
@ -244,14 +233,14 @@ public class XashService extends Service
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Notification createNotification()
|
public Notification createNotification(Context ctx)
|
||||||
{
|
{
|
||||||
createNotificationChannel();
|
createNotificationChannel();
|
||||||
|
|
||||||
builder = new Notification.Builder(ctx);
|
builder = new Notification.Builder(ctx);
|
||||||
builder.setChannelId(CHANNEL_ID);
|
builder.setChannelId(CHANNEL_ID);
|
||||||
|
|
||||||
return super.createNotification();
|
return super.createNotification(ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -229,9 +229,58 @@ public class FWGSLib
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void applyPermissions( final Activity act, final String permissions[], final int code )
|
public static class Compat
|
||||||
{
|
{
|
||||||
if( sdk >= 23 )
|
public void applyPermissions( final Activity act, final String permissions[], final int code ) {}
|
||||||
|
public void applyImmersiveMode( boolean keyboardVisible, View decorView ) {}
|
||||||
|
public void startForegroundService( Context ctx, Intent intent ) {}
|
||||||
|
public String getNativeLibDir(Context ctx)
|
||||||
|
{
|
||||||
|
return ctx.getFilesDir().getParentFile().getPath() + "/lib";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Compat_9 extends Compat
|
||||||
|
{
|
||||||
|
public String getNativeLibDir(Context ctx)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
ApplicationInfo ai = getApplicationInfo(ctx, null, 0);
|
||||||
|
return ai.nativeLibraryDir;
|
||||||
|
}
|
||||||
|
catch(Exception e) {
|
||||||
|
return super.getNativeLibDir(ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void startForegroundService( Context ctx, Intent intent ) {
|
||||||
|
ctx.startService( intent );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Compat_19 extends Compat_9
|
||||||
|
{
|
||||||
|
public void applyImmersiveMode(boolean keyboardVisible, View decorView)
|
||||||
|
{
|
||||||
|
//if( !XashActivity.mPref.getBoolean( "immersive_mode", false ) )
|
||||||
|
// return;
|
||||||
|
if( keyboardVisible )
|
||||||
|
decorView.setSystemUiVisibility(
|
||||||
|
0x00000100 // View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||||
|
| 0x00000200 // View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||||
|
| 0x00000400 // View.SYSTEM_UI_FLAG_LAYOUT_FULSCREEN
|
||||||
|
| 0x00000002 // View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
|
||||||
|
| 0x00000004 // View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
|
||||||
|
| 0x00001000 // View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
|
||||||
|
);
|
||||||
|
else
|
||||||
|
decorView.setSystemUiVisibility( 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Compat_23 extends Compat_19
|
||||||
|
{
|
||||||
|
public void applyPermissions( final Activity act, final String permissions[], final int code )
|
||||||
{
|
{
|
||||||
List<String> requestPermissions = new ArrayList<String>();
|
List<String> requestPermissions = new ArrayList<String>();
|
||||||
|
|
||||||
|
@ -256,6 +305,25 @@ public class FWGSLib
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class Compat_26 extends Compat_23
|
||||||
|
{
|
||||||
|
public void startForegroundService(Context ctx, Intent intent){
|
||||||
|
ctx.startForegroundService(intent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Compat cmp;
|
||||||
|
static {
|
||||||
|
int sdk1 = Integer.valueOf(Build.VERSION.SDK);
|
||||||
|
if( sdk1 >= 26 )
|
||||||
|
cmp = new Compat_26();
|
||||||
|
if( sdk1 >= 23 )
|
||||||
|
cmp = new Compat_23();
|
||||||
|
else if( sdk1 >= 9 )
|
||||||
|
cmp = new Compat_9();
|
||||||
|
else cmp = new Compat();
|
||||||
|
}
|
||||||
|
|
||||||
public static ApplicationInfo getApplicationInfo(Context ctx, String pkgName, int flags) throws PackageManager.NameNotFoundException
|
public static ApplicationInfo getApplicationInfo(Context ctx, String pkgName, int flags) throws PackageManager.NameNotFoundException
|
||||||
{
|
{
|
||||||
PackageManager pm = ctx.getPackageManager();
|
PackageManager pm = ctx.getPackageManager();
|
||||||
|
@ -268,3 +336,4 @@ public class FWGSLib
|
||||||
|
|
||||||
public static final int sdk = Integer.valueOf(Build.VERSION.SDK);
|
public static final int sdk = Integer.valueOf(Build.VERSION.SDK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue