From cd454143be8190ec00ef4132753890ec0b339f85 Mon Sep 17 00:00:00 2001 From: Andrey Filipenkov Date: Thu, 2 Mar 2023 13:54:23 +0300 Subject: [PATCH] update SDL Java classes to v2.26.1 --- .../java/eu/vcmi/vcmi/VcmiSDLActivity.java | 7 + .../main/java/org/libsdl/app/DummyEdit.java | 74 ------- .../src/main/java/org/libsdl/app/SDL.java | 2 - .../main/java/org/libsdl/app/SDLActivity.java | 191 ++++++++++++++++-- .../org/libsdl/app/SDLInputConnection.java | 144 ------------- 5 files changed, 185 insertions(+), 233 deletions(-) delete mode 100644 android/vcmi-app/src/main/java/org/libsdl/app/DummyEdit.java delete mode 100644 android/vcmi-app/src/main/java/org/libsdl/app/SDLInputConnection.java diff --git a/android/vcmi-app/src/main/java/eu/vcmi/vcmi/VcmiSDLActivity.java b/android/vcmi-app/src/main/java/eu/vcmi/vcmi/VcmiSDLActivity.java index 4d00f8991..056321c53 100644 --- a/android/vcmi-app/src/main/java/eu/vcmi/vcmi/VcmiSDLActivity.java +++ b/android/vcmi-app/src/main/java/eu/vcmi/vcmi/VcmiSDLActivity.java @@ -78,6 +78,13 @@ public class VcmiSDLActivity extends SDLActivity LibsLoader.loadClientLibs(this); } + @Override + protected String[] getLibraries() { + // SDL is linked statically, no need to load anything + return new String[] { + }; + } + @Override protected String getMainSharedObject() { String library = "libvcmiclient.so"; diff --git a/android/vcmi-app/src/main/java/org/libsdl/app/DummyEdit.java b/android/vcmi-app/src/main/java/org/libsdl/app/DummyEdit.java deleted file mode 100644 index 6c504296c..000000000 --- a/android/vcmi-app/src/main/java/org/libsdl/app/DummyEdit.java +++ /dev/null @@ -1,74 +0,0 @@ -package org.libsdl.app; - -import android.content.Context; -import android.text.InputType; -import android.view.KeyEvent; -import android.view.View; -import android.view.inputmethod.EditorInfo; -import android.view.inputmethod.InputConnection; - -/* This is a fake invisible editor view that receives the input and defines the - * pan&scan region - */ -public 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 SDLActivity.handleKeyEvent(v, keyCode, event, ic); - } - - // - @Override - public boolean onKeyPreIme(int keyCode, KeyEvent event) - { - // As seen on StackOverflow: http://stackoverflow.com/questions/7634346/keyboard-hide-event - // FIXME: Discussion at http://bugzilla.libsdl.org/show_bug.cgi?id=1639 - // FIXME: This is not a 100% effective solution to the problem of detecting if the keyboard is showing or not - // FIXME: A more effective solution would be to assume our Layout to be RelativeLayout or LinearLayout - // FIXME: And determine the keyboard presence doing this: http://stackoverflow.com/questions/2150078/how-to-check-visibility-of-software-keyboard-in-android - // FIXME: An even more effective way would be if Android provided this out of the box, but where would the fun be in that :) - if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) - { - if (SDLActivity.mTextEdit != null && SDLActivity.mTextEdit.getVisibility() == View.VISIBLE) - { - SDLActivity.onNativeKeyboardFocusLost(); - } - } - return super.onKeyPreIme(keyCode, event); - } - - @Override - public InputConnection onCreateInputConnection(EditorInfo outAttrs) - { - ic = new SDLInputConnection(this, true); - - outAttrs.inputType = InputType.TYPE_CLASS_TEXT | - InputType.TYPE_TEXT_FLAG_MULTI_LINE; - outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_EXTRACT_UI | - EditorInfo.IME_FLAG_NO_FULLSCREEN /* API 11 */; - - return ic; - } - - public InputConnection getInputConnection() - { - return ic; - } -} diff --git a/android/vcmi-app/src/main/java/org/libsdl/app/SDL.java b/android/vcmi-app/src/main/java/org/libsdl/app/SDL.java index 39fc26428..dafc0cb87 100644 --- a/android/vcmi-app/src/main/java/org/libsdl/app/SDL.java +++ b/android/vcmi-app/src/main/java/org/libsdl/app/SDL.java @@ -5,8 +5,6 @@ import android.content.Context; import java.lang.Class; import java.lang.reflect.Method; -import eu.vcmi.vcmi.NativeMethods; - /** SDL library initialization */ diff --git a/android/vcmi-app/src/main/java/org/libsdl/app/SDLActivity.java b/android/vcmi-app/src/main/java/org/libsdl/app/SDLActivity.java index 09ce4ab12..cf598bd6c 100644 --- a/android/vcmi-app/src/main/java/org/libsdl/app/SDLActivity.java +++ b/android/vcmi-app/src/main/java/org/libsdl/app/SDLActivity.java @@ -53,8 +53,6 @@ import android.widget.Toast; import java.util.Hashtable; import java.util.Locale; -import eu.vcmi.vcmi.util.LibsLoader; - /** SDL Activity @@ -263,22 +261,21 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh * @return names of shared libraries to be loaded (e.g. "SDL2", "main"). */ protected String[] getLibraries() { - // SDL is linked statically, no need to load anything return new String[] { - // "SDL2", - // "SDL2_image", - // "SDL2_mixer", - // "SDL2_net", - // "SDL2_ttf", - // "main" + "SDL2", + // "SDL2_image", + // "SDL2_mixer", + // "SDL2_net", + // "SDL2_ttf", + "main" }; } // Load the .so public void loadLibraries() { - for (String lib : getLibraries()) { - SDL.loadLibrary(lib); - } + for (String lib : getLibraries()) { + SDL.loadLibrary(lib); + } } /** @@ -379,10 +376,10 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh // Initialize state SDL.initialize(); - SDL.setContext(this); // So we can call stuff from static callbacks mSingleton = this; + SDL.setContext(this); mClipboardHandler = new SDLClipboardHandler(); @@ -1887,6 +1884,174 @@ class SDLMain implements Runnable { } } +/* 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 SDLActivity.handleKeyEvent(v, keyCode, event, ic); + } + + // + @Override + public boolean onKeyPreIme (int keyCode, KeyEvent event) { + // As seen on StackOverflow: http://stackoverflow.com/questions/7634346/keyboard-hide-event + // FIXME: Discussion at http://bugzilla.libsdl.org/show_bug.cgi?id=1639 + // FIXME: This is not a 100% effective solution to the problem of detecting if the keyboard is showing or not + // FIXME: A more effective solution would be to assume our Layout to be RelativeLayout or LinearLayout + // FIXME: And determine the keyboard presence doing this: http://stackoverflow.com/questions/2150078/how-to-check-visibility-of-software-keyboard-in-android + // FIXME: An even more effective way would be if Android provided this out of the box, but where would the fun be in that :) + if (event.getAction()==KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) { + if (SDLActivity.mTextEdit != null && SDLActivity.mTextEdit.getVisibility() == View.VISIBLE) { + SDLActivity.onNativeKeyboardFocusLost(); + } + } + return super.onKeyPreIme(keyCode, event); + } + + @Override + public InputConnection onCreateInputConnection(EditorInfo outAttrs) { + ic = new SDLInputConnection(this, true); + + outAttrs.inputType = InputType.TYPE_CLASS_TEXT | + InputType.TYPE_TEXT_FLAG_MULTI_LINE; + outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_EXTRACT_UI | + EditorInfo.IME_FLAG_NO_FULLSCREEN /* API 11 */; + + return ic; + } +} + +class SDLInputConnection extends BaseInputConnection { + + protected EditText mEditText; + protected String mCommittedText = ""; + + public SDLInputConnection(View targetView, boolean fullEditor) { + super(targetView, fullEditor); + mEditText = new EditText(SDL.getContext()); + } + + @Override + public Editable getEditable() { + return mEditText.getEditableText(); + } + + @Override + public boolean sendKeyEvent(KeyEvent event) { + /* + * This used to handle the keycodes from soft keyboard (and IME-translated input from hardkeyboard) + * However, as of Ice Cream Sandwich and later, almost all soft keyboard doesn't generate key presses + * and so we need to generate them ourselves in commitText. To avoid duplicates on the handful of keys + * that still do, we empty this out. + */ + + /* + * Return DOES still generate a key event, however. So rather than using it as the 'click a button' key + * as we do with physical keyboards, let's just use it to hide the keyboard. + */ + + if (event.getKeyCode() == KeyEvent.KEYCODE_ENTER) { + if (SDLActivity.onNativeSoftReturnKey()) { + return true; + } + } + + return super.sendKeyEvent(event); + } + + @Override + public boolean commitText(CharSequence text, int newCursorPosition) { + if (!super.commitText(text, newCursorPosition)) { + return false; + } + updateText(); + return true; + } + + @Override + public boolean setComposingText(CharSequence text, int newCursorPosition) { + if (!super.setComposingText(text, newCursorPosition)) { + return false; + } + updateText(); + return true; + } + + @Override + public boolean deleteSurroundingText(int beforeLength, int afterLength) { + if (!super.deleteSurroundingText(beforeLength, afterLength)) { + return false; + } + updateText(); + return true; + } + + protected void updateText() { + final Editable content = getEditable(); + if (content == null) { + return; + } + + String text = content.toString(); + int compareLength = Math.min(text.length(), mCommittedText.length()); + int matchLength, offset; + + /* Backspace over characters that are no longer in the string */ + for (matchLength = 0; matchLength < compareLength; ) { + int codePoint = mCommittedText.codePointAt(matchLength); + if (codePoint != text.codePointAt(matchLength)) { + break; + } + matchLength += Character.charCount(codePoint); + } + /* FIXME: This doesn't handle graphemes, like '🌬️' */ + for (offset = matchLength; offset < mCommittedText.length(); ) { + int codePoint = mCommittedText.codePointAt(offset); + nativeGenerateScancodeForUnichar('\b'); + offset += Character.charCount(codePoint); + } + + if (matchLength < text.length()) { + String pendingText = text.subSequence(matchLength, text.length()).toString(); + for (offset = 0; offset < pendingText.length(); ) { + int codePoint = pendingText.codePointAt(offset); + if (codePoint == '\n') { + if (SDLActivity.onNativeSoftReturnKey()) { + return; + } + } + /* Higher code points don't generate simulated scancodes */ + if (codePoint < 128) { + nativeGenerateScancodeForUnichar((char)codePoint); + } + offset += Character.charCount(codePoint); + } + SDLInputConnection.nativeCommitText(pendingText, 0); + } + mCommittedText = text; + } + + public static native void nativeCommitText(String text, int newCursorPosition); + + public static native void nativeGenerateScancodeForUnichar(char c); +} + class SDLClipboardHandler implements ClipboardManager.OnPrimaryClipChangedListener { diff --git a/android/vcmi-app/src/main/java/org/libsdl/app/SDLInputConnection.java b/android/vcmi-app/src/main/java/org/libsdl/app/SDLInputConnection.java deleted file mode 100644 index 2647e317c..000000000 --- a/android/vcmi-app/src/main/java/org/libsdl/app/SDLInputConnection.java +++ /dev/null @@ -1,144 +0,0 @@ -package org.libsdl.app; - -import android.text.Editable; -import android.view.KeyEvent; -import android.view.View; -import android.view.inputmethod.BaseInputConnection; -import android.widget.EditText; - -public class SDLInputConnection extends BaseInputConnection -{ - - protected EditText mEditText; - protected String mCommittedText = ""; - - public SDLInputConnection(View targetView, boolean fullEditor) - { - super(targetView, fullEditor); - mEditText = new EditText(SDL.getContext()); - } - - @Override - public Editable getEditable() - { - return mEditText.getEditableText(); - } - - @Override - public boolean sendKeyEvent(KeyEvent event) - { - /* - * This used to handle the keycodes from soft keyboard (and IME-translated input from hardkeyboard) - * However, as of Ice Cream Sandwich and later, almost all soft keyboard doesn't generate key presses - * and so we need to generate them ourselves in commitText. To avoid duplicates on the handful of keys - * that still do, we empty this out. - */ - - /* - * Return DOES still generate a key event, however. So rather than using it as the 'click a button' key - * as we do with physical keyboards, let's just use it to hide the keyboard. - */ - - if (event.getKeyCode() == KeyEvent.KEYCODE_ENTER) - { - if (SDLActivity.onNativeSoftReturnKey()) - { - return true; - } - } - - return super.sendKeyEvent(event); - } - - @Override - public boolean commitText(CharSequence text, int newCursorPosition) - { - if (!super.commitText(text, newCursorPosition)) - { - return false; - } - updateText(); - return true; - } - - @Override - public boolean setComposingText(CharSequence text, int newCursorPosition) - { - if (!super.setComposingText(text, newCursorPosition)) - { - return false; - } - updateText(); - return true; - } - - @Override - public boolean deleteSurroundingText(int beforeLength, int afterLength) - { - if (!super.deleteSurroundingText(beforeLength, afterLength)) - { - return false; - } - updateText(); - return true; - } - - protected void updateText() - { - final Editable content = getEditable(); - if (content == null) - { - return; - } - - String text = content.toString(); - int compareLength = Math.min(text.length(), mCommittedText.length()); - int matchLength, offset; - - /* Backspace over characters that are no longer in the string */ - for (matchLength = 0; matchLength < compareLength; ) - { - int codePoint = mCommittedText.codePointAt(matchLength); - if (codePoint != text.codePointAt(matchLength)) - { - break; - } - matchLength += Character.charCount(codePoint); - } - /* FIXME: This doesn't handle graphemes, like '🌬️' */ - for (offset = matchLength; offset < mCommittedText.length(); ) - { - int codePoint = mCommittedText.codePointAt(offset); - nativeGenerateScancodeForUnichar('\b'); - offset += Character.charCount(codePoint); - } - - if (matchLength < text.length()) - { - String pendingText = text.subSequence(matchLength, text.length()).toString(); - for (offset = 0; offset < pendingText.length(); ) - { - int codePoint = pendingText.codePointAt(offset); - if (codePoint == '\n') - { - if (SDLActivity.onNativeSoftReturnKey()) - { - return; - } - } - /* Higher code points don't generate simulated scancodes */ - if (codePoint < 128) - { - nativeGenerateScancodeForUnichar((char) codePoint); - } - offset += Character.charCount(codePoint); - } - SDLInputConnection.nativeCommitText(pendingText, 0); - } - mCommittedText = text; - } - - public static native void nativeCommitText(String text, int newCursorPosition); - - public static native void nativeGenerateScancodeForUnichar(char c); -}