From 82b4b9e8692c349a45d319fe05c9fbfed4ab203d Mon Sep 17 00:00:00 2001 From: Po Lu Date: Sun, 12 Mar 2023 17:07:57 +0800 Subject: [PATCH] Update Android port * src/androidterm.c (NATIVE_NAME, JNICALL) (android_build_extracted_text, android_update_selection): Use 0-based indices for Android buffer positions. Also, report surrounding text relative to the region, not to the cursor. * src/textconv.c (textconv_query): Accept new values of position. (really_set_composing_text): Use ephemeral last point. --- src/androidterm.c | 81 +++++++++++++++++++++++++++-------------------- src/textconv.c | 36 +++++++++++++++++++-- 2 files changed, 80 insertions(+), 37 deletions(-) diff --git a/src/androidterm.c b/src/androidterm.c index 397971e3c87..ed375ef53fe 100644 --- a/src/androidterm.c +++ b/src/androidterm.c @@ -4811,7 +4811,7 @@ NATIVE_NAME (getTextAfterCursor) (JNIEnv *env, jobject object, jshort window, jstring string; /* First, set up the conversion query. */ - context.query.position = 0; + context.query.position = EMACS_INT_MAX; context.query.direction = TEXTCONV_FORWARD_CHAR; context.query.factor = min (length, 65535); context.query.operation = TEXTCONV_RETRIEVAL; @@ -4855,7 +4855,7 @@ NATIVE_NAME (getTextBeforeCursor) (JNIEnv *env, jobject object, jshort window, jstring string; /* First, set up the conversion query. */ - context.query.position = 0; + context.query.position = TYPE_MINIMUM (EMACS_INT); context.query.direction = TEXTCONV_BACKWARD_CHAR; context.query.factor = min (length, 65535); context.query.operation = TEXTCONV_RETRIEVAL; @@ -4936,8 +4936,8 @@ NATIVE_NAME (setComposingRegion) (JNIEnv *env, jobject object, jshort window, event.ime.serial = ++event_serial; event.ime.window = window; event.ime.operation = ANDROID_IME_SET_COMPOSING_REGION; - event.ime.start = start; - event.ime.end = end; + event.ime.start = start + 1; + event.ime.end = end + 1; event.ime.length = 0; event.ime.position = 0; event.ime.text = NULL; @@ -4961,8 +4961,8 @@ NATIVE_NAME (setSelection) (JNIEnv *env, jobject object, jshort window, event.ime.serial = ++event_serial; event.ime.window = window; event.ime.operation = ANDROID_IME_SET_POINT; - event.ime.start = start; - event.ime.end = end; + event.ime.start = start + 1; + event.ime.end = end + 1; event.ime.length = 0; event.ime.position = start; event.ime.text = NULL; @@ -5040,11 +5040,12 @@ NATIVE_NAME (getSelection) (JNIEnv *env, jobject object, jshort window) return NULL; /* Wraparound actually makes more sense than truncation; at least - editing will sort of work. */ + editing will sort of work. Convert the positions to start from + index 0, as that is what Android expects. */ contents[0] = (unsigned int) min (context.point, - context.mark); + context.mark) - 1; contents[1] = (unsigned int) max (context.point, - context.mark); + context.mark) - 1; /* Now create the array. */ array = (*env)->NewIntArray (env, 2); @@ -5209,8 +5210,11 @@ android_build_extracted_text (jstring text, ptrdiff_t start, min (offset, TYPE_MAXIMUM (jint))); (*env)->SetIntField (env, object, text_class.selection_end, min (offset, TYPE_MAXIMUM (jint))); + + /* Subtract 1 from start: point indices in Emacs start from 1, but + Android expects 0. */ (*env)->SetIntField (env, object, text_class.start_offset, - min (start, TYPE_MAXIMUM (jint))); + min (start - 1, TYPE_MAXIMUM (jint))); (*env)->SetObjectField (env, object, text_class.text, text); return object; } @@ -5311,8 +5315,11 @@ NATIVE_NAME (getExtractedText) (JNIEnv *env, jobject ignored_object, min (context.offset, TYPE_MAXIMUM (jint))); (*env)->SetIntField (env, object, text_class.selection_end, min (context.offset, TYPE_MAXIMUM (jint))); + + /* Subtract 1 from start: point indices in Emacs start from 1, but + Android expects 0. */ (*env)->SetIntField (env, object, text_class.start_offset, - min (context.start, TYPE_MAXIMUM (jint))); + min (context.start - 1, TYPE_MAXIMUM (jint))); (*env)->SetObjectField (env, object, text_class.text, string); return object; } @@ -5397,8 +5404,9 @@ android_update_selection (struct frame *f, struct window *w) { eassert (MARKERP (f->conversion.compose_region_end)); - start = marker_position (f->conversion.compose_region_start); - end = marker_position (f->conversion.compose_region_end); + /* Indexing in android starts from 0 instead of 1. */ + start = marker_position (f->conversion.compose_region_start) - 1; + end = marker_position (f->conversion.compose_region_end) - 1; } else start = -1, end = -1; @@ -5423,9 +5431,11 @@ android_update_selection (struct frame *f, struct window *w) /* Send the update. Android doesn't have a concept of ``point'' and ``mark''; instead, it only has a selection, where the start of - the selection is less than or equal to the end. */ - android_update_ic (FRAME_ANDROID_WINDOW (f), min (point, mark), - max (point, mark), start, end); + the selection is less than or equal to the end. Also, convert + the indices from 1-based Emacs indices to 0-based Android + ones. */ + android_update_ic (FRAME_ANDROID_WINDOW (f), min (point, mark) - 1, + max (point, mark) - 1, start, end); /* Update the extracted text as well, if the input method has asked for updates. 1 is @@ -5438,25 +5448,28 @@ android_update_selection (struct frame *f, struct window *w) text = get_extracted_text (f, min (hint, 600), &start, &offset, &length, &bytes); - /* Make a string out of the extracted text. */ - string = android_text_to_string (android_java_env, - text, length, bytes); - xfree (text); - android_exception_check (); - - /* Make extracted text out of that string. */ - extracted = android_build_extracted_text (string, start, - offset); - android_exception_check_1 (string); - ANDROID_DELETE_LOCAL_REF (string); - - if (extracted) + if (text) { - /* extracted is now an associated ExtractedText object. - Perform the update. */ - android_update_extracted_text (FRAME_ANDROID_WINDOW (f), - extracted, token); - ANDROID_DELETE_LOCAL_REF (extracted); + /* Make a string out of the extracted text. */ + string = android_text_to_string (android_java_env, + text, length, bytes); + xfree (text); + android_exception_check (); + + /* Make extracted text out of that string. */ + extracted = android_build_extracted_text (string, start, + offset); + android_exception_check_1 (string); + ANDROID_DELETE_LOCAL_REF (string); + + if (extracted) + { + /* extracted is now an associated ExtractedText object. + Perform the update. */ + android_update_extracted_text (FRAME_ANDROID_WINDOW (f), + extracted, token); + ANDROID_DELETE_LOCAL_REF (extracted); + } } } } diff --git a/src/textconv.c b/src/textconv.c index 3206bb48204..900277016f2 100644 --- a/src/textconv.c +++ b/src/textconv.c @@ -137,6 +137,10 @@ select_window (Lisp_Object window, Lisp_Object norecord) window and QUERY->factor times QUERY->direction from that position. Return it in QUERY->text. + If QUERY->position is TYPE_MINIMUM (EMACS_INT) or EMACS_INT_MAX, + start at the window's last point or mark, whichever is greater or + smaller. + Then, either delete that text from the buffer if QUERY->operation is TEXTCONV_SUBSTITUTION, or return 0. @@ -155,8 +159,9 @@ textconv_query (struct frame *f, struct textconv_callback_struct *query, { specpdl_ref count; ptrdiff_t pos, pos_byte, end, end_byte, start; - ptrdiff_t temp, temp1; + ptrdiff_t temp, temp1, mark; char *buffer; + struct window *w; /* Save the excursion, as there will be extensive changes to the selected window. */ @@ -171,12 +176,35 @@ textconv_query (struct frame *f, struct textconv_callback_struct *query, select_window ((WINDOW_LIVE_P (f->old_selected_window) ? f->old_selected_window : f->selected_window), Qt); + w = XWINDOW (selected_window); /* Now find the appropriate text bounds for QUERY. First, move point QUERY->position steps forward or backwards. */ pos = PT; + /* If QUERY->position is EMACS_INT_MAX, use the last mark or the + ephemeral last point, whichever is greater. + + The opposite applies for EMACS_INT_MIN. */ + + mark = get_mark (); + + if (query->position == EMACS_INT_MAX) + { + pos = (mark == -1 + ? w->ephemeral_last_point + : max (w->ephemeral_last_point, mark)); + goto escape1; + } + else if (query->position == TYPE_MINIMUM (EMACS_INT)) + { + pos = (mark == -1 + ? w->ephemeral_last_point + : min (w->ephemeral_last_point, mark)); + goto escape1; + } + /* Next, if POS lies within the conversion region and the caller asked for it to be moved away, move it away from the conversion region. */ @@ -210,7 +238,7 @@ textconv_query (struct frame *f, struct textconv_callback_struct *query, if (flags & TEXTCONV_SKIP_ACTIVE_REGION) { - temp = get_mark (); + temp = mark; if (temp == -1) goto escape; @@ -246,6 +274,8 @@ textconv_query (struct frame *f, struct textconv_callback_struct *query, if (INT_ADD_WRAPV (pos, query->position, &pos)) pos = PT; + escape1: + if (pos < BEGV) pos = BEGV; @@ -792,7 +822,7 @@ really_set_composing_text (struct frame *f, ptrdiff_t position, /* If PT hasn't changed, the conversion region definitely has. Otherwise, redisplay will update the input method instead. */ - if (PT == w->last_point + if (PT == w->ephemeral_last_point && text_interface && text_interface->compose_region_changed) { -- 2.39.2