From: Po Lu Date: Thu, 1 Jun 2023 07:16:02 +0000 (+0800) Subject: Update Android port X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=aed0a11147e29fc73405f1815fef91ecf6cca7fb;p=emacs.git Update Android port * java/org/gnu/emacs/EmacsInputConnection.java (EmacsInputConnection, performContextMenuAction): New function. * java/org/gnu/emacs/EmacsNative.java (EmacsNative) (performContextMenuAction): New function. * src/android.c (android_get_gc_values): Implement more efficiently. * src/androidterm.c (android_handle_ime_event): Pass through `update' argument to `finish_composing_text'. Fix thinko. * src/textconv.c (really_finish_composing_text) (really_set_composing_text, really_set_composing_region) (handle_pending_conversion_events_1, finish_composing_text): New argument `update'. Notify IME of conversion region changes if set. * src/textconv.h: Update structs and prototypes. --- diff --git a/java/org/gnu/emacs/EmacsInputConnection.java b/java/org/gnu/emacs/EmacsInputConnection.java index 54c98d950aa..eb6fd5f2763 100644 --- a/java/org/gnu/emacs/EmacsInputConnection.java +++ b/java/org/gnu/emacs/EmacsInputConnection.java @@ -256,6 +256,52 @@ public final class EmacsInputConnection extends BaseInputConnection return true; } + @Override + public boolean + performContextMenuAction (int contextMenuAction) + { + int action; + + if (EmacsService.DEBUG_IC) + Log.d (TAG, "performContextMenuAction: " + contextMenuAction); + + /* Translate the action in Java code. That way, a great deal of + JNI boilerplate can be avoided. */ + + switch (contextMenuAction) + { + case android.R.id.selectAll: + action = 0; + break; + + case android.R.id.startSelectingText: + action = 1; + break; + + case android.R.id.stopSelectingText: + action = 2; + break; + + case android.R.id.cut: + action = 3; + break; + + case android.R.id.copy: + action = 4; + break; + + case android.R.id.paste: + action = 5; + break; + + default: + return true; + } + + EmacsNative.performContextMenuAction (windowHandle, action); + return true; + } + @Override public ExtractedText getExtractedText (ExtractedTextRequest request, int flags) diff --git a/java/org/gnu/emacs/EmacsNative.java b/java/org/gnu/emacs/EmacsNative.java index 56c03ee38dc..eb75201088b 100644 --- a/java/org/gnu/emacs/EmacsNative.java +++ b/java/org/gnu/emacs/EmacsNative.java @@ -208,6 +208,8 @@ public final class EmacsNative public static native void setSelection (short window, int start, int end); public static native void performEditorAction (short window, int editorAction); + public static native void performContextMenuAction (short window, + int contextMenuAction); public static native ExtractedText getExtractedText (short window, ExtractedTextRequest req, int flags); diff --git a/src/android.c b/src/android.c index 67590ae373d..94587344eb5 100644 --- a/src/android.c +++ b/src/android.c @@ -3863,22 +3863,13 @@ android_get_gc_values (struct android_gc *gc, values->clip_y_origin = gc->clip_y_origin; if (mask & ANDROID_GC_FILL_STYLE) - values->fill_style - = (*android_java_env)->GetIntField (android_java_env, - gcontext, - emacs_gc_fill_style); + values->fill_style = gc->fill_style; if (mask & ANDROID_GC_TILE_STIP_X_ORIGIN) - values->ts_x_origin - = (*android_java_env)->GetIntField (android_java_env, - gcontext, - emacs_gc_ts_origin_x); + values->ts_x_origin = gc->ts_x_origin; if (mask & ANDROID_GC_TILE_STIP_Y_ORIGIN) - values->ts_y_origin - = (*android_java_env)->GetIntField (android_java_env, - gcontext, - emacs_gc_ts_origin_y); + values->ts_y_origin = gc->ts_y_origin; /* Fields involving handles are not used by Emacs, and thus not implemented */ diff --git a/src/androidterm.c b/src/androidterm.c index a9b5834c08f..c302e3f2877 100644 --- a/src/androidterm.c +++ b/src/androidterm.c @@ -681,7 +681,6 @@ android_handle_ime_event (union android_event *event, struct frame *f) switch (event->ime.operation) { case ANDROID_IME_COMMIT_TEXT: - case ANDROID_IME_FINISH_COMPOSING_TEXT: case ANDROID_IME_SET_COMPOSING_TEXT: text = android_decode_utf16 (event->ime.text, event->ime.length); @@ -708,7 +707,8 @@ android_handle_ime_event (union android_event *event, struct frame *f) break; case ANDROID_IME_FINISH_COMPOSING_TEXT: - finish_composing_text (f, event->ime.counter); + finish_composing_text (f, event->ime.counter, + event->ime.length); break; case ANDROID_IME_SET_COMPOSING_TEXT: @@ -5161,7 +5161,71 @@ NATIVE_NAME (performEditorAction) (JNIEnv *env, jobject object, /* Undocumented behavior: performEditorAction is apparently expected to finish composing any text. */ - NATIVE_NAME (finishComposingText) (env, object, window); + event.ime.type = ANDROID_INPUT_METHOD; + event.ime.serial = ++event_serial; + event.ime.window = window; + event.ime.operation = ANDROID_IME_FINISH_COMPOSING_TEXT; + event.ime.start = 0; + event.ime.end = 0; + + /* This value of `length' means that the input method should receive + an update containing the new conversion region. */ + + event.ime.length = 1; + event.ime.position = 0; + event.ime.text = NULL; + event.ime.counter = ++edit_counter; + + android_write_event (&event); + + /* Finally, send the return key press. */ + + event.xkey.type = ANDROID_KEY_PRESS; + event.xkey.serial = ++event_serial; + event.xkey.window = window; + event.xkey.time = 0; + event.xkey.state = 0; + event.xkey.keycode = 66; + event.xkey.unicode_char = 0; + + android_write_event (&event); +} + +JNIEXPORT void JNICALL +NATIVE_NAME (performContextMenuAction) (JNIEnv *env, jobject object, + jshort window, int action) +{ + JNI_STACK_ALIGNMENT_PROLOGUE; + + union android_event event; + int key; + + /* Note that ACTION is determined in EmacsInputConnection, and as + such they are not actual resource IDs. */ + + switch (action) + { + case 0: /* android.R.id.selectAll */ + case 1: /* android.R.id.startSelectingText */ + case 2: /* android.R.id.stopSelectingText */ + /* These actions are not implemented. */ + return; + + case 3: /* android.R.id.cut */ + key = 277; + break; + + case 4: /* android.R.id.copy */ + key = 278; + break; + + case 5: /* android.R.id.paste */ + key = 279; + break; + + default: + emacs_abort (); + } event.xkey.type = ANDROID_KEY_PRESS; event.xkey.serial = ++event_serial; diff --git a/src/textconv.c b/src/textconv.c index dcf016104fe..d8166bcfd03 100644 --- a/src/textconv.c +++ b/src/textconv.c @@ -676,10 +676,11 @@ really_commit_text (struct frame *f, EMACS_INT position, } /* Remove the composition region on the frame F, while leaving its - contents intact. */ + contents intact. If UPDATE, also notify the input method of the + change. */ static void -really_finish_composing_text (struct frame *f) +really_finish_composing_text (struct frame *f, bool update) { if (!NILP (f->conversion.compose_region_start)) { @@ -687,6 +688,10 @@ really_finish_composing_text (struct frame *f) Fset_marker (f->conversion.compose_region_end, Qnil, Qnil); f->conversion.compose_region_start = Qnil; f->conversion.compose_region_end = Qnil; + + if (update && text_interface + && text_interface->compose_region_changed) + (*text_interface->compose_region_changed) (f); } /* Delete the composition region overlay. */ @@ -796,7 +801,7 @@ really_set_composing_text (struct frame *f, ptrdiff_t position, the documentation, but is ultimately what programs expect. */ if (!SCHARS (text)) - really_finish_composing_text (f); + really_finish_composing_text (f, false); /* If PT hasn't changed, the conversion region definitely has. Otherwise, redisplay will update the input method instead. */ @@ -838,7 +843,7 @@ really_set_composing_region (struct frame *f, ptrdiff_t start, if (max (0, start) == max (0, end)) { - really_finish_composing_text (f); + really_finish_composing_text (f, false); return; } @@ -1167,7 +1172,7 @@ handle_pending_conversion_events_1 (struct frame *f, break; case TEXTCONV_FINISH_COMPOSING_TEXT: - really_finish_composing_text (f); + really_finish_composing_text (f, !NILP (data)); break; case TEXTCONV_SET_COMPOSING_TEXT: @@ -1360,16 +1365,20 @@ commit_text (struct frame *f, Lisp_Object string, /* Remove the composition region and its overlay from F's current buffer. Leave the text being composed intact. + If UPDATE, call `compose_region_changed' after the region is + removed. + COUNTER means the same as in `start_batch_edit'. */ void -finish_composing_text (struct frame *f, unsigned long counter) +finish_composing_text (struct frame *f, unsigned long counter, + bool update) { struct text_conversion_action *action, **last; action = xmalloc (sizeof *action); action->operation = TEXTCONV_FINISH_COMPOSING_TEXT; - action->data = Qnil; + action->data = update ? Qt : Qnil; action->next = NULL; action->counter = counter; for (last = &f->conversion.actions; *last; last = &(*last)->next) diff --git a/src/textconv.h b/src/textconv.h index 055bf251651..e632a9dddcf 100644 --- a/src/textconv.h +++ b/src/textconv.h @@ -128,7 +128,8 @@ extern void start_batch_edit (struct frame *, unsigned long); extern void end_batch_edit (struct frame *, unsigned long); extern void commit_text (struct frame *, Lisp_Object, ptrdiff_t, unsigned long); -extern void finish_composing_text (struct frame *, unsigned long); +extern void finish_composing_text (struct frame *, unsigned long, + bool); extern void set_composing_text (struct frame *, Lisp_Object, ptrdiff_t, unsigned long); extern void set_composing_region (struct frame *, ptrdiff_t, ptrdiff_t,