root/src/androidterm.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. android_window_to_frame
  2. android_clear_frame
  3. android_show_hourglass
  4. android_hide_hourglass
  5. android_flash
  6. android_ring_bell
  7. make_invisible_cursor
  8. android_toggle_visible_pointer
  9. android_toggle_invisible_pointer
  10. android_update_begin
  11. android_update_end
  12. show_back_buffer
  13. android_flush_dirty_back_buffer_on
  14. android_android_to_emacs_modifiers
  15. android_emacs_to_android_modifiers
  16. android_lower_frame
  17. android_raise_frame
  18. android_new_focus_frame
  19. android_focus_changed
  20. android_detect_focus_change
  21. android_note_mouse_movement
  22. mouse_or_wdesc_frame
  23. android_construct_mouse_click
  24. android_update_tools
  25. android_find_tool
  26. android_decode_utf16
  27. android_request_cursor_updates
  28. android_handle_ime_event
  29. handle_one_android_event
  30. android_read_socket
  31. android_frame_up_to_date
  32. android_buffer_flipping_unblocked_hook
  33. android_query_frame_background_color
  34. android_parse_color
  35. android_alloc_nearest_color
  36. android_query_colors
  37. android_mouse_position
  38. android_get_focus_frame
  39. android_focus_frame
  40. android_frame_highlight
  41. android_frame_unhighlight
  42. android_frame_rehighlight
  43. android_frame_rehighlight_hook
  44. android_frame_raise_lower
  45. android_make_frame_visible
  46. android_make_frame_invisible
  47. android_make_frame_visible_invisible
  48. android_fullscreen_hook
  49. android_iconify_frame
  50. android_wait_for_event
  51. android_set_window_size_1
  52. android_set_window_size
  53. android_set_offset
  54. android_set_alpha
  55. android_new_font
  56. android_bitmap_icon
  57. android_free_pixmap_hook
  58. android_free_frame_resources
  59. android_delete_frame
  60. android_delete_terminal
  61. android_scroll_run
  62. android_after_update_window_line
  63. android_flip_and_flush
  64. android_clear_rectangle
  65. android_reset_clip_rectangles
  66. android_clip_to_row
  67. android_draw_fringe_bitmap
  68. android_set_cursor_gc
  69. android_set_mouse_face_gc
  70. android_set_mode_line_face_gc
  71. android_set_glyph_string_gc
  72. android_set_glyph_string_clipping
  73. android_set_glyph_string_clipping_exactly
  74. android_compute_glyph_string_overhangs
  75. android_clear_glyph_string_rect
  76. android_draw_glyph_string_background
  77. android_fill_triangle
  78. android_make_point
  79. android_inside_rect_p
  80. android_clear_point
  81. android_draw_relief_rect
  82. android_draw_box_rect
  83. android_alloc_lighter_color
  84. android_setup_relief_color
  85. android_setup_relief_colors
  86. android_draw_glyph_string_box
  87. android_draw_glyph_string_bg_rect
  88. android_draw_image_relief
  89. android_draw_image_foreground
  90. android_draw_image_glyph_string
  91. android_draw_stretch_glyph_string
  92. android_get_scale_factor
  93. android_draw_underwave
  94. android_draw_glyph_string_foreground
  95. android_draw_composite_glyph_string_foreground
  96. android_draw_glyphless_glyph_string_foreground
  97. android_draw_glyph_string
  98. android_define_frame_cursor
  99. android_clear_frame_area
  100. android_clear_under_internal_border
  101. android_draw_hollow_cursor
  102. android_draw_bar_cursor
  103. android_draw_window_cursor
  104. android_draw_vertical_window_border
  105. android_draw_window_divider
  106. android_sync_edit
  107. android_copy_java_string
  108. android_perform_conversion_query
  109. android_text_to_string
  110. android_get_selection
  111. android_get_extracted_text
  112. android_build_extracted_text
  113. android_get_surrounding_text
  114. android_get_surrounding_text_internal
  115. android_update_selection
  116. android_event_is_for_frame
  117. android_reset_conversion
  118. android_set_point
  119. android_compose_region_changed
  120. android_notify_conversion
  121. frame_set_mouse_pixel_position
  122. get_keysym_name
  123. android_create_terminal
  124. android_term_init
  125. android_set_build_fingerprint
  126. syms_of_androidterm
  127. mark_androidterm

     1 /* Communication module for Android terminals.
     2 
     3 Copyright (C) 2023 Free Software Foundation, Inc.
     4 
     5 This file is part of GNU Emacs.
     6 
     7 GNU Emacs is free software: you can redistribute it and/or modify
     8 it under the terms of the GNU General Public License as published by
     9 the Free Software Foundation, either version 3 of the License, or (at
    10 your option) any later version.
    11 
    12 GNU Emacs is distributed in the hope that it will be useful,
    13 but WITHOUT ANY WARRANTY; without even the implied warranty of
    14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    15 GNU General Public License for more details.
    16 
    17 You should have received a copy of the GNU General Public License
    18 along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
    19 
    20 #include <config.h>
    21 #include <stdio.h>
    22 #include <math.h>
    23 #include <stdlib.h>
    24 #include <assert.h>
    25 #include <semaphore.h>
    26 
    27 #include "lisp.h"
    28 #include "androidterm.h"
    29 #include "keyboard.h"
    30 #include "blockinput.h"
    31 #include "android.h"
    32 #include "buffer.h"
    33 #include "window.h"
    34 #include "textconv.h"
    35 #include "coding.h"
    36 #include "pdumper.h"
    37 
    38 /* This is a chain of structures for all the X displays currently in
    39    use.  */
    40 
    41 struct android_display_info *x_display_list;
    42 
    43 
    44 
    45 /* Android terminal interface functions.  */
    46 
    47 #ifndef ANDROID_STUBIFY
    48 
    49 #include <android/log.h>
    50 
    51 /* Non-zero means that a HELP_EVENT has been generated since Emacs
    52    start.  */
    53 
    54 static bool any_help_event_p;
    55 
    56 /* Counters for tallying up scroll wheel events if
    57    mwheel_coalesce_scroll_events is true.  */
    58 
    59 static double wheel_event_x, wheel_event_y;
    60 
    61 enum
    62   {
    63     ANDROID_EVENT_NORMAL,
    64     ANDROID_EVENT_GOTO_OUT,
    65     ANDROID_EVENT_DROP,
    66   };
    67 
    68 /* Find the frame whose window has the identifier WDESC.
    69 
    70    This is like x_window_to_frame in xterm.c, except that DPYINFO may
    71    be NULL, as there is only at most one Android display, and is only
    72    specified in order to stay consistent with X.  */
    73 
    74 static struct frame *
    75 android_window_to_frame (struct android_display_info *dpyinfo,
    76                          android_window wdesc)
    77 {
    78   Lisp_Object tail, frame;
    79   struct frame *f;
    80 
    81   if (wdesc == ANDROID_NONE)
    82     return NULL;
    83 
    84   FOR_EACH_FRAME (tail, frame)
    85     {
    86       f = XFRAME (frame);
    87 
    88       if (!FRAME_ANDROID_P (f))
    89         continue;
    90 
    91       if (FRAME_ANDROID_WINDOW (f) == wdesc)
    92         return f;
    93     }
    94 
    95   return NULL;
    96 }
    97 
    98 static void
    99 android_clear_frame (struct frame *f)
   100 {
   101   /* Clearing the frame will erase any cursor, so mark them all as no
   102      longer visible.  */
   103   mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f)));
   104   android_clear_window (FRAME_ANDROID_DRAWABLE (f));
   105 }
   106 
   107 static void
   108 android_show_hourglass (struct frame *f)
   109 {
   110   struct android_output *x;
   111 
   112   /* This isn't implemented like X because a window brings alongside
   113      too many unneeded resources.  */
   114 
   115   x = FRAME_ANDROID_OUTPUT (f);
   116 
   117   /* If the hourglass window is mapped inside a popup menu, input
   118      could be lost if the menu is popped down and the grab is
   119      relinquished, but the hourglass window is still up.  Just
   120      avoid displaying the hourglass at all while popups are
   121      active.  */
   122 
   123   if (popup_activated ())
   124     return;
   125 
   126   x->hourglass = true;
   127 
   128   if (!f->pointer_invisible)
   129     android_define_cursor (FRAME_ANDROID_WINDOW (f),
   130                            x->hourglass_cursor);
   131 }
   132 
   133 static void
   134 android_hide_hourglass (struct frame *f)
   135 {
   136   struct android_output *x;
   137 
   138   x = FRAME_ANDROID_OUTPUT (f);
   139   x->hourglass = false;
   140 
   141   if (!f->pointer_invisible)
   142     android_define_cursor (FRAME_ANDROID_WINDOW (f),
   143                            x->current_cursor);
   144 }
   145 
   146 static void
   147 android_flash (struct frame *f)
   148 {
   149   struct android_gc *gc;
   150   struct android_gc_values values;
   151   int rc;
   152   fd_set fds;
   153 
   154   block_input ();
   155 
   156   values.function = ANDROID_GC_XOR;
   157   values.foreground = (FRAME_FOREGROUND_PIXEL (f)
   158                        ^ FRAME_BACKGROUND_PIXEL (f));
   159 
   160   gc = android_create_gc ((ANDROID_GC_FUNCTION
   161                            | ANDROID_GC_FOREGROUND),
   162                           &values);
   163 
   164   /* Get the height not including a menu bar widget.  */
   165   int height = FRAME_PIXEL_HEIGHT (f);
   166   /* Height of each line to flash.  */
   167   int flash_height = FRAME_LINE_HEIGHT (f);
   168   /* These will be the left and right margins of the rectangles.  */
   169   int flash_left = FRAME_INTERNAL_BORDER_WIDTH (f);
   170   int flash_right = FRAME_PIXEL_WIDTH (f) - FRAME_INTERNAL_BORDER_WIDTH (f);
   171   int width = flash_right - flash_left;
   172 
   173   /* If window is tall, flash top and bottom line.  */
   174   if (height > 3 * FRAME_LINE_HEIGHT (f))
   175     {
   176       android_fill_rectangle (FRAME_ANDROID_DRAWABLE (f), gc,
   177                               flash_left,
   178                               (FRAME_INTERNAL_BORDER_WIDTH (f)
   179                                + FRAME_TOP_MARGIN_HEIGHT (f)),
   180                               width, flash_height);
   181       android_fill_rectangle (FRAME_ANDROID_DRAWABLE (f), gc,
   182                               flash_left,
   183                               (height - flash_height
   184                                - FRAME_INTERNAL_BORDER_WIDTH (f)
   185                                - FRAME_BOTTOM_MARGIN_HEIGHT (f)),
   186                               width, flash_height);
   187 
   188     }
   189   else
   190     /* If it is short, flash it all.  */
   191     android_fill_rectangle (FRAME_ANDROID_DRAWABLE (f), gc,
   192                             flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
   193                             width, (height - 2
   194                                     * FRAME_INTERNAL_BORDER_WIDTH (f)));
   195 
   196   flush_frame (f);
   197 
   198   struct timespec delay = make_timespec (0, 150 * 1000 * 1000);
   199   struct timespec wakeup = timespec_add (current_timespec (), delay);
   200 
   201   /* Keep waiting until past the time wakeup or any input gets
   202      available.  */
   203   while (! detect_input_pending ())
   204     {
   205       struct timespec current = current_timespec ();
   206       struct timespec timeout;
   207 
   208       /* Break if result would not be positive.  */
   209       if (timespec_cmp (wakeup, current) <= 0)
   210         break;
   211 
   212       /* How long `select' should wait.  */
   213       timeout = make_timespec (0, 10 * 1000 * 1000);
   214 
   215       /* Wait for some input to become available on the X
   216          connection.  */
   217       FD_ZERO (&fds);
   218 
   219       /* Try to wait that long--but we might wake up sooner.  */
   220       rc = pselect (0, &fds, NULL, NULL, &timeout, NULL);
   221 
   222       /* Some input is available, exit the visible bell.  */
   223       if (rc >= 0)
   224         break;
   225     }
   226 
   227   /* If window is tall, flash top and bottom line.  */
   228   if (height > 3 * FRAME_LINE_HEIGHT (f))
   229     {
   230       android_fill_rectangle (FRAME_ANDROID_DRAWABLE (f), gc,
   231                               flash_left,
   232                               (FRAME_INTERNAL_BORDER_WIDTH (f)
   233                                + FRAME_TOP_MARGIN_HEIGHT (f)),
   234                               width, flash_height);
   235       android_fill_rectangle (FRAME_ANDROID_DRAWABLE (f), gc,
   236                               flash_left,
   237                               (height - flash_height
   238                                - FRAME_INTERNAL_BORDER_WIDTH (f)
   239                                - FRAME_BOTTOM_MARGIN_HEIGHT (f)),
   240                               width, flash_height);
   241     }
   242   else
   243     /* If it is short, flash it all.  */
   244     android_fill_rectangle (FRAME_ANDROID_DRAWABLE (f), gc,
   245                             flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
   246                             width, (height - 2
   247                                     * FRAME_INTERNAL_BORDER_WIDTH (f)));
   248 
   249   android_free_gc (gc);
   250   flush_frame (f);
   251 
   252   unblock_input ();
   253 }
   254 
   255 static void
   256 android_ring_bell (struct frame *f)
   257 {
   258   if (visible_bell)
   259     android_flash (f);
   260   else
   261     {
   262       block_input ();
   263       android_bell ();
   264       unblock_input ();
   265     }
   266 }
   267 
   268 static android_cursor
   269 make_invisible_cursor (struct android_display_info *dpyinfo)
   270 {
   271   return android_create_font_cursor (ANDROID_XC_NULL);
   272 }
   273 
   274 static void
   275 android_toggle_visible_pointer (struct frame *f, bool invisible)
   276 {
   277   struct android_display_info *dpyinfo;
   278 
   279   dpyinfo = FRAME_DISPLAY_INFO (f);
   280 
   281   if (!dpyinfo->invisible_cursor)
   282     dpyinfo->invisible_cursor = make_invisible_cursor (dpyinfo);
   283 
   284   if (invisible)
   285     android_define_cursor (FRAME_ANDROID_WINDOW (f),
   286                            dpyinfo->invisible_cursor);
   287   else
   288     android_define_cursor (FRAME_ANDROID_WINDOW (f),
   289                            (FRAME_ANDROID_OUTPUT (f)->hourglass
   290                             ? f->output_data.android->hourglass_cursor
   291                             : f->output_data.android->current_cursor));
   292 
   293   f->pointer_invisible = invisible;
   294 }
   295 
   296 static void
   297 android_toggle_invisible_pointer (struct frame *f, bool invisible)
   298 {
   299   block_input ();
   300   android_toggle_visible_pointer (f, invisible);
   301   unblock_input ();
   302 }
   303 
   304 /* Start an update of frame F.  This function is installed as a hook
   305    for update_begin, i.e. it is called when update_begin is called.
   306    This function is called prior to calls to gui_update_window_begin
   307    for each window being updated.  Currently, there is nothing to do
   308    here because all interesting stuff is done on a window basis.  */
   309 
   310 static void
   311 android_update_begin (struct frame *f)
   312 {
   313   /* The frame is no longer complete, as it is in the midst of an
   314      update.  */
   315   FRAME_ANDROID_COMPLETE_P (f) = false;
   316 }
   317 
   318 /* End update of frame F.  This function is installed as a hook in
   319    update_end.  */
   320 
   321 static void
   322 android_update_end (struct frame *f)
   323 {
   324   /* Mouse highlight may be displayed again.  */
   325   MOUSE_HL_INFO (f)->mouse_face_defer = false;
   326 }
   327 
   328 static void
   329 show_back_buffer (struct frame *f)
   330 {
   331   struct android_swap_info swap_info;
   332 
   333   memset (&swap_info, 0, sizeof (swap_info));
   334   swap_info.swap_window = FRAME_ANDROID_WINDOW (f);
   335   swap_info.swap_action = ANDROID_COPIED;
   336   android_swap_buffers (&swap_info, 1);
   337 
   338   /* Now the back buffer no longer needs to be flipped.  */
   339   FRAME_ANDROID_NEED_BUFFER_FLIP (f) = false;
   340 }
   341 
   342 /* Flip back buffers on F if it has undrawn content.  */
   343 
   344 static void
   345 android_flush_dirty_back_buffer_on (struct frame *f)
   346 {
   347   if (FRAME_GARBAGED_P (f)
   348       || buffer_flipping_blocked_p ()
   349       /* If the frame is not already up to date, do not flush buffers
   350          on input, as that will result in flicker.  */
   351       || !FRAME_ANDROID_COMPLETE_P (f)
   352       || !FRAME_ANDROID_NEED_BUFFER_FLIP (f))
   353     return;
   354 
   355   show_back_buffer (f);
   356 }
   357 
   358 /* Convert between the modifier bits Android uses and the modifier
   359    bits Emacs uses.  */
   360 
   361 static int
   362 android_android_to_emacs_modifiers (struct android_display_info *dpyinfo,
   363                                     int state)
   364 {
   365   return (((state & ANDROID_CONTROL_MASK) ? ctrl_modifier  : 0)
   366           | ((state & ANDROID_SHIFT_MASK) ? shift_modifier : 0)
   367           | ((state & ANDROID_ALT_MASK)   ? meta_modifier  : 0)
   368           | ((state & ANDROID_SUPER_MASK) ? super_modifier : 0)
   369           | ((state & ANDROID_META_MASK)  ? alt_modifier   : 0));
   370 }
   371 
   372 static int
   373 android_emacs_to_android_modifiers (struct android_display_info *dpyinfo,
   374                                     intmax_t state)
   375 {
   376   return (((state & ctrl_modifier)    ? ANDROID_CONTROL_MASK : 0)
   377           | ((state & shift_modifier) ? ANDROID_SHIFT_MASK   : 0)
   378           | ((state & meta_modifier)  ? ANDROID_ALT_MASK     : 0)
   379           | ((state & super_modifier) ? ANDROID_SUPER_MASK   : 0)
   380           | ((state & alt_modifier)   ? ANDROID_META_MASK    : 0));
   381 }
   382 
   383 static void android_frame_rehighlight (struct android_display_info *);
   384 
   385 static void
   386 android_lower_frame (struct frame *f)
   387 {
   388   android_lower_window (FRAME_ANDROID_WINDOW (f));
   389 }
   390 
   391 static void
   392 android_raise_frame (struct frame *f)
   393 {
   394   android_raise_window (FRAME_ANDROID_WINDOW (f));
   395 }
   396 
   397 static void
   398 android_new_focus_frame (struct android_display_info *dpyinfo,
   399                          struct frame *frame)
   400 {
   401   struct frame *old_focus;
   402 
   403   old_focus = dpyinfo->focus_frame;
   404 
   405   if (frame != dpyinfo->focus_frame)
   406     {
   407       /* Set this before calling other routines, so that they see
   408          the correct value of x_focus_frame.  */
   409       dpyinfo->focus_frame = frame;
   410 
   411       if (old_focus && old_focus->auto_lower)
   412         android_lower_frame (old_focus);
   413 
   414       if (dpyinfo->focus_frame && dpyinfo->focus_frame->auto_raise)
   415         dpyinfo->pending_autoraise_frame = dpyinfo->focus_frame;
   416       else
   417         dpyinfo->pending_autoraise_frame = NULL;
   418     }
   419 
   420   android_frame_rehighlight (dpyinfo);
   421 }
   422 
   423 static void
   424 android_focus_changed (int type, int state,
   425                        struct android_display_info *dpyinfo,
   426                        struct frame *frame, struct input_event *bufp)
   427 {
   428   if (type == ANDROID_FOCUS_IN)
   429     {
   430       if (dpyinfo->x_focus_event_frame != frame)
   431         {
   432           android_new_focus_frame (dpyinfo, frame);
   433           dpyinfo->x_focus_event_frame = frame;
   434           bufp->kind = FOCUS_IN_EVENT;
   435           XSETFRAME (bufp->frame_or_window, frame);
   436         }
   437 
   438       frame->output_data.android->focus_state |= state;
   439     }
   440   else if (type == ANDROID_FOCUS_OUT)
   441     {
   442       frame->output_data.android->focus_state &= ~state;
   443 
   444       if (dpyinfo->x_focus_event_frame == frame)
   445         {
   446           dpyinfo->x_focus_event_frame = 0;
   447           android_new_focus_frame (dpyinfo, 0);
   448 
   449           bufp->kind = FOCUS_OUT_EVENT;
   450           XSETFRAME (bufp->frame_or_window, frame);
   451         }
   452 
   453       if (frame->pointer_invisible)
   454         android_toggle_invisible_pointer (frame, false);
   455     }
   456 }
   457 
   458 static void
   459 android_detect_focus_change (struct android_display_info *dpyinfo,
   460                              struct frame *frame,
   461                              union android_event *event,
   462                              struct input_event *bufp)
   463 {
   464   if (!frame)
   465     return;
   466 
   467   switch (event->type)
   468     {
   469     case ANDROID_FOCUS_IN:
   470     case ANDROID_FOCUS_OUT:
   471       android_focus_changed (event->type, FOCUS_EXPLICIT,
   472                              dpyinfo, frame, bufp);
   473       break;
   474 
   475     default:
   476       break;
   477     }
   478 }
   479 
   480 static bool
   481 android_note_mouse_movement (struct frame *frame,
   482                              struct android_motion_event *event)
   483 {
   484   struct android_display_info *dpyinfo;
   485   Emacs_Rectangle *r;
   486 
   487   if (!FRAME_ANDROID_OUTPUT (frame))
   488     return false;
   489 
   490   dpyinfo = FRAME_DISPLAY_INFO (frame);
   491   dpyinfo->last_mouse_motion_frame = frame;
   492   dpyinfo->last_mouse_motion_x = event->x;
   493   dpyinfo->last_mouse_motion_y = event->y;
   494   dpyinfo->last_mouse_movement_time = event->time;
   495 
   496   /* Has the mouse moved off the glyph it was on at the last sighting?  */
   497   r = &dpyinfo->last_mouse_glyph;
   498   if (frame != dpyinfo->last_mouse_glyph_frame
   499       || event->x < r->x || event->x >= r->x + r->width
   500       || event->y < r->y || event->y >= r->y + r->height)
   501     {
   502       frame->mouse_moved = true;
   503       note_mouse_highlight (frame, event->x, event->y);
   504       /* Remember which glyph we're now on.  */
   505       remember_mouse_glyph (frame, event->x, event->y, r);
   506       dpyinfo->last_mouse_glyph_frame = frame;
   507       return true;
   508     }
   509 
   510   return false;
   511 }
   512 
   513 static struct frame *
   514 mouse_or_wdesc_frame (struct android_display_info *dpyinfo, int wdesc)
   515 {
   516   struct frame *lm_f = (gui_mouse_grabbed (dpyinfo)
   517                         ? dpyinfo->last_mouse_frame
   518                         : NULL);
   519 
   520   if (lm_f && !EQ (track_mouse, Qdropping)
   521       && !EQ (track_mouse, Qdrag_source))
   522     return lm_f;
   523   else
   524     {
   525       struct frame *w_f = android_window_to_frame (dpyinfo, wdesc);
   526 
   527       /* Do not return a tooltip frame.  */
   528       if (!w_f || FRAME_TOOLTIP_P (w_f))
   529         return EQ (track_mouse, Qdropping) ? lm_f : NULL;
   530       else
   531         /* When dropping it would be probably nice to raise w_f
   532            here.  */
   533         return w_f;
   534     }
   535 }
   536 
   537 static Lisp_Object
   538 android_construct_mouse_click (struct input_event *result,
   539                                struct android_button_event *event,
   540                                struct frame *f)
   541 {
   542   struct android_display_info *dpyinfo;
   543   int x, y;
   544 
   545   dpyinfo = FRAME_DISPLAY_INFO (f);
   546   x = event->x;
   547   y = event->y;
   548 
   549   /* Make the event type NO_EVENT; we'll change that when we decide
   550      otherwise.  */
   551   result->kind = MOUSE_CLICK_EVENT;
   552   result->code = event->button - 1;
   553   result->timestamp = event->time;
   554   result->modifiers = (android_android_to_emacs_modifiers (dpyinfo,
   555                                                            event->state)
   556                        | (event->type == ANDROID_BUTTON_RELEASE
   557                           ? up_modifier : down_modifier));
   558 
   559   XSETINT (result->x, x);
   560   XSETINT (result->y, y);
   561   XSETFRAME (result->frame_or_window, f);
   562   result->arg = Qnil;
   563   return Qnil;
   564 }
   565 
   566 /* Generate a TOUCHSCREEN_UPDATE_EVENT for all pressed tools in FRAME.
   567    Return the event in IE.  Do not set IE->timestamp, as that is left
   568    to the caller.  */
   569 
   570 static void
   571 android_update_tools (struct frame *f, struct input_event *ie)
   572 {
   573   struct android_touch_point *touchpoint;
   574 
   575   ie->kind = TOUCHSCREEN_UPDATE_EVENT;
   576   XSETFRAME (ie->frame_or_window, f);
   577   ie->arg = Qnil;
   578 
   579   /* Build the list of active touches.  */
   580   for (touchpoint = FRAME_OUTPUT_DATA (f)->touch_points;
   581        touchpoint; touchpoint = touchpoint->next)
   582     {
   583       /* Skip touch points which originated on the tool bar.  */
   584 
   585       if (touchpoint->tool_bar_p)
   586         continue;
   587 
   588       ie->arg = Fcons (list3i (touchpoint->x,
   589                                touchpoint->y,
   590                                touchpoint->tool_id),
   591                        ie->arg);
   592     }
   593 }
   594 
   595 /* Find and return an existing tool pressed against FRAME, identified
   596    by POINTER_ID.  Return NULL if no tool by that ID was found.  */
   597 
   598 static struct android_touch_point *
   599 android_find_tool (struct frame *f, int pointer_id)
   600 {
   601   struct android_touch_point *touchpoint;
   602 
   603   for (touchpoint = FRAME_OUTPUT_DATA (f)->touch_points;
   604        touchpoint; touchpoint = touchpoint->next)
   605     {
   606       if (touchpoint->tool_id == pointer_id)
   607         return touchpoint;
   608     }
   609 
   610   return NULL;
   611 }
   612 
   613 /* Decode STRING, an array of N little endian UTF-16 characters, into
   614    a Lisp string.  Return Qnil if the string is too large, and the
   615    encoded string otherwise.  */
   616 
   617 static Lisp_Object
   618 android_decode_utf16 (unsigned short *utf16, size_t n)
   619 {
   620   struct coding_system coding;
   621   ptrdiff_t size;
   622 
   623   if (INT_MULTIPLY_WRAPV (n, sizeof *utf16, &size))
   624     return Qnil;
   625 
   626   /* Set up the coding system.  Decoding a UTF-16 string (with no BOM)
   627      should not signal.  */
   628 
   629   memset (&coding, 0, sizeof coding);
   630 
   631   setup_coding_system (Qutf_16le, &coding);
   632   coding.source = (const unsigned char *) utf16;
   633   decode_coding_object (&coding, Qnil, 0, 0, size,
   634                         size, Qt);
   635 
   636   return coding.dst_object;
   637 }
   638 
   639 /* Handle a cursor update request for F from the input method.
   640    MODE specifies whether or not an update should be sent immediately,
   641    and whether or not they are needed in the future.
   642 
   643    If MODE & ANDROID_CURSOR_UPDATE_IMMEDIATE, report the position of
   644    F's old selected window's phys cursor now.
   645 
   646    If MODE & ANDROID_CURSOR_UPDATE_MONITOR, set
   647    `need_cursor_updates'.  */
   648 
   649 static void
   650 android_request_cursor_updates (struct frame *f, int mode)
   651 {
   652   struct window *w;
   653 
   654   if (mode & ANDROID_CURSOR_UPDATE_IMMEDIATE
   655       && WINDOWP (WINDOW_LIVE_P (f->old_selected_window)
   656                   ? f->old_selected_window
   657                   : f->selected_window))
   658     {
   659       /* Prefer the old selected window, as its selection is what was
   660          reported to the IME previously.  */
   661 
   662       w = XWINDOW (WINDOW_LIVE_P (f->old_selected_window)
   663                    ? f->old_selected_window
   664                    : f->selected_window);
   665       android_set_preeditarea (w, w->cursor.x, w->cursor.y);
   666     }
   667 
   668   /* Now say whether or not updates are needed in the future.  */
   669   FRAME_OUTPUT_DATA (f)->need_cursor_updates
   670     = (mode & ANDROID_CURSOR_UPDATE_MONITOR);
   671 }
   672 
   673 /* Handle a single input method event EVENT, delivered to the frame
   674    F.
   675 
   676    Perform the text conversion action specified inside.  */
   677 
   678 static void
   679 android_handle_ime_event (union android_event *event, struct frame *f)
   680 {
   681   Lisp_Object text UNINIT;
   682   struct android_output *output;
   683 
   684   /* First, decode the text if necessary.  */
   685 
   686   switch (event->ime.operation)
   687     {
   688     case ANDROID_IME_COMMIT_TEXT:
   689     case ANDROID_IME_SET_COMPOSING_TEXT:
   690       text = android_decode_utf16 (event->ime.text,
   691                                    event->ime.length);
   692       xfree (event->ime.text);
   693       break;
   694 
   695     default:
   696       break;
   697     }
   698 
   699   /* Finally, perform the appropriate conversion action.  */
   700 
   701   switch (event->ime.operation)
   702     {
   703     case ANDROID_IME_COMMIT_TEXT:
   704       commit_text (f, text, event->ime.position,
   705                    event->ime.counter);
   706       break;
   707 
   708     case ANDROID_IME_DELETE_SURROUNDING_TEXT:
   709       delete_surrounding_text (f, event->ime.start,
   710                                event->ime.end,
   711                                event->ime.counter);
   712       break;
   713 
   714     case ANDROID_IME_FINISH_COMPOSING_TEXT:
   715 
   716       if (event->ime.length == 2)
   717         {
   718           output = FRAME_ANDROID_OUTPUT (f);
   719 
   720           /* A new input method has connected to Emacs.  Stop
   721              reporting changes that the previous input method has
   722              asked to monitor.  */
   723 
   724           output->extracted_text_flags = 0;
   725           output->extracted_text_token = 0;
   726           output->extracted_text_hint = 0;
   727           output->need_cursor_updates = false;
   728         }
   729 
   730       finish_composing_text (f, event->ime.counter,
   731                              event->ime.length == 1);
   732 
   733       if (event->ime.length == 2)
   734         {
   735           /* Now cancel outstanding batch edits if a new input method
   736              has connected.  */
   737 
   738           f->conversion.batch_edit_flags = 0;
   739           f->conversion.batch_edit_count = 0;
   740         }
   741 
   742       break;
   743 
   744     case ANDROID_IME_SET_COMPOSING_TEXT:
   745       set_composing_text (f, text, event->ime.position,
   746                           event->ime.counter);
   747       break;
   748 
   749     case ANDROID_IME_SET_COMPOSING_REGION:
   750       set_composing_region (f, event->ime.start,
   751                             event->ime.end,
   752                             event->ime.counter);
   753       break;
   754 
   755     case ANDROID_IME_SET_POINT:
   756       textconv_set_point_and_mark (f, event->ime.start,
   757                                    event->ime.end,
   758                                    event->ime.counter);
   759       break;
   760 
   761     case ANDROID_IME_START_BATCH_EDIT:
   762       start_batch_edit (f, event->ime.counter);
   763       break;
   764 
   765     case ANDROID_IME_END_BATCH_EDIT:
   766       end_batch_edit (f, event->ime.counter);
   767       break;
   768 
   769     case ANDROID_IME_REQUEST_SELECTION_UPDATE:
   770       request_point_update (f, event->ime.counter);
   771       break;
   772 
   773     case ANDROID_IME_REQUEST_CURSOR_UPDATES:
   774       android_request_cursor_updates (f, event->ime.length);
   775       break;
   776     }
   777 }
   778 
   779 
   780 
   781 /* Forward declaration.  */
   782 static void android_notify_conversion (unsigned long);
   783 
   784 static int
   785 handle_one_android_event (struct android_display_info *dpyinfo,
   786                           union android_event *event, int *finish,
   787                           struct input_event *hold_quit)
   788 {
   789   union android_event configureEvent;
   790   struct frame *f, *any, *mouse_frame;
   791   Mouse_HLInfo *hlinfo;
   792   union buffered_input_event inev;
   793   int modifiers, count, do_help;
   794   struct android_touch_point *touchpoint, **last;
   795   Lisp_Object window;
   796   int scroll_height;
   797   double scroll_unit;
   798   int keysym;
   799   ptrdiff_t nchars, i;
   800   struct window *w;
   801 
   802   /* It is okay for this to not resemble handle_one_xevent so much.
   803      Differences in event handling code are much less nasty than
   804      stuble differences in the graphics code.  */
   805 
   806   do_help = count = 0;
   807   hlinfo = &dpyinfo->mouse_highlight;
   808   *finish = ANDROID_EVENT_NORMAL;
   809   any = android_window_to_frame (dpyinfo, event->xany.window);
   810   nchars = 0;
   811 
   812   if (any && any->wait_event_type == event->type)
   813     any->wait_event_type = 0; /* Indicates we got it.  */
   814 
   815   EVENT_INIT (inev.ie);
   816 
   817   switch (event->type)
   818     {
   819     case ANDROID_CONFIGURE_NOTIFY:
   820       configureEvent = *event;
   821 
   822       f = android_window_to_frame (dpyinfo,
   823                                    configureEvent.xconfigure.window);
   824 
   825       if (!f)
   826         goto OTHER;
   827 
   828       if (FRAME_TOOLTIP_P (f))
   829         {
   830           if (FRAME_PIXEL_HEIGHT (f) != configureEvent.xconfigure.height
   831               || FRAME_PIXEL_WIDTH (f) != configureEvent.xconfigure.width)
   832             SET_FRAME_GARBAGED (f);
   833 
   834           FRAME_PIXEL_HEIGHT (f) = configureEvent.xconfigure.height;
   835           FRAME_PIXEL_WIDTH (f) = configureEvent.xconfigure.width;
   836         }
   837 
   838       int width = configureEvent.xconfigure.width;
   839       int height = configureEvent.xconfigure.height;
   840 
   841       if (CONSP (frame_size_history))
   842         frame_size_history_extra (f, build_string ("ConfigureNotify"),
   843                                   FRAME_PIXEL_WIDTH (f),
   844                                   FRAME_PIXEL_HEIGHT (f),
   845                                   width, height, f->new_width,
   846                                   f->new_height);
   847 
   848       /* Even if the number of character rows and columns has
   849          not changed, the font size may have changed, so we need
   850          to check the pixel dimensions as well.  */
   851 
   852       if (width != FRAME_PIXEL_WIDTH (f)
   853           || height != FRAME_PIXEL_HEIGHT (f)
   854           || (f->new_size_p
   855               && ((f->new_width >= 0 && width != f->new_width)
   856                   || (f->new_height >= 0 && height != f->new_height))))
   857         {
   858           change_frame_size (f, width, height, false, true, false);
   859           android_clear_under_internal_border (f);
   860           SET_FRAME_GARBAGED (f);
   861           cancel_mouse_face (f);
   862         }
   863 
   864       /* Now change the left and top position of this window.  */
   865 
   866       {
   867         int old_left = f->left_pos;
   868         int old_top = f->top_pos;
   869         Lisp_Object frame;
   870 
   871         XSETFRAME (frame, f);
   872 
   873         {
   874           android_window root;
   875           unsigned int dummy_uint;
   876 
   877           android_get_geometry (FRAME_ANDROID_WINDOW (f),
   878                                 &root, &f->left_pos, &f->top_pos,
   879                                 &dummy_uint, &dummy_uint,
   880                                 &dummy_uint);
   881         }
   882 
   883         if (!FRAME_TOOLTIP_P (f)
   884             && (old_left != f->left_pos || old_top != f->top_pos))
   885           {
   886             inev.ie.kind = MOVE_FRAME_EVENT;
   887             XSETFRAME (inev.ie.frame_or_window, f);
   888           }
   889 
   890       if (f && FRAME_OUTPUT_DATA (f)->need_cursor_updates)
   891         {
   892           w = XWINDOW (f->selected_window);
   893           android_set_preeditarea (w, w->cursor.x, w->cursor.y);
   894         }
   895       }
   896 
   897       goto OTHER;
   898 
   899     case ANDROID_KEY_PRESS:
   900 
   901       /* Set f to any.  There are no ``outer windows'' on Android.  */
   902       f = any;
   903 
   904       /* If mouse-highlight is an integer, input clears out
   905          mouse highlighting.  */
   906       if (!hlinfo->mouse_face_hidden && FIXNUMP (Vmouse_highlight)
   907           && (any == 0
   908               || !EQ (any->tool_bar_window, hlinfo->mouse_face_window)
   909               || !EQ (any->tab_bar_window, hlinfo->mouse_face_window)))
   910         {
   911           mouse_frame = hlinfo->mouse_face_mouse_frame;
   912 
   913           clear_mouse_face (hlinfo);
   914           hlinfo->mouse_face_hidden = true;
   915 
   916           if (mouse_frame)
   917             android_flush_dirty_back_buffer_on (mouse_frame);
   918         }
   919 
   920       if (!f)
   921         goto OTHER;
   922 
   923       if (event->xkey.counter)
   924         /* This event was generated by `performEditorAction'.  Make
   925            sure it is processed before any subsequent edits.  */
   926         textconv_barrier (f, event->xkey.counter);
   927 
   928       wchar_t copy_buffer[129];
   929       wchar_t *copy_bufptr = copy_buffer;
   930       int copy_bufsiz = 128 * sizeof (wchar_t);
   931 
   932       event->xkey.state
   933         |= android_emacs_to_android_modifiers (dpyinfo,
   934                                                extra_keyboard_modifiers);
   935       modifiers = event->xkey.state;
   936 
   937       /* Common for all keysym input events.  */
   938       XSETFRAME (inev.ie.frame_or_window, any);
   939       inev.ie.modifiers
   940         = android_android_to_emacs_modifiers (dpyinfo, modifiers);
   941       inev.ie.timestamp = event->xkey.time;
   942 
   943       keysym = event->xkey.keycode;
   944 
   945       {
   946         enum android_lookup_status status_return;
   947 
   948         nchars = android_wc_lookup_string (&event->xkey, copy_bufptr,
   949                                            copy_bufsiz, &keysym,
   950                                            &status_return);
   951 
   952         /* android_lookup_string can't be called twice, so there's no
   953            way to recover from buffer overflow.  */
   954         if (status_return == ANDROID_BUFFER_OVERFLOW)
   955           goto done_keysym;
   956         else if (status_return == ANDROID_LOOKUP_NONE)
   957           {
   958             /* Don't skip preedit text events.  */
   959             if (event->xkey.keycode != (uint32_t) -1)
   960               goto done_keysym;
   961           }
   962         else if (status_return == ANDROID_LOOKUP_CHARS)
   963           keysym = ANDROID_NO_SYMBOL;
   964         else if (status_return != ANDROID_LOOKUP_KEYSYM
   965                  && status_return != ANDROID_LOOKUP_BOTH)
   966           emacs_abort ();
   967 
   968         /* Deal with pre-edit text events.  On Android, these are
   969            simply encoded as events with associated strings and a
   970            keycode set to ``-1''.  */
   971 
   972         if (event->xkey.keycode == (uint32_t) -1)
   973           {
   974             inev.ie.kind = PREEDIT_TEXT_EVENT;
   975             inev.ie.arg = Qnil;
   976 
   977             /* If text was looked up, decode it and make it the
   978                preedit text.  */
   979 
   980             if (status_return == ANDROID_LOOKUP_CHARS && nchars)
   981               {
   982                 copy_bufptr[nchars] = 0;
   983                 inev.ie.arg = from_unicode_buffer (copy_bufptr);
   984               }
   985 
   986             goto done_keysym;
   987           }
   988       }
   989 
   990       if (nchars == 1 && copy_bufptr[0] >= 32)
   991         {
   992           /* Deal with characters.  */
   993 
   994           if (copy_bufptr[0] < 128)
   995             inev.ie.kind = ASCII_KEYSTROKE_EVENT;
   996           else
   997             inev.ie.kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
   998 
   999           inev.ie.code = copy_bufptr[0];
  1000         }
  1001       else if (nchars < 2 && keysym)
  1002         {
  1003           /* If the key is a modifier key, just return.  */
  1004           if (ANDROID_IS_MODIFIER_KEY (keysym))
  1005             goto done_keysym;
  1006 
  1007           /* Next, deal with special ``characters'' by giving the
  1008              keycode to keyboard.c.  */
  1009           inev.ie.kind = NON_ASCII_KEYSTROKE_EVENT;
  1010           inev.ie.code = keysym;
  1011         }
  1012       else
  1013         {
  1014           /* Finally, deal with strings.  */
  1015 
  1016           for (i = 0; i < nchars; ++i)
  1017             {
  1018               inev.ie.kind = (SINGLE_BYTE_CHAR_P (copy_bufptr[i])
  1019                               ? ASCII_KEYSTROKE_EVENT
  1020                               : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
  1021               inev.ie.code = copy_bufptr[i];
  1022 
  1023               /* If the character is actually '\n', then change this
  1024                  to RET.  */
  1025 
  1026               if (copy_bufptr[i] == '\n')
  1027                 {
  1028                   inev.ie.kind = NON_ASCII_KEYSTROKE_EVENT;
  1029                   inev.ie.code = 66;
  1030                 }
  1031 
  1032               kbd_buffer_store_buffered_event (&inev, hold_quit);
  1033             }
  1034 
  1035           count += nchars;
  1036           inev.ie.kind = NO_EVENT;  /* Already stored above.  */
  1037         }
  1038 
  1039       goto done_keysym;
  1040 
  1041     done_keysym:
  1042 
  1043       /* Now proceed to tell the input method the current position of
  1044          the cursor, if required.  */
  1045 
  1046       if (f && FRAME_OUTPUT_DATA (f)->need_cursor_updates)
  1047         {
  1048           w = XWINDOW (f->selected_window);
  1049           android_set_preeditarea (w, w->cursor.x, w->cursor.y);
  1050         }
  1051 
  1052       goto OTHER;
  1053 
  1054     case ANDROID_FOCUS_IN:
  1055     case ANDROID_FOCUS_OUT:
  1056       android_detect_focus_change (dpyinfo, any, event, &inev.ie);
  1057       goto OTHER;
  1058 
  1059     case ANDROID_WINDOW_ACTION:
  1060 
  1061       /* This is a special event sent by android_run_in_emacs_thread
  1062          used to make Android run stuff.  */
  1063 
  1064       if (!event->xaction.window && !event->xaction.action)
  1065         /* Don't run queries here, as it may run inside editor
  1066            commands, which can expose an inconsistent view of buffer
  1067            contents to the input method during command execution.
  1068 
  1069            Instead, wait for Emacs to return to `android_select'.  */
  1070         goto OTHER;
  1071 
  1072       f = any;
  1073 
  1074       if (event->xaction.action == 0)
  1075         {
  1076           /* Action 0 either means that a window has been destroyed
  1077              and its associated frame should be as well.  */
  1078 
  1079           if (event->xaction.window)
  1080             {
  1081               if (!f)
  1082                 goto OTHER;
  1083 
  1084               inev.ie.kind = DELETE_WINDOW_EVENT;
  1085               XSETFRAME (inev.ie.frame_or_window, f);
  1086             }
  1087         }
  1088 
  1089     case ANDROID_ENTER_NOTIFY:
  1090       f = any;
  1091 
  1092       if (f)
  1093         android_note_mouse_movement (f, &event->xmotion);
  1094       goto OTHER;
  1095 
  1096     case ANDROID_MOTION_NOTIFY:
  1097 
  1098       previous_help_echo_string = help_echo_string;
  1099       help_echo_string = Qnil;
  1100 
  1101       if (hlinfo->mouse_face_hidden)
  1102         {
  1103           hlinfo->mouse_face_hidden = false;
  1104           clear_mouse_face (hlinfo);
  1105         }
  1106 
  1107       f = any;
  1108 
  1109       if (f)
  1110         {
  1111           /* Maybe generate a SELECT_WINDOW_EVENT for
  1112              `mouse-autoselect-window' but don't let popup menus
  1113              interfere with this (Bug#1261).  */
  1114           if (!NILP (Vmouse_autoselect_window)
  1115               && !popup_activated ()
  1116               /* Don't switch if we're currently in the minibuffer.
  1117                  This tries to work around problems where the
  1118                  minibuffer gets unselected unexpectedly, and where
  1119                  you then have to move your mouse all the way down to
  1120                  the minibuffer to select it.  */
  1121               && !MINI_WINDOW_P (XWINDOW (selected_window))
  1122               /* With `focus-follows-mouse' non-nil create an event
  1123                  also when the target window is on another frame.  */
  1124               && (f == XFRAME (selected_frame)
  1125                   || !NILP (focus_follows_mouse)))
  1126             {
  1127               static Lisp_Object last_mouse_window;
  1128               Lisp_Object window
  1129                 = window_from_coordinates (f, event->xmotion.x,
  1130                                            event->xmotion.y, 0,
  1131                                            false, false);
  1132 
  1133               /* A window will be autoselected only when it is not
  1134                  selected now and the last mouse movement event was
  1135                  not in it.  The remainder of the code is a bit vague
  1136                  wrt what a "window" is.  For immediate autoselection,
  1137                  the window is usually the entire window but for GTK
  1138                  where the scroll bars don't count.  For delayed
  1139                  autoselection the window is usually the window's text
  1140                  area including the margins.  */
  1141               if (WINDOWP (window)
  1142                   && !EQ (window, last_mouse_window)
  1143                   && !EQ (window, selected_window))
  1144                 {
  1145                   inev.ie.kind = SELECT_WINDOW_EVENT;
  1146                   inev.ie.frame_or_window = window;
  1147                 }
  1148 
  1149               /* Remember the last window where we saw the mouse.  */
  1150               last_mouse_window = window;
  1151             }
  1152 
  1153           if (!android_note_mouse_movement (f, &event->xmotion))
  1154             help_echo_string = previous_help_echo_string;
  1155         }
  1156 
  1157       /* If the contents of the global variable help_echo_string
  1158          has changed, generate a HELP_EVENT.  */
  1159       if (!NILP (help_echo_string)
  1160           || !NILP (previous_help_echo_string))
  1161         do_help = 1;
  1162 
  1163       if (f)
  1164         android_flush_dirty_back_buffer_on (f);
  1165 
  1166       goto OTHER;
  1167 
  1168     case ANDROID_LEAVE_NOTIFY:
  1169       f = any;
  1170 
  1171       if (f)
  1172         {
  1173           /* Now clear dpyinfo->last_mouse_motion_frame, or
  1174              gui_redo_mouse_highlight will end up highlighting the
  1175              last known position of the mouse if a tooltip frame is
  1176              later unmapped.  */
  1177 
  1178           if (f == dpyinfo->last_mouse_motion_frame)
  1179             dpyinfo->last_mouse_motion_frame = NULL;
  1180 
  1181           /* Something similar applies to
  1182              dpyinfo->last_mouse_glyph_frame.  */
  1183           if (f == dpyinfo->last_mouse_glyph_frame)
  1184             dpyinfo->last_mouse_glyph_frame = NULL;
  1185 
  1186           if (f == hlinfo->mouse_face_mouse_frame)
  1187             {
  1188               /* If we move outside the frame, then we're
  1189                  certainly no longer on any text in the frame.  */
  1190               clear_mouse_face (hlinfo);
  1191               hlinfo->mouse_face_mouse_frame = 0;
  1192               android_flush_dirty_back_buffer_on (f);
  1193             }
  1194 
  1195           /* Generate a nil HELP_EVENT to cancel a help-echo.
  1196              Do it only if there's something to cancel.
  1197              Otherwise, the startup message is cleared when
  1198              the mouse leaves the frame.  */
  1199           if (any_help_event_p
  1200               /* But never if `mouse-drag-and-drop-region' is in
  1201                  progress, since that results in the tooltip being
  1202                  dismissed when the mouse moves on top.  */
  1203               && !((EQ (track_mouse, Qdrag_source)
  1204                     || EQ (track_mouse, Qdropping))
  1205                    && gui_mouse_grabbed (dpyinfo)))
  1206             do_help = -1;
  1207         }
  1208 
  1209       goto OTHER;
  1210 
  1211     case ANDROID_EXPOSE:
  1212 
  1213       f = any;
  1214 
  1215       if (f)
  1216         {
  1217           if (!FRAME_VISIBLE_P (f))
  1218             {
  1219               f->output_data.android->has_been_visible = true;
  1220               SET_FRAME_GARBAGED (f);
  1221             }
  1222 
  1223           if (!FRAME_GARBAGED_P (f))
  1224             {
  1225               expose_frame (f, event->xexpose.x, event->xexpose.y,
  1226                             event->xexpose.width, event->xexpose.height);
  1227               show_back_buffer (f);
  1228             }
  1229         }
  1230 
  1231       goto OTHER;
  1232 
  1233     case ANDROID_BUTTON_PRESS:
  1234     case ANDROID_BUTTON_RELEASE:
  1235       /* If we decide we want to generate an event to be seen
  1236          by the rest of Emacs, we put it here.  */
  1237 
  1238       f = any;
  1239 
  1240       Lisp_Object tab_bar_arg = Qnil;
  1241       bool tab_bar_p = false;
  1242       bool tool_bar_p = false;
  1243 
  1244       dpyinfo->last_mouse_glyph_frame = NULL;
  1245 
  1246       f = mouse_or_wdesc_frame (dpyinfo, event->xbutton.window);
  1247 
  1248       if (f && event->xbutton.type == ANDROID_BUTTON_PRESS
  1249           && !popup_activated ()
  1250           /* && !x_window_to_scroll_bar (event->xbutton.display, */
  1251           /*                          event->xbutton.window, 2) */
  1252           && !FRAME_NO_ACCEPT_FOCUS (f))
  1253         {
  1254           /* When clicking into a child frame or when clicking
  1255              into a parent frame with the child frame selected and
  1256              `no-accept-focus' is not set, select the clicked
  1257              frame.  */
  1258           struct frame *hf = dpyinfo->highlight_frame;
  1259 
  1260           if (FRAME_PARENT_FRAME (f) || (hf && frame_ancestor_p (f, hf)))
  1261             {
  1262               android_set_input_focus (FRAME_ANDROID_WINDOW (f),
  1263                                        event->xbutton.time);
  1264 
  1265               if (FRAME_PARENT_FRAME (f))
  1266                 android_raise_window (FRAME_ANDROID_WINDOW (f));
  1267             }
  1268         }
  1269 
  1270       if (f)
  1271         {
  1272           /* Is this in the tab-bar?  */
  1273           if (WINDOWP (f->tab_bar_window)
  1274               && WINDOW_TOTAL_LINES (XWINDOW (f->tab_bar_window)))
  1275             {
  1276               Lisp_Object window;
  1277               int x = event->xbutton.x;
  1278               int y = event->xbutton.y;
  1279 
  1280               window = window_from_coordinates (f, x, y, 0, true, true);
  1281               tab_bar_p = EQ (window, f->tab_bar_window);
  1282 
  1283               if (tab_bar_p)
  1284                 {
  1285                   tab_bar_arg = handle_tab_bar_click
  1286                     (f, x, y, (event->xbutton.type
  1287                                == ANDROID_BUTTON_PRESS),
  1288                      android_android_to_emacs_modifiers (dpyinfo,
  1289                                                          event->xbutton.state));
  1290                   android_flush_dirty_back_buffer_on (f);
  1291                 }
  1292             }
  1293 
  1294           /* Is this in the tool-bar?  */
  1295           if (WINDOWP (f->tool_bar_window)
  1296               && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)))
  1297             {
  1298               Lisp_Object window;
  1299               int x = event->xbutton.x;
  1300               int y = event->xbutton.y;
  1301 
  1302               window = window_from_coordinates (f, x, y, 0, true, true);
  1303               tool_bar_p = (EQ (window, f->tool_bar_window)
  1304                             && ((event->xbutton.type
  1305                                  != ANDROID_BUTTON_RELEASE)
  1306                                 || f->last_tool_bar_item != -1));
  1307 
  1308               if (tool_bar_p && event->xbutton.button < 4)
  1309                 {
  1310                   handle_tool_bar_click
  1311                     (f, x, y, (event->xbutton.type
  1312                                == ANDROID_BUTTON_PRESS),
  1313                      android_android_to_emacs_modifiers (dpyinfo,
  1314                                                          event->xbutton.state));
  1315                   android_flush_dirty_back_buffer_on (f);
  1316                 }
  1317             }
  1318 
  1319           if (!(tab_bar_p && NILP (tab_bar_arg)) && !tool_bar_p)
  1320             if (! popup_activated ())
  1321               {
  1322                 android_construct_mouse_click (&inev.ie, &event->xbutton, f);
  1323 
  1324                 if (!NILP (tab_bar_arg))
  1325                   inev.ie.arg = tab_bar_arg;
  1326               }
  1327         }
  1328 
  1329       if (event->type == ANDROID_BUTTON_PRESS)
  1330         {
  1331           dpyinfo->grabbed |= (1 << event->xbutton.button);
  1332           dpyinfo->last_mouse_frame = f;
  1333           if (f && !tab_bar_p)
  1334             f->last_tab_bar_item = -1;
  1335           if (f && !tool_bar_p)
  1336             f->last_tool_bar_item = -1;
  1337         }
  1338       else
  1339         dpyinfo->grabbed &= ~(1 << event->xbutton.button);
  1340 
  1341       /* Ignore any mouse motion that happened before this event;
  1342          any subsequent mouse-movement Emacs events should reflect
  1343          only motion after the ButtonPress/Release.  */
  1344       if (f != 0)
  1345         f->mouse_moved = false;
  1346 
  1347       goto OTHER;
  1348 
  1349       /* Touch events.  The events here don't parallel X so much.  */
  1350     case ANDROID_TOUCH_DOWN:
  1351 
  1352       if (!any)
  1353         goto OTHER;
  1354 
  1355       /* This event is sent when a tool is put on the screen.  X and Y
  1356          are the location of the finger, and pointer_id identifies the
  1357          tool for as long as it is still held down.  First, see if the
  1358          touch point already exists and can be reused (this shouldn't
  1359          happen, but be safe.)  */
  1360 
  1361       touchpoint = android_find_tool (any, event->touch.pointer_id);
  1362 
  1363       if (touchpoint)
  1364         {
  1365           /* Simply update the tool position and send an update.  */
  1366           touchpoint->x = event->touch.x;
  1367           touchpoint->y = event->touch.x;
  1368           android_update_tools (any, &inev.ie);
  1369           inev.ie.timestamp = event->touch.time;
  1370 
  1371           goto OTHER;
  1372         }
  1373 
  1374       /* Otherwise, link a new touchpoint onto the output's list of
  1375          pressed tools.  */
  1376 
  1377       touchpoint = xmalloc (sizeof *touchpoint);
  1378       touchpoint->tool_id = event->touch.pointer_id;
  1379       touchpoint->x = event->touch.x;
  1380       touchpoint->y = event->touch.x;
  1381       touchpoint->next = FRAME_OUTPUT_DATA (any)->touch_points;
  1382       touchpoint->tool_bar_p = false;
  1383       FRAME_OUTPUT_DATA (any)->touch_points = touchpoint;
  1384 
  1385       /* Figure out whether or not the tool was pressed on the tool
  1386          bar.  Note that the code which runs when it was is more or
  1387          less an abuse of the mouse highlight machinery, but it works
  1388          well enough in practice.  */
  1389 
  1390       if (WINDOWP (any->tool_bar_window)
  1391           && WINDOW_TOTAL_LINES (XWINDOW (any->tool_bar_window)))
  1392         {
  1393           Lisp_Object window;
  1394           int x = event->touch.x;
  1395           int y = event->touch.y;
  1396 
  1397           window = window_from_coordinates (any, x, y, 0, true,
  1398                                             true);
  1399 
  1400           /* If this touch has started in the tool bar, do not
  1401              send it to Lisp.  Instead, simulate a tool bar
  1402              click, releasing it once it goes away.  */
  1403 
  1404           if (EQ (window, any->tool_bar_window))
  1405             {
  1406               /* Call note_mouse_highlight on the tool bar
  1407                  item.  Otherwise, get_tool_bar_item will
  1408                  return 1.
  1409 
  1410                  This is not necessary when mouse-highlight is
  1411                  nil.  */
  1412 
  1413               if (!NILP (Vmouse_highlight))
  1414                 {
  1415                   /* Clear the pointer invisible flag to always make
  1416                      note_mouse_highlight do its thing.  */
  1417                   any->pointer_invisible = false;
  1418                   note_mouse_highlight (any, x, y);
  1419 
  1420                   /* Always allow future mouse motion to
  1421                      update the mouse highlight, no matter
  1422                      where it is.  */
  1423                   memset (&dpyinfo->last_mouse_glyph, 0,
  1424                           sizeof dpyinfo->last_mouse_glyph);
  1425                   dpyinfo->last_mouse_glyph_frame = any;
  1426                 }
  1427 
  1428               handle_tool_bar_click (any, x, y, true, 0);
  1429 
  1430               /* Flush any changes made by that to the front
  1431                  buffer.  */
  1432               android_flush_dirty_back_buffer_on (any);
  1433 
  1434               /* Mark the touch point as being grabbed by the tool
  1435                  bar.  */
  1436               touchpoint->tool_bar_p = true;
  1437               goto OTHER;
  1438             }
  1439         }
  1440 
  1441       /* Now generate the Emacs event.  */
  1442       inev.ie.kind = TOUCHSCREEN_BEGIN_EVENT;
  1443       inev.ie.timestamp = event->touch.time;
  1444       XSETFRAME (inev.ie.frame_or_window, any);
  1445       XSETINT (inev.ie.x, event->touch.x);
  1446       XSETINT (inev.ie.y, event->touch.y);
  1447       XSETINT (inev.ie.arg, event->touch.pointer_id);
  1448 
  1449       goto OTHER;
  1450 
  1451     case ANDROID_TOUCH_MOVE:
  1452 
  1453       if (!any)
  1454         goto OTHER;
  1455 
  1456       /* Look for the tool that moved.  */
  1457 
  1458       touchpoint = android_find_tool (any, event->touch.pointer_id);
  1459 
  1460       /* If it doesn't exist or has been grabbed by the tool bar, skip
  1461          processing this event.  */
  1462 
  1463       if (!touchpoint || touchpoint->tool_bar_p)
  1464         goto OTHER;
  1465 
  1466       /* Otherwise, update the position and send the update event.  */
  1467 
  1468       touchpoint->x = event->touch.x;
  1469       touchpoint->y = event->touch.y;
  1470       android_update_tools (any, &inev.ie);
  1471       inev.ie.timestamp = event->touch.time;
  1472 
  1473       goto OTHER;
  1474 
  1475     case ANDROID_TOUCH_UP:
  1476 
  1477       if (!any)
  1478         goto OTHER;
  1479 
  1480       /* Now find and unlink the tool in question.  */
  1481 
  1482       last = &FRAME_OUTPUT_DATA (any)->touch_points;
  1483       while ((touchpoint = *last))
  1484         {
  1485           if (touchpoint->tool_id == event->touch.pointer_id)
  1486             {
  1487               *last = touchpoint->next;
  1488 
  1489               if (touchpoint->tool_bar_p)
  1490                 {
  1491                   xfree (touchpoint);
  1492 
  1493                   /* Do what is necessary to release the tool bar and
  1494                      possibly trigger a click.  */
  1495 
  1496                   if (any->last_tool_bar_item != -1)
  1497                     handle_tool_bar_click (any, event->touch.x,
  1498                                            event->touch.y, false,
  1499                                            0);
  1500 
  1501                   /* Cancel any outstanding mouse highlight.  */
  1502                   note_mouse_highlight (any, -1, -1);
  1503                   android_flush_dirty_back_buffer_on (any);
  1504 
  1505                   goto OTHER;
  1506                 }
  1507 
  1508               /* The tool was unlinked.  Free it and generate the
  1509                  appropriate Emacs event (assuming that it was not
  1510                  grabbed by the tool bar).  */
  1511               xfree (touchpoint);
  1512 
  1513               inev.ie.kind = TOUCHSCREEN_END_EVENT;
  1514               inev.ie.timestamp = event->touch.time;
  1515 
  1516               /* Report whether the sequence has been canceled.  */
  1517 
  1518               if (event->touch.flags & ANDROID_TOUCH_SEQUENCE_CANCELED)
  1519                 inev.ie.modifiers = 1;
  1520 
  1521               XSETFRAME (inev.ie.frame_or_window, any);
  1522               XSETINT (inev.ie.x, event->touch.x);
  1523               XSETINT (inev.ie.y, event->touch.y);
  1524               XSETINT (inev.ie.arg, event->touch.pointer_id);
  1525 
  1526               /* Break out of the loop.  */
  1527               goto OTHER;
  1528             }
  1529           else
  1530             last = &touchpoint->next;
  1531         }
  1532 
  1533       /* No touch point was found.  This shouldn't happen.  */
  1534       goto OTHER;
  1535 
  1536       /* Wheel motion.  The events here don't parallel X because
  1537          Android doesn't have scroll valuators.  */
  1538 
  1539     case ANDROID_WHEEL:
  1540 
  1541       if (!any)
  1542         goto OTHER;
  1543 
  1544       if (fabs (event->wheel.x_delta) > 0
  1545           || fabs (event->wheel.y_delta) > 0)
  1546         {
  1547           if (mwheel_coalesce_scroll_events)
  1548             {
  1549               if (signbit (event->wheel.x_delta)
  1550                   != signbit (wheel_event_x))
  1551                 wheel_event_x = 0.0;
  1552 
  1553               if (signbit (event->wheel.y_delta)
  1554                   != signbit (wheel_event_y))
  1555                 wheel_event_y = 0.0;
  1556 
  1557               /* Tally up deltas until one of them exceeds 1.0.  */
  1558               wheel_event_x += event->wheel.x_delta;
  1559               wheel_event_y += event->wheel.y_delta;
  1560 
  1561               if (fabs (wheel_event_x) < 1.0
  1562                   && fabs (wheel_event_y) < 1.0)
  1563                 goto OTHER;
  1564             }
  1565           else
  1566             {
  1567               /* Use the deltas in the event.  */
  1568               wheel_event_x = event->wheel.x_delta;
  1569               wheel_event_y = event->wheel.y_delta;
  1570             }
  1571 
  1572           /* Determine what kind of event to send.  */
  1573           inev.ie.kind = ((fabs (wheel_event_y)
  1574                            >= fabs (wheel_event_x))
  1575                           ? WHEEL_EVENT : HORIZ_WHEEL_EVENT);
  1576           inev.ie.timestamp = event->wheel.time;
  1577 
  1578           /* Set the event coordinates.  */
  1579           XSETINT (inev.ie.x, event->wheel.x);
  1580           XSETINT (inev.ie.y, event->wheel.y);
  1581 
  1582           /* Set the frame.  */
  1583           XSETFRAME (inev.ie.frame_or_window, any);
  1584 
  1585           /* Figure out the scroll direction.  */
  1586           inev.ie.modifiers = (signbit ((fabs (wheel_event_x)
  1587                                          >= fabs (wheel_event_y))
  1588                                         ? wheel_event_x
  1589                                         : wheel_event_y)
  1590                                ? down_modifier : up_modifier);
  1591 
  1592           /* Figure out how much to scale the deltas by.  */
  1593           window = window_from_coordinates (any, event->wheel.x,
  1594                                             event->wheel.y, NULL,
  1595                                             false, false);
  1596 
  1597           if (WINDOWP (window))
  1598             scroll_height = XWINDOW (window)->pixel_height;
  1599           else
  1600             /* EVENT_X and EVENT_Y can be outside the
  1601                frame if F holds the input grab, so fall
  1602                back to the height of the frame instead.  */
  1603             scroll_height = FRAME_PIXEL_HEIGHT (any);
  1604 
  1605           scroll_unit = pow (scroll_height, 2.0 / 3.0);
  1606 
  1607           /* Add the keyboard modifiers.  */
  1608           inev.ie.modifiers
  1609             |= android_android_to_emacs_modifiers (dpyinfo,
  1610                                                    event->wheel.state);
  1611 
  1612           /* Finally include the scroll deltas.  */
  1613           inev.ie.arg = list3 (Qnil,
  1614                                make_float (wheel_event_x
  1615                                            * scroll_unit),
  1616                                make_float (wheel_event_y
  1617                                            * scroll_unit));
  1618 
  1619           wheel_event_x = 0.0;
  1620           wheel_event_y = 0.0;
  1621         }
  1622 
  1623       goto OTHER;
  1624 
  1625       /* Iconification.  This is vastly simpler than on X.  */
  1626     case ANDROID_ICONIFIED:
  1627 
  1628       if (!any)
  1629         goto OTHER;
  1630 
  1631       if (FRAME_ICONIFIED_P (any))
  1632         goto OTHER;
  1633 
  1634       SET_FRAME_VISIBLE (any, false);
  1635       SET_FRAME_ICONIFIED (any, true);
  1636 
  1637       inev.ie.kind = ICONIFY_EVENT;
  1638       XSETFRAME (inev.ie.frame_or_window, any);
  1639       goto OTHER;
  1640 
  1641     case ANDROID_DEICONIFIED:
  1642 
  1643       if (!any)
  1644         goto OTHER;
  1645 
  1646       if (!FRAME_ICONIFIED_P (any))
  1647         goto OTHER;
  1648 
  1649       SET_FRAME_VISIBLE (any, true);
  1650       SET_FRAME_ICONIFIED (any, false);
  1651 
  1652       inev.ie.kind = DEICONIFY_EVENT;
  1653       XSETFRAME (inev.ie.frame_or_window, any);
  1654       goto OTHER;
  1655 
  1656       /* Context menu handling.  */
  1657     case ANDROID_CONTEXT_MENU:
  1658 
  1659       if (dpyinfo->menu_event_id == -1
  1660           /* Previously displayed popup menus might generate events
  1661              after dismissal, which might interfere.
  1662              `current_menu_serial' is always set to an identifier
  1663              identifying the last context menu to be displayed.  */
  1664           && event->menu.menu_event_serial == current_menu_serial)
  1665         dpyinfo->menu_event_id = event->menu.menu_event_id;
  1666 
  1667       goto OTHER;
  1668 
  1669       /* Input method events.  textconv.c functions are called here to
  1670          queue events, which are then executed in a safe context
  1671          inside keyboard.c.  */
  1672     case ANDROID_INPUT_METHOD:
  1673 
  1674       if (!any)
  1675         {
  1676           /* Free any text allocated for this event.  */
  1677           xfree (event->ime.text);
  1678 
  1679           /* If edits associated with this event haven't been
  1680              processed yet, signal their completion to avoid delays
  1681              the next time a call to `android_sync_edit' is made.
  1682 
  1683              If events for a deleted frame are interleaved with events
  1684              for another frame, the edit counter may be prematurely
  1685              incremented before edits associated with the other frames
  1686              are processed.  This is not a problem in practice.  */
  1687 
  1688           android_notify_conversion (event->ime.counter);
  1689         }
  1690       else
  1691         android_handle_ime_event (event, any);
  1692 
  1693       goto OTHER;
  1694 
  1695     default:
  1696       goto OTHER;
  1697     }
  1698 
  1699  OTHER:
  1700   if (inev.ie.kind != NO_EVENT)
  1701     {
  1702       kbd_buffer_store_buffered_event (&inev, hold_quit);
  1703       count++;
  1704     }
  1705 
  1706   if (do_help
  1707       && !(hold_quit && hold_quit->kind != NO_EVENT))
  1708     {
  1709       Lisp_Object frame;
  1710 
  1711       if (f)
  1712         XSETFRAME (frame, f);
  1713       else
  1714         frame = Qnil;
  1715 
  1716       if (do_help > 0)
  1717         {
  1718           any_help_event_p = true;
  1719           gen_help_event (help_echo_string, frame, help_echo_window,
  1720                           help_echo_object, help_echo_pos);
  1721         }
  1722       else
  1723         {
  1724           help_echo_string = Qnil;
  1725           gen_help_event (Qnil, frame, Qnil, Qnil, 0);
  1726         }
  1727       count++;
  1728     }
  1729 
  1730   return count;
  1731 }
  1732 
  1733 static int
  1734 android_read_socket (struct terminal *terminal,
  1735                      struct input_event *hold_quit)
  1736 {
  1737   int count = 0;
  1738   struct android_display_info *dpyinfo;
  1739 
  1740   dpyinfo = terminal->display_info.android;
  1741 
  1742   block_input ();
  1743   while (android_pending ())
  1744     {
  1745       int finish;
  1746       union android_event event;
  1747 
  1748       android_next_event (&event);
  1749       count += handle_one_android_event (dpyinfo, &event, &finish,
  1750                                          hold_quit);
  1751 
  1752       if (finish == ANDROID_EVENT_GOTO_OUT)
  1753         break;
  1754     }
  1755   unblock_input ();
  1756 
  1757   /* If the focus was just given to an auto-raising frame, raise it
  1758      now.  */
  1759   if (dpyinfo->pending_autoraise_frame)
  1760     {
  1761       android_raise_frame (dpyinfo->pending_autoraise_frame);
  1762       dpyinfo->pending_autoraise_frame = NULL;
  1763     }
  1764 
  1765   return count;
  1766 }
  1767 
  1768 static void
  1769 android_frame_up_to_date (struct frame *f)
  1770 {
  1771   eassert (FRAME_ANDROID_P (f));
  1772   block_input ();
  1773   FRAME_MOUSE_UPDATE (f);
  1774 
  1775   if (!buffer_flipping_blocked_p ()
  1776       && FRAME_ANDROID_NEED_BUFFER_FLIP (f))
  1777     show_back_buffer (f);
  1778 
  1779   /* The frame is now complete, as its contents have been drawn.  */
  1780   FRAME_ANDROID_COMPLETE_P (f) = true;
  1781 
  1782   /* Shrink the scanline buffer used by the font backend.  */
  1783   sfntfont_android_shrink_scanline_buffer ();
  1784   unblock_input ();
  1785 }
  1786 
  1787 static void
  1788 android_buffer_flipping_unblocked_hook (struct frame *f)
  1789 {
  1790   block_input ();
  1791 
  1792   if (FRAME_ANDROID_NEED_BUFFER_FLIP (f))
  1793     show_back_buffer (f);
  1794 
  1795   unblock_input ();
  1796 }
  1797 
  1798 static void
  1799 android_query_frame_background_color (struct frame *f, Emacs_Color *bgcolor)
  1800 {
  1801   unsigned long background;
  1802 
  1803   background = FRAME_BACKGROUND_PIXEL (f);
  1804   bgcolor->pixel = background;
  1805 
  1806   android_query_colors (f, bgcolor, 1);
  1807 }
  1808 
  1809 int
  1810 android_parse_color (struct frame *f, const char *color_name,
  1811                      Emacs_Color *color)
  1812 {
  1813   unsigned short r, g, b;
  1814   Lisp_Object tem, tem1;
  1815   unsigned long lisp_color;
  1816 
  1817   if (parse_color_spec (color_name, &r, &g, &b))
  1818     {
  1819       color->red = r;
  1820       color->green = g;
  1821       color->blue = b;
  1822 
  1823       return 1;
  1824     }
  1825 
  1826   tem = x_display_list->color_map;
  1827   for (; CONSP (tem); tem = XCDR (tem))
  1828     {
  1829       tem1 = XCAR (tem);
  1830 
  1831       if (CONSP (tem1)
  1832           && !xstrcasecmp (SSDATA (XCAR (tem1)), color_name))
  1833         {
  1834           lisp_color = XFIXNUM (XCDR (tem1));
  1835           color->red = RED_FROM_ULONG (lisp_color) * 257;
  1836           color->green = GREEN_FROM_ULONG (lisp_color) * 257;
  1837           color->blue = BLUE_FROM_ULONG (lisp_color) * 257;
  1838           return 1;
  1839         }
  1840     }
  1841 
  1842   return 0;
  1843 }
  1844 
  1845 bool
  1846 android_alloc_nearest_color (struct frame *f, Emacs_Color *color)
  1847 {
  1848   gamma_correct (f, color);
  1849   color->pixel = RGB_TO_ULONG (color->red / 256,
  1850                                color->green / 256,
  1851                                color->blue / 256);
  1852 
  1853   return true;
  1854 }
  1855 
  1856 void
  1857 android_query_colors (struct frame *f, Emacs_Color *colors, int ncolors)
  1858 {
  1859   int i;
  1860 
  1861   for (i = 0; i < ncolors; ++i)
  1862     {
  1863       colors[i].red = RED_FROM_ULONG (colors[i].pixel) * 257;
  1864       colors[i].green = RED_FROM_ULONG (colors[i].pixel) * 257;
  1865       colors[i].blue = RED_FROM_ULONG (colors[i].pixel) * 257;
  1866     }
  1867 }
  1868 
  1869 static void
  1870 android_mouse_position (struct frame **fp, int insist,
  1871                         Lisp_Object *bar_window,
  1872                         enum scroll_bar_part *part, Lisp_Object *x,
  1873                         Lisp_Object *y, Time *timestamp)
  1874 {
  1875   Lisp_Object tail, frame;
  1876   struct android_display_info *dpyinfo;
  1877 
  1878   dpyinfo = FRAME_DISPLAY_INFO (*fp);
  1879 
  1880   /* This is the best implementation possible on Android, where the
  1881      system doesn't let Emacs obtain any information about the mouse
  1882      pointer at all.  */
  1883 
  1884   if (dpyinfo->last_mouse_motion_frame)
  1885     {
  1886       *fp = dpyinfo->last_mouse_motion_frame;
  1887       *timestamp = dpyinfo->last_mouse_movement_time;
  1888       *x = make_fixnum (dpyinfo->last_mouse_motion_x);
  1889       *y = make_fixnum (dpyinfo->last_mouse_motion_y);
  1890       *bar_window = Qnil;
  1891       *part = scroll_bar_nowhere;
  1892 
  1893       FOR_EACH_FRAME (tail, frame)
  1894         {
  1895           if (FRAME_ANDROID_P (XFRAME (frame)))
  1896             XFRAME (frame)->mouse_moved = false;
  1897         }
  1898 
  1899       dpyinfo->last_mouse_motion_frame->mouse_moved = false;
  1900     }
  1901 }
  1902 
  1903 static Lisp_Object
  1904 android_get_focus_frame (struct frame *f)
  1905 {
  1906   Lisp_Object lisp_focus;
  1907   struct frame *focus;
  1908 
  1909   focus = FRAME_DISPLAY_INFO (f)->focus_frame;
  1910 
  1911   if (!focus)
  1912     return Qnil;
  1913 
  1914   XSETFRAME (lisp_focus, focus);
  1915   return lisp_focus;
  1916 }
  1917 
  1918 static void
  1919 android_focus_frame (struct frame *f, bool noactivate)
  1920 {
  1921   /* Set the input focus to the frame's window.  The system only lets
  1922      this work on child frames.  */
  1923   android_set_input_focus (FRAME_ANDROID_WINDOW (f),
  1924                            ANDROID_CURRENT_TIME);
  1925 }
  1926 
  1927 /* The two procedures below only have to update the cursor on Android,
  1928    as there are no window borders there.  */
  1929 
  1930 static void
  1931 android_frame_highlight (struct frame *f)
  1932 {
  1933   gui_update_cursor (f, true);
  1934 }
  1935 
  1936 static void
  1937 android_frame_unhighlight (struct frame *f)
  1938 {
  1939   gui_update_cursor (f, true);
  1940 }
  1941 
  1942 static void
  1943 android_frame_rehighlight (struct android_display_info *dpyinfo)
  1944 {
  1945   struct frame *old_highlight;
  1946 
  1947   old_highlight = dpyinfo->highlight_frame;
  1948 
  1949   if (dpyinfo->focus_frame)
  1950     {
  1951       dpyinfo->highlight_frame
  1952         = ((FRAMEP (FRAME_FOCUS_FRAME (dpyinfo->focus_frame)))
  1953            ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo->focus_frame))
  1954            : dpyinfo->focus_frame);
  1955       if (!FRAME_LIVE_P (dpyinfo->highlight_frame))
  1956         {
  1957           fset_focus_frame (dpyinfo->focus_frame, Qnil);
  1958           dpyinfo->highlight_frame = dpyinfo->focus_frame;
  1959         }
  1960     }
  1961   else
  1962     dpyinfo->highlight_frame = 0;
  1963 
  1964   if (dpyinfo->highlight_frame != old_highlight)
  1965     {
  1966       /* This is not yet required on Android.  */
  1967       if (old_highlight)
  1968         android_frame_unhighlight (old_highlight);
  1969       if (dpyinfo->highlight_frame)
  1970         android_frame_highlight (dpyinfo->highlight_frame);
  1971     }
  1972 }
  1973 
  1974 static void
  1975 android_frame_rehighlight_hook (struct frame *f)
  1976 {
  1977   android_frame_rehighlight (FRAME_DISPLAY_INFO (f));
  1978 }
  1979 
  1980 static void
  1981 android_frame_raise_lower (struct frame *f, bool raise_flag)
  1982 {
  1983   if (raise_flag)
  1984     android_raise_frame (f);
  1985   else
  1986     android_lower_frame (f);
  1987 }
  1988 
  1989 void
  1990 android_make_frame_visible (struct frame *f)
  1991 {
  1992   android_map_window (FRAME_ANDROID_WINDOW (f));
  1993 
  1994   SET_FRAME_VISIBLE (f, true);
  1995   SET_FRAME_ICONIFIED (f, false);
  1996 }
  1997 
  1998 void
  1999 android_make_frame_invisible (struct frame *f)
  2000 {
  2001   /* Don't keep the highlight on an invisible frame.  */
  2002   if (FRAME_DISPLAY_INFO (f)->highlight_frame == f)
  2003     FRAME_DISPLAY_INFO (f)->highlight_frame = 0;
  2004 
  2005   android_unmap_window (FRAME_ANDROID_WINDOW (f));
  2006 
  2007   SET_FRAME_VISIBLE (f, false);
  2008   SET_FRAME_ICONIFIED (f, false);
  2009 }
  2010 
  2011 static void
  2012 android_make_frame_visible_invisible (struct frame *f, bool visible)
  2013 {
  2014   if (visible)
  2015     android_make_frame_visible (f);
  2016   else
  2017     android_make_frame_invisible (f);
  2018 }
  2019 
  2020 static void
  2021 android_fullscreen_hook (struct frame *f)
  2022 {
  2023   Lisp_Object wanted;
  2024 
  2025   if (!FRAME_PARENT_FRAME (f))
  2026     {
  2027       /* Explicitly setting fullscreen is not supported on older
  2028          Android versions.  */
  2029 
  2030       wanted = (f->want_fullscreen == FULLSCREEN_BOTH
  2031                 ? Qfullscreen : Qmaximized);
  2032 
  2033       if (android_set_fullscreen (FRAME_ANDROID_WINDOW (f),
  2034                                   EQ (wanted, Qfullscreen)))
  2035         store_frame_param (f, Qfullscreen, Qmaximized);
  2036       else
  2037         store_frame_param (f, Qfullscreen, wanted);
  2038     }
  2039   else
  2040     {
  2041       store_frame_param (f, Qfullscreen, Qnil);
  2042 
  2043       /* If this is a child frame, don't keep it fullscreen
  2044          anymore.  */
  2045       android_set_fullscreen (FRAME_ANDROID_WINDOW (f), false);
  2046     }
  2047 }
  2048 
  2049 void
  2050 android_iconify_frame (struct frame *f)
  2051 {
  2052   /* This really doesn't work on Android.  */
  2053   error ("Can't notify window manager of iconification");
  2054 }
  2055 
  2056 static void
  2057 android_wait_for_event (struct frame *f, int eventtype)
  2058 {
  2059   if (!FLOATP (Vandroid_wait_for_event_timeout))
  2060     return;
  2061 
  2062   int level = interrupt_input_blocked;
  2063   struct timespec tmo, tmo_at, time_now;
  2064 
  2065   f->wait_event_type = eventtype;
  2066 
  2067   /* Default timeout is 0.1 second.  Hopefully not noticeable.  */
  2068   double timeout = XFLOAT_DATA (Vandroid_wait_for_event_timeout);
  2069   time_t timeout_seconds = (time_t) timeout;
  2070   tmo = make_timespec (timeout_seconds,
  2071                        (long int) ((timeout - timeout_seconds)
  2072                                    * 1000 * 1000 * 1000));
  2073   tmo_at = timespec_add (current_timespec (), tmo);
  2074 
  2075   while (f->wait_event_type)
  2076     {
  2077       pending_signals = true;
  2078       totally_unblock_input ();
  2079       /* XTread_socket is called after unblock.  */
  2080       block_input ();
  2081       interrupt_input_blocked = level;
  2082 
  2083       time_now = current_timespec ();
  2084       if (timespec_cmp (tmo_at, time_now) < 0)
  2085         break;
  2086 
  2087       tmo = timespec_sub (tmo_at, time_now);
  2088       if (android_select (0, NULL, NULL, NULL, &tmo) == 0)
  2089         break; /* Timeout */
  2090     }
  2091 
  2092   f->wait_event_type = 0;
  2093 }
  2094 
  2095 static void
  2096 android_set_window_size_1 (struct frame *f, bool change_gravity,
  2097                            int width, int height)
  2098 {
  2099   if (change_gravity)
  2100     f->win_gravity = NorthWestGravity;
  2101 
  2102   android_resize_window (FRAME_ANDROID_WINDOW (f), width,
  2103                          height);
  2104 
  2105   SET_FRAME_GARBAGED (f);
  2106 
  2107   if (FRAME_VISIBLE_P (f))
  2108     {
  2109       android_wait_for_event (f, ANDROID_CONFIGURE_NOTIFY);
  2110 
  2111       if (CONSP (frame_size_history))
  2112         frame_size_history_extra (f, build_string ("set_window_size_1 visible"),
  2113                                   FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
  2114                                   width, height, f->new_width, f->new_height);
  2115     }
  2116   else
  2117     {
  2118       if (CONSP (frame_size_history))
  2119         frame_size_history_extra (f, build_string ("set_window_size_1 "
  2120                                                    "invisible"),
  2121                                   FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
  2122                                   width, height, f->new_width, f->new_height);
  2123 
  2124       adjust_frame_size (f, FRAME_PIXEL_TO_TEXT_WIDTH (f, width),
  2125                          FRAME_PIXEL_TO_TEXT_HEIGHT (f, height),
  2126                          5, 0, Qx_set_window_size_1);
  2127     }
  2128 }
  2129 
  2130 void
  2131 android_set_window_size (struct frame *f, bool change_gravity,
  2132                          int width, int height)
  2133 {
  2134   block_input ();
  2135 
  2136   android_set_window_size_1 (f, change_gravity, width, height);
  2137   android_clear_under_internal_border (f);
  2138 
  2139   /* If cursor was outside the new size, mark it as off.  */
  2140   mark_window_cursors_off (XWINDOW (f->root_window));
  2141 
  2142   /* Clear out any recollection of where the mouse highlighting was,
  2143      since it might be in a place that's outside the new frame size.
  2144      Actually checking whether it is outside is a pain in the neck,
  2145      so don't try--just let the highlighting be done afresh with new size.  */
  2146   cancel_mouse_face (f);
  2147 
  2148   unblock_input ();
  2149 
  2150   do_pending_window_change (false);
  2151 }
  2152 
  2153 static void
  2154 android_set_offset (struct frame *f, int xoff, int yoff,
  2155                     int change_gravity)
  2156 {
  2157   if (change_gravity > 0)
  2158     {
  2159       f->top_pos = yoff;
  2160       f->left_pos = xoff;
  2161       f->size_hint_flags &= ~ (XNegative | YNegative);
  2162       if (xoff < 0)
  2163         f->size_hint_flags |= XNegative;
  2164       if (yoff < 0)
  2165         f->size_hint_flags |= YNegative;
  2166       f->win_gravity = NorthWestGravity;
  2167     }
  2168 
  2169   android_move_window (FRAME_ANDROID_WINDOW (f), xoff, yoff);
  2170 }
  2171 
  2172 static void
  2173 android_set_alpha (struct frame *f)
  2174 {
  2175   /* Not supported on Android.  */
  2176 }
  2177 
  2178 static Lisp_Object
  2179 android_new_font (struct frame *f, Lisp_Object font_object, int fontset)
  2180 {
  2181   struct font *font = XFONT_OBJECT (font_object);
  2182   int unit, font_ascent, font_descent;
  2183 
  2184   if (fontset < 0)
  2185     fontset = fontset_from_font (font_object);
  2186   FRAME_FONTSET (f) = fontset;
  2187   if (FRAME_FONT (f) == font)
  2188     /* This font is already set in frame F.  There's nothing more to
  2189        do.  */
  2190     return font_object;
  2191 
  2192   FRAME_FONT (f) = font;
  2193   FRAME_BASELINE_OFFSET (f) = font->baseline_offset;
  2194   FRAME_COLUMN_WIDTH (f) = font->average_width;
  2195   get_font_ascent_descent (font, &font_ascent, &font_descent);
  2196   FRAME_LINE_HEIGHT (f) = font_ascent + font_descent;
  2197 
  2198   /* We could use a more elaborate calculation here.  */
  2199   FRAME_TAB_BAR_HEIGHT (f) = FRAME_TAB_BAR_LINES (f) * FRAME_LINE_HEIGHT (f);
  2200 
  2201   /* Compute character columns occupied by scrollbar.
  2202 
  2203      Don't do things differently for non-toolkit scrollbars
  2204      (Bug#17163).  */
  2205   unit = FRAME_COLUMN_WIDTH (f);
  2206   if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0)
  2207     FRAME_CONFIG_SCROLL_BAR_COLS (f)
  2208       = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) + unit - 1) / unit;
  2209   else
  2210     FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + unit - 1) / unit;
  2211 
  2212 
  2213   /* Don't change the size of a tip frame; there's no point in doing it
  2214      because it's done in Fx_show_tip, and it leads to problems because
  2215      the tip frame has no widget.  */
  2216   if (FRAME_ANDROID_WINDOW (f) != 0 && !FRAME_TOOLTIP_P (f))
  2217     adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
  2218                        FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3,
  2219                        false, Qfont);
  2220 
  2221   return font_object;
  2222 }
  2223 
  2224 static bool
  2225 android_bitmap_icon (struct frame *f, Lisp_Object file)
  2226 {
  2227   return false;
  2228 }
  2229 
  2230 static void
  2231 android_free_pixmap_hook (struct frame *f, Emacs_Pixmap pixmap)
  2232 {
  2233   android_free_pixmap (pixmap);
  2234 }
  2235 
  2236 void
  2237 android_free_frame_resources (struct frame *f)
  2238 {
  2239   struct android_display_info *dpyinfo;
  2240   Mouse_HLInfo *hlinfo;
  2241   struct android_touch_point *last, *next;
  2242 
  2243   dpyinfo = FRAME_DISPLAY_INFO (f);
  2244   hlinfo = &dpyinfo->mouse_highlight;
  2245 
  2246   block_input ();
  2247   free_frame_faces (f);
  2248 
  2249   /* FRAME_ANDROID_WINDOW can be 0 if frame creation failed.  */
  2250   if (FRAME_ANDROID_WINDOW (f))
  2251     android_destroy_window (FRAME_ANDROID_WINDOW (f));
  2252 
  2253   android_free_gcs (f);
  2254 
  2255   /* Free cursors.  */
  2256   if (f->output_data.android->text_cursor)
  2257     android_free_cursor (f->output_data.android->text_cursor);
  2258   if (f->output_data.android->nontext_cursor)
  2259     android_free_cursor (f->output_data.android->nontext_cursor);
  2260   if (f->output_data.android->modeline_cursor)
  2261     android_free_cursor (f->output_data.android->modeline_cursor);
  2262   if (f->output_data.android->hand_cursor)
  2263     android_free_cursor (f->output_data.android->hand_cursor);
  2264   if (f->output_data.android->hourglass_cursor)
  2265     android_free_cursor (f->output_data.android->hourglass_cursor);
  2266   if (f->output_data.android->horizontal_drag_cursor)
  2267     android_free_cursor (f->output_data.android->horizontal_drag_cursor);
  2268   if (f->output_data.android->vertical_drag_cursor)
  2269     android_free_cursor (f->output_data.android->vertical_drag_cursor);
  2270   if (f->output_data.android->left_edge_cursor)
  2271     android_free_cursor (f->output_data.android->left_edge_cursor);
  2272   if (f->output_data.android->top_left_corner_cursor)
  2273     android_free_cursor (f->output_data.android->top_left_corner_cursor);
  2274   if (f->output_data.android->top_edge_cursor)
  2275     android_free_cursor (f->output_data.android->top_edge_cursor);
  2276   if (f->output_data.android->top_right_corner_cursor)
  2277     android_free_cursor (f->output_data.android->top_right_corner_cursor);
  2278   if (f->output_data.android->right_edge_cursor)
  2279     android_free_cursor (f->output_data.android->right_edge_cursor);
  2280   if (f->output_data.android->bottom_right_corner_cursor)
  2281     android_free_cursor (f->output_data.android->bottom_right_corner_cursor);
  2282   if (f->output_data.android->bottom_edge_cursor)
  2283     android_free_cursor (f->output_data.android->bottom_edge_cursor);
  2284   if (f->output_data.android->bottom_left_corner_cursor)
  2285     android_free_cursor (f->output_data.android->bottom_left_corner_cursor);
  2286 
  2287   /* Free extra GCs allocated by android_setup_relief_colors.  */
  2288   if (f->output_data.android->white_relief.gc)
  2289     {
  2290       android_free_gc (f->output_data.android->white_relief.gc);
  2291       f->output_data.android->white_relief.gc = 0;
  2292     }
  2293   if (f->output_data.android->black_relief.gc)
  2294     {
  2295       android_free_gc (f->output_data.android->black_relief.gc);
  2296       f->output_data.android->black_relief.gc = 0;
  2297     }
  2298 
  2299   if (f == dpyinfo->focus_frame)
  2300     dpyinfo->focus_frame = 0;
  2301   if (f == dpyinfo->x_focus_event_frame)
  2302     dpyinfo->x_focus_event_frame = 0;
  2303   if (f == dpyinfo->highlight_frame)
  2304     dpyinfo->highlight_frame = 0;
  2305   if (f == hlinfo->mouse_face_mouse_frame)
  2306     reset_mouse_highlight (hlinfo);
  2307 
  2308   /* These two need to be freed now that they are used to compute the
  2309      mouse position, I think.  */
  2310   if (f == dpyinfo->last_mouse_motion_frame)
  2311     dpyinfo->last_mouse_motion_frame = NULL;
  2312   if (f == dpyinfo->last_mouse_frame)
  2313     dpyinfo->last_mouse_frame = NULL;
  2314 
  2315   /* Free all tool presses currently active on this frame.  */
  2316   next = FRAME_OUTPUT_DATA (f)->touch_points;
  2317   while (next)
  2318     {
  2319       last = next;
  2320       next = next->next;
  2321       xfree (last);
  2322     }
  2323 
  2324   /* Clear this in case unblock_input reads events.  */
  2325   FRAME_OUTPUT_DATA (f)->touch_points = NULL;
  2326 
  2327   unblock_input ();
  2328 }
  2329 
  2330 static void
  2331 android_delete_frame (struct frame *f)
  2332 {
  2333   android_free_frame_resources (f);
  2334   xfree (f->output_data.android);
  2335   f->output_data.android = NULL;
  2336 }
  2337 
  2338 static void
  2339 android_delete_terminal (struct terminal *terminal)
  2340 {
  2341   error ("Cannot terminate connection to Android display server");
  2342 }
  2343 
  2344 
  2345 
  2346 /* RIF functions.  */
  2347 
  2348 static void
  2349 android_scroll_run (struct window *w, struct run *run)
  2350 {
  2351   struct frame *f = XFRAME (w->frame);
  2352   int x, y, width, height, from_y, to_y, bottom_y;
  2353 
  2354   /* Get frame-relative bounding box of the text display area of W,
  2355      without mode lines.  Include in this box the left and right
  2356      fringe of W.  */
  2357   window_box (w, ANY_AREA, &x, &y, &width, &height);
  2358 
  2359   from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y);
  2360   to_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->desired_y);
  2361   bottom_y = y + height;
  2362 
  2363   if (to_y < from_y)
  2364     {
  2365       /* Scrolling up.  Make sure we don't copy part of the mode
  2366          line at the bottom.  */
  2367       if (from_y + run->height > bottom_y)
  2368         height = bottom_y - from_y;
  2369       else
  2370         height = run->height;
  2371     }
  2372   else
  2373     {
  2374       /* Scrolling down.  Make sure we don't copy over the mode line.
  2375          at the bottom.  */
  2376       if (to_y + run->height > bottom_y)
  2377         height = bottom_y - to_y;
  2378       else
  2379         height = run->height;
  2380     }
  2381 
  2382   block_input ();
  2383 
  2384   /* Cursor off.  Will be switched on again in gui_update_window_end.  */
  2385   gui_clear_cursor (w);
  2386 
  2387   /* To avoid sequence point problems, make sure to only call
  2388      FRAME_ANDROID_DRAWABLE once.  */
  2389   android_copy_area (FRAME_ANDROID_DRAWABLE (f),
  2390                      FRAME_ANDROID_WINDOW (f),
  2391                      f->output_data.android->normal_gc,
  2392                      x, from_y, width, height, x, to_y);
  2393 
  2394   unblock_input ();
  2395 }
  2396 
  2397 static void
  2398 android_after_update_window_line (struct window *w, struct glyph_row *desired_row)
  2399 {
  2400   eassert (w);
  2401 
  2402   if (!desired_row->mode_line_p && !w->pseudo_window_p)
  2403     desired_row->redraw_fringe_bitmaps_p = true;
  2404 }
  2405 
  2406 static void
  2407 android_flip_and_flush (struct frame *f)
  2408 {
  2409   block_input ();
  2410 
  2411   if (FRAME_ANDROID_NEED_BUFFER_FLIP (f))
  2412     show_back_buffer (f);
  2413 
  2414   /* The frame is complete again as its contents were just
  2415      flushed.  */
  2416   FRAME_ANDROID_COMPLETE_P (f) = true;
  2417   unblock_input ();
  2418 }
  2419 
  2420 static void
  2421 android_clear_rectangle (struct frame *f, struct android_gc *gc, int x,
  2422                          int y, int width, int height)
  2423 {
  2424   struct android_gc_values xgcv;
  2425 
  2426   android_get_gc_values (gc, (ANDROID_GC_BACKGROUND
  2427                               | ANDROID_GC_FOREGROUND),
  2428                          &xgcv);
  2429   android_set_foreground (gc, xgcv.background);
  2430   android_fill_rectangle (FRAME_ANDROID_DRAWABLE (f), gc,
  2431                           x, y, width, height);
  2432   android_set_foreground (gc, xgcv.foreground);
  2433 }
  2434 
  2435 static void
  2436 android_reset_clip_rectangles (struct frame *f, struct android_gc *gc)
  2437 {
  2438   android_set_clip_mask (gc, ANDROID_NONE);
  2439 }
  2440 
  2441 static void
  2442 android_clip_to_row (struct window *w, struct glyph_row *row,
  2443                      enum glyph_row_area area, struct android_gc *gc)
  2444 {
  2445   struct android_rectangle clip_rect;
  2446   int window_x, window_y, window_width;
  2447 
  2448   window_box (w, area, &window_x, &window_y, &window_width, 0);
  2449 
  2450   clip_rect.x = window_x;
  2451   clip_rect.y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, row->y));
  2452   clip_rect.y = max (clip_rect.y, window_y);
  2453   clip_rect.width = window_width;
  2454   clip_rect.height = row->visible_height;
  2455 
  2456   android_set_clip_rectangles (gc, 0, 0, &clip_rect, 1);
  2457 }
  2458 
  2459 static void
  2460 android_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
  2461                             struct draw_fringe_bitmap_params *p)
  2462 {
  2463   struct frame *f = XFRAME (WINDOW_FRAME (w));
  2464   struct android_gc *gc = f->output_data.android->normal_gc;
  2465   struct face *face = p->face;
  2466 
  2467   /* Must clip because of partially visible lines.  */
  2468   android_clip_to_row (w, row, ANY_AREA, gc);
  2469 
  2470   if (p->bx >= 0 && !p->overlay_p)
  2471     {
  2472       /* In case the same realized face is used for fringes and for
  2473          something displayed in the text (e.g. face `region' on
  2474          mono-displays, the fill style may have been changed to
  2475          ANDROID_FILL_SOLID in
  2476          android_draw_glyph_string_background.  */
  2477       if (face->stipple)
  2478         {
  2479           android_set_fill_style (face->gc, ANDROID_FILL_OPAQUE_STIPPLED);
  2480           android_fill_rectangle (FRAME_ANDROID_DRAWABLE (f), face->gc,
  2481                                   p->bx, p->by, p->nx, p->ny);
  2482           android_set_fill_style (face->gc, ANDROID_FILL_SOLID);
  2483 
  2484           row->stipple_p = true;
  2485         }
  2486       else
  2487         {
  2488           android_set_background (face->gc, face->background);
  2489           android_clear_rectangle (f, face->gc, p->bx, p->by, p->nx, p->ny);
  2490           android_set_foreground (face->gc, face->foreground);
  2491         }
  2492     }
  2493 
  2494   if (p->which)
  2495     {
  2496       android_drawable drawable;
  2497       char *bits;
  2498       android_pixmap pixmap, clipmask;
  2499       struct android_gc_values gcv;
  2500       unsigned long background, cursor_pixel;
  2501       int depth;
  2502 
  2503       drawable = FRAME_ANDROID_DRAWABLE (f);
  2504       clipmask = ANDROID_NONE;
  2505       background = face->background;
  2506       cursor_pixel = f->output_data.android->cursor_pixel;
  2507       depth = FRAME_DISPLAY_INFO (f)->n_planes;
  2508 
  2509       if (p->wd > 8)
  2510         bits = (char *) (p->bits + p->dh);
  2511       else
  2512         bits = (char *) p->bits + p->dh;
  2513 
  2514       pixmap = android_create_pixmap_from_bitmap_data (bits, p->wd, p->h,
  2515                                                        (p->cursor_p
  2516                                                         ? (p->overlay_p
  2517                                                            ? face->background
  2518                                                            : cursor_pixel)
  2519                                                         : face->foreground),
  2520                                                        background, depth);
  2521 
  2522       if (p->overlay_p)
  2523         {
  2524           clipmask = android_create_pixmap_from_bitmap_data (bits, p->wd, p->h,
  2525                                                              1, 0, 1);
  2526 
  2527           gcv.clip_mask = clipmask;
  2528           gcv.clip_x_origin = p->x;
  2529           gcv.clip_y_origin = p->y;
  2530           android_change_gc (gc, (ANDROID_GC_CLIP_MASK
  2531                                   | ANDROID_GC_CLIP_X_ORIGIN
  2532                                   | ANDROID_GC_CLIP_Y_ORIGIN),
  2533                              &gcv);
  2534         }
  2535 
  2536       android_copy_area (pixmap, drawable, gc, 0, 0, p->wd, p->h,
  2537                          p->x, p->y);
  2538       android_free_pixmap (pixmap);
  2539 
  2540       if (p->overlay_p)
  2541         {
  2542           gcv.clip_mask = ANDROID_NONE;
  2543           android_change_gc (gc, ANDROID_GC_CLIP_MASK, &gcv);
  2544           android_free_pixmap (clipmask);
  2545         }
  2546     }
  2547 
  2548   android_reset_clip_rectangles (f, gc);
  2549 }
  2550 
  2551 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
  2552    face.  */
  2553 
  2554 static void
  2555 android_set_cursor_gc (struct glyph_string *s)
  2556 {
  2557   if (s->font == FRAME_FONT (s->f)
  2558       && s->face->background == FRAME_BACKGROUND_PIXEL (s->f)
  2559       && s->face->foreground == FRAME_FOREGROUND_PIXEL (s->f)
  2560       && !s->cmp)
  2561     s->gc = s->f->output_data.android->cursor_gc;
  2562   else
  2563     {
  2564       /* Cursor on non-default face: must merge.  */
  2565       struct android_gc_values xgcv;
  2566       unsigned long mask;
  2567 
  2568       xgcv.background = s->f->output_data.android->cursor_pixel;
  2569       xgcv.foreground = s->face->background;
  2570 
  2571       /* If the glyph would be invisible, try a different foreground.  */
  2572       if (xgcv.foreground == xgcv.background)
  2573         xgcv.foreground = s->face->foreground;
  2574       if (xgcv.foreground == xgcv.background)
  2575         xgcv.foreground = s->f->output_data.android->cursor_foreground_pixel;
  2576       if (xgcv.foreground == xgcv.background)
  2577         xgcv.foreground = s->face->foreground;
  2578 
  2579       /* Make sure the cursor is distinct from text in this face.  */
  2580       if (xgcv.background == s->face->background
  2581           && xgcv.foreground == s->face->foreground)
  2582         {
  2583           xgcv.background = s->face->foreground;
  2584           xgcv.foreground = s->face->background;
  2585         }
  2586 
  2587       mask = (ANDROID_GC_FOREGROUND | ANDROID_GC_BACKGROUND);
  2588 
  2589       if (FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc)
  2590         android_change_gc (FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc,
  2591                            mask, &xgcv);
  2592       else
  2593         FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc
  2594           = android_create_gc (mask, &xgcv);
  2595 
  2596       s->gc = FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc;
  2597     }
  2598 }
  2599 
  2600 
  2601 /* Set up S->gc of glyph string S for drawing text in mouse face.  */
  2602 
  2603 static void
  2604 android_set_mouse_face_gc (struct glyph_string *s)
  2605 {
  2606   if (s->font == s->face->font)
  2607     s->gc = s->face->gc;
  2608   else
  2609     {
  2610       /* Otherwise construct scratch_cursor_gc with values from FACE
  2611          except for FONT.  */
  2612       struct android_gc_values xgcv;
  2613       unsigned long mask;
  2614 
  2615       xgcv.background = s->face->background;
  2616       xgcv.foreground = s->face->foreground;
  2617 
  2618       mask = (ANDROID_GC_FOREGROUND | ANDROID_GC_BACKGROUND);
  2619 
  2620       if (FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc)
  2621         android_change_gc (FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc,
  2622                            mask, &xgcv);
  2623       else
  2624         FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc
  2625           = android_create_gc (mask, &xgcv);
  2626 
  2627       s->gc = FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc;
  2628     }
  2629 
  2630   eassert (s->gc != 0);
  2631 }
  2632 
  2633 
  2634 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
  2635    Faces to use in the mode line have already been computed when the
  2636    matrix was built, so there isn't much to do, here.  */
  2637 
  2638 static void
  2639 android_set_mode_line_face_gc (struct glyph_string *s)
  2640 {
  2641   s->gc = s->face->gc;
  2642 }
  2643 
  2644 /* Set S->gc of glyph string S for drawing that glyph string.  Set
  2645    S->stippled_p to a non-zero value if the face of S has a stipple
  2646    pattern.  */
  2647 
  2648 static void
  2649 android_set_glyph_string_gc (struct glyph_string *s)
  2650 {
  2651   prepare_face_for_display (s->f, s->face);
  2652 
  2653   if (s->hl == DRAW_NORMAL_TEXT)
  2654     {
  2655       s->gc = s->face->gc;
  2656       s->stippled_p = s->face->stipple != 0;
  2657     }
  2658   else if (s->hl == DRAW_INVERSE_VIDEO)
  2659     {
  2660       android_set_mode_line_face_gc (s);
  2661       s->stippled_p = s->face->stipple != 0;
  2662     }
  2663   else if (s->hl == DRAW_CURSOR)
  2664     {
  2665       android_set_cursor_gc (s);
  2666       s->stippled_p = false;
  2667     }
  2668   else if (s->hl == DRAW_MOUSE_FACE)
  2669     {
  2670       android_set_mouse_face_gc (s);
  2671       s->stippled_p = s->face->stipple != 0;
  2672     }
  2673   else if (s->hl == DRAW_IMAGE_RAISED
  2674            || s->hl == DRAW_IMAGE_SUNKEN)
  2675     {
  2676       s->gc = s->face->gc;
  2677       s->stippled_p = s->face->stipple != 0;
  2678     }
  2679   else
  2680     emacs_abort ();
  2681 
  2682   /* GC must have been set.  */
  2683   eassert (s->gc != 0);
  2684 }
  2685 
  2686 
  2687 /* Set clipping for output of glyph string S.  S may be part of a mode
  2688    line or menu if we don't have X toolkit support.  */
  2689 
  2690 static void
  2691 android_set_glyph_string_clipping (struct glyph_string *s)
  2692 {
  2693   struct android_rectangle *r = s->clip;
  2694   int n = get_glyph_string_clip_rects (s, r, 2);
  2695 
  2696   if (n > 0)
  2697     android_set_clip_rectangles (s->gc, 0, 0, r, n);
  2698   s->num_clips = n;
  2699 }
  2700 
  2701 
  2702 /* Set SRC's clipping for output of glyph string DST.  This is called
  2703    when we are drawing DST's left_overhang or right_overhang only in
  2704    the area of SRC.  */
  2705 
  2706 static void
  2707 android_set_glyph_string_clipping_exactly (struct glyph_string *src,
  2708                                            struct glyph_string *dst)
  2709 {
  2710   struct android_rectangle r;
  2711 
  2712   r.x = src->x;
  2713   r.width = src->width;
  2714   r.y = src->y;
  2715   r.height = src->height;
  2716   dst->clip[0] = r;
  2717   dst->num_clips = 1;
  2718   android_set_clip_rectangles (dst->gc, 0, 0, &r, 1);
  2719 }
  2720 
  2721 static void
  2722 android_compute_glyph_string_overhangs (struct glyph_string *s)
  2723 {
  2724   if (s->cmp == NULL
  2725       && (s->first_glyph->type == CHAR_GLYPH
  2726           || s->first_glyph->type == COMPOSITE_GLYPH))
  2727     {
  2728       struct font_metrics metrics;
  2729 
  2730       if (s->first_glyph->type == CHAR_GLYPH)
  2731         {
  2732           struct font *font = s->font;
  2733           font->driver->text_extents (font, s->char2b, s->nchars, &metrics);
  2734         }
  2735       else
  2736         {
  2737           Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
  2738 
  2739           composition_gstring_width (gstring, s->cmp_from, s->cmp_to, &metrics);
  2740         }
  2741       s->right_overhang = (metrics.rbearing > metrics.width
  2742                            ? metrics.rbearing - metrics.width : 0);
  2743       s->left_overhang = metrics.lbearing < 0 ? - metrics.lbearing : 0;
  2744     }
  2745   else if (s->cmp)
  2746     {
  2747       s->right_overhang = s->cmp->rbearing - s->cmp->pixel_width;
  2748       s->left_overhang = - s->cmp->lbearing;
  2749     }
  2750 }
  2751 
  2752 static void
  2753 android_clear_glyph_string_rect (struct glyph_string *s, int x, int y,
  2754                                  int w, int h)
  2755 {
  2756   android_clear_rectangle (s->f, s->gc, x, y, w, h);
  2757 }
  2758 
  2759 static void
  2760 android_draw_glyph_string_background (struct glyph_string *s, bool force_p)
  2761 {
  2762   /* Nothing to do if background has already been drawn or if it
  2763      shouldn't be drawn in the first place.  */
  2764   if (!s->background_filled_p)
  2765     {
  2766       int box_line_width = max (s->face->box_horizontal_line_width, 0);
  2767 
  2768       if (s->stippled_p)
  2769         {
  2770           /* Fill background with a stipple pattern.  */
  2771           android_set_fill_style (s->gc, ANDROID_FILL_OPAQUE_STIPPLED);
  2772           android_fill_rectangle (FRAME_ANDROID_DRAWABLE (s->f), s->gc,
  2773                                   s->x, s->y + box_line_width,
  2774                                   s->background_width,
  2775                                   s->height - 2 * box_line_width);
  2776           android_set_fill_style (s->gc, ANDROID_FILL_SOLID);
  2777           s->background_filled_p = true;
  2778         }
  2779       else if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
  2780                /* When xdisp.c ignores FONT_HEIGHT, we cannot trust
  2781                   font dimensions, since the actual glyphs might be
  2782                   much smaller.  So in that case we always clear the
  2783                   rectangle with background color.  */
  2784                || FONT_TOO_HIGH (s->font)
  2785                || s->font_not_found_p
  2786                || s->extends_to_end_of_line_p
  2787                || force_p)
  2788         {
  2789           android_clear_glyph_string_rect (s, s->x, s->y + box_line_width,
  2790                                            s->background_width,
  2791                                            s->height - 2 * box_line_width);
  2792           s->background_filled_p = true;
  2793         }
  2794     }
  2795 }
  2796 
  2797 static void
  2798 android_fill_triangle (struct frame *f, struct android_gc *gc,
  2799                        struct android_point point1,
  2800                        struct android_point point2,
  2801                        struct android_point point3)
  2802 {
  2803   struct android_point abc[3];
  2804 
  2805   abc[0] = point1;
  2806   abc[1] = point2;
  2807   abc[2] = point3;
  2808 
  2809   android_fill_polygon (FRAME_ANDROID_DRAWABLE (f),
  2810                         gc, abc, 3, ANDROID_CONVEX,
  2811                         ANDROID_COORD_MODE_ORIGIN);
  2812 }
  2813 
  2814 static struct android_point
  2815 android_make_point (int x, int y)
  2816 {
  2817   struct android_point pt;
  2818 
  2819   pt.x = x;
  2820   pt.y = y;
  2821 
  2822   return pt;
  2823 }
  2824 
  2825 static bool
  2826 android_inside_rect_p (struct android_rectangle *rects, int nrects, int x,
  2827                        int y)
  2828 {
  2829   int i;
  2830 
  2831   for (i = 0; i < nrects; ++i)
  2832     {
  2833       if (x >= rects[i].x && y >= rects[i].y
  2834           && x < rects[i].x + rects[i].width
  2835           && y < rects[i].y + rects[i].height)
  2836         return true;
  2837     }
  2838 
  2839   return false;
  2840 }
  2841 
  2842 static void
  2843 android_clear_point (struct frame *f, struct android_gc *gc,
  2844                      int x, int y)
  2845 {
  2846   struct android_gc_values xgcv;
  2847 
  2848   android_get_gc_values (gc, ANDROID_GC_BACKGROUND | ANDROID_GC_FOREGROUND,
  2849                          &xgcv);
  2850   android_set_foreground (gc, xgcv.background);
  2851   android_draw_point (FRAME_ANDROID_DRAWABLE (f), gc, x, y);
  2852   android_set_foreground (gc, xgcv.foreground);
  2853 }
  2854 
  2855 static void
  2856 android_draw_relief_rect (struct frame *f, int left_x, int top_y, int right_x,
  2857                           int bottom_y, int hwidth, int vwidth, bool raised_p,
  2858                           bool top_p, bool bot_p, bool left_p, bool right_p,
  2859                           struct android_rectangle *clip_rect)
  2860 {
  2861   struct android_gc *gc, *white_gc, *black_gc, *normal_gc;
  2862   android_drawable drawable;
  2863 
  2864   /* This code is more complicated than it has to be, because of two
  2865      minor hacks to make the boxes look nicer: (i) if width > 1, draw
  2866      the outermost line using the black relief.  (ii) Omit the four
  2867      corner pixels.  */
  2868 
  2869   white_gc = f->output_data.android->white_relief.gc;
  2870   black_gc = f->output_data.android->black_relief.gc;
  2871   normal_gc = f->output_data.android->normal_gc;
  2872 
  2873   drawable = FRAME_ANDROID_DRAWABLE (f);
  2874 
  2875   android_set_clip_rectangles (white_gc, 0, 0, clip_rect, 1);
  2876   android_set_clip_rectangles (black_gc, 0, 0, clip_rect, 1);
  2877 
  2878   if (raised_p)
  2879     gc = white_gc;
  2880   else
  2881     gc = black_gc;
  2882 
  2883   /* Draw lines.  */
  2884 
  2885   if (top_p)
  2886     android_fill_rectangle (FRAME_ANDROID_DRAWABLE (f), gc, left_x, top_y,
  2887                             right_x - left_x + 1, hwidth);
  2888 
  2889   if (left_p)
  2890     android_fill_rectangle (FRAME_ANDROID_DRAWABLE (f), gc, left_x, top_y,
  2891                             vwidth, bottom_y - top_y + 1);
  2892 
  2893   if (raised_p)
  2894     gc = black_gc;
  2895   else
  2896     gc = white_gc;
  2897 
  2898   if (bot_p)
  2899     android_fill_rectangle (FRAME_ANDROID_DRAWABLE (f), gc, left_x,
  2900                             bottom_y - hwidth + 1,
  2901                             right_x - left_x + 1, hwidth);
  2902 
  2903   if (right_p)
  2904     android_fill_rectangle (FRAME_ANDROID_DRAWABLE (f), gc,
  2905                             right_x - vwidth + 1,
  2906                             top_y, vwidth, bottom_y - top_y + 1);
  2907 
  2908   /* Draw corners.  */
  2909 
  2910   if (bot_p && left_p)
  2911     android_fill_triangle (f, raised_p ? white_gc : black_gc,
  2912                            android_make_point (left_x, bottom_y - hwidth),
  2913                            android_make_point (left_x + vwidth,
  2914                                                bottom_y - hwidth),
  2915                            android_make_point (left_x, bottom_y));
  2916 
  2917   if (top_p && right_p)
  2918     android_fill_triangle (f, raised_p ? white_gc : black_gc,
  2919                            android_make_point (right_x - vwidth, top_y),
  2920                            android_make_point (right_x, top_y),
  2921                            android_make_point (right_x - vwidth,
  2922                                                top_y + hwidth));
  2923 
  2924   /* Draw outer line.  */
  2925 
  2926   if (top_p && left_p && bot_p && right_p
  2927       && hwidth > 1 && vwidth > 1)
  2928     android_draw_rectangle (FRAME_ANDROID_DRAWABLE (f),
  2929                             black_gc, left_x, top_y,
  2930                             right_x - left_x, bottom_y - top_y);
  2931   else
  2932     {
  2933       if (top_p && hwidth > 1)
  2934         android_draw_line (drawable, black_gc, left_x, top_y,
  2935                            right_x + 1, top_y);
  2936 
  2937       if (bot_p && hwidth > 1)
  2938         android_draw_line (drawable, black_gc, left_x, bottom_y,
  2939                            right_x + 1, bottom_y);
  2940 
  2941       if (left_p && vwidth > 1)
  2942         android_draw_line (drawable, black_gc, left_x, top_y,
  2943                            left_x, bottom_y + 1);
  2944 
  2945       if (right_p && vwidth > 1)
  2946         android_draw_line (drawable, black_gc, right_x, top_y,
  2947                            right_x, bottom_y + 1);
  2948     }
  2949 
  2950   /* Erase corners.  */
  2951 
  2952   if (hwidth > 1 && vwidth > 1)
  2953     {
  2954       if (left_p && top_p && android_inside_rect_p (clip_rect, 1,
  2955                                                     left_x, top_y))
  2956         android_clear_point (f, normal_gc, left_x, top_y);
  2957 
  2958       if (left_p && bot_p && android_inside_rect_p (clip_rect, 1,
  2959                                                     left_x, bottom_y))
  2960         android_clear_point (f, normal_gc, left_x, bottom_y);
  2961 
  2962       if (right_p && top_p && android_inside_rect_p (clip_rect, 1,
  2963                                                      right_x, top_y))
  2964         android_clear_point (f, normal_gc, right_x, top_y);
  2965 
  2966       if (right_p && bot_p && android_inside_rect_p (clip_rect, 1,
  2967                                                      right_x, bottom_y))
  2968         android_clear_point (f, normal_gc, right_x, bottom_y);
  2969     }
  2970 
  2971   android_reset_clip_rectangles (f, white_gc);
  2972   android_reset_clip_rectangles (f, black_gc);
  2973 }
  2974 
  2975 static void
  2976 android_draw_box_rect (struct glyph_string *s,
  2977                        int left_x, int top_y, int right_x, int bottom_y,
  2978                        int hwidth, int vwidth, bool left_p, bool right_p,
  2979                        struct android_rectangle *clip_rect)
  2980 {
  2981   struct android_gc_values xgcv;
  2982 
  2983   android_get_gc_values (s->gc, ANDROID_GC_FOREGROUND, &xgcv);
  2984   android_set_foreground (s->gc, s->face->box_color);
  2985   android_set_clip_rectangles (s->gc, 0, 0, clip_rect, 1);
  2986 
  2987   /* Top.  */
  2988   android_fill_rectangle (FRAME_ANDROID_DRAWABLE (s->f), s->gc, left_x,
  2989                           top_y, right_x - left_x + 1, hwidth);
  2990 
  2991   /* Left.  */
  2992   if (left_p)
  2993     android_fill_rectangle (FRAME_ANDROID_DRAWABLE (s->f), s->gc, left_x,
  2994                             top_y, vwidth, bottom_y - top_y + 1);
  2995 
  2996   /* Bottom.  */
  2997   android_fill_rectangle (FRAME_ANDROID_DRAWABLE (s->f), s->gc, left_x,
  2998                           bottom_y - hwidth + 1, right_x - left_x + 1,
  2999                           hwidth);
  3000 
  3001   /* Right.  */
  3002   if (right_p)
  3003     android_fill_rectangle (FRAME_ANDROID_DRAWABLE (s->f), s->gc,
  3004                             right_x - vwidth + 1, top_y, vwidth,
  3005                             bottom_y - top_y + 1);
  3006 
  3007   android_set_foreground (s->gc, xgcv.foreground);
  3008   android_reset_clip_rectangles (s->f, s->gc);
  3009 }
  3010 
  3011 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 48000
  3012 
  3013 static bool
  3014 android_alloc_lighter_color (struct frame *f, unsigned long *pixel,
  3015                              double factor, int delta)
  3016 {
  3017   Emacs_Color color, new;
  3018   long bright;
  3019   bool success_p;
  3020 
  3021   /* Get RGB color values.  */
  3022   color.pixel = *pixel;
  3023   android_query_colors (f, &color, 1);
  3024 
  3025   /* Change RGB values by specified FACTOR.  Avoid overflow!  */
  3026   eassert (factor >= 0);
  3027   new.red = min (0xffff, factor * color.red);
  3028   new.green = min (0xffff, factor * color.green);
  3029   new.blue = min (0xffff, factor * color.blue);
  3030 
  3031   /* Calculate brightness of COLOR.  */
  3032   bright = (2 * color.red + 3 * color.green + color.blue) / 6;
  3033 
  3034   /* We only boost colors that are darker than
  3035      HIGHLIGHT_COLOR_DARK_BOOST_LIMIT.  */
  3036   if (bright < HIGHLIGHT_COLOR_DARK_BOOST_LIMIT)
  3037     /* Make an additive adjustment to NEW, because it's dark enough so
  3038        that scaling by FACTOR alone isn't enough.  */
  3039     {
  3040       /* How far below the limit this color is (0 - 1, 1 being darker).  */
  3041       double dimness = 1 - (double) bright / HIGHLIGHT_COLOR_DARK_BOOST_LIMIT;
  3042       /* The additive adjustment.  */
  3043       int min_delta = delta * dimness * factor / 2;
  3044 
  3045       if (factor < 1)
  3046         {
  3047           new.red =   max (0, new.red -   min_delta);
  3048           new.green = max (0, new.green - min_delta);
  3049           new.blue =  max (0, new.blue -  min_delta);
  3050         }
  3051       else
  3052         {
  3053           new.red =   min (0xffff, min_delta + new.red);
  3054           new.green = min (0xffff, min_delta + new.green);
  3055           new.blue =  min (0xffff, min_delta + new.blue);
  3056         }
  3057     }
  3058 
  3059   /* Try to allocate the color.  */
  3060   success_p = android_alloc_nearest_color (f, &new);
  3061 
  3062   if (success_p)
  3063     {
  3064       if (new.pixel == *pixel)
  3065         {
  3066           /* If we end up with the same color as before, try adding
  3067              delta to the RGB values.  */
  3068           new.red = min (0xffff, delta + color.red);
  3069           new.green = min (0xffff, delta + color.green);
  3070           new.blue = min (0xffff, delta + color.blue);
  3071           success_p = android_alloc_nearest_color (f, &new);
  3072         }
  3073       else
  3074         success_p = true;
  3075 
  3076       *pixel = new.pixel;
  3077     }
  3078 
  3079   return success_p;
  3080 }
  3081 
  3082 /* Set up the foreground color for drawing relief lines of glyph
  3083    string S.  RELIEF is a pointer to a struct relief containing the GC
  3084    with which lines will be drawn.  Use a color that is FACTOR or
  3085    DELTA lighter or darker than the relief's background which is found
  3086    in S->f->output_data.android->relief_background.  If such a color
  3087    cannot be allocated, use DEFAULT_PIXEL, instead.  */
  3088 
  3089 static void
  3090 android_setup_relief_color (struct frame *f, struct relief *relief,
  3091                             double factor, int delta,
  3092                             unsigned long default_pixel)
  3093 {
  3094   struct android_gc_values xgcv;
  3095   struct android_output *di = f->output_data.android;
  3096   unsigned long mask = ANDROID_GC_FOREGROUND;
  3097   unsigned long pixel;
  3098   unsigned long background = di->relief_background;
  3099   struct android_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
  3100 
  3101   if (relief->gc && relief->pixel != -1)
  3102     relief->pixel = -1;
  3103 
  3104   /* Allocate new color.  */
  3105   xgcv.foreground = default_pixel;
  3106   pixel = background;
  3107 
  3108   if (dpyinfo->n_planes != 1
  3109       && android_alloc_lighter_color (f, &pixel, factor, delta))
  3110     xgcv.foreground = relief->pixel = pixel;
  3111 
  3112   if (relief->gc == 0)
  3113     relief->gc = android_create_gc (mask, &xgcv);
  3114   else
  3115     android_change_gc (relief->gc, mask, &xgcv);
  3116 }
  3117 
  3118 /* Set up colors for the relief lines around glyph string S.  */
  3119 
  3120 static void
  3121 android_setup_relief_colors (struct glyph_string *s)
  3122 {
  3123   struct android_output *di;
  3124   unsigned long color;
  3125 
  3126   di = s->f->output_data.android;
  3127 
  3128   if (s->face->use_box_color_for_shadows_p)
  3129     color = s->face->box_color;
  3130   else if (s->first_glyph->type == IMAGE_GLYPH
  3131            && s->img->pixmap
  3132            && !IMAGE_BACKGROUND_TRANSPARENT (s->img, s->f, 0))
  3133     color = IMAGE_BACKGROUND (s->img, s->f, 0);
  3134   else
  3135     {
  3136       struct android_gc_values xgcv;
  3137 
  3138       /* Get the background color of the face.  */
  3139       android_get_gc_values (s->gc, ANDROID_GC_BACKGROUND, &xgcv);
  3140       color = xgcv.background;
  3141     }
  3142 
  3143   if (di->white_relief.gc == 0
  3144       || color != di->relief_background)
  3145     {
  3146       di->relief_background = color;
  3147       android_setup_relief_color (s->f, &di->white_relief, 1.2, 0x8000,
  3148                                   WHITE_PIX_DEFAULT (s->f));
  3149       android_setup_relief_color (s->f, &di->black_relief, 0.6, 0x4000,
  3150                                   BLACK_PIX_DEFAULT (s->f));
  3151     }
  3152 }
  3153 
  3154 static void
  3155 android_draw_glyph_string_box (struct glyph_string *s)
  3156 {
  3157   int hwidth, vwidth, left_x, right_x, top_y, bottom_y, last_x;
  3158   bool raised_p, left_p, right_p;
  3159   struct glyph *last_glyph;
  3160   struct android_rectangle clip_rect;
  3161 
  3162   last_x = ((s->row->full_width_p && !s->w->pseudo_window_p)
  3163             ? WINDOW_RIGHT_EDGE_X (s->w)
  3164             : window_box_right (s->w, s->area));
  3165 
  3166   /* The glyph that may have a right box line.  For static
  3167      compositions and images, the right-box flag is on the first glyph
  3168      of the glyph string; for other types it's on the last glyph.  */
  3169   if (s->cmp || s->img)
  3170     last_glyph = s->first_glyph;
  3171   else if (s->first_glyph->type == COMPOSITE_GLYPH
  3172            && s->first_glyph->u.cmp.automatic)
  3173     {
  3174       /* For automatic compositions, we need to look up the last glyph
  3175          in the composition.  */
  3176         struct glyph *end = s->row->glyphs[s->area] + s->row->used[s->area];
  3177         struct glyph *g = s->first_glyph;
  3178         for (last_glyph = g++;
  3179              g < end && g->u.cmp.automatic && g->u.cmp.id == s->cmp_id
  3180                && g->slice.cmp.to < s->cmp_to;
  3181              last_glyph = g++)
  3182           ;
  3183     }
  3184   else
  3185     last_glyph = s->first_glyph + s->nchars - 1;
  3186 
  3187   vwidth = eabs (s->face->box_vertical_line_width);
  3188   hwidth = eabs (s->face->box_horizontal_line_width);
  3189   raised_p = s->face->box == FACE_RAISED_BOX;
  3190   left_x = s->x;
  3191   right_x = (s->row->full_width_p && s->extends_to_end_of_line_p
  3192              ? last_x - 1
  3193              : min (last_x, s->x + s->background_width) - 1);
  3194   top_y = s->y;
  3195   bottom_y = top_y + s->height - 1;
  3196 
  3197   left_p = (s->first_glyph->left_box_line_p
  3198             || (s->hl == DRAW_MOUSE_FACE
  3199                 && (s->prev == NULL
  3200                     || s->prev->hl != s->hl)));
  3201   right_p = (last_glyph->right_box_line_p
  3202              || (s->hl == DRAW_MOUSE_FACE
  3203                  && (s->next == NULL
  3204                      || s->next->hl != s->hl)));
  3205 
  3206   get_glyph_string_clip_rect (s, &clip_rect);
  3207 
  3208   if (s->face->box == FACE_SIMPLE_BOX)
  3209     android_draw_box_rect (s, left_x, top_y, right_x, bottom_y, hwidth,
  3210                            vwidth, left_p, right_p, &clip_rect);
  3211   else
  3212     {
  3213       android_setup_relief_colors (s);
  3214       android_draw_relief_rect (s->f, left_x, top_y, right_x, bottom_y, hwidth,
  3215                                 vwidth, raised_p, true, true, left_p, right_p,
  3216                                 &clip_rect);
  3217     }
  3218 }
  3219 
  3220 static void
  3221 android_draw_glyph_string_bg_rect (struct glyph_string *s, int x, int y,
  3222                                    int w, int h)
  3223 {
  3224   if (s->stippled_p)
  3225     {
  3226       /* Fill background with a stipple pattern.  */
  3227       android_set_fill_style (s->gc, ANDROID_FILL_OPAQUE_STIPPLED);
  3228       android_fill_rectangle (FRAME_ANDROID_DRAWABLE (s->f), s->gc, x,
  3229                               y, w, h);
  3230       android_set_fill_style (s->gc, ANDROID_FILL_SOLID);
  3231     }
  3232   else
  3233     android_clear_glyph_string_rect (s, x, y, w, h);
  3234 }
  3235 
  3236 static void
  3237 android_draw_image_relief (struct glyph_string *s)
  3238 {
  3239   int x1, y1, thick;
  3240   bool raised_p, top_p, bot_p, left_p, right_p;
  3241   int extra_x, extra_y;
  3242   struct android_rectangle r;
  3243   int x = s->x;
  3244   int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
  3245 
  3246   /* If first glyph of S has a left box line, start drawing it to the
  3247      right of that line.  */
  3248   if (s->face->box != FACE_NO_BOX
  3249       && s->first_glyph->left_box_line_p
  3250       && s->slice.x == 0)
  3251     x += max (s->face->box_vertical_line_width, 0);
  3252 
  3253   /* If there is a margin around the image, adjust x- and y-position
  3254      by that margin.  */
  3255   if (s->slice.x == 0)
  3256     x += s->img->hmargin;
  3257   if (s->slice.y == 0)
  3258     y += s->img->vmargin;
  3259 
  3260   if (s->hl == DRAW_IMAGE_SUNKEN
  3261       || s->hl == DRAW_IMAGE_RAISED)
  3262     {
  3263       if (s->face->id == TAB_BAR_FACE_ID)
  3264         thick = (tab_bar_button_relief < 0
  3265                  ? DEFAULT_TAB_BAR_BUTTON_RELIEF
  3266                  : min (tab_bar_button_relief, 1000000));
  3267       else
  3268         thick = (tool_bar_button_relief < 0
  3269                  ? DEFAULT_TOOL_BAR_BUTTON_RELIEF
  3270                  : min (tool_bar_button_relief, 1000000));
  3271       raised_p = s->hl == DRAW_IMAGE_RAISED;
  3272     }
  3273   else
  3274     {
  3275       thick = eabs (s->img->relief);
  3276       raised_p = s->img->relief > 0;
  3277     }
  3278 
  3279   x1 = x + s->slice.width - 1;
  3280   y1 = y + s->slice.height - 1;
  3281 
  3282   extra_x = extra_y = 0;
  3283   if (s->face->id == TAB_BAR_FACE_ID)
  3284     {
  3285       if (CONSP (Vtab_bar_button_margin)
  3286           && FIXNUMP (XCAR (Vtab_bar_button_margin))
  3287           && FIXNUMP (XCDR (Vtab_bar_button_margin)))
  3288         {
  3289           extra_x = XFIXNUM (XCAR (Vtab_bar_button_margin)) - thick;
  3290           extra_y = XFIXNUM (XCDR (Vtab_bar_button_margin)) - thick;
  3291         }
  3292       else if (FIXNUMP (Vtab_bar_button_margin))
  3293         extra_x = extra_y = XFIXNUM (Vtab_bar_button_margin) - thick;
  3294     }
  3295 
  3296   if (s->face->id == TOOL_BAR_FACE_ID)
  3297     {
  3298       if (CONSP (Vtool_bar_button_margin)
  3299           && FIXNUMP (XCAR (Vtool_bar_button_margin))
  3300           && FIXNUMP (XCDR (Vtool_bar_button_margin)))
  3301         {
  3302           extra_x = XFIXNUM (XCAR (Vtool_bar_button_margin));
  3303           extra_y = XFIXNUM (XCDR (Vtool_bar_button_margin));
  3304         }
  3305       else if (FIXNUMP (Vtool_bar_button_margin))
  3306         extra_x = extra_y = XFIXNUM (Vtool_bar_button_margin);
  3307     }
  3308 
  3309   top_p = bot_p = left_p = right_p = false;
  3310 
  3311   if (s->slice.x == 0)
  3312     x -= thick + extra_x, left_p = true;
  3313   if (s->slice.y == 0)
  3314     y -= thick + extra_y, top_p = true;
  3315   if (s->slice.x + s->slice.width == s->img->width)
  3316     x1 += thick + extra_x, right_p = true;
  3317   if (s->slice.y + s->slice.height == s->img->height)
  3318     y1 += thick + extra_y, bot_p = true;
  3319 
  3320   android_setup_relief_colors (s);
  3321   get_glyph_string_clip_rect (s, &r);
  3322   android_draw_relief_rect (s->f, x, y, x1, y1, thick, thick, raised_p,
  3323                             top_p, bot_p, left_p, right_p, &r);
  3324 }
  3325 
  3326 static void
  3327 android_draw_image_foreground (struct glyph_string *s)
  3328 {
  3329   int x = s->x;
  3330   int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
  3331 
  3332   /* If first glyph of S has a left box line, start drawing it to the
  3333      right of that line.  */
  3334   if (s->face->box != FACE_NO_BOX
  3335       && s->first_glyph->left_box_line_p
  3336       && s->slice.x == 0)
  3337     x += max (s->face->box_vertical_line_width, 0);
  3338 
  3339   /* If there is a margin around the image, adjust x- and y-position
  3340      by that margin.  */
  3341   if (s->slice.x == 0)
  3342     x += s->img->hmargin;
  3343   if (s->slice.y == 0)
  3344     y += s->img->vmargin;
  3345 
  3346   if (s->img->pixmap)
  3347     {
  3348       unsigned long mask = (ANDROID_GC_CLIP_MASK
  3349                             | ANDROID_GC_CLIP_X_ORIGIN
  3350                             | ANDROID_GC_CLIP_Y_ORIGIN
  3351                             | ANDROID_GC_FUNCTION);
  3352       struct android_gc_values xgcv;
  3353       struct android_rectangle clip_rect, image_rect, r;
  3354 
  3355       xgcv.clip_mask = s->img->mask;
  3356       xgcv.clip_x_origin = x - s->slice.x;
  3357       xgcv.clip_y_origin = y - s->slice.y;
  3358       xgcv.function = ANDROID_GC_COPY;
  3359       android_change_gc (s->gc, mask, &xgcv);
  3360 
  3361       get_glyph_string_clip_rect (s, &clip_rect);
  3362       image_rect.x = x;
  3363       image_rect.y = y;
  3364       image_rect.width = s->slice.width;
  3365       image_rect.height = s->slice.height;
  3366 
  3367       if (gui_intersect_rectangles (&clip_rect, &image_rect, &r))
  3368         android_copy_area (s->img->pixmap,
  3369                            FRAME_ANDROID_DRAWABLE (s->f),
  3370                            s->gc, s->slice.x + r.x - x,
  3371                            s->slice.y + r.y - y,
  3372                            r.width, r.height, r.x, r.y);
  3373 
  3374       /* When the image has a mask, we can expect that at least part
  3375          of a mouse highlight or a block cursor will be visible.  If
  3376          the image doesn't have a mask, make a block cursor visible by
  3377          drawing a rectangle around the image.  I believe it's looking
  3378          better if we do nothing here for mouse-face.  */
  3379       if (s->hl == DRAW_CURSOR && !s->img->mask)
  3380         {
  3381           int relief = eabs (s->img->relief);
  3382           android_draw_rectangle (FRAME_ANDROID_DRAWABLE (s->f), s->gc,
  3383                                   x - relief, y - relief,
  3384                                   s->slice.width + relief*2 - 1,
  3385                                   s->slice.height + relief*2 - 1);
  3386         }
  3387 
  3388       android_set_clip_mask (s->gc, ANDROID_NONE);
  3389     }
  3390   else
  3391     /* Draw a rectangle if image could not be loaded.  */
  3392     android_draw_rectangle (FRAME_ANDROID_DRAWABLE (s->f), s->gc, x, y,
  3393                             s->slice.width - 1, s->slice.height - 1);
  3394 }
  3395 
  3396 static void
  3397 android_draw_image_glyph_string (struct glyph_string *s)
  3398 {
  3399   int box_line_hwidth = max (s->face->box_vertical_line_width, 0);
  3400   int box_line_vwidth = max (s->face->box_horizontal_line_width, 0);
  3401   int height;
  3402 
  3403   height = s->height;
  3404   if (s->slice.y == 0)
  3405     height -= box_line_vwidth;
  3406   if (s->slice.y + s->slice.height >= s->img->height)
  3407     height -= box_line_vwidth;
  3408 
  3409   /* Fill background with face under the image.  Do it only if row is
  3410      taller than image or if image has a clip mask to reduce
  3411      flickering.  */
  3412   s->stippled_p = s->face->stipple != 0;
  3413   if (height > s->slice.height
  3414       || s->img->hmargin
  3415       || s->img->vmargin
  3416       || s->img->mask
  3417       || s->img->pixmap == 0
  3418       || s->width != s->background_width)
  3419     {
  3420       if (s->stippled_p)
  3421         s->row->stipple_p = true;
  3422 
  3423       int x = s->x;
  3424       int y = s->y;
  3425       int width = s->background_width;
  3426 
  3427       if (s->first_glyph->left_box_line_p
  3428           && s->slice.x == 0)
  3429         {
  3430           x += box_line_hwidth;
  3431           width -= box_line_hwidth;
  3432         }
  3433 
  3434       if (s->slice.y == 0)
  3435         y += box_line_vwidth;
  3436 
  3437       android_draw_glyph_string_bg_rect (s, x, y, width, height);
  3438 
  3439       s->background_filled_p = true;
  3440     }
  3441 
  3442   /* Draw the foreground.  */
  3443   android_draw_image_foreground (s);
  3444   android_set_glyph_string_clipping (s);
  3445 
  3446   /* If we must draw a relief around the image, do it.  */
  3447   if (s->img->relief
  3448       || s->hl == DRAW_IMAGE_RAISED
  3449       || s->hl == DRAW_IMAGE_SUNKEN)
  3450     android_draw_image_relief (s);
  3451 }
  3452 
  3453 static void
  3454 android_draw_stretch_glyph_string (struct glyph_string *s)
  3455 {
  3456   eassert (s->first_glyph->type == STRETCH_GLYPH);
  3457 
  3458   if (s->hl == DRAW_CURSOR && !x_stretch_cursor_p)
  3459     {
  3460       /* If `x-stretch-cursor' is nil, don't draw a block cursor as
  3461          wide as the stretch glyph.  */
  3462       int width, background_width = s->background_width;
  3463       int x = s->x;
  3464 
  3465       if (!s->row->reversed_p)
  3466         {
  3467           int left_x = window_box_left_offset (s->w, TEXT_AREA);
  3468 
  3469           if (x < left_x)
  3470             {
  3471               background_width -= left_x - x;
  3472               x = left_x;
  3473             }
  3474         }
  3475       else
  3476         {
  3477           /* In R2L rows, draw the cursor on the right edge of the
  3478              stretch glyph.  */
  3479           int right_x = window_box_right (s->w, TEXT_AREA);
  3480 
  3481           if (x + background_width > right_x)
  3482             background_width -= x - right_x;
  3483           x += background_width;
  3484         }
  3485       width = min (FRAME_COLUMN_WIDTH (s->f), background_width);
  3486       if (s->row->reversed_p)
  3487         x -= width;
  3488 
  3489       /* Draw cursor.  */
  3490       android_draw_glyph_string_bg_rect (s, x, s->y, width, s->height);
  3491 
  3492       /* Clear rest using the GC of the original non-cursor face.  */
  3493       if (width < background_width)
  3494         {
  3495           int y = s->y;
  3496           int w = background_width - width, h = s->height;
  3497           struct android_rectangle r;
  3498           struct android_gc *gc;
  3499 
  3500           if (!s->row->reversed_p)
  3501             x += width;
  3502           else
  3503             x = s->x;
  3504           if (s->row->mouse_face_p
  3505               && cursor_in_mouse_face_p (s->w))
  3506             {
  3507               android_set_mouse_face_gc (s);
  3508               gc = s->gc;
  3509             }
  3510           else
  3511             gc = s->face->gc;
  3512 
  3513           get_glyph_string_clip_rect (s, &r);
  3514           android_set_clip_rectangles (gc, 0, 0, &r, 1);
  3515 
  3516           if (s->face->stipple)
  3517             {
  3518               /* Fill background with a stipple pattern.  */
  3519               android_set_fill_style (gc, ANDROID_FILL_OPAQUE_STIPPLED);
  3520               android_fill_rectangle (FRAME_ANDROID_DRAWABLE (s->f),
  3521                                       gc, x, y, w, h);
  3522               android_set_fill_style (gc, ANDROID_FILL_SOLID);
  3523 
  3524               s->row->stipple_p = true;
  3525             }
  3526           else
  3527             {
  3528               struct android_gc_values xgcv;
  3529               android_get_gc_values (gc, (ANDROID_GC_FOREGROUND
  3530                                           | ANDROID_GC_BACKGROUND),
  3531                                      &xgcv);
  3532               android_set_foreground (gc, xgcv.background);
  3533               android_fill_rectangle (FRAME_ANDROID_DRAWABLE (s->f),
  3534                                       gc, x, y, w, h);
  3535               android_set_foreground (gc, xgcv.foreground);
  3536             }
  3537 
  3538           android_reset_clip_rectangles (s->f, gc);
  3539         }
  3540     }
  3541   else if (!s->background_filled_p)
  3542     {
  3543       int background_width = s->background_width;
  3544       int x = s->x, text_left_x = window_box_left (s->w, TEXT_AREA);
  3545 
  3546       /* Don't draw into left fringe or scrollbar area except for
  3547          header line and mode line.  */
  3548       if (s->area == TEXT_AREA
  3549           && x < text_left_x && !s->row->mode_line_p)
  3550         {
  3551           background_width -= text_left_x - x;
  3552           x = text_left_x;
  3553         }
  3554 
  3555       if (!s->row->stipple_p)
  3556         s->row->stipple_p = s->stippled_p;
  3557 
  3558       if (background_width > 0)
  3559         android_draw_glyph_string_bg_rect (s, x, s->y,
  3560                                            background_width,
  3561                                            s->height);
  3562     }
  3563 
  3564   s->background_filled_p = true;
  3565 }
  3566 
  3567 static void
  3568 android_get_scale_factor (int *scale_x, int *scale_y)
  3569 {
  3570   /* This is 96 everywhere else, but 160 on Android.  */
  3571   const int base_res = 160;
  3572   struct android_display_info *dpyinfo;
  3573 
  3574   dpyinfo = x_display_list;
  3575   *scale_x = *scale_y = 1;
  3576 
  3577   if (dpyinfo)
  3578     {
  3579       if (dpyinfo->resx > base_res)
  3580         *scale_x = floor (dpyinfo->resx / base_res);
  3581       if (dpyinfo->resy > base_res)
  3582         *scale_y = floor (dpyinfo->resy / base_res);
  3583     }
  3584 }
  3585 
  3586 static void
  3587 android_draw_underwave (struct glyph_string *s, int decoration_width)
  3588 {
  3589   int scale_x, scale_y;
  3590 
  3591   android_get_scale_factor (&scale_x, &scale_y);
  3592 
  3593   int wave_height = 3 * scale_y, wave_length = 2 * scale_x;
  3594 
  3595   int dx, dy, x0, y0, width, x1, y1, x2, y2, xmax;
  3596   bool odd;
  3597   struct android_rectangle wave_clip, string_clip, final_clip;
  3598 
  3599   dx = wave_length;
  3600   dy = wave_height - 1;
  3601   x0 = s->x;
  3602   y0 = s->ybase + wave_height / 2;
  3603   width = decoration_width;
  3604   xmax = x0 + width;
  3605 
  3606   /* Find and set clipping rectangle */
  3607 
  3608   wave_clip.x = x0;
  3609   wave_clip.y = y0;
  3610   wave_clip.width = width;
  3611   wave_clip.height = wave_height;
  3612   get_glyph_string_clip_rect (s, &string_clip);
  3613 
  3614   if (!gui_intersect_rectangles (&wave_clip, &string_clip, &final_clip))
  3615     return;
  3616 
  3617   android_set_clip_rectangles (s->gc, 0, 0, &final_clip, 1);
  3618 
  3619   /* Draw the waves */
  3620 
  3621   x1 = x0 - (x0 % dx);
  3622   x2 = x1 + dx;
  3623   odd = (x1 / dx) & 1;
  3624   y1 = y2 = y0;
  3625 
  3626   if (odd)
  3627     y1 += dy;
  3628   else
  3629     y2 += dy;
  3630 
  3631   if (INT_MAX - dx < xmax)
  3632     emacs_abort ();
  3633 
  3634   while (x1 <= xmax)
  3635     {
  3636       android_draw_line (FRAME_ANDROID_DRAWABLE (s->f), s->gc,
  3637                          x1, y1, x2, y2);
  3638       x1  = x2, y1 = y2;
  3639       x2 += dx, y2 = y0 + odd*dy;
  3640       odd = !odd;
  3641     }
  3642 
  3643   /* Restore previous clipping rectangle(s) */
  3644   android_set_clip_rectangles (s->gc, 0, 0, s->clip, s->num_clips);
  3645 }
  3646 
  3647 static void
  3648 android_draw_glyph_string_foreground (struct glyph_string *s)
  3649 {
  3650   int i, x;
  3651 
  3652   /* If first glyph of S has a left box line, start drawing the text
  3653      of S to the right of that box line.  */
  3654   if (s->face->box != FACE_NO_BOX
  3655       && s->first_glyph->left_box_line_p)
  3656     x = s->x + max (s->face->box_vertical_line_width, 0);
  3657   else
  3658     x = s->x;
  3659 
  3660   /* Draw characters of S as rectangles if S's font could not be
  3661      loaded.  */
  3662   if (s->font_not_found_p)
  3663     {
  3664       for (i = 0; i < s->nchars; ++i)
  3665         {
  3666           struct glyph *g = s->first_glyph + i;
  3667           android_draw_rectangle (FRAME_ANDROID_DRAWABLE (s->f),
  3668                                   s->gc, x, s->y,
  3669                                   g->pixel_width - 1,
  3670                                   s->height - 1);
  3671           x += g->pixel_width;
  3672         }
  3673     }
  3674   else
  3675     {
  3676       struct font *font = s->font;
  3677       int boff = font->baseline_offset;
  3678       int y;
  3679 
  3680       if (font->vertical_centering)
  3681         boff = VCENTER_BASELINE_OFFSET (font, s->f) - boff;
  3682 
  3683       y = s->ybase - boff;
  3684       if (s->for_overlaps
  3685           || (s->background_filled_p && s->hl != DRAW_CURSOR))
  3686         font->driver->draw (s, 0, s->nchars, x, y, false);
  3687       else
  3688         font->driver->draw (s, 0, s->nchars, x, y, true);
  3689       if (s->face->overstrike)
  3690         font->driver->draw (s, 0, s->nchars, x + 1, y, false);
  3691     }
  3692 }
  3693 
  3694 static void
  3695 android_draw_composite_glyph_string_foreground (struct glyph_string *s)
  3696 {
  3697   int i, j, x;
  3698   struct font *font = s->font;
  3699 
  3700   /* If first glyph of S has a left box line, start drawing the text
  3701      of S to the right of that box line.  */
  3702   if (s->face && s->face->box != FACE_NO_BOX
  3703       && s->first_glyph->left_box_line_p)
  3704     x = s->x + max (s->face->box_vertical_line_width, 0);
  3705   else
  3706     x = s->x;
  3707 
  3708   /* S is a glyph string for a composition.  S->cmp_from is the index
  3709      of the first character drawn for glyphs of this composition.
  3710      S->cmp_from == 0 means we are drawing the very first character of
  3711      this composition.  */
  3712 
  3713   /* Draw a rectangle for the composition if the font for the very
  3714      first character of the composition could not be loaded.  */
  3715   if (s->font_not_found_p)
  3716     {
  3717       if (s->cmp_from == 0)
  3718         android_draw_rectangle (FRAME_ANDROID_DRAWABLE (s->f),
  3719                                 s->gc, x, s->y,
  3720                                 s->width - 1, s->height - 1);
  3721     }
  3722   else if (! s->first_glyph->u.cmp.automatic)
  3723     {
  3724       int y = s->ybase;
  3725 
  3726       for (i = 0, j = s->cmp_from; i < s->nchars; i++, j++)
  3727         /* TAB in a composition means display glyphs with
  3728            padding space on the left or right.  */
  3729         if (COMPOSITION_GLYPH (s->cmp, j) != '\t')
  3730           {
  3731             int xx = x + s->cmp->offsets[j * 2];
  3732             int yy = y - s->cmp->offsets[j * 2 + 1];
  3733 
  3734             font->driver->draw (s, j, j + 1, xx, yy, false);
  3735             if (s->face->overstrike)
  3736               font->driver->draw (s, j, j + 1, xx + 1, yy, false);
  3737           }
  3738     }
  3739   else
  3740     {
  3741       Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
  3742       Lisp_Object glyph;
  3743       int y = s->ybase;
  3744       int width = 0;
  3745 
  3746       for (i = j = s->cmp_from; i < s->cmp_to; i++)
  3747         {
  3748           glyph = LGSTRING_GLYPH (gstring, i);
  3749           if (NILP (LGLYPH_ADJUSTMENT (glyph)))
  3750             width += LGLYPH_WIDTH (glyph);
  3751           else
  3752             {
  3753               int xoff, yoff, wadjust;
  3754 
  3755               if (j < i)
  3756                 {
  3757                   font->driver->draw (s, j, i, x, y, false);
  3758                   if (s->face->overstrike)
  3759                     font->driver->draw (s, j, i, x + 1, y, false);
  3760                   x += width;
  3761                 }
  3762               xoff = LGLYPH_XOFF (glyph);
  3763               yoff = LGLYPH_YOFF (glyph);
  3764               wadjust = LGLYPH_WADJUST (glyph);
  3765               font->driver->draw (s, i, i + 1, x + xoff, y + yoff, false);
  3766               if (s->face->overstrike)
  3767                 font->driver->draw (s, i, i + 1, x + xoff + 1, y + yoff,
  3768                                     false);
  3769               x += wadjust;
  3770               j = i + 1;
  3771               width = 0;
  3772             }
  3773         }
  3774       if (j < i)
  3775         {
  3776           font->driver->draw (s, j, i, x, y, false);
  3777           if (s->face->overstrike)
  3778             font->driver->draw (s, j, i, x + 1, y, false);
  3779         }
  3780     }
  3781 }
  3782 
  3783 static void
  3784 android_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
  3785 {
  3786   struct glyph *glyph = s->first_glyph;
  3787   unsigned char2b[8];
  3788   int x, i, j;
  3789 
  3790   /* If first glyph of S has a left box line, start drawing the text
  3791      of S to the right of that box line.  */
  3792   if (s->face && s->face->box != FACE_NO_BOX
  3793       && s->first_glyph->left_box_line_p)
  3794     x = s->x + max (s->face->box_vertical_line_width, 0);
  3795   else
  3796     x = s->x;
  3797 
  3798   s->char2b = char2b;
  3799 
  3800   for (i = 0; i < s->nchars; i++, glyph++)
  3801     {
  3802 #ifdef GCC_LINT
  3803       enum { PACIFY_GCC_BUG_81401 = 1 };
  3804 #else
  3805       enum { PACIFY_GCC_BUG_81401 = 0 };
  3806 #endif
  3807       char buf[7 + PACIFY_GCC_BUG_81401];
  3808       char *str = NULL;
  3809       int len = glyph->u.glyphless.len;
  3810 
  3811       if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_ACRONYM)
  3812         {
  3813           if (len > 0
  3814               && CHAR_TABLE_P (Vglyphless_char_display)
  3815               && (CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display))
  3816                   >= 1))
  3817             {
  3818               Lisp_Object acronym
  3819                 = (! glyph->u.glyphless.for_no_font
  3820                    ? CHAR_TABLE_REF (Vglyphless_char_display,
  3821                                      glyph->u.glyphless.ch)
  3822                    : XCHAR_TABLE (Vglyphless_char_display)->extras[0]);
  3823               if (CONSP (acronym))
  3824                 acronym = XCAR (acronym);
  3825               if (STRINGP (acronym))
  3826                 str = SSDATA (acronym);
  3827             }
  3828         }
  3829       else if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEX_CODE)
  3830         {
  3831           unsigned int ch = glyph->u.glyphless.ch;
  3832           eassume (ch <= MAX_CHAR);
  3833           sprintf (buf, "%0*X", ch < 0x10000 ? 4 : 6, ch);
  3834           str = buf;
  3835         }
  3836 
  3837       if (str)
  3838         {
  3839           int upper_len = (len + 1) / 2;
  3840 
  3841           /* It is assured that all LEN characters in STR is ASCII.  */
  3842           for (j = 0; j < len; j++)
  3843             char2b[j] = s->font->driver->encode_char (s->font, str[j]) & 0xFFFF;
  3844           s->font->driver->draw (s, 0, upper_len,
  3845                                  x + glyph->slice.glyphless.upper_xoff,
  3846                                  s->ybase + glyph->slice.glyphless.upper_yoff,
  3847                                  false);
  3848           s->font->driver->draw (s, upper_len, len,
  3849                                  x + glyph->slice.glyphless.lower_xoff,
  3850                                  s->ybase + glyph->slice.glyphless.lower_yoff,
  3851                                  false);
  3852         }
  3853       if (glyph->u.glyphless.method != GLYPHLESS_DISPLAY_THIN_SPACE)
  3854         android_draw_rectangle (FRAME_ANDROID_DRAWABLE (s->f), s->gc,
  3855                                 x, s->ybase - glyph->ascent,
  3856                                 glyph->pixel_width - 1,
  3857                                 glyph->ascent + glyph->descent - 1);
  3858       x += glyph->pixel_width;
  3859    }
  3860 
  3861   /* Defend against hypothetical bad code elsewhere that uses
  3862      s->char2b after this function returns.  */
  3863   s->char2b = NULL;
  3864 }
  3865 
  3866 static void
  3867 android_draw_glyph_string (struct glyph_string *s)
  3868 {
  3869   bool relief_drawn_p = false;
  3870 
  3871   /* If S draws into the background of its successors, draw the
  3872      background of the successors first so that S can draw into it.
  3873      This makes S->next use XDrawString instead of XDrawImageString.  */
  3874   if (s->next && s->right_overhang && !s->for_overlaps)
  3875     {
  3876       int width;
  3877       struct glyph_string *next;
  3878 
  3879       for (width = 0, next = s->next;
  3880            next && width < s->right_overhang;
  3881            width += next->width, next = next->next)
  3882         if (next->first_glyph->type != IMAGE_GLYPH)
  3883           {
  3884             android_set_glyph_string_gc (next);
  3885             android_set_glyph_string_clipping (next);
  3886             if (next->first_glyph->type == STRETCH_GLYPH)
  3887               android_draw_stretch_glyph_string (next);
  3888             else
  3889               android_draw_glyph_string_background (next, true);
  3890             next->num_clips = 0;
  3891           }
  3892     }
  3893 
  3894   /* Set up S->gc, set clipping and draw S.  */
  3895   android_set_glyph_string_gc (s);
  3896 
  3897   /* Draw relief (if any) in advance for char/composition so that the
  3898      glyph string can be drawn over it.  */
  3899   if (!s->for_overlaps
  3900       && s->face->box != FACE_NO_BOX
  3901       && (s->first_glyph->type == CHAR_GLYPH
  3902           || s->first_glyph->type == COMPOSITE_GLYPH))
  3903 
  3904     {
  3905       android_set_glyph_string_clipping (s);
  3906       android_draw_glyph_string_background (s, true);
  3907       android_draw_glyph_string_box (s);
  3908       android_set_glyph_string_clipping (s);
  3909       relief_drawn_p = true;
  3910     }
  3911   else if (!s->clip_head /* draw_glyphs didn't specify a clip mask. */
  3912            && !s->clip_tail
  3913            && ((s->prev && s->prev->hl != s->hl && s->left_overhang)
  3914                || (s->next && s->next->hl != s->hl && s->right_overhang)))
  3915     /* We must clip just this glyph.  left_overhang part has already
  3916        drawn when s->prev was drawn, and right_overhang part will be
  3917        drawn later when s->next is drawn. */
  3918     android_set_glyph_string_clipping_exactly (s, s);
  3919   else
  3920     android_set_glyph_string_clipping (s);
  3921 
  3922   switch (s->first_glyph->type)
  3923     {
  3924     case IMAGE_GLYPH:
  3925       android_draw_image_glyph_string (s);
  3926       break;
  3927 
  3928     case XWIDGET_GLYPH:
  3929       emacs_abort ();
  3930       break;
  3931 
  3932     case STRETCH_GLYPH:
  3933       android_draw_stretch_glyph_string (s);
  3934       break;
  3935 
  3936     case CHAR_GLYPH:
  3937       if (s->for_overlaps)
  3938         s->background_filled_p = true;
  3939       else
  3940         android_draw_glyph_string_background (s, false);
  3941       android_draw_glyph_string_foreground (s);
  3942       break;
  3943 
  3944     case COMPOSITE_GLYPH:
  3945       if (s->for_overlaps || (s->cmp_from > 0
  3946                               && ! s->first_glyph->u.cmp.automatic))
  3947         s->background_filled_p = true;
  3948       else
  3949         android_draw_glyph_string_background (s, true);
  3950       android_draw_composite_glyph_string_foreground (s);
  3951       break;
  3952 
  3953     case GLYPHLESS_GLYPH:
  3954       if (s->for_overlaps)
  3955         s->background_filled_p = true;
  3956       else
  3957         android_draw_glyph_string_background (s, true);
  3958       android_draw_glyphless_glyph_string_foreground (s);
  3959       break;
  3960 
  3961     default:
  3962       emacs_abort ();
  3963     }
  3964 
  3965   if (!s->for_overlaps)
  3966     {
  3967       int area_x, area_y, area_width, area_height;
  3968       int area_max_x, decoration_width;
  3969 
  3970       /* Prevent the underline from overwriting surrounding areas
  3971          and the fringe.  */
  3972       window_box (s->w, s->area, &area_x, &area_y,
  3973                   &area_width, &area_height);
  3974       area_max_x = area_x + area_width - 1;
  3975 
  3976       decoration_width = s->width;
  3977       if (!s->row->mode_line_p
  3978           && !s->row->tab_line_p
  3979           && area_max_x < (s->x + decoration_width - 1))
  3980         decoration_width -= (s->x + decoration_width - 1) - area_max_x;
  3981 
  3982       /* Draw relief if not yet drawn.  */
  3983       if (!relief_drawn_p && s->face->box != FACE_NO_BOX)
  3984         android_draw_glyph_string_box (s);
  3985 
  3986       /* Draw underline.  */
  3987       if (s->face->underline)
  3988         {
  3989           if (s->face->underline == FACE_UNDER_WAVE)
  3990             {
  3991               if (s->face->underline_defaulted_p)
  3992                 android_draw_underwave (s, decoration_width);
  3993               else
  3994                 {
  3995                   struct android_gc_values xgcv;
  3996                   android_get_gc_values (s->gc, ANDROID_GC_FOREGROUND, &xgcv);
  3997                   android_set_foreground (s->gc, s->face->underline_color);
  3998                   android_draw_underwave (s, decoration_width);
  3999                   android_set_foreground (s->gc, xgcv.foreground);
  4000                 }
  4001             }
  4002           else if (s->face->underline == FACE_UNDER_LINE)
  4003             {
  4004               unsigned long thickness, position;
  4005               int y;
  4006 
  4007               if (s->prev
  4008                   && s->prev->face->underline == FACE_UNDER_LINE
  4009                   && (s->prev->face->underline_at_descent_line_p
  4010                       == s->face->underline_at_descent_line_p)
  4011                   && (s->prev->face->underline_pixels_above_descent_line
  4012                       == s->face->underline_pixels_above_descent_line))
  4013                 {
  4014                   /* We use the same underline style as the previous one.  */
  4015                   thickness = s->prev->underline_thickness;
  4016                   position = s->prev->underline_position;
  4017                 }
  4018               else
  4019                 {
  4020                   struct font *font = font_for_underline_metrics (s);
  4021                   unsigned long minimum_offset;
  4022                   bool underline_at_descent_line;
  4023                   bool use_underline_position_properties;
  4024                   Lisp_Object val = (WINDOW_BUFFER_LOCAL_VALUE
  4025                                      (Qunderline_minimum_offset, s->w));
  4026 
  4027                   if (FIXNUMP (val))
  4028                     minimum_offset = max (0, XFIXNUM (val));
  4029                   else
  4030                     minimum_offset = 1;
  4031 
  4032                   val = (WINDOW_BUFFER_LOCAL_VALUE
  4033                          (Qx_underline_at_descent_line, s->w));
  4034                   underline_at_descent_line
  4035                     = (!(NILP (val) || BASE_EQ (val, Qunbound))
  4036                        || s->face->underline_at_descent_line_p);
  4037 
  4038                   val = (WINDOW_BUFFER_LOCAL_VALUE
  4039                          (Qx_use_underline_position_properties, s->w));
  4040                   use_underline_position_properties
  4041                     = !(NILP (val) || BASE_EQ (val, Qunbound));
  4042 
  4043                   /* Get the underline thickness.  Default is 1 pixel.  */
  4044                   if (font && font->underline_thickness > 0)
  4045                     thickness = font->underline_thickness;
  4046                   else
  4047                     thickness = 1;
  4048                   if (underline_at_descent_line)
  4049                     position = ((s->height - thickness)
  4050                                 - (s->ybase - s->y)
  4051                                 - s->face->underline_pixels_above_descent_line);
  4052                   else
  4053                     {
  4054                       /* Get the underline position.  This is the
  4055                          recommended vertical offset in pixels from
  4056                          the baseline to the top of the underline.
  4057                          This is a signed value according to the
  4058                          specs, and its default is
  4059 
  4060                          ROUND ((maximum descent) / 2), with
  4061                          ROUND(x) = floor (x + 0.5)  */
  4062 
  4063                       if (use_underline_position_properties
  4064                           && font && font->underline_position >= 0)
  4065                         position = font->underline_position;
  4066                       else if (font)
  4067                         position = (font->descent + 1) / 2;
  4068                       else
  4069                         position = minimum_offset;
  4070                     }
  4071 
  4072                   /* Ignore minimum_offset if the amount of pixels was
  4073                      explicitly specified.  */
  4074                   if (!s->face->underline_pixels_above_descent_line)
  4075                     position = max (position, minimum_offset);
  4076                 }
  4077               /* Check the sanity of thickness and position.  We should
  4078                  avoid drawing underline out of the current line area.  */
  4079               if (s->y + s->height <= s->ybase + position)
  4080                 position = (s->height - 1) - (s->ybase - s->y);
  4081               if (s->y + s->height < s->ybase + position + thickness)
  4082                 thickness = (s->y + s->height) - (s->ybase + position);
  4083               s->underline_thickness = thickness;
  4084               s->underline_position = position;
  4085               y = s->ybase + position;
  4086               if (s->face->underline_defaulted_p)
  4087                 android_fill_rectangle (FRAME_ANDROID_DRAWABLE (s->f), s->gc,
  4088                                         s->x, y, decoration_width, thickness);
  4089               else
  4090                 {
  4091                   struct android_gc_values xgcv;
  4092                   android_get_gc_values (s->gc, ANDROID_GC_FOREGROUND, &xgcv);
  4093                   android_set_foreground (s->gc, s->face->underline_color);
  4094                   android_fill_rectangle (FRAME_ANDROID_DRAWABLE (s->f), s->gc,
  4095                                           s->x, y, decoration_width, thickness);
  4096                   android_set_foreground (s->gc, xgcv.foreground);
  4097                 }
  4098             }
  4099         }
  4100       /* Draw overline.  */
  4101       if (s->face->overline_p)
  4102         {
  4103           unsigned long dy = 0, h = 1;
  4104 
  4105           if (s->face->overline_color_defaulted_p)
  4106             android_fill_rectangle (FRAME_ANDROID_DRAWABLE (s->f),
  4107                                     s->gc, s->x, s->y + dy,
  4108                                     decoration_width, h);
  4109           else
  4110             {
  4111               struct android_gc_values xgcv;
  4112               android_get_gc_values (s->gc, ANDROID_GC_FOREGROUND, &xgcv);
  4113               android_set_foreground (s->gc, s->face->overline_color);
  4114               android_fill_rectangle (FRAME_ANDROID_DRAWABLE (s->f), s->gc,
  4115                                       s->x, s->y + dy, decoration_width, h);
  4116               android_set_foreground (s->gc, xgcv.foreground);
  4117             }
  4118         }
  4119 
  4120       /* Draw strike-through.  */
  4121       if (s->face->strike_through_p)
  4122         {
  4123           /* Y-coordinate and height of the glyph string's first
  4124              glyph.  We cannot use s->y and s->height because those
  4125              could be larger if there are taller display elements
  4126              (e.g., characters displayed with a larger font) in the
  4127              same glyph row.  */
  4128           int glyph_y = s->ybase - s->first_glyph->ascent;
  4129           int glyph_height = s->first_glyph->ascent + s->first_glyph->descent;
  4130           /* Strike-through width and offset from the glyph string's
  4131              top edge.  */
  4132           unsigned long h = 1;
  4133           unsigned long dy = (glyph_height - h) / 2;
  4134 
  4135           if (s->face->strike_through_color_defaulted_p)
  4136             android_fill_rectangle (FRAME_ANDROID_WINDOW (s->f),
  4137                                     s->gc, s->x, glyph_y + dy,
  4138                                     s->width, h);
  4139           else
  4140             {
  4141               struct android_gc_values xgcv;
  4142               android_get_gc_values (s->gc, ANDROID_GC_FOREGROUND, &xgcv);
  4143               android_set_foreground (s->gc, s->face->strike_through_color);
  4144               android_fill_rectangle (FRAME_ANDROID_DRAWABLE (s->f), s->gc,
  4145                                       s->x, glyph_y + dy, decoration_width,
  4146                                       h);
  4147               android_set_foreground (s->gc, xgcv.foreground);
  4148             }
  4149         }
  4150 
  4151       if (s->prev)
  4152         {
  4153           struct glyph_string *prev;
  4154 
  4155           for (prev = s->prev; prev; prev = prev->prev)
  4156             if (prev->hl != s->hl
  4157                 && prev->x + prev->width + prev->right_overhang > s->x)
  4158               {
  4159                 /* As prev was drawn while clipped to its own area, we
  4160                    must draw the right_overhang part using s->hl now.  */
  4161                 enum draw_glyphs_face save = prev->hl;
  4162 
  4163                 prev->hl = s->hl;
  4164                 android_set_glyph_string_gc (prev);
  4165                 android_set_glyph_string_clipping_exactly (s, prev);
  4166                 if (prev->first_glyph->type == CHAR_GLYPH)
  4167                   android_draw_glyph_string_foreground (prev);
  4168                 else
  4169                   android_draw_composite_glyph_string_foreground (prev);
  4170                 android_reset_clip_rectangles (prev->f, prev->gc);
  4171                 prev->hl = save;
  4172                 prev->num_clips = 0;
  4173               }
  4174         }
  4175 
  4176       if (s->next)
  4177         {
  4178           struct glyph_string *next;
  4179 
  4180           for (next = s->next; next; next = next->next)
  4181             if (next->hl != s->hl
  4182                 && next->x - next->left_overhang < s->x + s->width)
  4183               {
  4184                 /* As next will be drawn while clipped to its own area,
  4185                    we must draw the left_overhang part using s->hl now.  */
  4186                 enum draw_glyphs_face save = next->hl;
  4187 
  4188                 next->hl = s->hl;
  4189                 android_set_glyph_string_gc (next);
  4190                 android_set_glyph_string_clipping_exactly (s, next);
  4191                 if (next->first_glyph->type == CHAR_GLYPH)
  4192                   android_draw_glyph_string_foreground (next);
  4193                 else
  4194                   android_draw_composite_glyph_string_foreground (next);
  4195                 android_reset_clip_rectangles (next->f, next->gc);
  4196                 next->hl = save;
  4197                 next->num_clips = 0;
  4198                 next->clip_head = s->next;
  4199               }
  4200         }
  4201     }
  4202 
  4203   /* Reset clipping.  */
  4204   android_reset_clip_rectangles (s->f, s->gc);
  4205   s->num_clips = 0;
  4206 
  4207   /* Set the stippled flag that tells redisplay whether or not a
  4208      stipple was actually draw.  */
  4209 
  4210   if (s->first_glyph->type != STRETCH_GLYPH
  4211       && s->first_glyph->type != IMAGE_GLYPH
  4212       && !s->row->stipple_p)
  4213     s->row->stipple_p = s->stippled_p;
  4214 }
  4215 
  4216 static void
  4217 android_define_frame_cursor (struct frame *f, Emacs_Cursor cursor)
  4218 {
  4219   if (!f->pointer_invisible
  4220       && !FRAME_ANDROID_OUTPUT (f)->hourglass
  4221       && f->output_data.android->current_cursor != cursor)
  4222     android_define_cursor (FRAME_ANDROID_WINDOW (f), cursor);
  4223 
  4224   f->output_data.android->current_cursor = cursor;
  4225 }
  4226 
  4227 static void
  4228 android_clear_frame_area (struct frame *f, int x, int y,
  4229                           int width, int height)
  4230 {
  4231   android_clear_area (FRAME_ANDROID_DRAWABLE (f),
  4232                       x, y, width, height);
  4233 }
  4234 
  4235 void
  4236 android_clear_under_internal_border (struct frame *f)
  4237 {
  4238   if (FRAME_INTERNAL_BORDER_WIDTH (f) > 0)
  4239     {
  4240       int border = FRAME_INTERNAL_BORDER_WIDTH (f);
  4241       int width = FRAME_PIXEL_WIDTH (f);
  4242       int height = FRAME_PIXEL_HEIGHT (f);
  4243       int margin = FRAME_TOP_MARGIN_HEIGHT (f);
  4244       int bottom_margin = FRAME_BOTTOM_MARGIN_HEIGHT (f);
  4245       int face_id = (FRAME_PARENT_FRAME (f)
  4246                      ? (!NILP (Vface_remapping_alist)
  4247                         ? lookup_basic_face (NULL, f,
  4248                                              CHILD_FRAME_BORDER_FACE_ID)
  4249                         : CHILD_FRAME_BORDER_FACE_ID)
  4250                      : (!NILP (Vface_remapping_alist)
  4251                         ? lookup_basic_face (NULL, f,
  4252                                              INTERNAL_BORDER_FACE_ID)
  4253                         : INTERNAL_BORDER_FACE_ID));
  4254       struct face *face = FACE_FROM_ID_OR_NULL (f, face_id);
  4255 
  4256       if (face)
  4257         {
  4258           unsigned long color = face->background;
  4259           struct android_gc *gc = f->output_data.android->normal_gc;
  4260 
  4261           android_set_foreground (gc, color);
  4262           android_fill_rectangle (FRAME_ANDROID_DRAWABLE (f), gc, 0, margin,
  4263                                   width, border);
  4264           android_fill_rectangle (FRAME_ANDROID_DRAWABLE (f), gc, 0, 0,
  4265                                   border, height);
  4266           android_fill_rectangle (FRAME_ANDROID_DRAWABLE (f), gc, width - border,
  4267                                   0, border, height);
  4268           android_fill_rectangle (FRAME_ANDROID_DRAWABLE (f), gc, 0,
  4269                                   height - bottom_margin - border,
  4270                                   width, border);
  4271           android_set_foreground (gc, FRAME_FOREGROUND_PIXEL (f));
  4272         }
  4273       else
  4274         {
  4275           android_clear_area (FRAME_ANDROID_DRAWABLE (f), 0, 0,
  4276                               border, height);
  4277           android_clear_area (FRAME_ANDROID_DRAWABLE (f), 0,
  4278                               margin, width, border);
  4279           android_clear_area (FRAME_ANDROID_DRAWABLE (f), width - border,
  4280                               0, border, height);
  4281           android_clear_area (FRAME_ANDROID_DRAWABLE (f), 0,
  4282                               height - bottom_margin - border,
  4283                               width, border);
  4284         }
  4285     }
  4286 }
  4287 
  4288 static void
  4289 android_draw_hollow_cursor (struct window *w, struct glyph_row *row)
  4290 {
  4291   struct frame *f = XFRAME (WINDOW_FRAME (w));
  4292   struct android_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
  4293   int x, y, wd, h;
  4294   struct android_gc_values xgcv;
  4295   struct glyph *cursor_glyph;
  4296   struct android_gc *gc;
  4297 
  4298   /* Get the glyph the cursor is on.  If we can't tell because
  4299      the current matrix is invalid or such, give up.  */
  4300   cursor_glyph = get_phys_cursor_glyph (w);
  4301   if (cursor_glyph == NULL)
  4302     return;
  4303 
  4304   /* Compute frame-relative coordinates for phys cursor.  */
  4305   get_phys_cursor_geometry (w, row, cursor_glyph, &x, &y, &h);
  4306   wd = w->phys_cursor_width - 1;
  4307 
  4308   /* The foreground of cursor_gc is typically the same as the normal
  4309      background color, which can cause the cursor box to be invisible.  */
  4310   xgcv.foreground = f->output_data.android->cursor_pixel;
  4311   if (dpyinfo->scratch_cursor_gc)
  4312     android_change_gc (dpyinfo->scratch_cursor_gc,
  4313                        ANDROID_GC_FOREGROUND, &xgcv);
  4314   else
  4315     dpyinfo->scratch_cursor_gc
  4316       =  android_create_gc (ANDROID_GC_FOREGROUND, &xgcv);
  4317   gc = dpyinfo->scratch_cursor_gc;
  4318 
  4319   /* When on R2L character, show cursor at the right edge of the
  4320      glyph, unless the cursor box is as wide as the glyph or wider
  4321      (the latter happens when x-stretch-cursor is non-nil).  */
  4322   if ((cursor_glyph->resolved_level & 1) != 0
  4323       && cursor_glyph->pixel_width > wd)
  4324     {
  4325       x += cursor_glyph->pixel_width - wd;
  4326       if (wd > 0)
  4327         wd -= 1;
  4328     }
  4329   /* Set clipping, draw the rectangle, and reset clipping again.  */
  4330   android_clip_to_row (w, row, TEXT_AREA, gc);
  4331   android_draw_rectangle (FRAME_ANDROID_DRAWABLE (f), gc, x, y, wd, h - 1);
  4332   android_reset_clip_rectangles (f, gc);
  4333 }
  4334 
  4335 static void
  4336 android_draw_bar_cursor (struct window *w, struct glyph_row *row, int width,
  4337                          enum text_cursor_kinds kind)
  4338 {
  4339   struct frame *f = XFRAME (w->frame);
  4340   struct glyph *cursor_glyph;
  4341   int cursor_start_y;
  4342 
  4343   /* If cursor is out of bounds, don't draw garbage.  This can happen
  4344      in mini-buffer windows when switching between echo area glyphs
  4345      and mini-buffer.  */
  4346   cursor_glyph = get_phys_cursor_glyph (w);
  4347   if (cursor_glyph == NULL)
  4348     return;
  4349 
  4350   /* Experimental avoidance of cursor on xwidget.  */
  4351   if (cursor_glyph->type == XWIDGET_GLYPH)
  4352     return;
  4353 
  4354   /* If on an image, draw like a normal cursor.  That's usually better
  4355      visible than drawing a bar, esp. if the image is large so that
  4356      the bar might not be in the window.  */
  4357   if (cursor_glyph->type == IMAGE_GLYPH)
  4358     {
  4359       struct glyph_row *r;
  4360       r = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos);
  4361       draw_phys_cursor_glyph (w, r, DRAW_CURSOR);
  4362     }
  4363   else
  4364     {
  4365       struct android_gc *gc = FRAME_DISPLAY_INFO (f)->scratch_cursor_gc;
  4366       unsigned long mask = ANDROID_GC_FOREGROUND | ANDROID_GC_BACKGROUND;
  4367       struct face *face = FACE_FROM_ID (f, cursor_glyph->face_id);
  4368       struct android_gc_values xgcv;
  4369 
  4370       /* If the glyph's background equals the color we normally draw
  4371          the bars cursor in, the bar cursor in its normal color is
  4372          invisible.  Use the glyph's foreground color instead in this
  4373          case, on the assumption that the glyph's colors are chosen so
  4374          that the glyph is legible.  */
  4375       if (face->background == f->output_data.android->cursor_pixel)
  4376         xgcv.background = xgcv.foreground = face->foreground;
  4377       else
  4378         xgcv.background = xgcv.foreground = f->output_data.android->cursor_pixel;
  4379 
  4380       if (gc)
  4381         android_change_gc (gc, mask, &xgcv);
  4382       else
  4383         {
  4384           gc = android_create_gc (mask, &xgcv);
  4385           FRAME_DISPLAY_INFO (f)->scratch_cursor_gc = gc;
  4386         }
  4387 
  4388       android_clip_to_row (w, row, TEXT_AREA, gc);
  4389 
  4390       if (kind == BAR_CURSOR)
  4391         {
  4392           int x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
  4393 
  4394           if (width < 0)
  4395             width = FRAME_CURSOR_WIDTH (f);
  4396           width = min (cursor_glyph->pixel_width, width);
  4397 
  4398           w->phys_cursor_width = width;
  4399 
  4400           /* If the character under cursor is R2L, draw the bar cursor
  4401              on the right of its glyph, rather than on the left.  */
  4402           if ((cursor_glyph->resolved_level & 1) != 0)
  4403             x += cursor_glyph->pixel_width - width;
  4404 
  4405           android_fill_rectangle (FRAME_ANDROID_DRAWABLE (f), gc, x,
  4406                                   WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
  4407                                   width, row->height);
  4408         }
  4409       else /* HBAR_CURSOR */
  4410         {
  4411           int dummy_x, dummy_y, dummy_h;
  4412           int x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
  4413 
  4414           if (width < 0)
  4415             width = row->height;
  4416 
  4417           width = min (row->height, width);
  4418 
  4419           get_phys_cursor_geometry (w, row, cursor_glyph, &dummy_x,
  4420                                     &dummy_y, &dummy_h);
  4421 
  4422           cursor_start_y = WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y
  4423                                                     + row->height - width);
  4424 
  4425           if ((cursor_glyph->resolved_level & 1) != 0
  4426               && cursor_glyph->pixel_width > w->phys_cursor_width - 1)
  4427             x += cursor_glyph->pixel_width - w->phys_cursor_width + 1;
  4428           android_fill_rectangle (FRAME_ANDROID_DRAWABLE (f), gc, x,
  4429                                   cursor_start_y,
  4430                                   w->phys_cursor_width - 1, width);
  4431         }
  4432 
  4433       android_reset_clip_rectangles (f, gc);
  4434     }
  4435 }
  4436 
  4437 static void
  4438 android_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
  4439                             int x, int y, enum text_cursor_kinds cursor_type,
  4440                             int cursor_width, bool on_p, bool active_p)
  4441 {
  4442   struct frame *f;
  4443 
  4444   f = WINDOW_XFRAME (w);
  4445 
  4446   if (on_p)
  4447     {
  4448       w->phys_cursor_type = cursor_type;
  4449       w->phys_cursor_on_p = true;
  4450 
  4451       if (glyph_row->exact_window_width_line_p
  4452           && (glyph_row->reversed_p
  4453               ? (w->phys_cursor.hpos < 0)
  4454               : (w->phys_cursor.hpos >= glyph_row->used[TEXT_AREA])))
  4455         {
  4456           glyph_row->cursor_in_fringe_p = true;
  4457           draw_fringe_bitmap (w, glyph_row, glyph_row->reversed_p);
  4458         }
  4459       else
  4460         {
  4461           switch (cursor_type)
  4462             {
  4463             case HOLLOW_BOX_CURSOR:
  4464               android_draw_hollow_cursor (w, glyph_row);
  4465               break;
  4466 
  4467             case FILLED_BOX_CURSOR:
  4468               draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
  4469               break;
  4470 
  4471             case BAR_CURSOR:
  4472               android_draw_bar_cursor (w, glyph_row, cursor_width, BAR_CURSOR);
  4473               break;
  4474 
  4475             case HBAR_CURSOR:
  4476               android_draw_bar_cursor (w, glyph_row, cursor_width, HBAR_CURSOR);
  4477               break;
  4478 
  4479             case NO_CURSOR:
  4480               w->phys_cursor_width = 0;
  4481               break;
  4482 
  4483             default:
  4484               emacs_abort ();
  4485             }
  4486         }
  4487 
  4488       /* Now proceed to tell the input method the current position of
  4489          the cursor, if required.  */
  4490 
  4491       if (FRAME_OUTPUT_DATA (f)->need_cursor_updates
  4492           && w == XWINDOW (f->selected_window))
  4493         android_set_preeditarea (w, x, y);
  4494     }
  4495 }
  4496 
  4497 static void
  4498 android_draw_vertical_window_border (struct window *w, int x, int y0, int y1)
  4499 {
  4500   struct frame *f = XFRAME (WINDOW_FRAME (w));
  4501   struct face *face;
  4502 
  4503   face = FACE_FROM_ID_OR_NULL (f, VERTICAL_BORDER_FACE_ID);
  4504   if (face)
  4505     android_set_foreground (f->output_data.android->normal_gc,
  4506                             face->foreground);
  4507 
  4508   android_draw_line (FRAME_ANDROID_DRAWABLE (f),
  4509                      f->output_data.android->normal_gc,
  4510                      x, y0, x, y1);
  4511 }
  4512 
  4513 static void
  4514 android_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1)
  4515 {
  4516   struct frame *f = XFRAME (WINDOW_FRAME (w));
  4517   struct face *face = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_FACE_ID);
  4518   struct face *face_first
  4519     = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID);
  4520   struct face *face_last
  4521     = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_LAST_PIXEL_FACE_ID);
  4522   unsigned long color = face ? face->foreground : FRAME_FOREGROUND_PIXEL (f);
  4523   unsigned long color_first = (face_first
  4524                                ? face_first->foreground
  4525                                : FRAME_FOREGROUND_PIXEL (f));
  4526   unsigned long color_last = (face_last
  4527                               ? face_last->foreground
  4528                               : FRAME_FOREGROUND_PIXEL (f));
  4529 
  4530   if ((y1 - y0 > x1 - x0) && (x1 - x0 >= 3))
  4531     /* A vertical divider, at least three pixels wide: Draw first and
  4532        last pixels differently.  */
  4533     {
  4534       android_set_foreground (f->output_data.android->normal_gc,
  4535                               color_first);
  4536       android_fill_rectangle (FRAME_ANDROID_DRAWABLE (f),
  4537                               f->output_data.android->normal_gc,
  4538                               x0, y0, 1, y1 - y0);
  4539       android_set_foreground (f->output_data.android->normal_gc,
  4540                               color);
  4541       android_fill_rectangle (FRAME_ANDROID_DRAWABLE (f),
  4542                               f->output_data.android->normal_gc,
  4543                               x0 + 1, y0, x1 - x0 - 2, y1 - y0);
  4544       android_set_foreground (f->output_data.android->normal_gc,
  4545                               color_last);
  4546       android_fill_rectangle (FRAME_ANDROID_DRAWABLE (f),
  4547                               f->output_data.android->normal_gc,
  4548                               x1 - 1, y0, 1, y1 - y0);
  4549     }
  4550   else if ((x1 - x0 > y1 - y0) && (y1 - y0 >= 3))
  4551     /* A horizontal divider, at least three pixels high: Draw first
  4552        and last pixels differently.  */
  4553     {
  4554       android_set_foreground (f->output_data.android->normal_gc,
  4555                               color_first);
  4556       android_fill_rectangle (FRAME_ANDROID_DRAWABLE (f),
  4557                               f->output_data.android->normal_gc,
  4558                               x0, y0, x1 - x0, 1);
  4559       android_set_foreground (f->output_data.android->normal_gc, color);
  4560       android_fill_rectangle (FRAME_ANDROID_DRAWABLE (f),
  4561                               f->output_data.android->normal_gc,
  4562                               x0, y0 + 1, x1 - x0, y1 - y0 - 2);
  4563       android_set_foreground (f->output_data.android->normal_gc,
  4564                               color_last);
  4565       android_fill_rectangle (FRAME_ANDROID_DRAWABLE (f),
  4566                               f->output_data.android->normal_gc,
  4567                               x0, y1 - 1, x1 - x0, 1);
  4568     }
  4569   else
  4570     {
  4571       /* In any other case do not draw the first and last pixels
  4572          differently.  */
  4573       android_set_foreground (f->output_data.android->normal_gc, color);
  4574       android_fill_rectangle (FRAME_ANDROID_DRAWABLE (f),
  4575                               f->output_data.android->normal_gc,
  4576                               x0, y0, x1 - x0, y1 - y0);
  4577     }
  4578 }
  4579 
  4580 
  4581 
  4582 #ifdef __clang__
  4583 #pragma clang diagnostic push
  4584 #pragma clang diagnostic ignored "-Wmissing-prototypes"
  4585 #else
  4586 #pragma GCC diagnostic push
  4587 #pragma GCC diagnostic ignored "-Wmissing-prototypes"
  4588 #endif
  4589 
  4590 /* Input method related functions.  Some of these are called from Java
  4591    within the UI thread.  */
  4592 
  4593 /* A counter used to decide when an editing request completes.  */
  4594 static unsigned long edit_counter;
  4595 
  4596 /* The last counter known to have completed.  */
  4597 static unsigned long last_edit_counter;
  4598 
  4599 /* Semaphore posted every time the counter increases.  */
  4600 static sem_t edit_sem;
  4601 
  4602 /* Try to synchronize with the UI thread, waiting a certain amount of
  4603    time for outstanding editing requests to complete.
  4604 
  4605    Every time one of the text retrieval functions is called and an
  4606    editing request is made, Emacs gives the main thread approximately
  4607    100 ms to process it, in order to mostly keep the input method in
  4608    sync with the buffer contents.  */
  4609 
  4610 static void
  4611 android_sync_edit (void)
  4612 {
  4613   struct timespec start, end, rem;
  4614   unsigned long counter;
  4615 
  4616   counter = __atomic_load_n (&last_edit_counter,
  4617                              __ATOMIC_SEQ_CST);
  4618 
  4619   if (counter == edit_counter)
  4620     return;
  4621 
  4622   start = current_timespec ();
  4623   end = timespec_add (start, make_timespec (0, 100000000));
  4624 
  4625   while (true)
  4626     {
  4627       rem = timespec_sub (end, current_timespec ());
  4628 
  4629       /* Timeout.  */
  4630       if (timespec_sign (rem) < 0)
  4631         break;
  4632 
  4633       if (__atomic_load_n (&last_edit_counter,
  4634                            __ATOMIC_SEQ_CST)
  4635           == edit_counter)
  4636         break;
  4637 
  4638       sem_timedwait (&edit_sem, &end);
  4639     }
  4640 }
  4641 
  4642 /* Return a copy of the specified Java string and its length in
  4643    *LENGTH.  Use the JNI environment ENV.  Value is NULL if copying
  4644    *the string fails.  */
  4645 
  4646 static unsigned short *
  4647 android_copy_java_string (JNIEnv *env, jstring string, size_t *length)
  4648 {
  4649   jsize size, i;
  4650   const jchar *java;
  4651   unsigned short *buffer;
  4652 
  4653   size = (*env)->GetStringLength (env, string);
  4654   buffer = malloc (size * sizeof *buffer);
  4655 
  4656   if (!buffer)
  4657     return NULL;
  4658 
  4659   java = (*env)->GetStringChars (env, string, NULL);
  4660 
  4661   if (!java)
  4662     {
  4663       free (buffer);
  4664       return NULL;
  4665     }
  4666 
  4667   for (i = 0; i < size; ++i)
  4668     buffer[i] = java[i];
  4669 
  4670   *length = size;
  4671   (*env)->ReleaseStringChars (env, string, java);
  4672   return buffer;
  4673 }
  4674 
  4675 JNIEXPORT void JNICALL
  4676 NATIVE_NAME (beginBatchEdit) (JNIEnv *env, jobject object, jshort window)
  4677 {
  4678   JNI_STACK_ALIGNMENT_PROLOGUE;
  4679 
  4680   union android_event event;
  4681 
  4682   event.ime.type = ANDROID_INPUT_METHOD;
  4683   event.ime.serial = ++event_serial;
  4684   event.ime.window = window;
  4685   event.ime.operation = ANDROID_IME_START_BATCH_EDIT;
  4686   event.ime.start = 0;
  4687   event.ime.end = 0;
  4688   event.ime.length = 0;
  4689   event.ime.position = 0;
  4690   event.ime.text = NULL;
  4691   event.ime.counter = ++edit_counter;
  4692 
  4693   android_write_event (&event);
  4694 }
  4695 
  4696 JNIEXPORT void JNICALL
  4697 NATIVE_NAME (endBatchEdit) (JNIEnv *env, jobject object, jshort window)
  4698 {
  4699   JNI_STACK_ALIGNMENT_PROLOGUE;
  4700 
  4701   union android_event event;
  4702 
  4703   event.ime.type = ANDROID_INPUT_METHOD;
  4704   event.ime.serial = ++event_serial;
  4705   event.ime.window = window;
  4706   event.ime.operation = ANDROID_IME_END_BATCH_EDIT;
  4707   event.ime.start = 0;
  4708   event.ime.end = 0;
  4709   event.ime.length = 0;
  4710   event.ime.position = 0;
  4711   event.ime.text = NULL;
  4712   event.ime.counter = ++edit_counter;
  4713 
  4714   android_write_event (&event);
  4715 }
  4716 
  4717 JNIEXPORT void JNICALL
  4718 NATIVE_NAME (commitCompletion) (JNIEnv *env, jobject object, jshort window,
  4719                                 jstring completion_text, jint position)
  4720 {
  4721   JNI_STACK_ALIGNMENT_PROLOGUE;
  4722 
  4723   union android_event event;
  4724   unsigned short *text;
  4725   size_t length;
  4726 
  4727   /* First, obtain a copy of the Java string.  */
  4728   text = android_copy_java_string (env, completion_text, &length);
  4729 
  4730   if (!text)
  4731     return;
  4732 
  4733   /* Next, populate the event.  Events will always eventually be
  4734      delivered on Android, so handle_one_android_event can be relied
  4735      on to free text.  */
  4736 
  4737   event.ime.type = ANDROID_INPUT_METHOD;
  4738   event.ime.serial = ++event_serial;
  4739   event.ime.window = window;
  4740   event.ime.operation = ANDROID_IME_COMMIT_TEXT;
  4741   event.ime.start = 0;
  4742   event.ime.end = 0;
  4743   event.ime.length = min (length, PTRDIFF_MAX);
  4744   event.ime.position = position;
  4745   event.ime.text = text;
  4746   event.ime.counter = ++edit_counter;
  4747 
  4748   android_write_event (&event);
  4749 }
  4750 
  4751 JNIEXPORT void JNICALL
  4752 NATIVE_NAME (commitText) (JNIEnv *env, jobject object, jshort window,
  4753                           jstring commit_text, jint position)
  4754 {
  4755   JNI_STACK_ALIGNMENT_PROLOGUE;
  4756 
  4757   union android_event event;
  4758   unsigned short *text;
  4759   size_t length;
  4760 
  4761   /* First, obtain a copy of the Java string.  */
  4762   text = android_copy_java_string (env, commit_text, &length);
  4763 
  4764   if (!text)
  4765     return;
  4766 
  4767   /* Next, populate the event.  Events will always eventually be
  4768      delivered on Android, so handle_one_android_event can be relied
  4769      on to free text.  */
  4770 
  4771   event.ime.type = ANDROID_INPUT_METHOD;
  4772   event.ime.serial = ++event_serial;
  4773   event.ime.window = window;
  4774   event.ime.operation = ANDROID_IME_COMMIT_TEXT;
  4775   event.ime.start = 0;
  4776   event.ime.end = 0;
  4777   event.ime.length = min (length, PTRDIFF_MAX);
  4778   event.ime.position = position;
  4779   event.ime.text = text;
  4780   event.ime.counter = ++edit_counter;
  4781 
  4782   android_write_event (&event);
  4783 }
  4784 
  4785 JNIEXPORT void JNICALL
  4786 NATIVE_NAME (deleteSurroundingText) (JNIEnv *env, jobject object,
  4787                                      jshort window, jint left_length,
  4788                                      jint right_length)
  4789 {
  4790   JNI_STACK_ALIGNMENT_PROLOGUE;
  4791 
  4792   union android_event event;
  4793 
  4794   event.ime.type = ANDROID_INPUT_METHOD;
  4795   event.ime.serial = ++event_serial;
  4796   event.ime.window = window;
  4797   event.ime.operation = ANDROID_IME_DELETE_SURROUNDING_TEXT;
  4798   event.ime.start = left_length;
  4799   event.ime.end = right_length;
  4800   event.ime.length = 0;
  4801   event.ime.position = 0;
  4802   event.ime.text = NULL;
  4803   event.ime.counter = ++edit_counter;
  4804 
  4805   android_write_event (&event);
  4806 }
  4807 
  4808 JNIEXPORT void JNICALL
  4809 NATIVE_NAME (finishComposingText) (JNIEnv *env, jobject object,
  4810                                    jshort window)
  4811 {
  4812   JNI_STACK_ALIGNMENT_PROLOGUE;
  4813 
  4814   union android_event event;
  4815 
  4816   event.ime.type = ANDROID_INPUT_METHOD;
  4817   event.ime.serial = ++event_serial;
  4818   event.ime.window = window;
  4819   event.ime.operation = ANDROID_IME_FINISH_COMPOSING_TEXT;
  4820   event.ime.start = 0;
  4821   event.ime.end = 0;
  4822   event.ime.length = 0;
  4823   event.ime.position = 0;
  4824   event.ime.text = NULL;
  4825   event.ime.counter = ++edit_counter;
  4826 
  4827   android_write_event (&event);
  4828 }
  4829 
  4830 /* Structure describing the context used for a text query.  */
  4831 
  4832 struct android_conversion_query_context
  4833 {
  4834   /* The conversion request.  */
  4835   struct textconv_callback_struct query;
  4836 
  4837   /* The window the request is being made on.  */
  4838   android_window window;
  4839 
  4840   /* Whether or not the request was successful.  */
  4841   bool success;
  4842 };
  4843 
  4844 /* Obtain the text from the frame whose window is that specified in
  4845    DATA using the text conversion query specified there.
  4846 
  4847    Set ((struct android_conversion_query_context *) DATA)->success on
  4848    success.  */
  4849 
  4850 static void
  4851 android_perform_conversion_query (void *data)
  4852 {
  4853   struct android_conversion_query_context *context;
  4854   struct frame *f;
  4855 
  4856   context = data;
  4857 
  4858   /* Find the frame associated with the window.  */
  4859   f = android_window_to_frame (NULL, context->window);
  4860 
  4861   if (!f)
  4862     return;
  4863 
  4864   textconv_query (f, &context->query, 0);
  4865 
  4866   /* context->query.text will have been set even if textconv_query
  4867      returns 1.  */
  4868 
  4869   context->success = true;
  4870 }
  4871 
  4872 /* Convert a string in BUFFER, containing N characters in Emacs's
  4873    internal multibyte encoding, to a Java string utilizing the
  4874    specified JNI environment ENV.
  4875 
  4876    If N is equal to BYTES, then BUFFER holds unibyte or plain-ASCII
  4877    characters.  Otherwise, BUFFER holds multibyte characters.
  4878 
  4879    Make sure N and BYTES are absolutely correct, or you are asking for
  4880    trouble.
  4881 
  4882    Value is a jstring upon success, NULL otherwise.  Any exceptions
  4883    generated are not cleared.  */
  4884 
  4885 static jstring
  4886 android_text_to_string (JNIEnv *env, char *buffer, ptrdiff_t n,
  4887                         ptrdiff_t bytes)
  4888 {
  4889   jchar *utf16;
  4890   size_t size, index;
  4891   jstring string;
  4892   int encoded;
  4893 
  4894   if (n == bytes)
  4895     {
  4896       /* This buffer holds no multibyte characters.  */
  4897 
  4898       if (INT_MULTIPLY_WRAPV (n, sizeof *utf16, &size))
  4899         return NULL;
  4900 
  4901       utf16 = malloc (size);
  4902       index = 0;
  4903 
  4904       if (!utf16)
  4905         return NULL;
  4906 
  4907       while (n--)
  4908         {
  4909           utf16[index] = buffer[index];
  4910           index++;
  4911         }
  4912 
  4913       string = (*env)->NewString (env, utf16, bytes);
  4914       free (utf16);
  4915 
  4916       return string;
  4917     }
  4918 
  4919   /* Allocate enough to hold N characters.  */
  4920 
  4921   if (INT_MULTIPLY_WRAPV (n, sizeof *utf16, &size))
  4922     return NULL;
  4923 
  4924   utf16 = malloc (size);
  4925   index = 0;
  4926 
  4927   if (!utf16)
  4928     return NULL;
  4929 
  4930   while (n--)
  4931     {
  4932       eassert (CHAR_HEAD_P (*buffer));
  4933       encoded = STRING_CHAR ((unsigned char *) buffer);
  4934 
  4935       /* Now establish how to save ENCODED into the string.
  4936          Emacs operates on multibyte characters, not UTF-16 characters
  4937          with surrogate pairs as Android does.
  4938 
  4939          However, character positions in Java are represented as
  4940          character (rather than codepoint) indices into UTF-16
  4941          strings, meaning that text positions reported to Android can
  4942          become decoupled from their actual values if the text
  4943          returned incorporates characters that must be encoded as
  4944          surrogate pairs.
  4945 
  4946          The hack used by Emacs is to simply replace each multibyte
  4947          character that doesn't fit in a jchar with the NULL
  4948          character.  */
  4949 
  4950       if (encoded >= 65536)
  4951         encoded = 0;
  4952 
  4953       utf16[index++] = encoded;
  4954       buffer += BYTES_BY_CHAR_HEAD (*buffer);
  4955     }
  4956 
  4957   /* Create the string.  */
  4958   string = (*env)->NewString (env, utf16, index);
  4959   free (utf16);
  4960   return string;
  4961 }
  4962 
  4963 JNIEXPORT jstring JNICALL
  4964 NATIVE_NAME (getTextAfterCursor) (JNIEnv *env, jobject object, jshort window,
  4965                                   jint length, jint flags)
  4966 {
  4967   JNI_STACK_ALIGNMENT_PROLOGUE;
  4968 
  4969   struct android_conversion_query_context context;
  4970   jstring string;
  4971 
  4972   /* First, set up the conversion query.  */
  4973   context.query.position = EMACS_INT_MAX;
  4974   context.query.direction = TEXTCONV_FORWARD_CHAR;
  4975   context.query.factor = min (length, 65535);
  4976   context.query.operation = TEXTCONV_RETRIEVAL;
  4977 
  4978   /* Next, set the rest of the context.  */
  4979   context.window = window;
  4980   context.success = false;
  4981 
  4982   /* Now try to perform the query.  */
  4983   android_sync_edit ();
  4984   if (android_run_in_emacs_thread (android_perform_conversion_query,
  4985                                    &context))
  4986     return NULL;
  4987 
  4988   if (!context.success)
  4989     return NULL;
  4990 
  4991   /* context->query.text now contains the text in Emacs's internal
  4992      UTF-8 based encoding.
  4993 
  4994      Convert it to Java's UTF-16 encoding, which is the same as
  4995      UTF-16, except that NULL bytes are encoded as surrogate pairs.
  4996 
  4997      This assumes that `free' can free data allocated with xmalloc.  */
  4998 
  4999   string = android_text_to_string (env, context.query.text.text,
  5000                                    context.query.text.length,
  5001                                    context.query.text.bytes);
  5002   free (context.query.text.text);
  5003 
  5004   return string;
  5005 }
  5006 
  5007 JNIEXPORT jstring JNICALL
  5008 NATIVE_NAME (getTextBeforeCursor) (JNIEnv *env, jobject object, jshort window,
  5009                                    jint length, jint flags)
  5010 {
  5011   JNI_STACK_ALIGNMENT_PROLOGUE;
  5012 
  5013   struct android_conversion_query_context context;
  5014   jstring string;
  5015 
  5016   /* First, set up the conversion query.  */
  5017   context.query.position = TYPE_MINIMUM (EMACS_INT);
  5018   context.query.direction = TEXTCONV_BACKWARD_CHAR;
  5019   context.query.factor = min (length, 65535);
  5020   context.query.operation = TEXTCONV_RETRIEVAL;
  5021 
  5022   /* Next, set the rest of the context.  */
  5023   context.window = window;
  5024   context.success = false;
  5025 
  5026   /* Now try to perform the query.  */
  5027   android_sync_edit ();
  5028   if (android_run_in_emacs_thread (android_perform_conversion_query,
  5029                                    &context))
  5030     return NULL;
  5031 
  5032   if (!context.success)
  5033     return NULL;
  5034 
  5035   /* context->query.text now contains the text in Emacs's internal
  5036      UTF-8 based encoding.
  5037 
  5038      Convert it to Java's UTF-16 encoding, which is the same as
  5039      UTF-16, except that NULL bytes are encoded as surrogate pairs.
  5040 
  5041      This assumes that `free' can free data allocated with xmalloc.  */
  5042 
  5043   string = android_text_to_string (env, context.query.text.text,
  5044                                    context.query.text.length,
  5045                                    context.query.text.bytes);
  5046   free (context.query.text.text);
  5047 
  5048   return string;
  5049 }
  5050 
  5051 JNIEXPORT void JNICALL
  5052 NATIVE_NAME (setComposingText) (JNIEnv *env, jobject object, jshort window,
  5053                                 jstring composing_text,
  5054                                 jint new_cursor_position)
  5055 {
  5056   JNI_STACK_ALIGNMENT_PROLOGUE;
  5057 
  5058   union android_event event;
  5059   unsigned short *text;
  5060   size_t length;
  5061 
  5062   /* First, obtain a copy of the Java string.  */
  5063   text = android_copy_java_string (env, composing_text, &length);
  5064 
  5065   if (!text)
  5066     return;
  5067 
  5068   /* Next, populate the event.  Events will always eventually be
  5069      delivered on Android, so handle_one_android_event can be relied
  5070      on to free text.  */
  5071 
  5072   event.ime.type = ANDROID_INPUT_METHOD;
  5073   event.ime.serial = ++event_serial;
  5074   event.ime.window = window;
  5075   event.ime.operation = ANDROID_IME_SET_COMPOSING_TEXT;
  5076   event.ime.start = 0;
  5077   event.ime.end = 0;
  5078   event.ime.length = min (length, PTRDIFF_MAX);
  5079   event.ime.position = new_cursor_position;
  5080   event.ime.text = text;
  5081   event.ime.counter = ++edit_counter;
  5082 
  5083   android_write_event (&event);
  5084 }
  5085 
  5086 JNIEXPORT void JNICALL
  5087 NATIVE_NAME (setComposingRegion) (JNIEnv *env, jobject object, jshort window,
  5088                                   jint start, jint end)
  5089 {
  5090   JNI_STACK_ALIGNMENT_PROLOGUE;
  5091 
  5092   union android_event event;
  5093 
  5094   event.ime.type = ANDROID_INPUT_METHOD;
  5095   event.ime.serial = ++event_serial;
  5096   event.ime.window = window;
  5097   event.ime.operation = ANDROID_IME_SET_COMPOSING_REGION;
  5098   event.ime.start = start + 1;
  5099   event.ime.end = end + 1;
  5100   event.ime.length = 0;
  5101   event.ime.position = 0;
  5102   event.ime.text = NULL;
  5103   event.ime.counter = ++edit_counter;
  5104 
  5105   android_write_event (&event);
  5106 }
  5107 
  5108 JNIEXPORT void JNICALL
  5109 NATIVE_NAME (setSelection) (JNIEnv *env, jobject object, jshort window,
  5110                             jint start, jint end)
  5111 {
  5112   JNI_STACK_ALIGNMENT_PROLOGUE;
  5113 
  5114   union android_event event;
  5115 
  5116   /* While IMEs want access to the entire selection, Emacs only
  5117      supports setting the point.  */
  5118 
  5119   event.ime.type = ANDROID_INPUT_METHOD;
  5120   event.ime.serial = ++event_serial;
  5121   event.ime.window = window;
  5122   event.ime.operation = ANDROID_IME_SET_POINT;
  5123   event.ime.start = start + 1;
  5124   event.ime.end = end + 1;
  5125   event.ime.length = 0;
  5126   event.ime.position = start;
  5127   event.ime.text = NULL;
  5128   event.ime.counter = ++edit_counter;
  5129 
  5130   android_write_event (&event);
  5131 }
  5132 
  5133 /* Structure describing the context for `getSelection'.  */
  5134 
  5135 struct android_get_selection_context
  5136 {
  5137   /* The window in question.  */
  5138   android_window window;
  5139 
  5140   /* The position of the window's point when it was last
  5141      redisplayed, and its last mark if active.  */
  5142   ptrdiff_t point, mark;
  5143 };
  5144 
  5145 /* Function run on the main thread by `getSelection'.
  5146    Place the character position of point in PT.  */
  5147 
  5148 static void
  5149 android_get_selection (void *data)
  5150 {
  5151   struct android_get_selection_context *context;
  5152   struct frame *f;
  5153   struct window *w;
  5154   struct buffer *b;
  5155 
  5156   context = data;
  5157 
  5158   /* Look up the associated frame and its selected window.  */
  5159   f = android_window_to_frame (NULL, context->window);
  5160 
  5161   if (!f)
  5162     context->point = -1;
  5163   else
  5164     {
  5165       w = XWINDOW (f->selected_window);
  5166 
  5167       /* Return W's point as it is now.  Then, set
  5168          W->ephemeral_last_point to match the current point.  */
  5169       context->point = window_point (w);
  5170       w->ephemeral_last_point = context->point;
  5171 
  5172       /* Default context->mark to w->last_point too.  */
  5173       context->mark = context->point;
  5174 
  5175       /* If the mark is active, then set it properly.  Also, adjust
  5176          w->last_mark to match.  */
  5177       b = XBUFFER (w->contents);
  5178       if (!NILP (BVAR (b, mark_active)))
  5179         {
  5180           context->mark = marker_position (BVAR (b, mark));
  5181           w->last_mark = context->mark;
  5182         }
  5183     }
  5184 }
  5185 
  5186 JNIEXPORT jintArray JNICALL
  5187 NATIVE_NAME (getSelection) (JNIEnv *env, jobject object, jshort window)
  5188 {
  5189   JNI_STACK_ALIGNMENT_PROLOGUE;
  5190 
  5191   struct android_get_selection_context context;
  5192   jintArray array;
  5193   jint contents[2];
  5194 
  5195   context.window = window;
  5196 
  5197   android_sync_edit ();
  5198   if (android_run_in_emacs_thread (android_get_selection,
  5199                                    &context))
  5200     return NULL;
  5201 
  5202   if (context.point == -1)
  5203     return NULL;
  5204 
  5205   /* Wraparound actually makes more sense than truncation; at least
  5206      editing will sort of work.  Convert the positions to start from
  5207      index 0, as that is what Android expects.  */
  5208   contents[0] = (unsigned int) min (context.point,
  5209                                     context.mark) - 1;
  5210   contents[1] = (unsigned int) max (context.point,
  5211                                     context.mark) - 1;
  5212 
  5213   /* Now create the array.  */
  5214   array = (*env)->NewIntArray (env, 2);
  5215 
  5216   if (!array)
  5217     return NULL;
  5218 
  5219   /* Set its contents.  */
  5220   (*env)->SetIntArrayRegion (env, array, 0, 2, contents);
  5221   return array;
  5222 }
  5223 
  5224 JNIEXPORT void JNICALL
  5225 NATIVE_NAME (performEditorAction) (JNIEnv *env, jobject object,
  5226                                    jshort window, int action)
  5227 {
  5228   JNI_STACK_ALIGNMENT_PROLOGUE;
  5229 
  5230   union android_event event;
  5231 
  5232   /* It's a good idea to call `android_sync_edit' before sending the
  5233      key event.  Otherwise, if RET causes the current window to be
  5234      changed, any text previously committed might end up in the newly
  5235      selected window.  */
  5236 
  5237   android_sync_edit ();
  5238 
  5239   /* Undocumented behavior: performEditorAction is apparently expected
  5240      to finish composing any text.  */
  5241 
  5242   event.ime.type = ANDROID_INPUT_METHOD;
  5243   event.ime.serial = ++event_serial;
  5244   event.ime.window = window;
  5245   event.ime.operation = ANDROID_IME_FINISH_COMPOSING_TEXT;
  5246   event.ime.start = 0;
  5247   event.ime.end = 0;
  5248 
  5249   /* This value of `length' means that the input method should receive
  5250      an update containing the new conversion region.  */
  5251 
  5252   event.ime.length = 1;
  5253   event.ime.position = 0;
  5254   event.ime.text = NULL;
  5255   event.ime.counter = ++edit_counter;
  5256 
  5257   android_write_event (&event);
  5258 
  5259   /* Finally, send the return key press.  `counter' is set; this means
  5260      that a text conversion barrier will be generated once the event
  5261      is read, which will cause subsequent edits to wait until the
  5262      edits associated with this key press complete.  */
  5263 
  5264   event.xkey.type = ANDROID_KEY_PRESS;
  5265   event.xkey.serial = ++event_serial;
  5266   event.xkey.window = window;
  5267   event.xkey.time = 0;
  5268   event.xkey.state = 0;
  5269   event.xkey.keycode = 66;
  5270   event.xkey.unicode_char = 0;
  5271   event.xkey.counter = ++edit_counter;
  5272 
  5273   android_write_event (&event);
  5274 }
  5275 
  5276 JNIEXPORT void JNICALL
  5277 NATIVE_NAME (performContextMenuAction) (JNIEnv *env, jobject object,
  5278                                         jshort window, int action)
  5279 {
  5280   JNI_STACK_ALIGNMENT_PROLOGUE;
  5281 
  5282   union android_event event;
  5283   int key;
  5284 
  5285   /* Note that ACTION is determined in EmacsInputConnection, and as
  5286      such they are not actual resource IDs.  */
  5287 
  5288   switch (action)
  5289     {
  5290     case 0: /* android.R.id.selectAll */
  5291     case 1: /* android.R.id.startSelectingText */
  5292     case 2: /* android.R.id.stopSelectingText */
  5293     default:
  5294       /* These actions are not implemented.  */
  5295       return;
  5296 
  5297     case 3: /* android.R.id.cut */
  5298       key = 277;
  5299       break;
  5300 
  5301     case 4: /* android.R.id.copy */
  5302       key = 278;
  5303       break;
  5304 
  5305     case 5: /* android.R.id.paste */
  5306       key = 279;
  5307       break;
  5308     }
  5309 
  5310   event.xkey.type = ANDROID_KEY_PRESS;
  5311   event.xkey.serial = ++event_serial;
  5312   event.xkey.window = window;
  5313   event.xkey.time = 0;
  5314   event.xkey.state = 0;
  5315   event.xkey.keycode = key;
  5316   event.xkey.unicode_char = 0;
  5317   event.xkey.counter = ++edit_counter;
  5318 
  5319   android_write_event (&event);
  5320 }
  5321 
  5322 
  5323 
  5324 /* Text extraction.  */
  5325 
  5326 struct android_get_extracted_text_context
  5327 {
  5328   /* The parameters of the request.  */
  5329   int hint_max_chars;
  5330 
  5331   /* Token for the request.  */
  5332   int token;
  5333 
  5334   /* Flags associated with the request.  */
  5335   int flags;
  5336 
  5337   /* The returned text, or NULL.  */
  5338   char *text;
  5339 
  5340   /* The size of that text in characters and bytes.  */
  5341   ptrdiff_t length, bytes;
  5342 
  5343   /* Offsets into that text.  */
  5344   ptrdiff_t start, start_offset, end_offset;
  5345 
  5346   /* The window.  */
  5347   android_window window;
  5348 
  5349   /* Whether or not the mark is active.  */
  5350   bool mark_active;
  5351 };
  5352 
  5353 /* Return the extracted text in the extracted text context specified
  5354    by DATA.  Save its flags and token into its frame's state.  */
  5355 
  5356 static void
  5357 android_get_extracted_text (void *data)
  5358 {
  5359   struct android_get_extracted_text_context *request;
  5360   struct frame *f;
  5361 
  5362   request = data;
  5363 
  5364   /* Find the frame associated with the window.  */
  5365   f = android_window_to_frame (NULL, request->window);
  5366 
  5367   if (!f)
  5368     return;
  5369 
  5370   /* Now get the extracted text.  */
  5371   request->text
  5372     = get_extracted_text (f, min (request->hint_max_chars, 600),
  5373                           &request->start, &request->start_offset,
  5374                           &request->end_offset, &request->length,
  5375                           &request->bytes, &request->mark_active);
  5376 
  5377   /* See if request->flags & GET_EXTRACTED_TEXT_MONITOR.  If so, then
  5378      the input method has asked to monitor changes to the extracted
  5379      text until the next IM context reset.  */
  5380 
  5381   FRAME_ANDROID_OUTPUT (f)->extracted_text_flags = request->flags;
  5382   FRAME_ANDROID_OUTPUT (f)->extracted_text_token = request->token;
  5383   FRAME_ANDROID_OUTPUT (f)->extracted_text_hint = request->hint_max_chars;
  5384 }
  5385 
  5386 /* Structure describing the `ExtractedTextRequest' class.
  5387    Valid only on the UI thread.  */
  5388 
  5389 struct android_extracted_text_request_class
  5390 {
  5391   bool initialized;
  5392   jfieldID hint_max_chars;
  5393   jfieldID token;
  5394 };
  5395 
  5396 /* Structure describing the `ExtractedText' class.
  5397    Valid only on the UI thread.  */
  5398 
  5399 struct android_extracted_text_class
  5400 {
  5401   jclass class;
  5402   jmethodID constructor;
  5403   jfieldID flags;
  5404   jfieldID partial_start_offset;
  5405   jfieldID partial_end_offset;
  5406   jfieldID selection_start;
  5407   jfieldID selection_end;
  5408   jfieldID start_offset;
  5409   jfieldID text;
  5410 };
  5411 
  5412 /* Fields and methods associated with the `ExtractedTextRequest'
  5413    class.  */
  5414 struct android_extracted_text_request_class request_class;
  5415 
  5416 /* Fields and methods associated with the `ExtractedText' class.  */
  5417 struct android_extracted_text_class text_class;
  5418 
  5419 /* Return an ExtractedText object corresponding to the extracted text
  5420    TEXT.  START is a character position describing the offset of the
  5421    first character in TEXT.  START_OFFSET is the offset of the lesser
  5422    of point or mark relative to START, and END_OFFSET is that of the
  5423    greater of point or mark relative to START.  MARK_ACTIVE specifies
  5424    whether or not the mark is currently active.
  5425 
  5426    Assume that request_class and text_class have already been
  5427    initialized.
  5428 
  5429    Value is NULL if an error occurs; the exception is not cleared,
  5430    else a local reference to the ExtractedText object.  */
  5431 
  5432 static jobject
  5433 android_build_extracted_text (jstring text, ptrdiff_t start,
  5434                               ptrdiff_t start_offset,
  5435                               ptrdiff_t end_offset, bool mark_active)
  5436 {
  5437   JNIEnv *env;
  5438   jobject object;
  5439 
  5440   env = android_java_env;
  5441 
  5442   /* Return NULL if the class has not yet been obtained.  */
  5443   if (!text_class.class)
  5444     return NULL;
  5445 
  5446   /* Create an ExtractedText object containing this information.  */
  5447   object = (*env)->NewObject (env, text_class.class,
  5448                               text_class.constructor);
  5449   if (!object)
  5450     return NULL;
  5451 
  5452   (*env)->SetIntField (env, object, text_class.flags,
  5453                        /* ExtractedText.FLAG_SELECTING */
  5454                        mark_active ? 2 : 0);
  5455   (*env)->SetIntField (env, object, text_class.partial_start_offset, -1);
  5456   (*env)->SetIntField (env, object, text_class.partial_end_offset, -1);
  5457   (*env)->SetIntField (env, object, text_class.selection_start,
  5458                        min (start_offset, TYPE_MAXIMUM (jint)));
  5459   (*env)->SetIntField (env, object, text_class.selection_end,
  5460                        min (end_offset, TYPE_MAXIMUM (jint)));
  5461 
  5462   /* Subtract 1 from start: point indices in Emacs start from 1, but
  5463      Android expects 0.  */
  5464   (*env)->SetIntField (env, object, text_class.start_offset,
  5465                        min (start - 1, TYPE_MAXIMUM (jint)));
  5466   (*env)->SetObjectField (env, object, text_class.text, text);
  5467   return object;
  5468 }
  5469 
  5470 JNIEXPORT jobject JNICALL
  5471 NATIVE_NAME (getExtractedText) (JNIEnv *env, jobject ignored_object,
  5472                                 jshort window, jobject request,
  5473                                 jint flags)
  5474 {
  5475   JNI_STACK_ALIGNMENT_PROLOGUE;
  5476 
  5477   struct android_get_extracted_text_context context;
  5478   jstring string;
  5479   jclass class;
  5480   jobject object;
  5481 
  5482   /* Initialize both classes if necessary.  */
  5483 
  5484   if (!request_class.initialized)
  5485     {
  5486       class
  5487         = (*env)->FindClass (env, ("android/view/inputmethod"
  5488                                    "/ExtractedTextRequest"));
  5489       assert (class);
  5490 
  5491       request_class.hint_max_chars
  5492         = (*env)->GetFieldID (env, class, "hintMaxChars", "I");
  5493       assert (request_class.hint_max_chars);
  5494 
  5495       request_class.token
  5496         = (*env)->GetFieldID (env, class, "token", "I");
  5497       assert (request_class.token);
  5498 
  5499       request_class.initialized = true;
  5500     }
  5501 
  5502   if (!text_class.class)
  5503     {
  5504       text_class.class
  5505         = (*env)->FindClass (env, ("android/view/inputmethod"
  5506                                    "/ExtractedText"));
  5507       assert (text_class.class);
  5508 
  5509       class
  5510         = text_class.class
  5511         = (*env)->NewGlobalRef (env, text_class.class);
  5512       assert (text_class.class);
  5513 
  5514       text_class.flags
  5515         = (*env)->GetFieldID (env, class, "flags", "I");
  5516       text_class.partial_start_offset
  5517         = (*env)->GetFieldID (env, class, "partialStartOffset", "I");
  5518       text_class.partial_end_offset
  5519         = (*env)->GetFieldID (env, class, "partialEndOffset", "I");
  5520       text_class.selection_start
  5521         = (*env)->GetFieldID (env, class, "selectionStart", "I");
  5522       text_class.selection_end
  5523         = (*env)->GetFieldID (env, class, "selectionEnd", "I");
  5524       text_class.start_offset
  5525         = (*env)->GetFieldID (env, class, "startOffset", "I");
  5526       text_class.text
  5527         = (*env)->GetFieldID (env, class, "text", "Ljava/lang/CharSequence;");
  5528       text_class.constructor
  5529         = (*env)->GetMethodID (env, class, "<init>", "()V");
  5530     }
  5531 
  5532   context.hint_max_chars
  5533     = (*env)->GetIntField (env, request, request_class.hint_max_chars);
  5534   context.token
  5535     = (*env)->GetIntField (env, request, request_class.token);
  5536   context.flags = flags;
  5537   context.text = NULL;
  5538   context.window = window;
  5539 
  5540   android_sync_edit ();
  5541   if (android_run_in_emacs_thread (android_get_extracted_text,
  5542                                    &context))
  5543     return NULL;
  5544 
  5545   if (!context.text)
  5546     return NULL;
  5547 
  5548   /* Encode the returned text.  */
  5549   string = android_text_to_string (env, context.text, context.length,
  5550                                    context.bytes);
  5551   free (context.text);
  5552 
  5553   if (!string)
  5554     return NULL;
  5555 
  5556   /* Create an ExtractedText object containing this information.  */
  5557   object = (*env)->NewObject (env, text_class.class,
  5558                               text_class.constructor);
  5559   if (!object)
  5560     return NULL;
  5561 
  5562   (*env)->SetIntField (env, object, text_class.flags,
  5563                        /* ExtractedText.FLAG_SELECTING */
  5564                        context.mark_active ? 2 : 0);
  5565   (*env)->SetIntField (env, object, text_class.partial_start_offset, -1);
  5566   (*env)->SetIntField (env, object, text_class.partial_end_offset, -1);
  5567   (*env)->SetIntField (env, object, text_class.selection_start,
  5568                        min (context.start_offset, TYPE_MAXIMUM (jint)));
  5569   (*env)->SetIntField (env, object, text_class.selection_end,
  5570                        min (context.end_offset, TYPE_MAXIMUM (jint)));
  5571 
  5572   /* Subtract 1 from start: point indices in Emacs start from 1, but
  5573      Android expects 0.  */
  5574   (*env)->SetIntField (env, object, text_class.start_offset,
  5575                        min (context.start - 1, TYPE_MAXIMUM (jint)));
  5576   (*env)->SetObjectField (env, object, text_class.text, string);
  5577   return object;
  5578 }
  5579 
  5580 
  5581 
  5582 JNIEXPORT jstring JNICALL
  5583 NATIVE_NAME (getSelectedText) (JNIEnv *env, jobject object,
  5584                                jshort window)
  5585 {
  5586   JNI_STACK_ALIGNMENT_PROLOGUE;
  5587 
  5588   struct android_get_extracted_text_context context;
  5589   jstring string;
  5590 
  5591   context.hint_max_chars = -1;
  5592   context.token = 0;
  5593   context.text = NULL;
  5594   context.window = window;
  5595 
  5596   android_sync_edit ();
  5597   if (android_run_in_emacs_thread (android_get_extracted_text,
  5598                                    &context))
  5599     return NULL;
  5600 
  5601   if (!context.text)
  5602     return NULL;
  5603 
  5604   /* Encode the returned text.  */
  5605   string = android_text_to_string (env, context.text, context.length,
  5606                                    context.bytes);
  5607   free (context.text);
  5608 
  5609   return string;
  5610 }
  5611 
  5612 JNIEXPORT void JNICALL
  5613 NATIVE_NAME (requestSelectionUpdate) (JNIEnv *env, jobject object,
  5614                                       jshort window)
  5615 {
  5616   JNI_STACK_ALIGNMENT_PROLOGUE;
  5617 
  5618   union android_event event;
  5619 
  5620   event.ime.type = ANDROID_INPUT_METHOD;
  5621   event.ime.serial = ++event_serial;
  5622   event.ime.window = window;
  5623   event.ime.operation = ANDROID_IME_REQUEST_SELECTION_UPDATE;
  5624   event.ime.start = 0;
  5625   event.ime.end = 0;
  5626   event.ime.length = 0;
  5627   event.ime.position = 0;
  5628   event.ime.text = NULL;
  5629   event.ime.counter = ++edit_counter;
  5630 
  5631   android_write_event (&event);
  5632 }
  5633 
  5634 JNIEXPORT void JNICALL
  5635 NATIVE_NAME (requestCursorUpdates) (JNIEnv *env, jobject object,
  5636                                     jshort window, jint mode)
  5637 {
  5638   JNI_STACK_ALIGNMENT_PROLOGUE;
  5639 
  5640   union android_event event;
  5641 
  5642   event.ime.type = ANDROID_INPUT_METHOD;
  5643   event.ime.serial = ++event_serial;
  5644   event.ime.window = window;
  5645   event.ime.operation = ANDROID_IME_REQUEST_CURSOR_UPDATES;
  5646   event.ime.start = 0;
  5647   event.ime.end = 0;
  5648   event.ime.length = mode;
  5649   event.ime.position = 0;
  5650   event.ime.text = NULL;
  5651 
  5652   /* Since this does not affect the state of the buffer text, there is
  5653      no need to apply synchronization to this event.  */
  5654   event.ime.counter = 0;
  5655 
  5656   android_write_event (&event);
  5657 }
  5658 
  5659 /* Notice that a new input method connection has been initialized and
  5660    clear cursor update requests, extracted text requests, and the
  5661    composing region.  */
  5662 
  5663 JNIEXPORT void JNICALL
  5664 NATIVE_NAME (clearInputFlags) (JNIEnv *env, jobject object,
  5665                                jshort window)
  5666 {
  5667   JNI_STACK_ALIGNMENT_PROLOGUE;
  5668 
  5669   union android_event event;
  5670 
  5671   event.ime.type = ANDROID_INPUT_METHOD;
  5672   event.ime.serial = ++event_serial;
  5673   event.ime.window = window;
  5674   event.ime.operation = ANDROID_IME_FINISH_COMPOSING_TEXT;
  5675   event.ime.start = 0;
  5676   event.ime.end = 0;
  5677 
  5678   /* This value of `length' means that updates to the cursor position
  5679      and extracted text should not be reported anymore.  */
  5680 
  5681   event.ime.length = 2;
  5682   event.ime.position = 0;
  5683   event.ime.text = NULL;
  5684   event.ime.counter = ++edit_counter;
  5685 
  5686   android_write_event (&event);
  5687 }
  5688 
  5689 
  5690 
  5691 /* Context for a call to `getSurroundingText'.  */
  5692 
  5693 struct android_get_surrounding_text_context
  5694 {
  5695   /* Number of characters before the region to return.  */
  5696   int before_length;
  5697 
  5698   /* Number of characters after the region to return.  */
  5699   int after_length;
  5700 
  5701   /* The returned text, or NULL.  */
  5702   char *text;
  5703 
  5704   /* The size of that text in characters and bytes.  */
  5705   ptrdiff_t length, bytes;
  5706 
  5707   /* Offsets into that text.  */
  5708   ptrdiff_t offset, start, end;
  5709 
  5710   /* The start and end indices of the conversion region.
  5711      -1 if it does not exist.  */
  5712   ptrdiff_t conversion_start, conversion_end;
  5713 
  5714   /* The window.  */
  5715   android_window window;
  5716 };
  5717 
  5718 /* Return the surrounding text in the surrounding text context
  5719    specified by DATA.  */
  5720 
  5721 static void
  5722 android_get_surrounding_text (void *data)
  5723 {
  5724   struct android_get_surrounding_text_context *request;
  5725   struct frame *f;
  5726   ptrdiff_t temp;
  5727 
  5728   request = data;
  5729 
  5730   /* Find the frame associated with the window.  */
  5731   f = android_window_to_frame (NULL, request->window);
  5732 
  5733   if (!f)
  5734     return;
  5735 
  5736   /* Now get the surrounding text.  */
  5737   request->text
  5738     = get_surrounding_text (f, request->before_length,
  5739                             request->after_length, &request->length,
  5740                             &request->bytes, &request->offset,
  5741                             &request->start, &request->end);
  5742 
  5743   /* Sort request->start and request->end for compatibility with some
  5744      bad input methods.  */
  5745 
  5746   if (request->end < request->start)
  5747     {
  5748       temp = request->start;
  5749       request->start = request->end;
  5750       request->end = temp;
  5751     }
  5752 
  5753   /* Retrieve the conversion region.  */
  5754 
  5755   request->conversion_start = -1;
  5756   request->conversion_end = -1;
  5757 
  5758   if (MARKERP (f->conversion.compose_region_start))
  5759     {
  5760       request->conversion_start
  5761         = marker_position (f->conversion.compose_region_start) - 1;
  5762       request->conversion_end
  5763         = marker_position (f->conversion.compose_region_end) - 1;
  5764     }
  5765 }
  5766 
  5767 /* Return a local reference to a `SurroundingText' object describing
  5768    WINDOW's surrounding text.  ENV should be a valid JNI environment
  5769    for the current thread.
  5770 
  5771    BEFORE_LENGTH and AFTER_LENGTH specify the number of characters
  5772    around point and mark to return.
  5773 
  5774    Return the conversion region (or -1) in *CONVERSION_START and
  5775    *CONVERSION_END if non-NULL.
  5776 
  5777    Value is the object upon success, else NULL.  */
  5778 
  5779 static jobject
  5780 android_get_surrounding_text_internal (JNIEnv *env, jshort window,
  5781                                        jint before_length,
  5782                                        jint after_length,
  5783                                        ptrdiff_t *conversion_start,
  5784                                        ptrdiff_t *conversion_end)
  5785 {
  5786   struct android_get_surrounding_text_context context;
  5787   jstring string;
  5788   jobject object;
  5789 
  5790   static jclass class;
  5791   static jmethodID constructor;
  5792 
  5793   /* Initialize CLASS if it has not yet been initialized.  */
  5794 
  5795   if (!class)
  5796     {
  5797       class
  5798         = (*env)->FindClass (env, ("android/view/inputmethod"
  5799                                    "/SurroundingText"));
  5800 
  5801 #if __ANDROID_API__ < 31
  5802       /* If CLASS cannot be found, the version of Android currently
  5803          running is too old.  */
  5804 
  5805       if (!class)
  5806         {
  5807           (*env)->ExceptionClear (env);
  5808           return NULL;
  5809         }
  5810 #else /* __ANDROID_API__ >= 31 */
  5811       assert (class);
  5812 #endif /* __ANDROID_API__ < 31 */
  5813 
  5814       class = (*env)->NewGlobalRef (env, class);
  5815       if (!class)
  5816         /* Clear class to prevent a local reference from remaining in
  5817            `class'.  */
  5818         return (class = NULL);
  5819 
  5820       /* Now look for its constructor.  */
  5821       constructor = (*env)->GetMethodID (env, class, "<init>",
  5822                                          "(Ljava/lang/CharSequence;III)V");
  5823       assert (constructor);
  5824     }
  5825 
  5826   context.before_length = before_length;
  5827   context.after_length = after_length;
  5828   context.window = window;
  5829   context.text = NULL;
  5830 
  5831   android_sync_edit ();
  5832   if (android_run_in_emacs_thread (android_get_surrounding_text,
  5833                                    &context))
  5834     return NULL;
  5835 
  5836   if (!context.text)
  5837     return NULL;
  5838 
  5839   /* Encode the returned text.  */
  5840   string = android_text_to_string (env, context.text, context.length,
  5841                                    context.bytes);
  5842   free (context.text);
  5843 
  5844   if (!string)
  5845     return NULL;
  5846 
  5847   /* Create an SurroundingText object containing this information.  */
  5848   object = (*env)->NewObject (env, class, constructor, string,
  5849                               (jint) min (context.start,
  5850                                           TYPE_MAXIMUM (jint)),
  5851                               (jint) min (context.end,
  5852                                           TYPE_MAXIMUM (jint)),
  5853                               /* Adjust point offsets to fit into
  5854                                  Android's 0-based indexing. */
  5855                               (jint) min (context.offset - 1,
  5856                                           TYPE_MAXIMUM (jint)));
  5857   if (!object)
  5858     return NULL;
  5859 
  5860   /* Now return the conversion region if that was requested.  */
  5861 
  5862   if (conversion_start)
  5863     {
  5864       *conversion_start = context.conversion_start;
  5865       *conversion_end = context.conversion_start;
  5866     }
  5867 
  5868   return object;
  5869 }
  5870 
  5871 JNIEXPORT jobject JNICALL
  5872 NATIVE_NAME (getSurroundingText) (JNIEnv *env, jobject object,
  5873                                   jshort window, jint before_length,
  5874                                   jint after_length, jint flags)
  5875 {
  5876   JNI_STACK_ALIGNMENT_PROLOGUE;
  5877 
  5878   return android_get_surrounding_text_internal (env, window, before_length,
  5879                                                 after_length, NULL, NULL);
  5880 }
  5881 
  5882 JNIEXPORT jobject JNICALL
  5883 NATIVE_NAME (takeSnapshot) (JNIEnv *env, jobject object, jshort window)
  5884 {
  5885   JNI_STACK_ALIGNMENT_PROLOGUE;
  5886 
  5887   jobject text;
  5888   ptrdiff_t start, end;
  5889 
  5890   static jclass class;
  5891   static jmethodID constructor;
  5892 
  5893   /* First, obtain the surrounding text and conversion region.  */
  5894   text = android_get_surrounding_text_internal (env, window, 600, 600,
  5895                                                 &start, &end);
  5896 
  5897   /* If that fails, return NULL.  */
  5898 
  5899   if (!text)
  5900     return NULL;
  5901 
  5902   /* Next, initialize the TextSnapshot class.  */
  5903 
  5904   if (!class)
  5905     {
  5906       class
  5907         = (*env)->FindClass (env, ("android/view/inputmethod"
  5908                                    "/TextSnapshot"));
  5909 #if __ANDROID_API__ < 33
  5910       /* If CLASS cannot be found, the version of Android currently
  5911          running is too old.  */
  5912 
  5913       if (!class)
  5914         {
  5915           (*env)->ExceptionClear (env);
  5916           return NULL;
  5917         }
  5918 #else /* __ANDROID_API__ >= 33 */
  5919       assert (class);
  5920 #endif /* __ANDROID_API__ < 33 */
  5921 
  5922       class = (*env)->NewGlobalRef (env, class);
  5923       if (!class)
  5924         /* Clear class to prevent a local reference from remaining in
  5925            `class'.  */
  5926         return (class = NULL);
  5927 
  5928       constructor = (*env)->GetMethodID (env, class, "<init>",
  5929                                          "(Landroid/view/inputmethod"
  5930                                          "/SurroundingText;III)V");
  5931       assert (constructor);
  5932     }
  5933 
  5934   /* Try to create a TextSnapshot object.  */
  5935   eassert (start <= end);
  5936   object = (*env)->NewObject (env, class, constructor, text,
  5937                               (jint) min (start, TYPE_MAXIMUM (jint)),
  5938                               (jint) min (end, TYPE_MAXIMUM (jint)),
  5939                               (jint) 0);
  5940   return object;
  5941 }
  5942 
  5943 #ifdef __clang__
  5944 #pragma clang diagnostic pop
  5945 #else /* GCC */
  5946 #pragma GCC diagnostic pop
  5947 #endif /* __clang__ */
  5948 
  5949 
  5950 
  5951 /* Tell the input method where the composing region and selection of
  5952    F's selected window is located.  W should be F's selected window;
  5953    if it is NULL, then F->selected_window is used in its place.  */
  5954 
  5955 static void
  5956 android_update_selection (struct frame *f, struct window *w)
  5957 {
  5958   ptrdiff_t start, end, point, mark, start_offset, end_offset;
  5959   ptrdiff_t length, bytes;
  5960   struct buffer *b;
  5961   int hint, token;
  5962   char *text;
  5963   jobject extracted;
  5964   jstring string;
  5965   bool mark_active;
  5966 
  5967   if (MARKERP (f->conversion.compose_region_start))
  5968     {
  5969       eassert (MARKERP (f->conversion.compose_region_end));
  5970 
  5971       /* Indexing in android starts from 0 instead of 1.  */
  5972       start = marker_position (f->conversion.compose_region_start) - 1;
  5973       end = marker_position (f->conversion.compose_region_end) - 1;
  5974     }
  5975   else
  5976     start = -1, end = -1;
  5977 
  5978   /* Now constrain START and END to the maximium size of a Java
  5979      integer.  */
  5980   start = min (start, TYPE_MAXIMUM (jint));
  5981   end = min (end, TYPE_MAXIMUM (jint));
  5982 
  5983   if (!w)
  5984     w = XWINDOW (f->selected_window);
  5985 
  5986   /* Figure out where the point and mark are.  If the mark is not
  5987      active, then point is set to equal mark.  */
  5988   b = XBUFFER (w->contents);
  5989   point = min (w->ephemeral_last_point,
  5990                TYPE_MAXIMUM (jint));
  5991   mark = ((!NILP (BVAR (b, mark_active))
  5992            && w->last_mark != -1)
  5993           ? min (w->last_mark, TYPE_MAXIMUM (jint))
  5994           : point);
  5995 
  5996   /* Send the update.  Android doesn't employ a concept of ``point''
  5997      and ``mark''; instead, it only has a selection, where the start
  5998      of the selection is less than or equal to the end, and the region
  5999      is ``active'' when those two values differ.  Also, convert the
  6000      indices from 1-based Emacs indices to 0-based Android ones.  */
  6001   android_update_ic (FRAME_ANDROID_WINDOW (f), min (point, mark) - 1,
  6002                      max (point, mark) - 1, start, end);
  6003 
  6004   /* Update the extracted text as well, if the input method has asked
  6005      for updates.  1 is
  6006      InputConnection.GET_EXTRACTED_TEXT_MONITOR.  */
  6007 
  6008   if (FRAME_ANDROID_OUTPUT (f)->extracted_text_flags & 1)
  6009     {
  6010       hint = FRAME_ANDROID_OUTPUT (f)->extracted_text_hint;
  6011       token = FRAME_ANDROID_OUTPUT (f)->extracted_text_token;
  6012       text = get_extracted_text (f, min (hint, 600), &start,
  6013                                  &start_offset, &end_offset,
  6014                                  &length, &bytes, &mark_active);
  6015 
  6016       if (text)
  6017         {
  6018           /* Make a string out of the extracted text.  */
  6019           string = android_text_to_string (android_java_env,
  6020                                            text, length, bytes);
  6021           xfree (text);
  6022           android_exception_check ();
  6023 
  6024           /* Make extracted text out of that string.  */
  6025           extracted = android_build_extracted_text (string, start,
  6026                                                     start_offset,
  6027                                                     end_offset,
  6028                                                     mark_active);
  6029           android_exception_check_1 (string);
  6030           ANDROID_DELETE_LOCAL_REF (string);
  6031 
  6032           if (extracted)
  6033             {
  6034               /* extracted is now an associated ExtractedText object.
  6035                  Perform the update.  */
  6036               android_update_extracted_text (FRAME_ANDROID_WINDOW (f),
  6037                                              extracted, token);
  6038               ANDROID_DELETE_LOCAL_REF (extracted);
  6039             }
  6040         }
  6041     }
  6042 }
  6043 
  6044 /* Return whether or not EVENT is an input method event destined for
  6045    the frame (struct frame *) ARG.  */
  6046 
  6047 static bool
  6048 android_event_is_for_frame (union android_event *event, void *arg)
  6049 {
  6050   struct frame *f;
  6051 
  6052   f = arg;
  6053   return (event->type == ANDROID_INPUT_METHOD
  6054           && event->ime.window == FRAME_ANDROID_WINDOW (f));
  6055 }
  6056 
  6057 /* Notice that the input method connection to F should be reset as a
  6058    result of a change to its contents.  */
  6059 
  6060 static void
  6061 android_reset_conversion (struct frame *f)
  6062 {
  6063   enum android_ic_mode mode;
  6064   struct window *w;
  6065   struct buffer *buffer;
  6066   Lisp_Object style;
  6067   union android_event event;
  6068 
  6069   /* Reset the input method.
  6070 
  6071      Select an appropriate ``input mode'' based on whether or not the
  6072      minibuffer window is selected, which in turn affects if ``RET''
  6073      inserts a newline or sends an editor action Emacs transforms into
  6074      a key event (refer to `performEditorAction'.)  */
  6075 
  6076   w = XWINDOW (f->selected_window);
  6077   buffer = XBUFFER (WINDOW_BUFFER (w));
  6078 
  6079   style = (EQ (find_symbol_value (Qoverriding_text_conversion_style),
  6080                Qlambda)
  6081            ? BVAR (buffer, text_conversion_style)
  6082            : find_symbol_value (Qoverriding_text_conversion_style));
  6083 
  6084   if (NILP (style) || conversion_disabled_p ())
  6085     mode = ANDROID_IC_MODE_NULL;
  6086   else if (EQ (style, Qaction) || EQ (f->selected_window,
  6087                                       f->minibuffer_window))
  6088     mode = ANDROID_IC_MODE_ACTION;
  6089   else
  6090     mode = ANDROID_IC_MODE_TEXT;
  6091 
  6092   /* Remove any existing input method events that apply to FRAME from
  6093      the event queue.
  6094 
  6095      There's a small window between this and the call to
  6096      android_reset_ic between which more events can be generated.  */
  6097 
  6098   while (android_check_if_event (&event, android_event_is_for_frame, f))
  6099     {
  6100       switch (event.ime.operation)
  6101         {
  6102         case ANDROID_IME_COMMIT_TEXT:
  6103         case ANDROID_IME_FINISH_COMPOSING_TEXT:
  6104         case ANDROID_IME_SET_COMPOSING_TEXT:
  6105           xfree (event.ime.text);
  6106           break;
  6107 
  6108         default:
  6109           break;
  6110         }
  6111     }
  6112 
  6113   android_reset_ic (FRAME_ANDROID_WINDOW (f), mode);
  6114 
  6115   /* Clear extracted text flags.  Since the IM has been reinitialised,
  6116      it should no longer be displaying extracted text.  */
  6117   FRAME_ANDROID_OUTPUT (f)->extracted_text_flags = 0;
  6118 
  6119   /* Move its selection to the specified position.  */
  6120   android_update_selection (f, NULL);
  6121 }
  6122 
  6123 /* Notice that point has moved in the F's selected window's selected
  6124    buffer.  W is the window, and BUFFER is that buffer.  */
  6125 
  6126 static void
  6127 android_set_point (struct frame *f, struct window *w,
  6128                    struct buffer *buffer)
  6129 {
  6130   android_update_selection (f, w);
  6131 }
  6132 
  6133 /* Notice that the composition region on F's old selected window has
  6134    changed.  */
  6135 
  6136 static void
  6137 android_compose_region_changed (struct frame *f)
  6138 {
  6139   android_update_selection (f, XWINDOW (f->old_selected_window));
  6140 }
  6141 
  6142 /* Notice that the text conversion has completed.  */
  6143 
  6144 static void
  6145 android_notify_conversion (unsigned long counter)
  6146 {
  6147   int sval;
  6148 
  6149   if (last_edit_counter < counter)
  6150     __atomic_store_n (&last_edit_counter, counter,
  6151                       __ATOMIC_SEQ_CST);
  6152 
  6153   sem_getvalue (&edit_sem, &sval);
  6154 
  6155   if (sval <= 0)
  6156     sem_post (&edit_sem);
  6157 }
  6158 
  6159 /* Android text conversion interface.  */
  6160 
  6161 static struct textconv_interface text_conversion_interface =
  6162   {
  6163     android_reset_conversion,
  6164     android_set_point,
  6165     android_compose_region_changed,
  6166     android_notify_conversion,
  6167   };
  6168 
  6169 
  6170 
  6171 extern frame_parm_handler android_frame_parm_handlers[];
  6172 
  6173 #endif /* !ANDROID_STUBIFY */
  6174 
  6175 static struct redisplay_interface android_redisplay_interface =
  6176   {
  6177 #ifndef ANDROID_STUBIFY
  6178     android_frame_parm_handlers,
  6179     gui_produce_glyphs,
  6180     gui_write_glyphs,
  6181     gui_insert_glyphs,
  6182     gui_clear_end_of_line,
  6183     android_scroll_run,
  6184     android_after_update_window_line,
  6185     NULL, /* update_window_begin */
  6186     NULL, /* update_window_end   */
  6187     android_flip_and_flush,
  6188     gui_clear_window_mouse_face,
  6189     gui_get_glyph_overhangs,
  6190     gui_fix_overlapping_area,
  6191     android_draw_fringe_bitmap,
  6192     NULL, /* define_fringe_bitmap */
  6193     NULL, /* destroy_fringe_bitmap */
  6194     android_compute_glyph_string_overhangs,
  6195     android_draw_glyph_string,
  6196     android_define_frame_cursor,
  6197     android_clear_frame_area,
  6198     android_clear_under_internal_border,
  6199     android_draw_window_cursor,
  6200     android_draw_vertical_window_border,
  6201     android_draw_window_divider,
  6202     NULL,
  6203     android_show_hourglass,
  6204     android_hide_hourglass,
  6205     android_default_font_parameter,
  6206 #endif
  6207   };
  6208 
  6209 
  6210 
  6211 void
  6212 frame_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y)
  6213 {
  6214   /* This cannot be implemented on Android, and as such is left
  6215      blank.  */
  6216 }
  6217 
  6218 char *
  6219 get_keysym_name (int keysym)
  6220 {
  6221   static char buffer[64];
  6222 
  6223 #ifndef ANDROID_STUBIFY
  6224   android_get_keysym_name (keysym, buffer, 64);
  6225 #else
  6226   emacs_abort ();
  6227 #endif
  6228   return buffer;
  6229 }
  6230 
  6231 
  6232 
  6233 /* Create a struct terminal, initialize it with the Android specific
  6234    functions and make DISPLAY->TERMINAL point to it.  */
  6235 
  6236 static struct terminal *
  6237 android_create_terminal (struct android_display_info *dpyinfo)
  6238 {
  6239   struct terminal *terminal;
  6240 
  6241   terminal = create_terminal (output_android,
  6242                               &android_redisplay_interface);
  6243   terminal->display_info.android = dpyinfo;
  6244   dpyinfo->terminal = terminal;
  6245 
  6246   /* kboard is initialized in android_term_init.  */
  6247 
  6248 #ifndef ANDROID_STUBIFY
  6249 
  6250   terminal->clear_frame_hook = android_clear_frame;
  6251   terminal->ring_bell_hook = android_ring_bell;
  6252   terminal->toggle_invisible_pointer_hook
  6253     = android_toggle_invisible_pointer;
  6254   terminal->update_begin_hook = android_update_begin;
  6255   terminal->update_end_hook = android_update_end;
  6256   terminal->read_socket_hook = android_read_socket;
  6257   terminal->frame_up_to_date_hook = android_frame_up_to_date;
  6258   terminal->buffer_flipping_unblocked_hook
  6259     = android_buffer_flipping_unblocked_hook;
  6260   terminal->defined_color_hook = android_defined_color;
  6261   terminal->query_frame_background_color
  6262     = android_query_frame_background_color;
  6263   terminal->query_colors = android_query_colors;
  6264   terminal->mouse_position_hook = android_mouse_position;
  6265   terminal->get_focus_frame = android_get_focus_frame;
  6266   terminal->focus_frame_hook = android_focus_frame;
  6267   terminal->frame_rehighlight_hook = android_frame_rehighlight_hook;
  6268   terminal->frame_raise_lower_hook = android_frame_raise_lower;
  6269   terminal->frame_visible_invisible_hook
  6270     = android_make_frame_visible_invisible;
  6271   terminal->fullscreen_hook = android_fullscreen_hook;
  6272   terminal->iconify_frame_hook = android_iconify_frame;
  6273   terminal->set_window_size_hook = android_set_window_size;
  6274   terminal->set_frame_offset_hook = android_set_offset;
  6275   terminal->set_frame_alpha_hook = android_set_alpha;
  6276   terminal->set_new_font_hook = android_new_font;
  6277   terminal->set_bitmap_icon_hook = android_bitmap_icon;
  6278   terminal->implicit_set_name_hook = android_implicitly_set_name;
  6279   terminal->menu_show_hook = android_menu_show;
  6280   terminal->popup_dialog_hook = android_popup_dialog;
  6281   terminal->change_tab_bar_height_hook = android_change_tab_bar_height;
  6282   terminal->change_tool_bar_height_hook = android_change_tool_bar_height;
  6283   terminal->set_scroll_bar_default_width_hook
  6284     = android_set_scroll_bar_default_width;
  6285   terminal->set_scroll_bar_default_height_hook
  6286     = android_set_scroll_bar_default_height;
  6287   terminal->free_pixmap = android_free_pixmap_hook;
  6288   terminal->delete_frame_hook = android_delete_frame;
  6289   terminal->delete_terminal_hook = android_delete_terminal;
  6290 
  6291 #else
  6292   emacs_abort ();
  6293 #endif
  6294 
  6295   return terminal;
  6296 }
  6297 
  6298 /* Initialize the Android terminal interface.  The display connection
  6299    has already been set up by the system at this point.  */
  6300 
  6301 void
  6302 android_term_init (void)
  6303 {
  6304   struct terminal *terminal;
  6305   struct android_display_info *dpyinfo;
  6306   Lisp_Object color_file, color_map;
  6307 
  6308   dpyinfo = xzalloc (sizeof *dpyinfo);
  6309   terminal = android_create_terminal (dpyinfo);
  6310   terminal->kboard = allocate_kboard (Qandroid);
  6311   terminal->kboard->reference_count++;
  6312 
  6313   dpyinfo->n_planes = 24;
  6314 
  6315   /* This function should only be called once at startup.  */
  6316   eassert (!x_display_list);
  6317   x_display_list = dpyinfo;
  6318 
  6319   dpyinfo->name_list_element
  6320     = Fcons (build_pure_c_string ("android"), Qnil);
  6321 
  6322   color_file = Fexpand_file_name (build_string ("rgb.txt"),
  6323                                   Vdata_directory);
  6324   color_map = Fx_load_color_file (color_file);
  6325 
  6326   if (NILP (color_map))
  6327     fatal ("Could not read %s.\n", SDATA (color_file));
  6328 
  6329   dpyinfo->color_map = color_map;
  6330 
  6331 #ifndef ANDROID_STUBIFY
  6332   dpyinfo->resx = android_pixel_density_x;
  6333   dpyinfo->resy = android_pixel_density_y;
  6334   dpyinfo->font_resolution = android_scaled_pixel_density;
  6335 #endif /* ANDROID_STUBIFY */
  6336 
  6337   /* https://lists.gnu.org/r/emacs-devel/2015-11/msg00194.html  */
  6338   dpyinfo->smallest_font_height = 1;
  6339   dpyinfo->smallest_char_width = 1;
  6340 
  6341   terminal->name = xstrdup ("android");
  6342 
  6343   /* The display "connection" is now set up, and it must never go
  6344      away.  */
  6345   terminal->reference_count = 30000;
  6346 
  6347   /* Set the baud rate to the same value it gets set to on X.  */
  6348   baud_rate = 19200;
  6349 
  6350 #ifndef ANDROID_STUBIFY
  6351   sem_init (&edit_sem, false, 0);
  6352   register_textconv_interface (&text_conversion_interface);
  6353 #endif
  6354 }
  6355 
  6356 
  6357 
  6358 /* Set Vandroid_build_fingerprint to a reasonable value, and also
  6359    Vandroid_build_manufacturer.  */
  6360 
  6361 static void
  6362 android_set_build_fingerprint (void)
  6363 {
  6364 #ifdef ANDROID_STUBIFY
  6365   Vandroid_build_fingerprint = Qnil;
  6366 #else /* !ANDROID_STUBIFY */
  6367   jclass class;
  6368   jfieldID field;
  6369   jobject string;
  6370   const char *data;
  6371 
  6372   /* Set class to NULL so freeing an uninitialized local ref can be
  6373      avoided.  */
  6374   class = NULL;
  6375 
  6376   /* Likewise for string.  */
  6377   string = NULL;
  6378 
  6379   if (!android_init_gui)
  6380     goto fail;
  6381   else
  6382     {
  6383       /* Obtain Build.FINGERPRINT.  Clear exceptions after each query;
  6384          JNI can't find Build.FINGERPRINT on some systems.  */
  6385 
  6386       class = (*android_java_env)->FindClass (android_java_env,
  6387                                               "android/os/Build");
  6388       (*android_java_env)->ExceptionClear (android_java_env);
  6389 
  6390       if (!class)
  6391         goto fail;
  6392 
  6393       field = (*android_java_env)->GetStaticFieldID (android_java_env,
  6394                                                      class,
  6395                                                      "FINGERPRINT",
  6396                                                      "Ljava/lang/String;");
  6397       (*android_java_env)->ExceptionClear (android_java_env);
  6398 
  6399       if (!field)
  6400         goto fail;
  6401 
  6402       string
  6403         = (*android_java_env)->GetStaticObjectField (android_java_env,
  6404                                                      class, field);
  6405       (*android_java_env)->ExceptionClear (android_java_env);
  6406 
  6407       if (!string)
  6408         goto fail;
  6409 
  6410       data = (*android_java_env)->GetStringUTFChars (android_java_env,
  6411                                                      string, NULL);
  6412       (*android_java_env)->ExceptionClear (android_java_env);
  6413 
  6414       if (!data)
  6415         goto fail;
  6416 
  6417       Vandroid_build_fingerprint = build_string_from_utf8 (data);
  6418       (*android_java_env)->ReleaseStringUTFChars (android_java_env,
  6419                                                   string, data);
  6420 
  6421       /* Now retrieve Build.MANUFACTURER.  */
  6422 
  6423       ANDROID_DELETE_LOCAL_REF (string);
  6424       string = NULL;
  6425 
  6426       field = (*android_java_env)->GetStaticFieldID (android_java_env,
  6427                                                      class,
  6428                                                      "MANUFACTURER",
  6429                                                      "Ljava/lang/String;");
  6430       (*android_java_env)->ExceptionClear (android_java_env);
  6431 
  6432       if (!field)
  6433         goto fail;
  6434 
  6435       string
  6436         = (*android_java_env)->GetStaticObjectField (android_java_env,
  6437                                                      class, field);
  6438       (*android_java_env)->ExceptionClear (android_java_env);
  6439 
  6440       if (!string)
  6441         goto fail;
  6442 
  6443       data = (*android_java_env)->GetStringUTFChars (android_java_env,
  6444                                                      string, NULL);
  6445       (*android_java_env)->ExceptionClear (android_java_env);
  6446 
  6447       if (!data)
  6448         goto fail;
  6449 
  6450       Vandroid_build_manufacturer = build_string_from_utf8 (data);
  6451       (*android_java_env)->ReleaseStringUTFChars (android_java_env,
  6452                                                   string, data);
  6453     }
  6454 
  6455   if (string)
  6456     ANDROID_DELETE_LOCAL_REF (string);
  6457 
  6458   ANDROID_DELETE_LOCAL_REF (class);
  6459 
  6460   return;
  6461 
  6462  fail:
  6463   if (class)
  6464     ANDROID_DELETE_LOCAL_REF (class);
  6465 
  6466   Vandroid_build_fingerprint = Qnil;
  6467   Vandroid_build_manufacturer = Qnil;
  6468 #endif /* ANDROID_STUBIFY */
  6469 }
  6470 
  6471 void
  6472 syms_of_androidterm (void)
  6473 {
  6474   Fprovide (Qandroid, Qnil);
  6475 
  6476   DEFVAR_LISP ("android-wait-for-event-timeout",
  6477                Vandroid_wait_for_event_timeout,
  6478     doc: /* How long to wait for Android events.
  6479 
  6480 Emacs will wait up to this many seconds to receive events after
  6481 making changes which affect the state of the graphical interface.
  6482 Under some situations this can take an indefinite amount of time,
  6483 so it is important to limit the wait.
  6484 
  6485 If set to a non-float value, there will be no wait at all.  */);
  6486   Vandroid_wait_for_event_timeout = make_float (0.1);
  6487 
  6488   DEFVAR_BOOL ("x-use-underline-position-properties",
  6489                x_use_underline_position_properties,
  6490      doc: /* SKIP: real doc in xterm.c.  */);
  6491   x_use_underline_position_properties = true;
  6492   DEFSYM (Qx_use_underline_position_properties,
  6493           "x-use-underline-position-properties");
  6494 
  6495   DEFVAR_BOOL ("x-underline-at-descent-line",
  6496                x_underline_at_descent_line,
  6497      doc: /* SKIP: real doc in xterm.c.  */);
  6498   x_underline_at_descent_line = false;
  6499 
  6500   DEFVAR_LISP ("android-build-fingerprint", Vandroid_build_fingerprint,
  6501     doc: /* String identifying the device's OS version.
  6502 This is a string that uniquely identifies the version of Android
  6503 Emacs is running on.  */);
  6504   Vandroid_build_fingerprint = Qnil;
  6505 
  6506   DEFVAR_LISP ("android-build-manufacturer", Vandroid_build_manufacturer,
  6507     doc: /* Name of the developer of the running version of Android.  */);
  6508   Vandroid_build_manufacturer = Qnil;
  6509 
  6510   /* Only defined so loadup.el loads scroll-bar.el.  */
  6511   DEFVAR_LISP ("x-toolkit-scroll-bars", Vx_toolkit_scroll_bars,
  6512     doc: /* SKIP: real doc in xterm.c.  */);
  6513   Vx_toolkit_scroll_bars = Qnil;
  6514 
  6515   /* Avoid dumping Vandroid_build_fingerprint.  */
  6516   pdumper_do_now_and_after_load (android_set_build_fingerprint);
  6517 
  6518   DEFSYM (Qx_underline_at_descent_line, "x-underline-at-descent-line");
  6519 }
  6520 
  6521 void
  6522 mark_androidterm (void)
  6523 {
  6524   if (x_display_list)
  6525     mark_object (x_display_list->color_map);
  6526 }

/* [<][>][^][v][top][bottom][index][help] */