]> git.eshelyaron.com Git - emacs.git/commitdiff
Update Android port
authorPo Lu <luangruo@yahoo.com>
Thu, 1 Jun 2023 07:16:02 +0000 (15:16 +0800)
committerPo Lu <luangruo@yahoo.com>
Thu, 1 Jun 2023 07:16:02 +0000 (15:16 +0800)
* 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.

java/org/gnu/emacs/EmacsInputConnection.java
java/org/gnu/emacs/EmacsNative.java
src/android.c
src/androidterm.c
src/textconv.c
src/textconv.h

index 54c98d950aa498bbb5ba719809db637734d6f05e..eb6fd5f2763916c4d623be644c031da9a6b024f9 100644 (file)
@@ -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)
index 56c03ee38dca9767ccd10f4162edad7b4c064244..eb75201088b42fb5f40f7c229dca78df778aabe7 100644 (file)
@@ -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);
index 67590ae373d09d9207805cb8fb4c7468bdc5d819..94587344eb5343b389329fc715a43fe4b665c443 100644 (file)
@@ -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 */
index a9b5834c08f619b1b264f15635723c033a603986..c302e3f287752465643a5f1e502a6c637097e48a 100644 (file)
@@ -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;
index dcf016104fea50433aa6f220056ee845199a37ee..d8166bcfd03d85872212ab8ba10a84a8ff4e7987 100644 (file)
@@ -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)
index 055bf25165123aa1a0adeebca4d6d4c4a878d314..e632a9dddcff41056774c214bb79558b62784038 100644 (file)
@@ -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,