diff options
| author | Po Lu | 2023-06-15 12:36:50 +0800 |
|---|---|---|
| committer | Po Lu | 2023-06-15 12:36:50 +0800 |
| commit | 363e293cc919ab02c40bd9a8fa4875c2e5644b2d (patch) | |
| tree | 5fa537364e29fbcdb13cd195ac6da253a6d95771 /src/androidterm.c | |
| parent | ca120044ac11d38ca1e8cac7903be38d5ca15d2b (diff) | |
| download | emacs-363e293cc919ab02c40bd9a8fa4875c2e5644b2d.tar.gz emacs-363e293cc919ab02c40bd9a8fa4875c2e5644b2d.zip | |
Update Android port
* java/org/gnu/emacs/EmacsInputConnection.java
(EmacsInputConnection, beginBatchEdit, reset, endBatchEdit):
Keep track of the number of batch edits and return an
appropriate value.
(takeSnapshot): Implement function.
* java/org/gnu/emacs/EmacsNative.java (takeSnapshot): New
function.
* java/org/gnu/emacs/EmacsService.java (resetIC): Improve
debugging output.
* java/org/gnu/emacs/EmacsView.java (onCreateInputConnection):
Call `reset' to clear the UI side batch edit count.
* src/androidterm.c (struct
android_get_surrounding_text_context): New fields
`conversion_start' and `conversion_end'.
(android_get_surrounding_text): Return the conversion region.
(android_get_surrounding_text_internal, NATIVE_NAME): Factor out
`getSurroundingText'.
(takeSnapshot): New function.
Diffstat (limited to 'src/androidterm.c')
| -rw-r--r-- | src/androidterm.c | 129 |
1 files changed, 120 insertions, 9 deletions
diff --git a/src/androidterm.c b/src/androidterm.c index 191ff65199b..29076981a47 100644 --- a/src/androidterm.c +++ b/src/androidterm.c | |||
| @@ -5668,6 +5668,10 @@ struct android_get_surrounding_text_context | |||
| 5668 | /* Offsets into that text. */ | 5668 | /* Offsets into that text. */ |
| 5669 | ptrdiff_t offset, start, end; | 5669 | ptrdiff_t offset, start, end; |
| 5670 | 5670 | ||
| 5671 | /* The start and end indices of the conversion region. | ||
| 5672 | -1 if it does not exist. */ | ||
| 5673 | ptrdiff_t conversion_start, conversion_end; | ||
| 5674 | |||
| 5671 | /* The window. */ | 5675 | /* The window. */ |
| 5672 | android_window window; | 5676 | android_window window; |
| 5673 | }; | 5677 | }; |
| @@ -5706,22 +5710,47 @@ android_get_surrounding_text (void *data) | |||
| 5706 | request->start = request->end; | 5710 | request->start = request->end; |
| 5707 | request->end = temp; | 5711 | request->end = temp; |
| 5708 | } | 5712 | } |
| 5713 | |||
| 5714 | /* Retrieve the conversion region. */ | ||
| 5715 | |||
| 5716 | request->conversion_start = -1; | ||
| 5717 | request->conversion_end = -1; | ||
| 5718 | |||
| 5719 | if (MARKERP (f->conversion.compose_region_start)) | ||
| 5720 | { | ||
| 5721 | request->conversion_start | ||
| 5722 | = marker_position (f->conversion.compose_region_start) - 1; | ||
| 5723 | request->conversion_end | ||
| 5724 | = marker_position (f->conversion.compose_region_end) - 1; | ||
| 5725 | } | ||
| 5709 | } | 5726 | } |
| 5710 | 5727 | ||
| 5711 | JNIEXPORT jobject JNICALL | 5728 | /* Return a local reference to a `SurroundingText' object describing |
| 5712 | NATIVE_NAME (getSurroundingText) (JNIEnv *env, jobject ignored_object, | 5729 | WINDOW's surrounding text. ENV should be a valid JNI environment |
| 5713 | jshort window, jint before_length, | 5730 | for the current thread. |
| 5714 | jint after_length, jint flags) | ||
| 5715 | { | ||
| 5716 | JNI_STACK_ALIGNMENT_PROLOGUE; | ||
| 5717 | 5731 | ||
| 5718 | static jclass class; | 5732 | BEFORE_LENGTH and AFTER_LENGTH specify the number of characters |
| 5719 | static jmethodID constructor; | 5733 | around point and mark to return. |
| 5720 | 5734 | ||
| 5735 | Return the conversion region (or -1) in *CONVERSION_START and | ||
| 5736 | *CONVERSION_END if non-NULL. | ||
| 5737 | |||
| 5738 | Value is the object upon success, else NULL. */ | ||
| 5739 | |||
| 5740 | static jobject | ||
| 5741 | android_get_surrounding_text_internal (JNIEnv *env, jshort window, | ||
| 5742 | jint before_length, | ||
| 5743 | jint after_length, | ||
| 5744 | ptrdiff_t *conversion_start, | ||
| 5745 | ptrdiff_t *conversion_end) | ||
| 5746 | { | ||
| 5721 | struct android_get_surrounding_text_context context; | 5747 | struct android_get_surrounding_text_context context; |
| 5722 | jstring string; | 5748 | jstring string; |
| 5723 | jobject object; | 5749 | jobject object; |
| 5724 | 5750 | ||
| 5751 | static jclass class; | ||
| 5752 | static jmethodID constructor; | ||
| 5753 | |||
| 5725 | /* Initialize CLASS if it has not yet been initialized. */ | 5754 | /* Initialize CLASS if it has not yet been initialized. */ |
| 5726 | 5755 | ||
| 5727 | if (!class) | 5756 | if (!class) |
| @@ -5745,7 +5774,9 @@ NATIVE_NAME (getSurroundingText) (JNIEnv *env, jobject ignored_object, | |||
| 5745 | 5774 | ||
| 5746 | class = (*env)->NewGlobalRef (env, class); | 5775 | class = (*env)->NewGlobalRef (env, class); |
| 5747 | if (!class) | 5776 | if (!class) |
| 5748 | return NULL; | 5777 | /* Clear class to prevent a local reference from remaining in |
| 5778 | `class'. */ | ||
| 5779 | return (class = NULL); | ||
| 5749 | 5780 | ||
| 5750 | /* Now look for its constructor. */ | 5781 | /* Now look for its constructor. */ |
| 5751 | constructor = (*env)->GetMethodID (env, class, "<init>", | 5782 | constructor = (*env)->GetMethodID (env, class, "<init>", |
| @@ -5787,6 +5818,86 @@ NATIVE_NAME (getSurroundingText) (JNIEnv *env, jobject ignored_object, | |||
| 5787 | if (!object) | 5818 | if (!object) |
| 5788 | return NULL; | 5819 | return NULL; |
| 5789 | 5820 | ||
| 5821 | /* Now return the conversion region if that was requested. */ | ||
| 5822 | |||
| 5823 | if (conversion_start) | ||
| 5824 | { | ||
| 5825 | *conversion_start = context.conversion_start; | ||
| 5826 | *conversion_end = context.conversion_start; | ||
| 5827 | } | ||
| 5828 | |||
| 5829 | return object; | ||
| 5830 | } | ||
| 5831 | |||
| 5832 | JNIEXPORT jobject JNICALL | ||
| 5833 | NATIVE_NAME (getSurroundingText) (JNIEnv *env, jobject object, | ||
| 5834 | jshort window, jint before_length, | ||
| 5835 | jint after_length, jint flags) | ||
| 5836 | { | ||
| 5837 | JNI_STACK_ALIGNMENT_PROLOGUE; | ||
| 5838 | |||
| 5839 | return android_get_surrounding_text_internal (env, window, before_length, | ||
| 5840 | after_length, NULL, NULL); | ||
| 5841 | } | ||
| 5842 | |||
| 5843 | JNIEXPORT jobject JNICALL | ||
| 5844 | NATIVE_NAME (takeSnapshot) (JNIEnv *env, jobject object, jshort window) | ||
| 5845 | { | ||
| 5846 | JNI_STACK_ALIGNMENT_PROLOGUE; | ||
| 5847 | |||
| 5848 | jobject text; | ||
| 5849 | ptrdiff_t start, end; | ||
| 5850 | |||
| 5851 | static jclass class; | ||
| 5852 | static jmethodID constructor; | ||
| 5853 | |||
| 5854 | /* First, obtain the surrounding text and conversion region. */ | ||
| 5855 | text = android_get_surrounding_text_internal (env, window, 600, 600, | ||
| 5856 | &start, &end); | ||
| 5857 | |||
| 5858 | /* If that fails, return NULL. */ | ||
| 5859 | |||
| 5860 | if (!text) | ||
| 5861 | return NULL; | ||
| 5862 | |||
| 5863 | /* Next, initialize the TextSnapshot class. */ | ||
| 5864 | |||
| 5865 | if (!class) | ||
| 5866 | { | ||
| 5867 | class | ||
| 5868 | = (*env)->FindClass (env, ("android/view/inputmethod" | ||
| 5869 | "/TextSnapshot")); | ||
| 5870 | #if __ANDROID_API__ < 33 | ||
| 5871 | /* If CLASS cannot be found, the version of Android currently | ||
| 5872 | running is too old. */ | ||
| 5873 | |||
| 5874 | if (!class) | ||
| 5875 | { | ||
| 5876 | (*env)->ExceptionClear (env); | ||
| 5877 | return NULL; | ||
| 5878 | } | ||
| 5879 | #else /* __ANDROID_API__ >= 33 */ | ||
| 5880 | assert (class); | ||
| 5881 | #endif /* __ANDROID_API__ < 33 */ | ||
| 5882 | |||
| 5883 | class = (*env)->NewGlobalRef (env, class); | ||
| 5884 | if (!class) | ||
| 5885 | /* Clear class to prevent a local reference from remaining in | ||
| 5886 | `class'. */ | ||
| 5887 | return (class = NULL); | ||
| 5888 | |||
| 5889 | constructor = (*env)->GetMethodID (env, class, "<init>", | ||
| 5890 | "(Landroid/view/inputmethod" | ||
| 5891 | "/SurroundingText;III)V"); | ||
| 5892 | assert (constructor); | ||
| 5893 | } | ||
| 5894 | |||
| 5895 | /* Try to create a TextSnapshot object. */ | ||
| 5896 | eassert (start <= end); | ||
| 5897 | object = (*env)->NewObject (env, class, constructor, text, | ||
| 5898 | (jint) min (start, TYPE_MAXIMUM (jint)), | ||
| 5899 | (jint) min (end, TYPE_MAXIMUM (jint)), | ||
| 5900 | (jint) 0); | ||
| 5790 | return object; | 5901 | return object; |
| 5791 | } | 5902 | } |
| 5792 | 5903 | ||