summaryrefslogtreecommitdiff
path: root/src/androidterm.c
diff options
context:
space:
mode:
authorPo Lu <luangruo@yahoo.com>2023-02-15 22:51:44 +0800
committerPo Lu <luangruo@yahoo.com>2023-02-15 22:51:44 +0800
commitcf24b61985c26cbf2e5a24cb0b64a8528aa3a9cc (patch)
treeb69f8dbb50e3e2f6f09caa05aecbee5241876f62 /src/androidterm.c
parentdd7066901f67233c09f3b0409a57db7686c7ea5b (diff)
downloademacs-cf24b61985c26cbf2e5a24cb0b64a8528aa3a9cc.tar.gz
Update Android port
* doc/emacs/input.texi (On-Screen Keyboards): * doc/lispref/commands.texi (Misc Events): Improve documentation of text conversion stuff. * java/org/gnu/emacs/EmacsInputConnection.java (beginBatchEdit) (endBatchEdit, commitCompletion, commitText, deleteSurroundingText) (finishComposingText, getSelectedText, getTextAfterCursor) (EmacsInputConnection, setComposingRegion, performEditorAction) (getExtractedText): Condition debug code on DEBUG_IC. * java/org/gnu/emacs/EmacsService.java (EmacsService, updateIC): Likewise. * lisp/bindings.el (global-map): * lisp/electric.el (global-map): Make `text-conversion' `analyze-text-conversion'. * lisp/progmodes/prog-mode.el (prog-mode): Enable text conversion in input methods. * lisp/simple.el (analyze-text-conversion): New function. * lisp/textmodes/text-mode.el (text-conversion-style) (text-mode): Likewise. * src/androidterm.c (android_handle_ime_event): Handle set_point_and_mark. (android_sync_edit): Give Emacs 100 ms instead. (android_perform_conversion_query): Skip the active region, not the conversion region. (getSelectedText): Implement properly. (android_update_selection): Expose mark to input methods. (android_reset_conversion): Handle `text-conversion-style'. * src/buffer.c (init_buffer_once, syms_of_buffer): Add buffer local variable `text-conversion-style'. * src/buffer.h (struct buffer, bset_text_conversion_style): New fields. * src/emacs.c (android_emacs_init): Call syms_of_textconv. * src/frame.h (enum text_conversion_operation): Rename TEXTCONV_SET_POINT. * src/lisp.h: Export syms_of_textconv. * src/marker.c (set_marker_internal): Force redisplay when the mark is set and the buffer is visible on builds that use text conversion. Explain why. * src/textconv.c (copy_buffer): Fix copying past gap. (get_mark): New function. (textconv_query): Implement new flag. (sync_overlay): New function. Display conversion text in an overlay. (record_buffer_change, really_commit_text) (really_set_composing_text, really_set_composing_region) (really_delete_surrounding_text, really_set_point) (handle_pending_conversion_events_1, decrement_inside) (handle_pending_conversion_events, textconv_set_point) (get_extracted_text, register_textconv_interface): Various fixes and improvements. * src/textconv.h (struct textconv_interface): Update documentation. * src/window.h (GCALIGNED_STRUCT): New field `prev_mark'. * src/xdisp.c (mark_window_display_accurate_1): Handle prev_mark.
Diffstat (limited to 'src/androidterm.c')
-rw-r--r--src/androidterm.c88
1 files changed, 67 insertions, 21 deletions
diff --git a/src/androidterm.c b/src/androidterm.c
index 767b7d8240c..0c990d3d2d2 100644
--- a/src/androidterm.c
+++ b/src/androidterm.c
@@ -621,8 +621,9 @@ android_handle_ime_event (union android_event *event, struct frame *f)
break;
case ANDROID_IME_SET_POINT:
- textconv_set_point (f, event->ime.position,
- event->ime.counter);
+ textconv_set_point_and_mark (f, event->ime.start,
+ event->ime.end,
+ event->ime.counter);
break;
case ANDROID_IME_START_BATCH_EDIT:
@@ -4305,7 +4306,7 @@ static sem_t edit_sem;
Every time one of the text retrieval functions is called and an
editing request is made, Emacs gives the main thread approximately
- 50 ms to process it, in order to mostly keep the input method in
+ 100 ms to process it, in order to mostly keep the input method in
sync with the buffer contents. */
static void
@@ -4319,7 +4320,7 @@ android_sync_edit (void)
return;
start = current_timespec ();
- end = timespec_add (start, make_timespec (0, 50000000));
+ end = timespec_add (start, make_timespec (0, 100000000));
while (true)
{
@@ -4550,8 +4551,7 @@ android_perform_conversion_query (void *data)
if (!f)
return;
- textconv_query (f, &context->query,
- TEXTCONV_SKIP_CONVERSION_REGION);
+ textconv_query (f, &context->query, TEXTCONV_SKIP_ACTIVE_REGION);
/* context->query.text will have been set even if textconv_query
returns 1. */
@@ -4649,13 +4649,6 @@ android_text_to_string (JNIEnv *env, char *buffer, ptrdiff_t n,
}
JNIEXPORT jstring JNICALL
-NATIVE_NAME (getSelectedText) (JNIEnv *env, jobject object,
- jshort window)
-{
- return NULL;
-}
-
-JNIEXPORT jstring JNICALL
NATIVE_NAME (getTextAfterCursor) (JNIEnv *env, jobject object, jshort window,
jint length, jint flags)
{
@@ -4805,8 +4798,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 = 0;
- event.ime.end = 0;
+ event.ime.start = start;
+ event.ime.end = end;
event.ime.length = 0;
event.ime.position = start;
event.ime.text = NULL;
@@ -5068,6 +5061,34 @@ NATIVE_NAME (getExtractedText) (JNIEnv *env, jobject ignored_object,
return object;
}
+JNIEXPORT jstring JNICALL
+NATIVE_NAME (getSelectedText) (JNIEnv *env, jobject object,
+ jshort window)
+{
+ struct android_get_extracted_text_context context;
+ jstring string;
+
+ context.hint_max_chars = -1;
+ context.token = 0;
+ context.text = NULL;
+ context.window = window;
+
+ android_sync_edit ();
+ if (android_run_in_emacs_thread (android_get_extracted_text,
+ &context))
+ return NULL;
+
+ if (!context.text)
+ return NULL;
+
+ /* Encode the returned text. */
+ string = android_text_to_string (env, context.text, context.length,
+ context.bytes);
+ free (context.text);
+
+ return string;
+}
+
#ifdef __clang__
#pragma clang diagnostic pop
#else
@@ -5083,7 +5104,8 @@ NATIVE_NAME (getExtractedText) (JNIEnv *env, jobject ignored_object,
static void
android_update_selection (struct frame *f, struct window *w)
{
- ptrdiff_t start, end, point;
+ ptrdiff_t start, end, point, mark;
+ struct buffer *b;
if (MARKERP (f->conversion.compose_region_start))
{
@@ -5103,12 +5125,20 @@ android_update_selection (struct frame *f, struct window *w)
if (!w)
w = XWINDOW (f->selected_window);
- /* Figure out where the point is. */
+ /* Figure out where the point and mark are. If the mark is not
+ active, then point is set to equal mark. */
+ b = XBUFFER (w->contents);
point = min (w->last_point, TYPE_MAXIMUM (jint));
+ mark = ((!NILP (BVAR (b, mark_active))
+ && w->last_mark != -1)
+ ? min (w->last_mark, TYPE_MAXIMUM (jint))
+ : point);
- /* Send the update. */
- android_update_ic (FRAME_ANDROID_WINDOW (f), point, point,
- start, end);
+ /* 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);
}
/* Notice that the input method connection to F should be reset as a
@@ -5117,16 +5147,32 @@ android_update_selection (struct frame *f, struct window *w)
static void
android_reset_conversion (struct frame *f)
{
+ enum android_ic_mode mode;
+ struct window *w;
+ struct buffer *buffer;
+
/* Reset the input method.
Pick an appropriate ``input mode'' based on whether or not the
minibuffer window is selected; this controls whether or not
``RET'' inserts a newline or sends an actual key event. */
+
+ w = XWINDOW (f->selected_window);
+ buffer = XBUFFER (WINDOW_BUFFER (w));
+
+ if (NILP (BVAR (buffer, text_conversion_style)))
+ mode = ANDROID_IC_MODE_NULL;
+ else if (EQ (BVAR (buffer, text_conversion_style),
+ Qaction))
+ mode = ANDROID_IC_MODE_ACTION;
+ else
+ mode = ANDROID_IC_MODE_TEXT;
+
android_reset_ic (FRAME_ANDROID_WINDOW (f),
(EQ (f->selected_window,
f->minibuffer_window)
? ANDROID_IC_MODE_ACTION
- : ANDROID_IC_MODE_TEXT));
+ : mode));
/* Move its selection to the specified position. */
android_update_selection (f, NULL);