Some fixes, Additional keyboard and small improvements

Fixed: app restart after physical keyboard connected
Fixed: some eventCodes from physical keyboard were processed wrong
This commit is contained in:
Twaik Yont 2019-07-10 07:45:24 +03:00
parent 595c00d669
commit 458acd617b
18 changed files with 326 additions and 184 deletions

View File

@ -0,0 +1,4 @@
/home/twaik/WTermux/app/src/main/jni/lorie/backend-android.c:257:33: warning: result of comparison against a string literal is unspecified (use strncmp instead) [-Wstring-compare]
if (backend->xkb_names.layout != "us") {
^ ~~~~
1 warning generated.

View File

@ -3,38 +3,7 @@ Android NDK: This is likely to result in incorrect builds. Try using LOCAL_S
Android NDK: or LOCAL_SHARED_LIBRARIES instead to list the library dependencies of the Android NDK: or LOCAL_SHARED_LIBRARIES instead to list the library dependencies of the
Android NDK: current module Android NDK: current module
[arm64-v8a] Compile : lorie <= main.c [arm64-v8a] Compile : lorie <= main.c
[arm64-v8a] Compile : lorie <= android-utils.c
[arm64-v8a] Compile : lorie <= backend-android.c [arm64-v8a] Compile : lorie <= backend-android.c
[arm64-v8a] Compile : lorie <= renderer.c [arm64-v8a] Compile : lorie <= renderer.c
[arm64-v8a] Compile : xkbcommon <= parser.c
[arm64-v8a] Compile : xkbcommon <= paths.c
[arm64-v8a] Compile : xkbcommon <= state.c
[arm64-v8a] Compile : xkbcommon <= table.c
[arm64-v8a] Compile : xkbcommon <= action.c
[arm64-v8a] Compile : xkbcommon <= ast-build.c
[arm64-v8a] Compile : xkbcommon <= compat.c
[arm64-v8a] Compile : xkbcommon <= expr.c
[arm64-v8a] Compile : xkbcommon <= include.c
[arm64-v8a] Compile : xkbcommon <= keycodes.c
[arm64-v8a] Compile : xkbcommon <= keymap.c
[arm64-v8a] Compile : xkbcommon <= keymap-dump.c
[arm64-v8a] Compile : xkbcommon <= keywords.c
[arm64-v8a] Compile : xkbcommon <= parser.c
[arm64-v8a] Compile : xkbcommon <= rules.c
[arm64-v8a] Compile : xkbcommon <= scanner.c
[arm64-v8a] Compile : xkbcommon <= symbols.c
[arm64-v8a] Compile : xkbcommon <= types.c
[arm64-v8a] Compile : xkbcommon <= vmod.c
[arm64-v8a] Compile : xkbcommon <= xkbcomp.c
[arm64-v8a] Compile : xkbcommon <= atom.c
[arm64-v8a] Compile : xkbcommon <= context.c
[arm64-v8a] Compile : xkbcommon <= context-priv.c
[arm64-v8a] Compile : xkbcommon <= keysym.c
[arm64-v8a] Compile : xkbcommon <= keysym-utf.c
[arm64-v8a] Compile : xkbcommon <= keymap.c
[arm64-v8a] Compile : xkbcommon <= keymap-priv.c
[arm64-v8a] Compile : xkbcommon <= state.c
[arm64-v8a] Compile : xkbcommon <= text.c
[arm64-v8a] Compile : xkbcommon <= utf8.c
[arm64-v8a] Compile : xkbcommon <= utils.c
[arm64-v8a] SharedLibrary : libxkbcommon.so
[arm64-v8a] SharedLibrary : liblorie.so [arm64-v8a] SharedLibrary : liblorie.so

View File

@ -1,4 +0,0 @@
/home/twaik/WTermux/app/src/main/jni/lorie/backend-android.c:257:33: warning: result of comparison against a string literal is unspecified (use strncmp instead) [-Wstring-compare]
if (backend->xkb_names.layout != "us") {
^ ~~~~
1 warning generated.

View File

@ -2,5 +2,4 @@ Android NDK: WARNING:/home/twaik/WTermux/app/src/main/jni/lorie/Android.mk:lorie
Android NDK: This is likely to result in incorrect builds. Try using LOCAL_STATIC_LIBRARIES Android NDK: This is likely to result in incorrect builds. Try using LOCAL_STATIC_LIBRARIES
Android NDK: or LOCAL_SHARED_LIBRARIES instead to list the library dependencies of the Android NDK: or LOCAL_SHARED_LIBRARIES instead to list the library dependencies of the
Android NDK: current module Android NDK: current module
[armeabi-v7a] Compile thumb : lorie <= backend-android.c make: `/home/twaik/WTermux/app/build/intermediates/ndkBuild/debug/obj/local/armeabi-v7a/liblorie.so' is up to date.
[armeabi-v7a] SharedLibrary : liblorie.so

View File

@ -0,0 +1,4 @@
/home/twaik/WTermux/app/src/main/jni/lorie/backend-android.c:257:33: warning: result of comparison against a string literal is unspecified (use strncmp instead) [-Wstring-compare]
if (backend->xkb_names.layout != "us") {
^ ~~~~
1 warning generated.

View File

@ -3,38 +3,7 @@ Android NDK: This is likely to result in incorrect builds. Try using LOCAL_S
Android NDK: or LOCAL_SHARED_LIBRARIES instead to list the library dependencies of the Android NDK: or LOCAL_SHARED_LIBRARIES instead to list the library dependencies of the
Android NDK: current module Android NDK: current module
[x86_64] Compile : lorie <= main.c [x86_64] Compile : lorie <= main.c
[x86_64] Compile : lorie <= android-utils.c
[x86_64] Compile : lorie <= backend-android.c [x86_64] Compile : lorie <= backend-android.c
[x86_64] Compile : lorie <= renderer.c [x86_64] Compile : lorie <= renderer.c
[x86_64] Compile : xkbcommon <= parser.c
[x86_64] Compile : xkbcommon <= paths.c
[x86_64] Compile : xkbcommon <= state.c
[x86_64] Compile : xkbcommon <= table.c
[x86_64] Compile : xkbcommon <= action.c
[x86_64] Compile : xkbcommon <= ast-build.c
[x86_64] Compile : xkbcommon <= compat.c
[x86_64] Compile : xkbcommon <= expr.c
[x86_64] Compile : xkbcommon <= include.c
[x86_64] Compile : xkbcommon <= keycodes.c
[x86_64] Compile : xkbcommon <= keymap.c
[x86_64] Compile : xkbcommon <= keymap-dump.c
[x86_64] Compile : xkbcommon <= keywords.c
[x86_64] Compile : xkbcommon <= parser.c
[x86_64] Compile : xkbcommon <= rules.c
[x86_64] Compile : xkbcommon <= scanner.c
[x86_64] Compile : xkbcommon <= symbols.c
[x86_64] Compile : xkbcommon <= types.c
[x86_64] Compile : xkbcommon <= vmod.c
[x86_64] Compile : xkbcommon <= xkbcomp.c
[x86_64] Compile : xkbcommon <= atom.c
[x86_64] Compile : xkbcommon <= context.c
[x86_64] Compile : xkbcommon <= context-priv.c
[x86_64] Compile : xkbcommon <= keysym.c
[x86_64] Compile : xkbcommon <= keysym-utf.c
[x86_64] Compile : xkbcommon <= keymap.c
[x86_64] Compile : xkbcommon <= keymap-priv.c
[x86_64] Compile : xkbcommon <= state.c
[x86_64] Compile : xkbcommon <= text.c
[x86_64] Compile : xkbcommon <= utf8.c
[x86_64] Compile : xkbcommon <= utils.c
[x86_64] SharedLibrary : libxkbcommon.so
[x86_64] SharedLibrary : liblorie.so [x86_64] SharedLibrary : liblorie.so

1
app/.gitignore vendored
View File

@ -1 +1,2 @@
/build /build
/.externalNativeBuild

View File

@ -33,11 +33,6 @@
<output-test url="file://$MODULE_DIR$/build/intermediates/javac/debugUnitTest/compileDebugUnitTestJavaWithJavac/classes" /> <output-test url="file://$MODULE_DIR$/build/intermediates/javac/debugUnitTest/compileDebugUnitTestJavaWithJavac/classes" />
<exclude-output /> <exclude-output />
<content url="file://$MODULE_DIR$"> <content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/jni/libxkbcommon/xkbcommon/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/jni/libxkbcommon/xkbcommon/src/compose" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/jni/libxkbcommon/xkbcommon/src/xkbcomp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/jni/lorie" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/jni/lorie/locale" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/debug" isTestSource="false" generated="true" /> <sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/aidl_source_output_dir/debug/compileDebugAidl/out" isTestSource="false" generated="true" /> <sourceFolder url="file://$MODULE_DIR$/build/generated/aidl_source_output_dir/debug/compileDebugAidl/out" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" /> <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
@ -56,7 +51,6 @@
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" /> <sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/shaders" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/debug/shaders" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/res" type="java-test-resource" /> <sourceFolder url="file://$MODULE_DIR$/src/testDebug/res" type="java-test-resource" />
@ -64,7 +58,6 @@
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/assets" type="java-test-resource" /> <sourceFolder url="file://$MODULE_DIR$/src/testDebug/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/aidl" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/testDebug/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/java" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/testDebug/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/rs" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/testDebug/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/shaders" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/testDebug/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/res" type="java-test-resource" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/res" type="java-test-resource" />
@ -72,7 +65,6 @@
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/assets" type="java-test-resource" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/aidl" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/java" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/rs" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/shaders" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" /> <sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
@ -80,7 +72,6 @@
<sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" /> <sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/shaders" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/main/shaders" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" /> <sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
@ -88,7 +79,6 @@
<sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" /> <sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
@ -96,10 +86,9 @@
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/shaders" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTest/shaders" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/.externalNativeBuild" /> <sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/build/generated/not_namespaced_r_class_sources" /> <excludeFolder url="file://$MODULE_DIR$/build/generated/not_namespaced_r_class_sources" />
<excludeFolder url="file://$MODULE_DIR$/build/generated/source/r" /> <excludeFolder url="file://$MODULE_DIR$/build/generated/source/r" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/annotation_processor_list" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/annotation_processor_list" />

View File

@ -17,7 +17,7 @@
tools:ignore="GoogleAppIndexingWarning"> tools:ignore="GoogleAppIndexingWarning">
<activity android:name=".MainActivity" <activity android:name=".MainActivity"
android:theme="@style/NoActionBar" android:theme="@style/NoActionBar"
android:configChanges="orientation|screenSize"> android:configChanges="fontScale|orientation|screenSize|keyboard|keyboardHidden|layoutDirection|locale|mcc|mnc|navigation|screenLayout|touchscreen|uiMode|smallestScreenSize|density">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />

View File

@ -0,0 +1,173 @@
package com.termux.wtermux;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Rect;
import android.support.v7.widget.AppCompatTextView;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;
import java.util.HashMap;
import java.util.Map;
@SuppressWarnings("unused")
public class AdditionalKeyboardView extends HorizontalScrollView {
Context ctx;
View targetView = null;
View.OnKeyListener targetListener = null;
int density;
LinearLayout root;
public AdditionalKeyboardView(Context context) {
super(context);
init(context);
}
public AdditionalKeyboardView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
@SuppressLint("SetTextI18n")
private void init(Context context) {
ctx = context;
density = (int) context.getResources().getDisplayMetrics().density;
//setFillViewport(true);
LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
root = new LinearLayout(context);
root.setLayoutParams(lp);
root.setOrientation(LinearLayout.HORIZONTAL);
addView(root);
}
public void reload(int[] keys, View TargetView, View.OnKeyListener TargetListener) {
targetView = TargetView;
targetListener = TargetListener;
root.removeAllViews();
LayoutParams lp = new LayoutParams(60 * density,LayoutParams.MATCH_PARENT);
lp.setMargins(density*3, 0, density*3, 0);
for (int keyCode : keys) {
if (keyCode != KeyEvent.KEYCODE_UNKNOWN) {
Key key = new Key(ctx, keyCode);
root.addView(key, lp);
}
}
}
private class Key extends AppCompatTextView implements View.OnClickListener, View.OnTouchListener {
private static final int TEXT_COLOR = 0xFFFFFFFF;
private static final int BUTTON_COLOR = 0x0000FFFF;
private static final int INTERESTING_COLOR = 0xFF80DEEA;
private static final int BUTTON_PRESSED_COLOR = 0x7FFFFFFF;
/**
* Keys are displayed in a natural looking way, like "" for "RIGHT"
*/
final Map<Integer, String> keyCodesForString = new HashMap<Integer, String>() {{
put(KeyEvent.KEYCODE_ESCAPE, "ESC");
put(KeyEvent.KEYCODE_MOVE_HOME, "HOME");
put(KeyEvent.KEYCODE_MOVE_END, "END");
put(KeyEvent.KEYCODE_PAGE_UP, "PGUP");
put(KeyEvent.KEYCODE_PAGE_DOWN, "PGDN");
put(KeyEvent.KEYCODE_CTRL_LEFT, "CTRL");
put(KeyEvent.KEYCODE_ALT_LEFT, "ALT");
put(KeyEvent.KEYCODE_INSERT, "INS");
put(KeyEvent.KEYCODE_FORWARD_DEL, ""); // U+2326 ERASE TO THE RIGHT not well known but easy to understand
put(KeyEvent.KEYCODE_DEL, ""); // U+232B ERASE TO THE LEFT sometimes seen and easy to understand
put(KeyEvent.KEYCODE_DPAD_UP, ""); // U+25B2 BLACK UP-POINTING TRIANGLE
put(KeyEvent.KEYCODE_DPAD_LEFT, ""); // U+25C0 BLACK LEFT-POINTING TRIANGLE
put(KeyEvent.KEYCODE_DPAD_RIGHT, ""); // U+25B6 BLACK RIGHT-POINTING TRIANGLE
put(KeyEvent.KEYCODE_DPAD_DOWN, ""); // U+25BC BLACK DOWN-POINTING TRIANGLE
put(KeyEvent.KEYCODE_ENTER, ""); // U+21B2 DOWNWARDS ARROW WITH TIP LEFTWARDS
put(KeyEvent.KEYCODE_TAB, ""); // U+21B9 LEFTWARDS ARROW TO BAR OVER RIGHTWARDS ARROW TO BAR
put(KeyEvent.KEYCODE_MINUS, ""); // U+2015 HORIZONTAL BAR
}};
void sendKey(int keyCode, boolean down) {
if (targetListener == null || targetView == null) {
Log.e("AdditionalKeyboardView", "target view or target listener is unset");
return;
}
targetListener.onKey(targetView, keyCode, new KeyEvent((down?KeyEvent.ACTION_DOWN:KeyEvent.ACTION_UP), keyCode));
}
boolean toggle;
boolean checked = false;
int kc;
public Key(Context context, int keyCode) {
super(context);
kc = keyCode;
switch (keyCode) {
case KeyEvent.KEYCODE_CTRL_LEFT:
case KeyEvent.KEYCODE_CTRL_RIGHT:
case KeyEvent.KEYCODE_ALT_LEFT:
case KeyEvent.KEYCODE_ALT_RIGHT:
case KeyEvent.KEYCODE_SHIFT_LEFT:
case KeyEvent.KEYCODE_SHIFT_RIGHT:
toggle = true;
break;
default:
toggle = false;
}
setMinEms(4);
setPadding(10*density, 0, 10*density, 0);
setGravity(Gravity.CENTER);
setTextColor(TEXT_COLOR);
setBackgroundColor(BUTTON_COLOR);
String text = keyCodesForString.get(keyCode);
setText(text);
setOnClickListener(this);
setOnTouchListener(this);
}
@Override
public void onClick(View v) {
if (toggle) {
checked = !checked;
if (checked) {
setTextColor(INTERESTING_COLOR);
setBackgroundColor(BUTTON_PRESSED_COLOR);
sendKey(kc, true);
} else {
setTextColor(TEXT_COLOR);
setBackgroundColor(BUTTON_COLOR);
sendKey(kc, false);
}
}
}
private Rect rect;
@Override
public boolean onTouch(View v, MotionEvent e) {
switch(e.getAction()) {
case MotionEvent.ACTION_BUTTON_PRESS:
case MotionEvent.ACTION_POINTER_DOWN:
case MotionEvent.ACTION_DOWN:
setTextColor(INTERESTING_COLOR);
setBackgroundColor(BUTTON_PRESSED_COLOR);
if (!toggle) sendKey(kc, true);
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_BUTTON_RELEASE:
case MotionEvent.ACTION_POINTER_UP:
case MotionEvent.ACTION_UP:
if (!toggle) {
setTextColor(TEXT_COLOR);
setBackgroundColor(BUTTON_COLOR);
sendKey(kc, false);
}
break;
default:
break;
}
return false;
}
}
}

View File

@ -1,7 +1,9 @@
package com.termux.wtermux; package com.termux.wtermux;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Context; import android.app.Activity;
import android.content.res.Configuration;
import android.util.DisplayMetrics;
import android.util.Log; import android.util.Log;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.MotionEvent; import android.view.MotionEvent;
@ -9,12 +11,14 @@ import android.view.Surface;
import android.view.SurfaceHolder; import android.view.SurfaceHolder;
import android.view.SurfaceView; import android.view.SurfaceView;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager; import android.view.ViewGroup;
import android.view.inputmethod.InputMethodSubtype; import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
import android.widget.ScrollView;
import java.util.Locale; public class LorieService extends FrameLayout implements SurfaceHolder.Callback, View.OnTouchListener, View.OnKeyListener, KeyboardUtils.SoftKeyboardToggleListener {
private final static int SV2_ID = 0xACCEDED;
public class LorieService implements SurfaceHolder.Callback, View.OnTouchListener, View.OnKeyListener {
private static final int BTN_LEFT = 0x110; private static final int BTN_LEFT = 0x110;
private static final int BTN_MIDDLE = 0x110; private static final int BTN_MIDDLE = 0x110;
private static final int BTN_RIGHT = 0x110; private static final int BTN_RIGHT = 0x110;
@ -23,28 +27,68 @@ public class LorieService implements SurfaceHolder.Callback, View.OnTouchListene
private static final int WL_STATE_RELEASED = 0; private static final int WL_STATE_RELEASED = 0;
private static final int WL_POINTER_MOTION = 2; private static final int WL_POINTER_MOTION = 2;
private static int[] keys = {
KeyEvent.KEYCODE_ESCAPE,
KeyEvent.KEYCODE_TAB,
KeyEvent.KEYCODE_CTRL_LEFT,
KeyEvent.KEYCODE_ALT_LEFT,
KeyEvent.KEYCODE_DPAD_UP,
KeyEvent.KEYCODE_DPAD_DOWN,
KeyEvent.KEYCODE_DPAD_LEFT,
KeyEvent.KEYCODE_DPAD_RIGHT,
};
//private static final int WL_POINTER_BUTTON = 3; //private static final int WL_POINTER_BUTTON = 3;
private InputMethodManager imm;
private long compositor; private long compositor;
Context ctx; private Activity act;
LorieService(Context context) { private AdditionalKeyboardView kbd;
imm = (InputMethodManager)context.getSystemService(Context.INPUT_METHOD_SERVICE); @SuppressLint("ClickableViewAccessibility")
ctx = context; LorieService(Activity activity) {
super(activity);
act = activity;
compositor = createLorieThread(); compositor = createLorieThread();
if (compositor == 0) { if (compositor == 0) {
Log.e("WestonService", "compositor thread was not created"); Log.e("LorieService", "compositor thread was not created");
return;
} }
int dp = (int) act.getResources().getDisplayMetrics().density;
ViewGroup.LayoutParams match_parent = new WindowManager.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
setLayoutParams(match_parent);
SurfaceView lorieView = new SurfaceView(act);
addView(lorieView, match_parent);
RelativeLayout rl = new RelativeLayout(act);
ScrollView sv = new ScrollView(act);
kbd = new AdditionalKeyboardView(act);
RelativeLayout.LayoutParams svlp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
RelativeLayout.LayoutParams kbdlp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, 50*dp);
svlp.addRule(RelativeLayout.BELOW, SV2_ID);
kbdlp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
kbd.setId(SV2_ID);
rl.addView(kbd, kbdlp);
rl.addView(sv, svlp);
addView(rl);
kbd.setVisibility(View.INVISIBLE);
lorieView.getHolder().addCallback(this);
lorieView.setOnTouchListener(this);
lorieView.setOnKeyListener(this);
lorieView.setFocusable(true);
lorieView.setFocusableInTouchMode(true);
lorieView.requestFocus();
kbd.reload(keys, lorieView, this);
// prevents SurfaceView from being resized but interrupts additional keyboard showing process
// act.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
} }
@SuppressLint("ClickableViewAccessibility") void finishInit() {
void connectSurfaceView(SurfaceView surface) { KeyboardUtils.addKeyboardToggleListener(act, this);
surface.getHolder().addCallback(this);
surface.setOnTouchListener(this);
surface.setOnKeyListener(this);
surface.setFocusable(true);
surface.setFocusableInTouchMode(true);
surface.requestFocus();
} }
@Override @Override
@ -54,7 +98,22 @@ public class LorieService implements SurfaceHolder.Callback, View.OnTouchListene
@Override @Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
windowChanged(compositor, holder.getSurface(), width, height); DisplayMetrics dm = new DisplayMetrics();
int mmWidth, mmHeight;
act.getWindowManager().getDefaultDisplay().getMetrics(dm);
if (act.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
mmWidth = (int) Math.round((width * 25.4) / dm.xdpi);
mmHeight = (int) Math.round((height * 25.4) / dm.ydpi);
} else {
mmWidth = (int) Math.round((width * 25.4) / dm.ydpi);
mmHeight = (int) Math.round((height * 25.4) / dm.xdpi);
}
Log.e("debug","mmWidth: " + mmWidth + "; mmHeight: " + mmHeight + "; xdpi: " + dm.xdpi + "; ydpi: " + dm.ydpi);
windowChanged(compositor, holder.getSurface(), width, height, mmWidth, mmHeight);
} }
@Override @Override
@ -106,15 +165,25 @@ public class LorieService implements SurfaceHolder.Callback, View.OnTouchListene
@Override @Override
public boolean onKey(View v, int keyCode, KeyEvent e) { public boolean onKey(View v, int keyCode, KeyEvent e) {
int action = 0; int action = 0;
int shift = e.isShiftPressed() ? 1 : 0;
if (e.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) {
KeyboardUtils.toggleKeyboardVisibility(act);
}
if (e.getAction() == KeyEvent.ACTION_DOWN) action = WL_STATE_PRESSED; if (e.getAction() == KeyEvent.ACTION_DOWN) action = WL_STATE_PRESSED;
if (e.getAction() == KeyEvent.ACTION_UP) action = WL_STATE_RELEASED; if (e.getAction() == KeyEvent.ACTION_UP) action = WL_STATE_RELEASED;
onKey(compositor, action, keyCode, shift, e.getCharacters()); onKey(compositor, action, keyCode, e.isShiftPressed() ? 1 : 0, e.getCharacters());
return false; return false;
} }
@Override
public void onToggleSoftKeyboard(boolean isVisible) {
kbd.setVisibility((isVisible)?View.VISIBLE:View.INVISIBLE);
Log.d("LorieActivity", "keyboard is " + (isVisible?"visible":"not visible"));
}
private native long createLorieThread(); private native long createLorieThread();
private native void windowChanged(long compositor, Surface surface, int width, int height); private native void windowChanged(long compositor, Surface surface, int width, int height, int mmWidth, int mmHeight);
private native void onTouch(long compositor, int type, int button, int x, int y); private native void onTouch(long compositor, int type, int button, int x, int y);
private native void onKey(long compositor, int type, int key, int shift, String characters); private native void onKey(long compositor, int type, int key, int shift, String characters);

View File

@ -1,65 +1,22 @@
package com.termux.wtermux; package com.termux.wtermux;
import android.content.Context;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.SurfaceView;
import android.view.WindowManager; import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
public class MainActivity extends AppCompatActivity implements KeyboardUtils.SoftKeyboardToggleListener { public class MainActivity extends AppCompatActivity {
LorieService weston;
boolean kbdVisible = false;
InputMethodManager imm;
SurfaceView root;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
//jniLoader.loadLibrary("wayland-server");
setContentView(R.layout.activity_main);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
root = findViewById(R.id.WestonView); LorieService root = new LorieService(this);
weston = new LorieService(this); setContentView(root);
weston.connectSurfaceView(root); root.finishInit();
KeyboardUtils.addKeyboardToggleListener(this, this);
} }
@Override @Override
public boolean onKeyDown(int keyCode, KeyEvent event) { public void onBackPressed() {}
Log.d("LorieActivity", "keydown: " + keyCode + "(keycode_back = " + KeyEvent.KEYCODE_BACK + " )");
if (keyCode == KeyEvent.KEYCODE_BACK) {
onBackPressed();
return true;
}
return super.onKeyDown(keyCode, event);
}
@Override
public void onBackPressed() {
//KeyboardUtils.toggleKeyboardVisibility(this);
Log.d("Asdasd", "asdasdasd");
if (root == null) return;
if (kbdVisible) {
((InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE))
.hideSoftInputFromWindow(root.getWindowToken(), 0);
} else
{
((InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE))
.showSoftInput(root, InputMethodManager.SHOW_FORCED);
}
}
@Override
public void onToggleSoftKeyboard(boolean isVisible) {
kbdVisible = isVisible;
Log.d("LorieActivity", "keyboard is " + (isVisible?"visible":"not visible"));
}
} }

View File

@ -1,12 +0,0 @@
package com.termux.wtermux;
final class jniLoader {
static void loadLibrary(String name) {
_loadLibrary("lib" + name + ".so");
}
private static native void _loadLibrary(String name);
static {
System.loadLibrary("jniLoader");
}
}

View File

@ -85,7 +85,7 @@ typedef struct {
struct { struct {
EGLDisplay dpy; EGLDisplay dpy;
EGLNativeWindowType win; EGLNativeWindowType win;
uint32_t width, height; uint32_t width, height, mmWidth, mmHeight;
} window_change; } window_change;
#ifdef __ANDROID__ #ifdef __ANDROID__
struct { struct {
@ -155,7 +155,7 @@ void lorie_pointer_event(void __unused *b, uint8_t state, uint16_t button, uint3
write(backend->fds[0], &e, sizeof(lorie_event)); write(backend->fds[0], &e, sizeof(lorie_event));
} }
void lorie_window_change_event(void __unused *b, EGLDisplay dpy, EGLNativeWindowType win, uint32_t width, uint32_t height) { void lorie_window_change_event(void __unused *b, EGLDisplay dpy, EGLNativeWindowType win, uint32_t width, uint32_t height, uint32_t mmWidth, uint32_t mmHeight) {
if (!backend) return; if (!backend) return;
lorie_event e; lorie_event e;
@ -166,6 +166,8 @@ void lorie_window_change_event(void __unused *b, EGLDisplay dpy, EGLNativeWindow
e.window_change.win = win; e.window_change.win = win;
e.window_change.width = width; e.window_change.width = width;
e.window_change.height = height; e.window_change.height = height;
e.window_change.mmWidth = mmWidth;
e.window_change.mmHeight = mmHeight;
write(backend->fds[0], &e, sizeof(lorie_event)); write(backend->fds[0], &e, sizeof(lorie_event));
} }
@ -205,18 +207,18 @@ Java_com_termux_wtermux_LorieService_createLorieThread(JNIEnv __unused *env, job
} }
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_com_termux_wtermux_LorieService_windowChanged(JNIEnv *env, jobject __unused instance, jlong __unused jcompositor, jobject jsurface, jint width, jint height) { Java_com_termux_wtermux_LorieService_windowChanged(JNIEnv *env, jobject __unused instance, jlong __unused jcompositor, jobject jsurface, jint width, jint height, jint mmWidth, jint mmHeight) {
if (backend == NULL) return; if (backend == NULL) return;
#if 1 #if 1
EGLNativeWindowType win = ANativeWindow_fromSurface(env, jsurface); EGLNativeWindowType win = ANativeWindow_fromSurface(env, jsurface);
if (win == NULL) { if (win == NULL) {
LOGE("Surface is invalid"); LOGE("Surface is invalid");
lorie_window_change_event(backend, NULL, NULL, (uint32_t) width, (uint32_t) height); lorie_window_change_event(backend, NULL, NULL, (uint32_t) width, (uint32_t) height, (uint32_t) mmWidth, (uint32_t) mmHeight);
return; return;
} }
lorie_window_change_event(backend, NULL, win, (uint32_t) width, lorie_window_change_event(backend, NULL, win, (uint32_t) width,
(uint32_t) height); (uint32_t) height, (uint32_t) mmWidth, (uint32_t) mmHeight);
#else #else
JavaVM* jvm; JavaVM* jvm;
(*env)->GetJavaVM(env, &jvm); (*env)->GetJavaVM(env, &jvm);
@ -372,7 +374,7 @@ void backend_dispatch_nonblocking (void)
eglMakeCurrent(backend->dpy, backend->sfc, backend->sfc, backend->ctx); checkEGLError(); eglMakeCurrent(backend->dpy, backend->sfc, backend->sfc, backend->ctx); checkEGLError();
if (backend->callbacks.resize) if (backend->callbacks.resize)
backend->callbacks.resize(ev.window_change.width, ev.window_change.height); backend->callbacks.resize(ev.window_change.width, ev.window_change.height, ev.window_change.mmWidth, ev.window_change.mmHeight);
break; break;
case ACTION_LAYOUT_CHANGE: case ACTION_LAYOUT_CHANGE:
xkb_keymap_unref(backend->xkb_keymap); xkb_keymap_unref(backend->xkb_keymap);
@ -461,4 +463,5 @@ void backend_get_dimensions(uint32_t *width, uint32_t *height) {
if (width) *width = 480; if (width) *width = 480;
if (height) *height = 800; if (height) *height = 800;
} }
#pragma clang diagnostic pop #pragma clang diagnostic pop

View File

@ -7,7 +7,7 @@ struct modifier_state {
}; };
struct callbacks { struct callbacks {
void (*resize) (int width, int height); void (*resize) (int width, int height, int mmWidth, int mmHeight);
void (*draw) (void); void (*draw) (void);
void (*mouse_motion) (int x, int y); void (*mouse_motion) (int x, int y);
void (*mouse_button) (int button, int state); void (*mouse_button) (int button, int state);

View File

@ -54,6 +54,10 @@ int android_keycode_to_linux_event_code(int keyCode, int *eventCode, int *shift,
KEYCODE1(Z); KEYCODE1(Z);
KEYCODE1(COMMA); KEYCODE1(COMMA);
KEYCODE2(PERIOD, DOT); KEYCODE2(PERIOD, DOT);
KEYCODE2(DPAD_UP, UP);
KEYCODE2(DPAD_LEFT, LEFT);
KEYCODE2(DPAD_DOWN, DOWN);
KEYCODE2(DPAD_RIGHT, RIGHT);
KEYCODE2(ALT_LEFT, LEFTALT); KEYCODE2(ALT_LEFT, LEFTALT);
KEYCODE2(ALT_RIGHT, RIGHTALT); KEYCODE2(ALT_RIGHT, RIGHTALT);
KEYCODE2(SHIFT_LEFT, LEFTSHIFT); KEYCODE2(SHIFT_LEFT, LEFTSHIFT);
@ -107,7 +111,7 @@ int android_keycode_to_linux_event_code(int keyCode, int *eventCode, int *shift,
KEYCODE2(MOVE_END, END); KEYCODE2(MOVE_END, END);
KEYCODE1(INSERT); KEYCODE1(INSERT);
KEYCODE1(FORWARD); KEYCODE1(FORWARD);
KEYCODE1(BACK); KEYCODE2(BACK, ESC);
KEYCODE1(F1); KEYCODE1(F1);
KEYCODE1(F2); KEYCODE1(F2);
KEYCODE1(F3); KEYCODE1(F3);

View File

@ -86,8 +86,8 @@ static void surface_attach (struct wl_client *client, struct wl_resource *resour
return; return;
} }
surface->width = wl_shm_buffer_get_width (shm_buffer); surface->width = (uint32_t) wl_shm_buffer_get_width (shm_buffer);
surface->height = wl_shm_buffer_get_height (shm_buffer); surface->height = (uint32_t) wl_shm_buffer_get_height (shm_buffer);
if (!surface->texture || if (!surface->texture ||
surface->texture->width != surface->width || surface->texture->width != surface->width ||
@ -240,12 +240,13 @@ wl_output_bind(struct wl_client *client, void *data, uint32_t version, uint32_t
} }
// backend callbacks // backend callbacks
static void handle_resize_event (int width, int height) { static void handle_resize_event (int width, int height, int mmWidth, int mmHeight) {
if (width == c.width && height == c.height) return; if (width == c.width && height == c.height) return;
glViewport(0, 0, width, height); glViewport(0, 0, width, height);
c.width = width; c.width = width;
c.height = height; c.height = height;
if (c.wl_output) { if (c.wl_output) {
wl_output_send_geometry(c.wl_output, 0, 0, mmWidth, mmHeight, 0, "non-weston", "none", 0);
wl_output_send_mode(c.wl_output, 3, width, height, 60000); wl_output_send_mode(c.wl_output, 3, width, height, 60000);
wl_output_send_done(c.wl_output); wl_output_send_done(c.wl_output);

View File

@ -6,6 +6,7 @@
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".MainActivity"> tools:context=".MainActivity">
<SurfaceView <SurfaceView
android:id="@+id/WestonView" android:id="@+id/WestonView"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -13,9 +14,24 @@
android:visibility="visible" android:visibility="visible"
tools:visibility="visible" /> tools:visibility="visible" />
<LinearLayout <!-- RelativeLayout and ScrollView inside are needed to make ExtraKeysView visible after soft keyboard is shown -->
android:id="@+id/MenuHolder" <RelativeLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent">
android:orientation="vertical"></LinearLayout>
<ScrollView
android:id="@+id/scrollview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/extra_keys">
</ScrollView>
<com.termux.wtermux.AdditionalKeyboardView
android:id="@+id/extra_keys"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_alignParentBottom="true" />
</RelativeLayout>
</FrameLayout> </FrameLayout>