diff options
| author | Po Lu | 2023-06-07 11:03:56 +0800 |
|---|---|---|
| committer | Po Lu | 2023-06-07 11:03:56 +0800 |
| commit | 63339a9577f085074d16fa8c56ddd56864c94dda (patch) | |
| tree | f4cf00e784eec5c9616f38aa6241802de33f2a03 /java | |
| parent | 9a68041f2ccb07c2baf9cf6e1075243706f73b82 (diff) | |
| download | emacs-63339a9577f085074d16fa8c56ddd56864c94dda.tar.gz emacs-63339a9577f085074d16fa8c56ddd56864c94dda.zip | |
Update Android port
* java/org/gnu/emacs/EmacsInputConnection.java (beginBatchEdit)
(endBatchEdit, commitCompletion, commitText, deleteSurroundingText)
(finishComposingText, getSelectedText, getTextAfterCursor)
(getTextBeforeCursor, setComposingText, setComposingRegion)
(performEditorAction, performContextMenuAction, getExtractedText)
(setSelection, sendKeyEvent, deleteSurroundingTextInCodePoints)
(requestCursorUpdates): Ensure that the input connection is up
to date.
(getSurroundingText): New function.
* java/org/gnu/emacs/EmacsNative.java (getSurroundingText):
Export new C function.
* java/org/gnu/emacs/EmacsService.java (resetIC): Invalidate
previously created input connections.
* java/org/gnu/emacs/EmacsView.java (EmacsView)
(onCreateInputConnection): Signify that input connections are
now up to date.
* src/androidterm.c (struct
android_get_surrounding_text_context): New structure.
(android_get_surrounding_text, NATIVE_NAME):
* src/textconv.c (get_surrounding_text):
* src/textconv.h: New functions.
Diffstat (limited to 'java')
| -rw-r--r-- | java/org/gnu/emacs/EmacsInputConnection.java | 105 | ||||
| -rw-r--r-- | java/org/gnu/emacs/EmacsNative.java | 4 | ||||
| -rw-r--r-- | java/org/gnu/emacs/EmacsService.java | 1 | ||||
| -rw-r--r-- | java/org/gnu/emacs/EmacsView.java | 13 |
4 files changed, 123 insertions, 0 deletions
diff --git a/java/org/gnu/emacs/EmacsInputConnection.java b/java/org/gnu/emacs/EmacsInputConnection.java index 9ced7cb7aaf..73c93c67ac7 100644 --- a/java/org/gnu/emacs/EmacsInputConnection.java +++ b/java/org/gnu/emacs/EmacsInputConnection.java | |||
| @@ -23,7 +23,9 @@ import android.view.inputmethod.BaseInputConnection; | |||
| 23 | import android.view.inputmethod.CompletionInfo; | 23 | import android.view.inputmethod.CompletionInfo; |
| 24 | import android.view.inputmethod.ExtractedText; | 24 | import android.view.inputmethod.ExtractedText; |
| 25 | import android.view.inputmethod.ExtractedTextRequest; | 25 | import android.view.inputmethod.ExtractedTextRequest; |
| 26 | import android.view.inputmethod.SurroundingText; | ||
| 26 | import android.view.inputmethod.TextSnapshot; | 27 | import android.view.inputmethod.TextSnapshot; |
| 28 | |||
| 27 | import android.view.KeyEvent; | 29 | import android.view.KeyEvent; |
| 28 | 30 | ||
| 29 | import android.os.Build; | 31 | import android.os.Build; |
| @@ -88,6 +90,10 @@ public final class EmacsInputConnection extends BaseInputConnection | |||
| 88 | public boolean | 90 | public boolean |
| 89 | beginBatchEdit () | 91 | beginBatchEdit () |
| 90 | { | 92 | { |
| 93 | /* Return if the input connection is out of date. */ | ||
| 94 | if (view.icSerial < view.icGeneration) | ||
| 95 | return false; | ||
| 96 | |||
| 91 | if (EmacsService.DEBUG_IC) | 97 | if (EmacsService.DEBUG_IC) |
| 92 | Log.d (TAG, "beginBatchEdit"); | 98 | Log.d (TAG, "beginBatchEdit"); |
| 93 | 99 | ||
| @@ -99,6 +105,10 @@ public final class EmacsInputConnection extends BaseInputConnection | |||
| 99 | public boolean | 105 | public boolean |
| 100 | endBatchEdit () | 106 | endBatchEdit () |
| 101 | { | 107 | { |
| 108 | /* Return if the input connection is out of date. */ | ||
| 109 | if (view.icSerial < view.icGeneration) | ||
| 110 | return false; | ||
| 111 | |||
| 102 | if (EmacsService.DEBUG_IC) | 112 | if (EmacsService.DEBUG_IC) |
| 103 | Log.d (TAG, "endBatchEdit"); | 113 | Log.d (TAG, "endBatchEdit"); |
| 104 | 114 | ||
| @@ -110,6 +120,10 @@ public final class EmacsInputConnection extends BaseInputConnection | |||
| 110 | public boolean | 120 | public boolean |
| 111 | commitCompletion (CompletionInfo info) | 121 | commitCompletion (CompletionInfo info) |
| 112 | { | 122 | { |
| 123 | /* Return if the input connection is out of date. */ | ||
| 124 | if (view.icSerial < view.icGeneration) | ||
| 125 | return false; | ||
| 126 | |||
| 113 | if (EmacsService.DEBUG_IC) | 127 | if (EmacsService.DEBUG_IC) |
| 114 | Log.d (TAG, "commitCompletion: " + info); | 128 | Log.d (TAG, "commitCompletion: " + info); |
| 115 | 129 | ||
| @@ -125,6 +139,10 @@ public final class EmacsInputConnection extends BaseInputConnection | |||
| 125 | { | 139 | { |
| 126 | int[] selection; | 140 | int[] selection; |
| 127 | 141 | ||
| 142 | /* Return if the input connection is out of date. */ | ||
| 143 | if (view.icSerial < view.icGeneration) | ||
| 144 | return false; | ||
| 145 | |||
| 128 | if (EmacsService.DEBUG_IC) | 146 | if (EmacsService.DEBUG_IC) |
| 129 | Log.d (TAG, "commitText: " + text + " " + newCursorPosition); | 147 | Log.d (TAG, "commitText: " + text + " " + newCursorPosition); |
| 130 | 148 | ||
| @@ -156,6 +174,10 @@ public final class EmacsInputConnection extends BaseInputConnection | |||
| 156 | public boolean | 174 | public boolean |
| 157 | deleteSurroundingText (int leftLength, int rightLength) | 175 | deleteSurroundingText (int leftLength, int rightLength) |
| 158 | { | 176 | { |
| 177 | /* Return if the input connection is out of date. */ | ||
| 178 | if (view.icSerial < view.icGeneration) | ||
| 179 | return false; | ||
| 180 | |||
| 159 | if (EmacsService.DEBUG_IC) | 181 | if (EmacsService.DEBUG_IC) |
| 160 | Log.d (TAG, ("deleteSurroundingText: " | 182 | Log.d (TAG, ("deleteSurroundingText: " |
| 161 | + leftLength + " " + rightLength)); | 183 | + leftLength + " " + rightLength)); |
| @@ -169,6 +191,10 @@ public final class EmacsInputConnection extends BaseInputConnection | |||
| 169 | public boolean | 191 | public boolean |
| 170 | finishComposingText () | 192 | finishComposingText () |
| 171 | { | 193 | { |
| 194 | /* Return if the input connection is out of date. */ | ||
| 195 | if (view.icSerial < view.icGeneration) | ||
| 196 | return false; | ||
| 197 | |||
| 172 | if (EmacsService.DEBUG_IC) | 198 | if (EmacsService.DEBUG_IC) |
| 173 | Log.d (TAG, "finishComposingText"); | 199 | Log.d (TAG, "finishComposingText"); |
| 174 | 200 | ||
| @@ -180,6 +206,10 @@ public final class EmacsInputConnection extends BaseInputConnection | |||
| 180 | public String | 206 | public String |
| 181 | getSelectedText (int flags) | 207 | getSelectedText (int flags) |
| 182 | { | 208 | { |
| 209 | /* Return if the input connection is out of date. */ | ||
| 210 | if (view.icSerial < view.icGeneration) | ||
| 211 | return null; | ||
| 212 | |||
| 183 | if (EmacsService.DEBUG_IC) | 213 | if (EmacsService.DEBUG_IC) |
| 184 | Log.d (TAG, "getSelectedText: " + flags); | 214 | Log.d (TAG, "getSelectedText: " + flags); |
| 185 | 215 | ||
| @@ -192,6 +222,10 @@ public final class EmacsInputConnection extends BaseInputConnection | |||
| 192 | { | 222 | { |
| 193 | String string; | 223 | String string; |
| 194 | 224 | ||
| 225 | /* Return if the input connection is out of date. */ | ||
| 226 | if (view.icSerial < view.icGeneration) | ||
| 227 | return null; | ||
| 228 | |||
| 195 | if (EmacsService.DEBUG_IC) | 229 | if (EmacsService.DEBUG_IC) |
| 196 | Log.d (TAG, "getTextAfterCursor: " + length + " " + flags); | 230 | Log.d (TAG, "getTextAfterCursor: " + length + " " + flags); |
| 197 | 231 | ||
| @@ -210,6 +244,10 @@ public final class EmacsInputConnection extends BaseInputConnection | |||
| 210 | { | 244 | { |
| 211 | String string; | 245 | String string; |
| 212 | 246 | ||
| 247 | /* Return if the input connection is out of date. */ | ||
| 248 | if (view.icSerial < view.icGeneration) | ||
| 249 | return null; | ||
| 250 | |||
| 213 | if (EmacsService.DEBUG_IC) | 251 | if (EmacsService.DEBUG_IC) |
| 214 | Log.d (TAG, "getTextBeforeCursor: " + length + " " + flags); | 252 | Log.d (TAG, "getTextBeforeCursor: " + length + " " + flags); |
| 215 | 253 | ||
| @@ -226,6 +264,10 @@ public final class EmacsInputConnection extends BaseInputConnection | |||
| 226 | public boolean | 264 | public boolean |
| 227 | setComposingText (CharSequence text, int newCursorPosition) | 265 | setComposingText (CharSequence text, int newCursorPosition) |
| 228 | { | 266 | { |
| 267 | /* Return if the input connection is out of date. */ | ||
| 268 | if (view.icSerial < view.icGeneration) | ||
| 269 | return false; | ||
| 270 | |||
| 229 | if (EmacsService.DEBUG_IC) | 271 | if (EmacsService.DEBUG_IC) |
| 230 | Log.d (TAG, ("setComposingText: " | 272 | Log.d (TAG, ("setComposingText: " |
| 231 | + text + " ## " + newCursorPosition)); | 273 | + text + " ## " + newCursorPosition)); |
| @@ -239,6 +281,10 @@ public final class EmacsInputConnection extends BaseInputConnection | |||
| 239 | public boolean | 281 | public boolean |
| 240 | setComposingRegion (int start, int end) | 282 | setComposingRegion (int start, int end) |
| 241 | { | 283 | { |
| 284 | /* Return if the input connection is out of date. */ | ||
| 285 | if (view.icSerial < view.icGeneration) | ||
| 286 | return false; | ||
| 287 | |||
| 242 | if (EmacsService.DEBUG_IC) | 288 | if (EmacsService.DEBUG_IC) |
| 243 | Log.d (TAG, "setComposingRegion: " + start + " " + end); | 289 | Log.d (TAG, "setComposingRegion: " + start + " " + end); |
| 244 | 290 | ||
| @@ -250,6 +296,10 @@ public final class EmacsInputConnection extends BaseInputConnection | |||
| 250 | public boolean | 296 | public boolean |
| 251 | performEditorAction (int editorAction) | 297 | performEditorAction (int editorAction) |
| 252 | { | 298 | { |
| 299 | /* Return if the input connection is out of date. */ | ||
| 300 | if (view.icSerial < view.icGeneration) | ||
| 301 | return false; | ||
| 302 | |||
| 253 | if (EmacsService.DEBUG_IC) | 303 | if (EmacsService.DEBUG_IC) |
| 254 | Log.d (TAG, "performEditorAction: " + editorAction); | 304 | Log.d (TAG, "performEditorAction: " + editorAction); |
| 255 | 305 | ||
| @@ -263,6 +313,10 @@ public final class EmacsInputConnection extends BaseInputConnection | |||
| 263 | { | 313 | { |
| 264 | int action; | 314 | int action; |
| 265 | 315 | ||
| 316 | /* Return if the input connection is out of date. */ | ||
| 317 | if (view.icSerial < view.icGeneration) | ||
| 318 | return false; | ||
| 319 | |||
| 266 | if (EmacsService.DEBUG_IC) | 320 | if (EmacsService.DEBUG_IC) |
| 267 | Log.d (TAG, "performContextMenuAction: " + contextMenuAction); | 321 | Log.d (TAG, "performContextMenuAction: " + contextMenuAction); |
| 268 | 322 | ||
| @@ -310,6 +364,10 @@ public final class EmacsInputConnection extends BaseInputConnection | |||
| 310 | ExtractedText text; | 364 | ExtractedText text; |
| 311 | int[] selection; | 365 | int[] selection; |
| 312 | 366 | ||
| 367 | /* Return if the input connection is out of date. */ | ||
| 368 | if (view.icSerial < view.icGeneration) | ||
| 369 | return null; | ||
| 370 | |||
| 313 | if (EmacsService.DEBUG_IC) | 371 | if (EmacsService.DEBUG_IC) |
| 314 | Log.d (TAG, "getExtractedText: " + request.hintMaxChars + ", " | 372 | Log.d (TAG, "getExtractedText: " + request.hintMaxChars + ", " |
| 315 | + request.hintMaxLines + " " + flags); | 373 | + request.hintMaxLines + " " + flags); |
| @@ -360,6 +418,10 @@ public final class EmacsInputConnection extends BaseInputConnection | |||
| 360 | public boolean | 418 | public boolean |
| 361 | setSelection (int start, int end) | 419 | setSelection (int start, int end) |
| 362 | { | 420 | { |
| 421 | /* Return if the input connection is out of date. */ | ||
| 422 | if (view.icSerial < view.icGeneration) | ||
| 423 | return false; | ||
| 424 | |||
| 363 | if (EmacsService.DEBUG_IC) | 425 | if (EmacsService.DEBUG_IC) |
| 364 | Log.d (TAG, "setSelection: " + start + " " + end); | 426 | Log.d (TAG, "setSelection: " + start + " " + end); |
| 365 | 427 | ||
| @@ -371,6 +433,10 @@ public final class EmacsInputConnection extends BaseInputConnection | |||
| 371 | public boolean | 433 | public boolean |
| 372 | sendKeyEvent (KeyEvent key) | 434 | sendKeyEvent (KeyEvent key) |
| 373 | { | 435 | { |
| 436 | /* Return if the input connection is out of date. */ | ||
| 437 | if (view.icSerial < view.icGeneration) | ||
| 438 | return false; | ||
| 439 | |||
| 374 | if (EmacsService.DEBUG_IC) | 440 | if (EmacsService.DEBUG_IC) |
| 375 | Log.d (TAG, "sendKeyEvent: " + key); | 441 | Log.d (TAG, "sendKeyEvent: " + key); |
| 376 | 442 | ||
| @@ -381,6 +447,10 @@ public final class EmacsInputConnection extends BaseInputConnection | |||
| 381 | public boolean | 447 | public boolean |
| 382 | deleteSurroundingTextInCodePoints (int beforeLength, int afterLength) | 448 | deleteSurroundingTextInCodePoints (int beforeLength, int afterLength) |
| 383 | { | 449 | { |
| 450 | /* Return if the input connection is out of date. */ | ||
| 451 | if (view.icSerial < view.icGeneration) | ||
| 452 | return false; | ||
| 453 | |||
| 384 | /* This can be implemented the same way as | 454 | /* This can be implemented the same way as |
| 385 | deleteSurroundingText. */ | 455 | deleteSurroundingText. */ |
| 386 | return this.deleteSurroundingText (beforeLength, afterLength); | 456 | return this.deleteSurroundingText (beforeLength, afterLength); |
| @@ -390,6 +460,10 @@ public final class EmacsInputConnection extends BaseInputConnection | |||
| 390 | public boolean | 460 | public boolean |
| 391 | requestCursorUpdates (int cursorUpdateMode) | 461 | requestCursorUpdates (int cursorUpdateMode) |
| 392 | { | 462 | { |
| 463 | /* Return if the input connection is out of date. */ | ||
| 464 | if (view.icSerial < view.icGeneration) | ||
| 465 | return false; | ||
| 466 | |||
| 393 | if (EmacsService.DEBUG_IC) | 467 | if (EmacsService.DEBUG_IC) |
| 394 | Log.d (TAG, "requestCursorUpdates: " + cursorUpdateMode); | 468 | Log.d (TAG, "requestCursorUpdates: " + cursorUpdateMode); |
| 395 | 469 | ||
| @@ -397,6 +471,37 @@ public final class EmacsInputConnection extends BaseInputConnection | |||
| 397 | return true; | 471 | return true; |
| 398 | } | 472 | } |
| 399 | 473 | ||
| 474 | @Override | ||
| 475 | public SurroundingText | ||
| 476 | getSurroundingText (int beforeLength, int afterLength, | ||
| 477 | int flags) | ||
| 478 | { | ||
| 479 | SurroundingText text; | ||
| 480 | |||
| 481 | /* Return if the input connection is out of date. */ | ||
| 482 | if (view.icSerial < view.icGeneration) | ||
| 483 | return null; | ||
| 484 | |||
| 485 | if (EmacsService.DEBUG_IC) | ||
| 486 | Log.d (TAG, ("getSurroundingText: " + beforeLength + ", " | ||
| 487 | + afterLength)); | ||
| 488 | |||
| 489 | text = EmacsNative.getSurroundingText (windowHandle, beforeLength, | ||
| 490 | afterLength, flags); | ||
| 491 | |||
| 492 | if (text != null) | ||
| 493 | Log.d (TAG, ("getSurroundingText: " | ||
| 494 | + text.getSelectionStart () | ||
| 495 | + "," | ||
| 496 | + text.getSelectionEnd () | ||
| 497 | + "+" | ||
| 498 | + text.getOffset () | ||
| 499 | + ": " | ||
| 500 | + text.getText ())); | ||
| 501 | |||
| 502 | return text; | ||
| 503 | } | ||
| 504 | |||
| 400 | 505 | ||
| 401 | /* Override functions which are not implemented. */ | 506 | /* Override functions which are not implemented. */ |
| 402 | 507 | ||
diff --git a/java/org/gnu/emacs/EmacsNative.java b/java/org/gnu/emacs/EmacsNative.java index cb1c6caa79a..cb89cf6808a 100644 --- a/java/org/gnu/emacs/EmacsNative.java +++ b/java/org/gnu/emacs/EmacsNative.java | |||
| @@ -25,6 +25,7 @@ import android.graphics.Bitmap; | |||
| 25 | 25 | ||
| 26 | import android.view.inputmethod.ExtractedText; | 26 | import android.view.inputmethod.ExtractedText; |
| 27 | import android.view.inputmethod.ExtractedTextRequest; | 27 | import android.view.inputmethod.ExtractedTextRequest; |
| 28 | import android.view.inputmethod.SurroundingText; | ||
| 28 | 29 | ||
| 29 | public final class EmacsNative | 30 | public final class EmacsNative |
| 30 | { | 31 | { |
| @@ -222,6 +223,9 @@ public final class EmacsNative | |||
| 222 | public static native void requestSelectionUpdate (short window); | 223 | public static native void requestSelectionUpdate (short window); |
| 223 | public static native void requestCursorUpdates (short window, int mode); | 224 | public static native void requestCursorUpdates (short window, int mode); |
| 224 | public static native void clearInputFlags (short window); | 225 | public static native void clearInputFlags (short window); |
| 226 | public static native SurroundingText getSurroundingText (short window, | ||
| 227 | int left, int right, | ||
| 228 | int flags); | ||
| 225 | 229 | ||
| 226 | 230 | ||
| 227 | /* Return the current value of the selection, or -1 upon | 231 | /* Return the current value of the selection, or -1 upon |
diff --git a/java/org/gnu/emacs/EmacsService.java b/java/org/gnu/emacs/EmacsService.java index 2074a5b7c2b..48e39f8b355 100644 --- a/java/org/gnu/emacs/EmacsService.java +++ b/java/org/gnu/emacs/EmacsService.java | |||
| @@ -748,6 +748,7 @@ public final class EmacsService extends Service | |||
| 748 | window.view.setICMode (icMode); | 748 | window.view.setICMode (icMode); |
| 749 | 749 | ||
| 750 | icBeginSynchronous (); | 750 | icBeginSynchronous (); |
| 751 | window.view.icGeneration++; | ||
| 751 | window.view.imManager.restartInput (window.view); | 752 | window.view.imManager.restartInput (window.view); |
| 752 | icEndSynchronous (); | 753 | icEndSynchronous (); |
| 753 | } | 754 | } |
diff --git a/java/org/gnu/emacs/EmacsView.java b/java/org/gnu/emacs/EmacsView.java index a78dec08839..d432162132d 100644 --- a/java/org/gnu/emacs/EmacsView.java +++ b/java/org/gnu/emacs/EmacsView.java | |||
| @@ -111,6 +111,13 @@ public final class EmacsView extends ViewGroup | |||
| 111 | details. */ | 111 | details. */ |
| 112 | private int icMode; | 112 | private int icMode; |
| 113 | 113 | ||
| 114 | /* The number of calls to `resetIC' to have taken place the last | ||
| 115 | time an InputConnection was created. */ | ||
| 116 | public long icSerial; | ||
| 117 | |||
| 118 | /* The number of calls to `recetIC' that have taken place. */ | ||
| 119 | public volatile long icGeneration; | ||
| 120 | |||
| 114 | public | 121 | public |
| 115 | EmacsView (EmacsWindow window) | 122 | EmacsView (EmacsWindow window) |
| 116 | { | 123 | { |
| @@ -627,6 +634,12 @@ public final class EmacsView extends ViewGroup | |||
| 627 | return null; | 634 | return null; |
| 628 | } | 635 | } |
| 629 | 636 | ||
| 637 | /* Set icSerial. If icSerial < icGeneration, the input connection | ||
| 638 | has been reset, and future input should be ignored until a new | ||
| 639 | connection is created. */ | ||
| 640 | |||
| 641 | icSerial = icGeneration; | ||
| 642 | |||
| 630 | /* Reset flags set by the previous input method. */ | 643 | /* Reset flags set by the previous input method. */ |
| 631 | 644 | ||
| 632 | EmacsNative.clearInputFlags (window.handle); | 645 | EmacsNative.clearInputFlags (window.handle); |