root/src/android.c

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

DEFINITIONS

This source file includes following definitions.
  1. android_run_select_thread
  2. android_handle_sigusr1
  3. android_init_events
  4. android_pending
  5. android_wait_event
  6. android_next_event
  7. android_check_if_event
  8. android_write_event
  9. android_select
  10. android_run_debug_thread
  11. android_user_full_name
  12. android_is_special_directory
  13. android_url_encode
  14. android_get_content_name
  15. android_get_home_directory
  16. android_proc_name
  17. android_create_lib_link
  18. android_init_emacs_service
  19. android_init_emacs_pixmap
  20. android_init_graphics_point
  21. android_init_emacs_drawable
  22. android_init_emacs_window
  23. android_init_emacs_cursor
  24. NATIVE_NAME
  25. android_alloc_id
  26. android_destroy_handle
  27. android_resolve_handle
  28. android_resolve_handle2
  29. android_change_window_attributes
  30. android_create_window
  31. android_set_window_background
  32. android_destroy_window
  33. android_init_android_rect_class
  34. android_init_emacs_gc_class
  35. android_create_gc
  36. android_free_gc
  37. android_change_gc
  38. android_set_clip_rectangles
  39. android_reparent_window
  40. android_clear_window
  41. android_map_window
  42. android_unmap_window
  43. android_resize_window
  44. android_move_window
  45. android_swap_buffers
  46. android_get_gc_values
  47. android_set_foreground
  48. android_fill_rectangle
  49. android_create_pixmap_from_bitmap_data
  50. android_set_clip_mask
  51. android_set_fill_style
  52. android_neon_mask_line
  53. android_blit_copy
  54. android_blit_xor
  55. android_copy_area
  56. android_free_pixmap
  57. android_set_background
  58. android_fill_polygon
  59. android_draw_rectangle
  60. android_draw_point
  61. android_draw_line
  62. android_create_pixmap
  63. android_set_ts_origin
  64. android_clear_area
  65. android_create_bitmap_from_data
  66. android_create_image
  67. android_destroy_image
  68. android_put_pixel
  69. android_get_pixel
  70. android_get_image
  71. android_put_image
  72. android_bell
  73. android_set_input_focus
  74. android_raise_window
  75. android_lower_window
  76. android_query_tree
  77. android_get_geometry
  78. android_move_resize_window
  79. android_map_raised
  80. android_translate_coordinates
  81. android_wc_lookup_string
  82. android_lock_bitmap
  83. android_damage_window
  84. android_get_screen_width
  85. android_get_screen_height
  86. android_get_mm_width
  87. android_get_mm_height
  88. android_detect_mouse
  89. android_set_dont_focus_on_map
  90. android_set_dont_accept_focus
  91. android_get_keysym_name
  92. android_toggle_on_screen_keyboard
  93. emacs_abort
  94. android_check_string
  95. android_verify_jni_string
  96. android_build_string
  97. android_build_jstring
  98. android_exception_check
  99. android_exception_check_1
  100. android_exception_check_2
  101. android_exception_check_3
  102. android_exception_check_4
  103. android_exception_check_nonnull
  104. android_exception_check_nonnull_1
  105. android_transform_coordinates
  106. android_four_corners_bilinear
  107. android_fetch_pixel_bilinear
  108. android_project_image_bilinear
  109. android_fetch_pixel_nearest_24
  110. android_fetch_pixel_nearest_1
  111. android_project_image_nearest
  112. android_browse_url
  113. android_restart_emacs
  114. android_query_battery
  115. android_request_directory_access
  116. android_check_query
  117. android_check_query_urgent
  118. android_answer_query
  119. android_answer_query_spin
  120. android_begin_query
  121. android_end_query
  122. android_run_in_emacs_thread
  123. android_update_ic
  124. android_reset_ic
  125. android_update_extracted_text
  126. android_update_cursor_anchor_info
  127. android_set_fullscreen
  128. android_create_font_cursor
  129. android_define_cursor
  130. android_free_cursor
  131. android_rewrite_spawn_argv
  132. android_create_gc
  133. android_free_gc
  134. android_create_image
  135. android_destroy_image
  136. android_put_pixel
  137. android_get_pixel
  138. android_get_image
  139. android_put_image
  140. android_project_image_bilinear
  141. android_project_image_nearest

     1 /* Android initialization for GNU Emacs.
     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 <allocator.h>
    22 #include <assert.h>
    23 #include <careadlinkat.h>
    24 #include <errno.h>
    25 #include <fcntl.h>
    26 #include <fingerprint.h>
    27 #include <intprops.h>
    28 #include <libgen.h>
    29 #include <limits.h>
    30 #include <math.h>
    31 #include <pthread.h>
    32 #include <semaphore.h>
    33 #include <signal.h>
    34 #include <stdckdint.h>
    35 #include <string.h>
    36 #include <sys/param.h>
    37 #include <timespec.h>
    38 #include <unistd.h>
    39 
    40 /* Old NDK versions lack MIN and MAX.  */
    41 #include <minmax.h>
    42 
    43 #include "android.h"
    44 #include "androidgui.h"
    45 
    46 #include "lisp.h"
    47 #include "blockinput.h"
    48 #include "coding.h"
    49 #include "epaths.h"
    50 
    51 /* Whether or not Emacs is running inside the application process and
    52    Android windowing should be enabled.  */
    53 bool android_init_gui;
    54 
    55 #ifndef ANDROID_STUBIFY
    56 
    57 #include <android/bitmap.h>
    58 #include <android/log.h>
    59 
    60 #include <linux/unistd.h>
    61 
    62 #include <sys/syscall.h>
    63 
    64 #ifdef __aarch64__
    65 #include <arm_neon.h>
    66 #endif /* __aarch64__ */
    67 
    68 struct android_emacs_pixmap
    69 {
    70   jclass class;
    71   jmethodID constructor;
    72   jmethodID constructor_mutable;
    73 };
    74 
    75 struct android_graphics_point
    76 {
    77   jclass class;
    78   jmethodID constructor;
    79 };
    80 
    81 struct android_emacs_drawable
    82 {
    83   jclass class;
    84   jmethodID get_bitmap;
    85   jmethodID damage_rect;
    86 };
    87 
    88 struct android_emacs_window
    89 {
    90   jclass class;
    91   jmethodID swap_buffers;
    92   jmethodID toggle_on_screen_keyboard;
    93   jmethodID lookup_string;
    94   jmethodID set_fullscreen;
    95   jmethodID change_window_background;
    96   jmethodID reparent_to;
    97   jmethodID map_window;
    98   jmethodID unmap_window;
    99   jmethodID resize_window;
   100   jmethodID move_window;
   101   jmethodID make_input_focus;
   102   jmethodID raise;
   103   jmethodID lower;
   104   jmethodID get_window_geometry;
   105   jmethodID translate_coordinates;
   106   jmethodID set_dont_accept_focus;
   107   jmethodID set_dont_focus_on_map;
   108   jmethodID define_cursor;
   109 };
   110 
   111 struct android_emacs_cursor
   112 {
   113   jclass class;
   114   jmethodID constructor;
   115 };
   116 
   117 /* The API level of the current device.  */
   118 static int android_api_level;
   119 
   120 /* The directory used to store site-lisp.  */
   121 char *android_site_load_path;
   122 
   123 /* The directory used to store native libraries.  */
   124 char *android_lib_dir;
   125 
   126 /* The directory used to store game files.  */
   127 char *android_game_path;
   128 
   129 /* The directory used to store temporary files.  */
   130 char *android_cache_dir;
   131 
   132 /* The list of archive files within which the Java virtual macine
   133    looks for class files.  */
   134 char *android_class_path;
   135 
   136 /* The display's pixel densities.  */
   137 double android_pixel_density_x, android_pixel_density_y;
   138 
   139 /* The display pixel density used to convert between point and pixel
   140    font sizes.  */
   141 double android_scaled_pixel_density;
   142 
   143 /* The Android application data directory.  */
   144 static char *android_files_dir;
   145 
   146 /* The Java environment being used for the main thread.  */
   147 JNIEnv *android_java_env;
   148 
   149 /* The EmacsGC class.  */
   150 static jclass emacs_gc_class;
   151 
   152 /* Various fields.  */
   153 static jfieldID emacs_gc_foreground, emacs_gc_background;
   154 static jfieldID emacs_gc_function, emacs_gc_clip_rects;
   155 static jfieldID emacs_gc_clip_x_origin, emacs_gc_clip_y_origin;
   156 static jfieldID emacs_gc_stipple, emacs_gc_clip_mask;
   157 static jfieldID emacs_gc_fill_style, emacs_gc_ts_origin_x;
   158 static jfieldID emacs_gc_ts_origin_y;
   159 
   160 /* The constructor and one function.  */
   161 static jmethodID emacs_gc_constructor, emacs_gc_mark_dirty;
   162 
   163 /* The Rect class.  */
   164 static jclass android_rect_class;
   165 
   166 /* Its constructor.  */
   167 static jmethodID android_rect_constructor;
   168 
   169 /* The EmacsService object.  */
   170 jobject emacs_service;
   171 
   172 /* Various methods associated with the EmacsService.  */
   173 struct android_emacs_service service_class;
   174 
   175 /* Various methods associated with the EmacsPixmap class.  */
   176 static struct android_emacs_pixmap pixmap_class;
   177 
   178 /* Various methods associated with the Point class.  */
   179 static struct android_graphics_point point_class;
   180 
   181 /* Various methods associated with the EmacsDrawable class.  */
   182 static struct android_emacs_drawable drawable_class;
   183 
   184 /* Various methods associated with the EmacsWindow class.  */
   185 static struct android_emacs_window window_class;
   186 
   187 /* Various methods associated with the EmacsCursor class.  */
   188 static struct android_emacs_cursor cursor_class;
   189 
   190 /* The last event serial used.  This is a 32 bit value, but it is
   191    stored in unsigned long to be consistent with X.  */
   192 unsigned int event_serial;
   193 
   194 #ifdef __i386__
   195 
   196 /* Unused pointer used to control compiler optimizations.  */
   197 void *unused_pointer;
   198 
   199 #endif /* __i386__ */
   200 
   201 /* Whether or not the default signal mask has been changed.  If so,
   202    the signal mask must be restored before calling
   203    android_emacs_init.  */
   204 static bool signal_mask_changed_p;
   205 
   206 /* The signal mask at the time Emacs was started.  */
   207 static sigset_t startup_signal_mask;
   208 
   209 
   210 
   211 /* Event handling functions.  Events are stored on a (circular) queue
   212    that is read synchronously.  The Android port replaces pselect with
   213    a function android_select, which runs pselect in a separate thread,
   214    but more importantly also waits for events to be available on the
   215    android event queue.  */
   216 
   217 struct android_event_container
   218 {
   219   /* The next and last events in this queue.  */
   220   struct android_event_container *next, *last;
   221 
   222   /* The event itself.  */
   223   union android_event event;
   224 };
   225 
   226 struct android_event_queue
   227 {
   228   /* Mutex protecting the event queue.  */
   229   pthread_mutex_t mutex;
   230 
   231   /* Mutex protecting the select data.  */
   232   pthread_mutex_t select_mutex;
   233 
   234   /* The thread used to run select.  */
   235   pthread_t select_thread;
   236 
   237   /* Condition variables for the reading side.  */
   238   pthread_cond_t read_var;
   239 
   240   /* The number of events in the queue.  If this is greater than 1024,
   241      writing will block.  */
   242   int num_events;
   243 
   244   /* Circular queue of events.  */
   245   struct android_event_container events;
   246 };
   247 
   248 /* Arguments to pselect used by the select thread.  */
   249 static int android_pselect_nfds;
   250 static fd_set *android_pselect_readfds;
   251 static fd_set *android_pselect_writefds;
   252 static fd_set *android_pselect_exceptfds;
   253 static struct timespec *android_pselect_timeout;
   254 
   255 /* Value of pselect.  */
   256 static int android_pselect_rc;
   257 
   258 /* The global event queue.  */
   259 static struct android_event_queue event_queue;
   260 
   261 /* Semaphores used to signal select completion and start.  */
   262 static sem_t android_pselect_sem, android_pselect_start_sem;
   263 
   264 #if __ANDROID_API__ < 16
   265 
   266 /* Select self-pipe.  */
   267 static int select_pipe[2];
   268 
   269 #else
   270 
   271 /* Whether or not pselect has been interrupted.  */
   272 static volatile sig_atomic_t android_pselect_interrupted;
   273 
   274 #endif
   275 
   276 static void *
   277 android_run_select_thread (void *data)
   278 {
   279   /* Apparently this is required too.  */
   280   JNI_STACK_ALIGNMENT_PROLOGUE;
   281 
   282   int rc;
   283 #if __ANDROID_API__ < 16
   284   int nfds;
   285   fd_set readfds;
   286   char byte;
   287 #else
   288   sigset_t signals, waitset;
   289   int sig;
   290 #endif
   291 
   292 #if __ANDROID_API__ < 16
   293   /* A completely different implementation is used when building for
   294      Android versions earlier than 16, because pselect with a signal
   295      mask does not work there.  Instead of blocking SIGUSR1 and
   296      unblocking it inside pselect, a file descriptor is used instead.
   297      Something is written to the file descriptor every time select is
   298      supposed to return.  */
   299 
   300   while (true)
   301     {
   302       /* Wait for the thread to be released.  */
   303       while (sem_wait (&android_pselect_start_sem) < 0)
   304         ;;
   305 
   306       /* Get the select lock and call pselect.  API 8 does not have
   307          working pselect in any sense.  Instead, pselect wakes up on
   308          select_pipe[0].  */
   309 
   310       pthread_mutex_lock (&event_queue.select_mutex);
   311       nfds = android_pselect_nfds;
   312 
   313       if (android_pselect_readfds)
   314         readfds = *android_pselect_readfds;
   315       else
   316         FD_ZERO (&readfds);
   317 
   318       if (nfds < select_pipe[0] + 1)
   319         nfds = select_pipe[0] + 1;
   320       FD_SET (select_pipe[0], &readfds);
   321 
   322       rc = pselect (nfds, &readfds,
   323                     android_pselect_writefds,
   324                     android_pselect_exceptfds,
   325                     android_pselect_timeout,
   326                     NULL);
   327 
   328       /* Subtract 1 from rc if readfds contains the select pipe, and
   329          also remove it from that set.  */
   330 
   331       if (rc != -1 && FD_ISSET (select_pipe[0], &readfds))
   332         {
   333           rc -= 1;
   334           FD_CLR (select_pipe[0], &readfds);
   335 
   336           /* If no file descriptors aside from the select pipe are
   337              ready, then pretend that an error has occurred.  */
   338           if (!rc)
   339             rc = -1;
   340         }
   341 
   342       /* Save the read file descriptor set back again.  */
   343 
   344       if (android_pselect_readfds)
   345         *android_pselect_readfds = readfds;
   346 
   347       android_pselect_rc = rc;
   348       pthread_mutex_unlock (&event_queue.select_mutex);
   349 
   350       /* Signal the main thread that there is now data to read.  Hold
   351          the event queue lock during this process to make sure this
   352          does not happen before the main thread begins to wait for the
   353          condition variable.  */
   354 
   355       pthread_mutex_lock (&event_queue.mutex);
   356       pthread_cond_broadcast (&event_queue.read_var);
   357       pthread_mutex_unlock (&event_queue.mutex);
   358 
   359       /* Read a single byte from the select pipe.  */
   360       read (select_pipe[0], &byte, 1);
   361 
   362       /* Signal the Emacs thread that pselect is done.  If read_var
   363          was signaled by android_write_event, event_queue.mutex could
   364          still be locked, so this must come before.  */
   365       sem_post (&android_pselect_sem);
   366     }
   367 #else
   368   if (pthread_sigmask (SIG_BLOCK, &signals, NULL))
   369     __android_log_print (ANDROID_LOG_FATAL, __func__,
   370                          "pthread_sigmask: %s",
   371                          strerror (errno));
   372 
   373   sigfillset (&signals);
   374   sigdelset (&signals, SIGUSR1);
   375   sigemptyset (&waitset);
   376   sigaddset (&waitset, SIGUSR1);
   377 
   378   while (true)
   379     {
   380       /* Wait for the thread to be released.  */
   381       while (sem_wait (&android_pselect_start_sem) < 0)
   382         ;;
   383 
   384       /* Clear the ``pselect interrupted'' flag.  This is safe because
   385          right now, SIGUSR1 is blocked.  */
   386       android_pselect_interrupted = 0;
   387 
   388       /* Get the select lock and call pselect.  */
   389       pthread_mutex_lock (&event_queue.select_mutex);
   390       rc = pselect (android_pselect_nfds,
   391                     android_pselect_readfds,
   392                     android_pselect_writefds,
   393                     android_pselect_exceptfds,
   394                     android_pselect_timeout,
   395                     &signals);
   396       android_pselect_rc = rc;
   397       pthread_mutex_unlock (&event_queue.select_mutex);
   398 
   399       /* Signal the main thread that there is now data to read.  Hold
   400          the event queue lock during this process to make sure this
   401          does not happen before the main thread begins to wait for the
   402          condition variable.  */
   403 
   404       pthread_mutex_lock (&event_queue.mutex);
   405       pthread_cond_broadcast (&event_queue.read_var);
   406       pthread_mutex_unlock (&event_queue.mutex);
   407 
   408       /* Check `android_pselect_interrupted' instead of rc and errno.
   409 
   410          This is because `pselect' does not return an rc of -1 upon
   411          being interrupted in some versions of Android, but does set
   412          signal masks correctly.  */
   413 
   414       if (!android_pselect_interrupted)
   415         /* Now, wait for SIGUSR1, unless pselect was interrupted and
   416            the signal was already delivered.  The Emacs thread will
   417            always send this signal after read_var is triggered or the
   418            UI thread has sent an event.  */
   419         sigwait (&waitset, &sig);
   420 
   421       /* Signal the Emacs thread that pselect is done.  If read_var
   422          was signaled by android_write_event, event_queue.mutex could
   423          still be locked, so this must come before.  */
   424       sem_post (&android_pselect_sem);
   425     }
   426 #endif
   427 
   428   return NULL;
   429 }
   430 
   431 #if __ANDROID_API__ >= 16
   432 
   433 static void
   434 android_handle_sigusr1 (int sig, siginfo_t *siginfo, void *arg)
   435 {
   436   /* Notice that pselect has been interrupted.  */
   437   android_pselect_interrupted = 1;
   438 }
   439 
   440 #endif
   441 
   442 /* Semaphore used to indicate completion of a query.
   443    This should ideally be defined further down.  */
   444 static sem_t android_query_sem;
   445 
   446 /* Set up the global event queue by initializing the mutex and two
   447    condition variables, and the linked list of events.  This must be
   448    called before starting the Emacs thread.  Also, initialize the
   449    thread used to run pselect.
   450 
   451    These functions must also use the C library malloc and free,
   452    because xmalloc is not thread safe.  */
   453 
   454 static void
   455 android_init_events (void)
   456 {
   457   struct sigaction sa;
   458 
   459   if (pthread_mutex_init (&event_queue.mutex, NULL))
   460     __android_log_print (ANDROID_LOG_FATAL, __func__,
   461                          "pthread_mutex_init: %s",
   462                          strerror (errno));
   463 
   464   if (pthread_mutex_init (&event_queue.select_mutex, NULL))
   465     __android_log_print (ANDROID_LOG_FATAL, __func__,
   466                          "pthread_mutex_init: %s",
   467                          strerror (errno));
   468 
   469   if (pthread_cond_init (&event_queue.read_var, NULL))
   470     __android_log_print (ANDROID_LOG_FATAL, __func__,
   471                          "pthread_cond_init: %s",
   472                          strerror (errno));
   473 
   474   sem_init (&android_pselect_sem, 0, 0);
   475   sem_init (&android_pselect_start_sem, 0, 0);
   476   sem_init (&android_query_sem, 0, 0);
   477 
   478   event_queue.events.next = &event_queue.events;
   479   event_queue.events.last = &event_queue.events;
   480 
   481 #if __ANDROID_API__ >= 16
   482 
   483   /* Before starting the select thread, make sure the disposition for
   484      SIGUSR1 is correct.  */
   485   sigfillset (&sa.sa_mask);
   486   sa.sa_sigaction = android_handle_sigusr1;
   487   sa.sa_flags = SA_SIGINFO;
   488 
   489 #else
   490 
   491   /* Set up the file descriptor used to wake up pselect.  */
   492   if (pipe2 (select_pipe, O_CLOEXEC) < 0)
   493     __android_log_print (ANDROID_LOG_FATAL, __func__,
   494                          "pipe2: %s", strerror (errno));
   495 
   496   /* Make sure the read end will fit in fd_set.  */
   497   if (select_pipe[0] >= FD_SETSIZE)
   498     __android_log_print (ANDROID_LOG_FATAL, __func__,
   499                          "read end of select pipe"
   500                          " lies outside FD_SETSIZE!");
   501 
   502 #endif
   503 
   504   if (sigaction (SIGUSR1, &sa, NULL))
   505     __android_log_print (ANDROID_LOG_FATAL, __func__,
   506                          "sigaction: %s",
   507                          strerror (errno));
   508 
   509   /* Start the select thread.  */
   510   if (pthread_create (&event_queue.select_thread, NULL,
   511                       android_run_select_thread, NULL))
   512     __android_log_print (ANDROID_LOG_FATAL, __func__,
   513                          "pthread_create: %s",
   514                          strerror (errno));
   515 }
   516 
   517 int
   518 android_pending (void)
   519 {
   520   int i;
   521 
   522   pthread_mutex_lock (&event_queue.mutex);
   523   i = event_queue.num_events;
   524   pthread_mutex_unlock (&event_queue.mutex);
   525 
   526   return i;
   527 }
   528 
   529 /* Forward declaration.  */
   530 
   531 static void android_check_query (void);
   532 
   533 /* Wait for events to become available synchronously.  Return once an
   534    event arrives.  Also, reply to the UI thread whenever it requires a
   535    response.  */
   536 
   537 void
   538 android_wait_event (void)
   539 {
   540   /* Run queries from the UI thread to the Emacs thread.  */
   541   android_check_query ();
   542 
   543   pthread_mutex_lock (&event_queue.mutex);
   544 
   545   /* Wait for events to appear if there are none available to
   546      read.  */
   547   if (!event_queue.num_events)
   548     pthread_cond_wait (&event_queue.read_var,
   549                        &event_queue.mutex);
   550 
   551   pthread_mutex_unlock (&event_queue.mutex);
   552 
   553   /* Check for queries again.  If a query is sent after the call to
   554      `android_check_query' above, `read_var' will be signaled.  */
   555   android_check_query ();
   556 }
   557 
   558 void
   559 android_next_event (union android_event *event_return)
   560 {
   561   struct android_event_container *container;
   562 
   563   pthread_mutex_lock (&event_queue.mutex);
   564 
   565   /* Wait for events to appear if there are none available to
   566      read.  */
   567   if (!event_queue.num_events)
   568     pthread_cond_wait (&event_queue.read_var,
   569                        &event_queue.mutex);
   570 
   571   /* Obtain the event from the end of the queue.  */
   572   container = event_queue.events.last;
   573   eassert (container != &event_queue.events);
   574 
   575   /* Remove the event from the queue and copy it to the caller
   576      supplied buffer.  */
   577   container->last->next = container->next;
   578   container->next->last = container->last;
   579   *event_return = container->event;
   580   event_queue.num_events--;
   581 
   582   /* Free the container.  */
   583   free (container);
   584 
   585   /* Unlock the queue.  */
   586   pthread_mutex_unlock (&event_queue.mutex);
   587 }
   588 
   589 bool
   590 android_check_if_event (union android_event *event_return,
   591                         bool (*predicate) (union android_event *,
   592                                            void *),
   593                         void *arg)
   594 {
   595   struct android_event_container *container;
   596 
   597   pthread_mutex_lock (&event_queue.mutex);
   598 
   599   /* Loop over each event.  */
   600   container = event_queue.events.last;
   601   for (; container != &event_queue.events; container = container->last)
   602     {
   603       /* See if the predicate matches.  */
   604       if ((*predicate) (&container->event, arg))
   605         {
   606           /* Copy out the event and return true.  */
   607           *event_return = container->event;
   608           --event_queue.num_events;
   609 
   610           /* Unlink container.  */
   611           container->last->next = container->next;
   612           container->next->last = container->last;
   613           free (container);
   614           pthread_mutex_unlock (&event_queue.mutex);
   615           return true;
   616         }
   617     }
   618 
   619   pthread_mutex_unlock (&event_queue.mutex);
   620   return false;
   621 }
   622 
   623 void
   624 android_write_event (union android_event *event)
   625 {
   626   struct android_event_container *container;
   627 
   628   container = malloc (sizeof *container);
   629 
   630   if (!container)
   631     return;
   632 
   633   /* If the event queue hasn't been initialized yet, return false.  */
   634   if (!event_queue.events.next)
   635     return;
   636 
   637   pthread_mutex_lock (&event_queue.mutex);
   638   container->next = event_queue.events.next;
   639   container->last = &event_queue.events;
   640   container->next->last = container;
   641   container->last->next = container;
   642   container->event = *event;
   643   event_queue.num_events++;
   644   pthread_cond_broadcast (&event_queue.read_var);
   645   pthread_mutex_unlock (&event_queue.mutex);
   646 
   647   /* Now set pending_signals to true, and raise SIGIO to interrupt any
   648      ongoing reads if the event is important.  */
   649   pending_signals = true;
   650 
   651   switch (event->type)
   652     {
   653       /* Key press and window action events are considered important,
   654          as they either end up quitting or asking for responses to the
   655          IME.  */
   656     case ANDROID_KEY_PRESS:
   657     case ANDROID_WINDOW_ACTION:
   658       kill (getpid (), SIGIO);
   659       break;
   660 
   661     default:
   662       break;
   663     }
   664 }
   665 
   666 
   667 
   668 /* Whether or not the UI thread has been waiting for a significant
   669    amount of time for a function to run in the main thread, and Emacs
   670    should answer the query ASAP.  */
   671 static bool android_urgent_query;
   672 
   673 int
   674 android_select (int nfds, fd_set *readfds, fd_set *writefds,
   675                 fd_set *exceptfds, struct timespec *timeout)
   676 {
   677   int nfds_return;
   678 #if __ANDROID_API__ < 16
   679   static char byte;
   680 #endif
   681 
   682   /* Since Emacs is reading keyboard input again, signify that queries
   683      from input methods are no longer ``urgent''.  */
   684 
   685   __atomic_clear (&android_urgent_query, __ATOMIC_RELEASE);
   686 
   687   /* Check for and run anything the UI thread wants to run on the main
   688      thread.  */
   689   android_check_query ();
   690 
   691   pthread_mutex_lock (&event_queue.mutex);
   692 
   693   if (event_queue.num_events)
   694     {
   695       pthread_mutex_unlock (&event_queue.mutex);
   696       return 1;
   697     }
   698 
   699   nfds_return = 0;
   700 
   701   pthread_mutex_lock (&event_queue.select_mutex);
   702   android_pselect_nfds = nfds;
   703   android_pselect_readfds = readfds;
   704   android_pselect_writefds = writefds;
   705   android_pselect_exceptfds = exceptfds;
   706   android_pselect_timeout = timeout;
   707   pthread_mutex_unlock (&event_queue.select_mutex);
   708 
   709   /* Release the select thread.  */
   710   sem_post (&android_pselect_start_sem);
   711 
   712   /* Start waiting for the event queue condition to be set.  */
   713   pthread_cond_wait (&event_queue.read_var, &event_queue.mutex);
   714 
   715 #if __ANDROID_API__ >= 16
   716   /* Interrupt the select thread now, in case it's still in
   717      pselect.  */
   718   pthread_kill (event_queue.select_thread, SIGUSR1);
   719 #else
   720   /* Interrupt the select thread by writing to the select pipe.  */
   721   if (write (select_pipe[1], &byte, 1) != 1)
   722     __android_log_print (ANDROID_LOG_FATAL, __func__,
   723                          "write: %s", strerror (errno));
   724 #endif
   725 
   726   /* Unlock the event queue mutex.  */
   727   pthread_mutex_unlock (&event_queue.mutex);
   728 
   729   /* Wait for pselect to return in any case.  This must be done with
   730      the event queue mutex unlocked.  Otherwise, the pselect thread
   731      can hang if it tries to lock the event queue mutex to signal
   732      read_var after the UI thread has already done so.  */
   733   while (sem_wait (&android_pselect_sem) < 0)
   734     ;;
   735 
   736   /* If there are now events in the queue, return 1.  */
   737 
   738   pthread_mutex_lock (&event_queue.mutex);
   739   if (event_queue.num_events)
   740     nfds_return = 1;
   741   pthread_mutex_unlock (&event_queue.mutex);
   742 
   743   /* Add the return value of pselect if it has also found ready file
   744      descriptors.  */
   745 
   746   if (android_pselect_rc >= 0)
   747     nfds_return += android_pselect_rc;
   748   else if (!nfds_return)
   749     /* If pselect was interrupted and nfds_return is 0 (meaning that
   750        no events have been read), indicate that an error has taken
   751        place.  */
   752     nfds_return = android_pselect_rc;
   753 
   754   if ((android_pselect_rc < 0) && nfds_return >= 0)
   755     {
   756       /* Clear the file descriptor sets if events will be delivered
   757          but no file descriptors have become ready to prevent the
   758          caller from misinterpreting a non-zero return value.  */
   759 
   760       if (readfds)
   761         FD_ZERO (readfds);
   762 
   763       if (writefds)
   764         FD_ZERO (writefds);
   765 
   766       if (exceptfds)
   767         FD_ZERO (exceptfds);
   768     }
   769 
   770   /* This is to shut up process.c when pselect gets EINTR.  */
   771   if (nfds_return < 0)
   772     errno = EINTR;
   773 
   774   /* Now check for and run anything the UI thread wants to run in the
   775      main thread.  */
   776   android_check_query ();
   777 
   778   return nfds_return;
   779 }
   780 
   781 
   782 
   783 static void *
   784 android_run_debug_thread (void *data)
   785 {
   786   FILE *file;
   787   int fd;
   788   char *line;
   789   size_t n;
   790 
   791   fd = (int) (intptr_t) data;
   792   file = fdopen (fd, "r");
   793 
   794   if (!file)
   795     return NULL;
   796 
   797   line = NULL;
   798 
   799   while (true)
   800     {
   801       if (getline (&line, &n, file) < 0)
   802         {
   803           free (line);
   804           break;
   805         }
   806 
   807       __android_log_print (ANDROID_LOG_INFO, __func__, "%s", line);
   808     }
   809 
   810   fclose (file);
   811   return NULL;
   812 }
   813 
   814 
   815 
   816 /* Intercept USER_FULL_NAME and return something that makes sense if
   817    pw->pw_gecos is NULL.  */
   818 
   819 char *
   820 android_user_full_name (struct passwd *pw)
   821 {
   822 #ifdef HAVE_STRUCT_PASSWD_PW_GECOS
   823   if (!pw->pw_gecos)
   824     return (char *) "Android user";
   825 
   826   return pw->pw_gecos;
   827 #else
   828   return "Android user";
   829 #endif
   830 }
   831 
   832 
   833 
   834 /* Determine whether or not the specified file NAME describes a file
   835    in the directory DIR, which should be an absolute file name.  NAME
   836    must be in canonical form.
   837 
   838    Value is NULL if not.  Otherwise, it is a pointer to the first
   839    character in NAME after the part containing DIR and its trailing
   840    directory separator.  */
   841 
   842 const char *
   843 android_is_special_directory (const char *name, const char *dir)
   844 {
   845   size_t len;
   846 
   847   /* Compare up to strlen (DIR) bytes of NAME with DIR.  */
   848 
   849   len = strlen (dir);
   850   if (strncmp (name, dir, len))
   851     return NULL;
   852 
   853   /* Now see if the character of NAME after len is either a directory
   854      separator or a terminating NULL.  */
   855 
   856   name += len;
   857   switch (*name)
   858     {
   859     case '\0':
   860       /* Return the empty string if this is the end of the file
   861          name.  */
   862       return name;
   863 
   864     case '/':
   865       /* Return NAME (with the separator removed) if it describes a
   866          file.  */
   867       return name + 1;
   868 
   869     default:
   870       /* The file name doesn't match.  */
   871       return NULL;
   872     }
   873 }
   874 
   875 #if 0
   876 
   877 /* URL-encode N bytes of the specified STRING into at most N bytes of
   878    BUFFER; STRING is assumed to be encoded in a `utf-8-emacs'
   879    compatible coding system.  Value is the number of bytes encoded
   880    (excluding the trailing null byte placed at the end of the encoded
   881    text) or -1 upon failure.  */
   882 
   883 static ssize_t
   884 android_url_encode (const char *restrict string, size_t length,
   885                     char *restrict buffer, size_t n)
   886 {
   887   int len, character;
   888   size_t num_encoded;
   889   char *end;
   890   char format[1 + 25];
   891 
   892   /* For each multibyte character... */
   893 
   894   end = string + length;
   895   num_encoded = 0;
   896 
   897   while (string < end)
   898     {
   899       /* XXX: Android documentation claims that URIs is encoded
   900          according to the ``Unicode'' scheme, but what this means in
   901          reality is that the URI is encoded in UTF-8, and then
   902          each of its bytes are encoded.  */
   903       /* Find the length of the multibyte character at STRING.  */
   904       len = /* multibyte_length (string, end, true, true) */ 1;
   905 
   906       /* 0 means that STRING is not a valid multibyte string.  */
   907       if (!len || string + len > end)
   908         goto failure;
   909 
   910       /* Now fetch the character and increment string.  */
   911       /* character = /\* STRING_CHAR ((unsigned char *) string) *\/; */
   912       character = *(unsigned char *) string;
   913       string += len;
   914 
   915       /* If CHARACTER is not a letter or an unreserved character,
   916          escape it.  */
   917 
   918       if (!((character >= 'A'
   919              && character <= 'Z')
   920             || (character >= 'a'
   921                 && character <= 'z')
   922             || (character >= '0'
   923                 && character <= '9')
   924             || character == '_'
   925             || character == '-'
   926             || character == '!'
   927             || character == '.'
   928             || character == '~'
   929             || character == '\''
   930             || character == '('
   931             || character == ')'
   932             || character == '*'))
   933         {
   934           len = sprintf (format, "%%%X", (unsigned int) character);
   935           if (len < 0)
   936             goto failure;
   937 
   938           /* See if there is enough space left to hold the encoded
   939              string.  */
   940 
   941           if (n < len)
   942             goto failure;
   943 
   944           n -= len;
   945           num_encoded += len;
   946 
   947           /* Copy the encoded string to STRING.  */
   948           memcpy (buffer, format, n);
   949           buffer += len;
   950         }
   951       else
   952         {
   953           /* No more space within BUFFER.  */
   954           if (!n)
   955             goto failure;
   956 
   957           /* Don't encode this ASCII character; just store it.  */
   958           n--, num_encoded++;
   959           *(buffer++) = character;
   960         }
   961     }
   962 
   963   /* If there's no space for a trailing null byte or more bytes have
   964      been encoded than representable in ssize_t, fail.  */
   965 
   966   if (!n || num_encoded > SSIZE_MAX)
   967     goto failure;
   968 
   969   /* Store the terminating NULL byte.  */
   970   *buffer = '\0';
   971   return num_encoded;
   972 
   973  failure:
   974   return -1;
   975 }
   976 
   977 /* Return the content URI corresponding to a `/content' file name,
   978    or NULL if it is not a content URI.
   979 
   980    This function is not reentrant.  */
   981 
   982 static const char *
   983 android_get_content_name (const char *filename)
   984 {
   985   static char buffer[PATH_MAX + 1];
   986   char *head, *token, *next, *saveptr, *copy, *mark, *mark1;
   987   ssize_t rc;
   988   size_t n, length;
   989 
   990   /* Find the file name described if it starts with `/content'.  If
   991      just the directory is described, return content://.  */
   992 
   993   filename = android_is_special_directory (filename, "/content");
   994 
   995   if (!filename)
   996     return NULL;
   997 
   998   if (!*filename)
   999     return "content://";
  1000 
  1001   /* Now copy FILENAME into a buffer and convert it into a content
  1002      URI.  */
  1003 
  1004   copy = xstrdup (filename);
  1005   mark = saveptr = NULL;
  1006   head = stpcpy (buffer, "content:/");
  1007 
  1008   /* Split FILENAME by slashes.  */
  1009 
  1010   token = strtok_r (copy, "/", &saveptr);
  1011 
  1012   while (token)
  1013     {
  1014       /* Compute the number of bytes remaining in buffer excluding a
  1015          trailing null byte.  */
  1016       n = PATH_MAX - (head - buffer);
  1017 
  1018       /* Write / to the buffer.  Return failure if there is no space
  1019          for it.  */
  1020 
  1021       if (!n)
  1022         goto failure;
  1023 
  1024       *head++ = '/';
  1025       n--;
  1026 
  1027       /* Find the next token now.  */
  1028       next = strtok_r (NULL, "/", &saveptr);
  1029 
  1030       /* Detect and avoid encoding an encoded URL query affixed to the
  1031          end of the last component within the content file name.
  1032 
  1033          Content URIs can include a query describing parameters that
  1034          must be provided to the content provider.  They are separated
  1035          from the rest of the URI by a single question mark character,
  1036          which should not be encoded.
  1037 
  1038          However, the distinction between the separator and question
  1039          marks that appear inside file name components is lost when a
  1040          content URI is decoded into a content path.  To compensate
  1041          for this loss of information, Emacs assumes that the last
  1042          question mark is always a URI separator, and suffixes content
  1043          file names which contain question marks with a trailing
  1044          question mark.  */
  1045 
  1046       if (!next)
  1047         {
  1048           /* Find the last question mark character.  */
  1049 
  1050           mark1 = strchr (token, '?');
  1051 
  1052           while (mark1)
  1053             {
  1054               mark = mark1;
  1055               mark1 = strchr (mark + 1, '?');
  1056             }
  1057         }
  1058 
  1059       if (mark)
  1060         {
  1061           /* First, encode the part leading to the question mark
  1062              character.  */
  1063 
  1064           rc = 0;
  1065           if (mark > token)
  1066             rc = android_url_encode (token, mark - token,
  1067                                      head, n + 1);
  1068 
  1069           /* If this fails, bail out.  */
  1070 
  1071           if (rc < 0)
  1072             goto failure;
  1073 
  1074           /* Copy mark to the file name.  */
  1075 
  1076           n -= rc, head += rc;
  1077           length = strlen (mark);
  1078 
  1079           if (n < length)
  1080             goto failure;
  1081 
  1082           strcpy (head, mark);
  1083 
  1084           /* Now break out of the loop, since this is the last
  1085              component anyway.  */
  1086           break;
  1087         }
  1088       else
  1089         /* Now encode this file name component into the buffer.  */
  1090         rc = android_url_encode (token, strlen (token),
  1091                                  head, n + 1);
  1092 
  1093       if (rc < 0)
  1094         goto failure;
  1095 
  1096       head += rc;
  1097       token = next;
  1098     }
  1099 
  1100   /* buffer must have been null terminated by
  1101      `android_url_encode'.  */
  1102   xfree (copy);
  1103   return buffer;
  1104 
  1105  failure:
  1106   xfree (copy);
  1107   return NULL;
  1108 }
  1109 
  1110 #endif /* 0 */
  1111 
  1112 /* Return the current user's ``home'' directory, which is actually the
  1113    app data directory on Android.  */
  1114 
  1115 const char *
  1116 android_get_home_directory (void)
  1117 {
  1118   return android_files_dir;
  1119 }
  1120 
  1121 /* Return the name of the file behind a file descriptor FD by reading
  1122    /proc/self/fd/.  Value is allocated memory holding the file name
  1123    upon success, and 0 upon failure.  */
  1124 
  1125 static char *
  1126 android_proc_name (int fd)
  1127 {
  1128   char format[sizeof "/proc/self/fd/"
  1129               + INT_STRLEN_BOUND (int)];
  1130   static struct allocator allocator = {
  1131     /* Fill the allocator with C library malloc functions.  xmalloc
  1132        and so aren't thread safe.  */
  1133     malloc, realloc, free, NULL,
  1134   };
  1135 
  1136   sprintf (format, "/proc/self/fd/%d", fd);
  1137   return careadlinkat (AT_FDCWD, format, NULL, 0,
  1138                        &allocator, readlinkat);
  1139 }
  1140 
  1141 /* Try to guarantee the existence of the `lib' directory within the
  1142    parent directory of the application files directory.
  1143 
  1144    If `/data/data/org.gnu.emacs/lib' (or
  1145    `/data/user/N/org.gnu.emacs/lib') does not exist or is a dangling
  1146    symbolic link, create a symlink from it to the library
  1147    directory.
  1148 
  1149    Newer versions of Android don't create this link by default, making
  1150    it difficult to locate the directory containing Emacs library
  1151    files, particularly from scripts in other programs sharing the same
  1152    user ID as Emacs that don't have access to `exec-path'.  */
  1153 
  1154 static void
  1155 android_create_lib_link (void)
  1156 {
  1157   char *filename;
  1158   char lib_directory[PATH_MAX];
  1159   int fd;
  1160 
  1161   /* Find the directory containing the files directory.  */
  1162   filename = dirname (android_files_dir);
  1163   if (!filename)
  1164     goto failure;
  1165 
  1166   /* Now make `lib_directory' the name of the library directory
  1167      within.  */
  1168   snprintf (lib_directory, PATH_MAX, "%s/lib", filename);
  1169 
  1170   /* Try to open this directory.  */
  1171   fd = open (lib_directory, O_DIRECTORY);
  1172 
  1173   /* If the directory can be opened normally, close it and return
  1174      now.  */
  1175   if (fd >= 0)
  1176     goto success;
  1177 
  1178   /* Try to unlink the directory in case it's a dangling symbolic
  1179      link.  */
  1180   unlink (lib_directory);
  1181 
  1182   /* Otherwise, try to symlink lib_directory to the actual library
  1183      directory.  */
  1184 
  1185   if (symlink (android_lib_dir, lib_directory))
  1186     /* Print a warning message if creating the link fails.  */
  1187     __android_log_print (ANDROID_LOG_WARN, __func__,
  1188                          "Failed to create symbolic link from"
  1189                          " application library directory `%s'"
  1190                          " to its actual location at `%s'",
  1191                          lib_directory, android_files_dir);
  1192 
  1193  success:
  1194   close (fd);
  1195  failure:
  1196   return;
  1197 }
  1198 
  1199 
  1200 
  1201 /* JNI functions called by Java.  */
  1202 
  1203 #ifdef __clang__
  1204 #pragma clang diagnostic push
  1205 #pragma clang diagnostic ignored "-Wmissing-prototypes"
  1206 #else
  1207 #pragma GCC diagnostic push
  1208 #pragma GCC diagnostic ignored "-Wmissing-prototypes"
  1209 #endif
  1210 
  1211 JNIEXPORT jint JNICALL
  1212 NATIVE_NAME (dup) (JNIEnv *env, jobject object, jint fd)
  1213 {
  1214   JNI_STACK_ALIGNMENT_PROLOGUE;
  1215 
  1216   return dup (fd);
  1217 }
  1218 
  1219 JNIEXPORT jstring JNICALL
  1220 NATIVE_NAME (getFingerprint) (JNIEnv *env, jobject object)
  1221 {
  1222   JNI_STACK_ALIGNMENT_PROLOGUE;
  1223 
  1224   char buffer[sizeof fingerprint * 2 + 1];
  1225 
  1226   memset (buffer, 0, sizeof buffer);
  1227   hexbuf_digest (buffer, (char *) fingerprint,
  1228                  sizeof fingerprint);
  1229 
  1230   return (*env)->NewStringUTF (env, buffer);
  1231 }
  1232 
  1233 JNIEXPORT void JNICALL
  1234 NATIVE_NAME (setEmacsParams) (JNIEnv *env, jobject object,
  1235                               jobject local_asset_manager,
  1236                               jobject files_dir, jobject libs_dir,
  1237                               jobject cache_dir,
  1238                               jfloat pixel_density_x,
  1239                               jfloat pixel_density_y,
  1240                               jfloat scaled_density,
  1241                               jobject class_path,
  1242                               jobject emacs_service_object,
  1243                               jint api_level)
  1244 {
  1245   JNI_STACK_ALIGNMENT_PROLOGUE;
  1246 
  1247   int pipefd[2];
  1248   pthread_t thread;
  1249   const char *java_string;
  1250 
  1251   /* Set the Android API level early, as it is used by
  1252      `android_vfs_init'.  */
  1253   android_api_level = api_level;
  1254 
  1255   /* This function should only be called from the main thread.  */
  1256 
  1257   android_pixel_density_x = pixel_density_x;
  1258   android_pixel_density_y = pixel_density_y;
  1259   android_scaled_pixel_density = scaled_density;
  1260 
  1261   __android_log_print (ANDROID_LOG_INFO, __func__,
  1262                        "Initializing "PACKAGE_STRING"...\nPlease report bugs to "
  1263                        PACKAGE_BUGREPORT".  Thanks.\n");
  1264 
  1265   if (emacs_service_object)
  1266     {
  1267       /* Create a pipe and duplicate it to stdout and stderr.  Next,
  1268          make a thread that prints stderr to the system log.
  1269 
  1270          Notice that this function is called in one of two ways.  The
  1271          first is when Emacs is being started as a GUI application by
  1272          the system, and the second is when Emacs is being started by
  1273          libandroid-emacs.so as an ordinary noninteractive Emacs.
  1274 
  1275          In the second case, stderr is usually connected to a PTY, so
  1276          this is unnecessary.  */
  1277 
  1278       if (pipe2 (pipefd, O_CLOEXEC) < 0)
  1279         emacs_abort ();
  1280 
  1281       if (dup2 (pipefd[1], 2) < 0)
  1282         emacs_abort ();
  1283       close (pipefd[1]);
  1284 
  1285       if (pthread_create (&thread, NULL, android_run_debug_thread,
  1286                           (void *) (intptr_t) pipefd[0]))
  1287         emacs_abort ();
  1288     }
  1289 
  1290   /* Now set the path to the site load directory.  */
  1291 
  1292   java_string = (*env)->GetStringUTFChars (env, (jstring) files_dir,
  1293                                            NULL);
  1294 
  1295   if (!java_string)
  1296     emacs_abort ();
  1297 
  1298   android_files_dir = strdup ((const char *) java_string);
  1299 
  1300   if (!android_files_dir)
  1301     emacs_abort ();
  1302 
  1303   (*env)->ReleaseStringUTFChars (env, (jstring) files_dir,
  1304                                  java_string);
  1305 
  1306   java_string = (*env)->GetStringUTFChars (env, (jstring) libs_dir,
  1307                                            NULL);
  1308 
  1309   if (!java_string)
  1310     emacs_abort ();
  1311 
  1312   android_lib_dir = strdup ((const char *) java_string);
  1313 
  1314   if (!android_files_dir)
  1315     emacs_abort ();
  1316 
  1317   (*env)->ReleaseStringUTFChars (env, (jstring) libs_dir,
  1318                                  java_string);
  1319 
  1320   java_string = (*env)->GetStringUTFChars (env, (jstring) cache_dir,
  1321                                            NULL);
  1322 
  1323   if (!java_string)
  1324     emacs_abort ();
  1325 
  1326   android_cache_dir = strdup ((const char *) java_string);
  1327 
  1328   if (!android_files_dir)
  1329     emacs_abort ();
  1330 
  1331   (*env)->ReleaseStringUTFChars (env, (jstring) cache_dir,
  1332                                  java_string);
  1333 
  1334   if (class_path)
  1335     {
  1336       java_string = (*env)->GetStringUTFChars (env, (jstring) class_path,
  1337                                                NULL);
  1338 
  1339       if (!java_string)
  1340         emacs_abort ();
  1341 
  1342       android_class_path = strdup ((const char *) java_string);
  1343 
  1344       if (!android_files_dir)
  1345         emacs_abort ();
  1346 
  1347       (*env)->ReleaseStringUTFChars (env, (jstring) class_path,
  1348                                      java_string);
  1349     }
  1350 
  1351   /* Calculate the site-lisp path.  */
  1352 
  1353   android_site_load_path = malloc (PATH_MAX + 1);
  1354 
  1355   if (!android_site_load_path)
  1356     emacs_abort ();
  1357 
  1358   android_game_path = malloc (PATH_MAX + 1);
  1359 
  1360   if (!android_game_path)
  1361     emacs_abort ();
  1362 
  1363   snprintf (android_site_load_path, PATH_MAX, "%s/site-lisp",
  1364             android_files_dir);
  1365   snprintf (android_game_path, PATH_MAX, "%s/scores", android_files_dir);
  1366 
  1367   __android_log_print (ANDROID_LOG_INFO, __func__,
  1368                        "Site-lisp directory: %s\n"
  1369                        "Files directory: %s\n"
  1370                        "Native code directory: %s\n"
  1371                        "Game score path: %s\n"
  1372                        "Class path: %s\n",
  1373                        android_site_load_path,
  1374                        android_files_dir,
  1375                        android_lib_dir, android_game_path,
  1376                        (android_class_path
  1377                         ? android_class_path
  1378                         : "None"));
  1379 
  1380   if (android_class_path)
  1381     /* Set EMACS_CLASS_PATH to the class path where
  1382        EmacsNoninteractive can be found.  */
  1383     setenv ("EMACS_CLASS_PATH", android_class_path, 1);
  1384 
  1385   /* Set LD_LIBRARY_PATH to an appropriate value.  */
  1386   setenv ("LD_LIBRARY_PATH", android_lib_dir, 1);
  1387 
  1388   /* EMACS_LD_LIBRARY_PATH records the location of the app library
  1389      directory.  android-emacs refers to this, since users have valid
  1390      reasons for changing LD_LIBRARY_PATH to a value that precludes
  1391      the possibility of Java locating libemacs later.  */
  1392   setenv ("EMACS_LD_LIBRARY_PATH", android_lib_dir, 1);
  1393 
  1394   /* Make a reference to the Emacs service.  */
  1395 
  1396   if (emacs_service_object)
  1397     {
  1398       emacs_service = (*env)->NewGlobalRef (env, emacs_service_object);
  1399 
  1400       if (!emacs_service)
  1401         emacs_abort ();
  1402 
  1403       /* If the service is set this Emacs is being initialized as part
  1404          of the Emacs application itself.
  1405 
  1406          Try to create a symlink from where scripts expect Emacs to
  1407          place its library files to the directory that actually holds
  1408          them; earlier versions of Android used to do this
  1409          automatically, but that feature has been removed.  */
  1410 
  1411       android_create_lib_link ();
  1412     }
  1413 
  1414   /* Set up events.  */
  1415   android_init_events ();
  1416 
  1417   /* Set up the Android virtual filesystem layer.  */
  1418   android_vfs_init (env, local_asset_manager);
  1419 
  1420   /* OK, setup is now complete.  The caller may call initEmacs
  1421      now.  */
  1422 }
  1423 
  1424 JNIEXPORT jobject JNICALL
  1425 NATIVE_NAME (getProcName) (JNIEnv *env, jobject object, jint fd)
  1426 {
  1427   JNI_STACK_ALIGNMENT_PROLOGUE;
  1428 
  1429   char *buffer;
  1430   size_t length;
  1431   jbyteArray array;
  1432 
  1433   buffer = android_proc_name (fd);
  1434   if (!buffer)
  1435     return NULL;
  1436 
  1437   /* Return a byte array, as Java strings cannot always encode file
  1438      names.  */
  1439   length = strlen (buffer);
  1440   array = (*env)->NewByteArray (env, length);
  1441   if (!array)
  1442     goto finish;
  1443 
  1444   (*env)->SetByteArrayRegion (env, array, 0, length,
  1445                               (jbyte *) buffer);
  1446 
  1447  finish:
  1448   free (buffer);
  1449   return array;
  1450 }
  1451 
  1452 /* Initialize service_class, aborting if something goes wrong.  */
  1453 
  1454 static void
  1455 android_init_emacs_service (void)
  1456 {
  1457   jclass old;
  1458 
  1459   service_class.class
  1460     = (*android_java_env)->FindClass (android_java_env,
  1461                                       "org/gnu/emacs/EmacsService");
  1462   eassert (service_class.class);
  1463 
  1464   old = service_class.class;
  1465   service_class.class
  1466     = (jclass) (*android_java_env)->NewGlobalRef (android_java_env,
  1467                                                   (jobject) old);
  1468   ANDROID_DELETE_LOCAL_REF (old);
  1469 
  1470   if (!service_class.class)
  1471     emacs_abort ();
  1472 
  1473 #define FIND_METHOD(c_name, name, signature)                    \
  1474   service_class.c_name                                          \
  1475     = (*android_java_env)->GetMethodID (android_java_env,       \
  1476                                         service_class.class,    \
  1477                                         name, signature);       \
  1478   assert (service_class.c_name);
  1479 
  1480   FIND_METHOD (fill_rectangle, "fillRectangle",
  1481                "(Lorg/gnu/emacs/EmacsDrawable;"
  1482                "Lorg/gnu/emacs/EmacsGC;IIII)V");
  1483   FIND_METHOD (fill_polygon, "fillPolygon",
  1484                "(Lorg/gnu/emacs/EmacsDrawable;"
  1485                "Lorg/gnu/emacs/EmacsGC;"
  1486                "[Landroid/graphics/Point;)V");
  1487   FIND_METHOD (draw_rectangle, "drawRectangle",
  1488                "(Lorg/gnu/emacs/EmacsDrawable;"
  1489                "Lorg/gnu/emacs/EmacsGC;IIII)V");
  1490   FIND_METHOD (draw_line, "drawLine",
  1491                "(Lorg/gnu/emacs/EmacsDrawable;"
  1492                "Lorg/gnu/emacs/EmacsGC;IIII)V");
  1493   FIND_METHOD (draw_point, "drawPoint",
  1494                "(Lorg/gnu/emacs/EmacsDrawable;"
  1495                "Lorg/gnu/emacs/EmacsGC;II)V");
  1496   FIND_METHOD (clear_window, "clearWindow",
  1497                "(Lorg/gnu/emacs/EmacsWindow;)V");
  1498   FIND_METHOD (clear_area, "clearArea",
  1499                "(Lorg/gnu/emacs/EmacsWindow;IIII)V");
  1500   FIND_METHOD (ring_bell, "ringBell", "()V");
  1501   FIND_METHOD (query_tree, "queryTree",
  1502                "(Lorg/gnu/emacs/EmacsWindow;)[S");
  1503   FIND_METHOD (get_screen_width, "getScreenWidth", "(Z)I");
  1504   FIND_METHOD (get_screen_height, "getScreenHeight", "(Z)I");
  1505   FIND_METHOD (detect_mouse, "detectMouse", "()Z");
  1506   FIND_METHOD (name_keysym, "nameKeysym", "(I)Ljava/lang/String;");
  1507   FIND_METHOD (browse_url, "browseUrl", "(Ljava/lang/String;Z)"
  1508                "Ljava/lang/String;");
  1509   FIND_METHOD (restart_emacs, "restartEmacs", "()V");
  1510   FIND_METHOD (update_ic, "updateIC",
  1511                "(Lorg/gnu/emacs/EmacsWindow;IIII)V");
  1512   FIND_METHOD (reset_ic, "resetIC",
  1513                "(Lorg/gnu/emacs/EmacsWindow;I)V");
  1514   FIND_METHOD (open_content_uri, "openContentUri",
  1515                "([BZZZ)I");
  1516   FIND_METHOD (check_content_uri, "checkContentUri",
  1517                "(Ljava/lang/String;ZZ)Z");
  1518   FIND_METHOD (query_battery, "queryBattery", "()[J");
  1519   FIND_METHOD (update_extracted_text, "updateExtractedText",
  1520                "(Lorg/gnu/emacs/EmacsWindow;"
  1521                "Landroid/view/inputmethod/ExtractedText;I)V");
  1522   FIND_METHOD (update_cursor_anchor_info, "updateCursorAnchorInfo",
  1523                "(Lorg/gnu/emacs/EmacsWindow;FFFF)V");
  1524   FIND_METHOD (get_document_authorities, "getDocumentAuthorities",
  1525                "()[Ljava/lang/String;");
  1526   FIND_METHOD (request_directory_access, "requestDirectoryAccess",
  1527                "()I");
  1528   FIND_METHOD (get_document_trees, "getDocumentTrees",
  1529                "([B)[Ljava/lang/String;");
  1530   FIND_METHOD (document_id_from_name, "documentIdFromName",
  1531                "(Ljava/lang/String;Ljava/lang/String;"
  1532                "[Ljava/lang/String;)I");
  1533   FIND_METHOD (get_tree_uri, "getTreeUri",
  1534                "(Ljava/lang/String;Ljava/lang/String;)"
  1535                "Ljava/lang/String;");
  1536   FIND_METHOD (stat_document, "statDocument",
  1537                "(Ljava/lang/String;Ljava/lang/String;Z)[J");
  1538   FIND_METHOD (access_document, "accessDocument",
  1539                "(Ljava/lang/String;Ljava/lang/String;Z)I");
  1540   FIND_METHOD (open_document_directory, "openDocumentDirectory",
  1541                "(Ljava/lang/String;Ljava/lang/String;)"
  1542                "Landroid/database/Cursor;");
  1543   FIND_METHOD (read_directory_entry, "readDirectoryEntry",
  1544                "(Landroid/database/Cursor;)Lorg/gnu/emacs/"
  1545                "EmacsDirectoryEntry;");
  1546   FIND_METHOD (open_document, "openDocument",
  1547                "(Ljava/lang/String;Ljava/lang/String;ZZZ)"
  1548                "Landroid/os/ParcelFileDescriptor;");
  1549   FIND_METHOD (create_document, "createDocument",
  1550                "(Ljava/lang/String;Ljava/lang/String;"
  1551                "Ljava/lang/String;)Ljava/lang/String;");
  1552   FIND_METHOD (create_directory, "createDirectory",
  1553                "(Ljava/lang/String;Ljava/lang/String;"
  1554                "Ljava/lang/String;)Ljava/lang/String;");
  1555   FIND_METHOD (delete_document, "deleteDocument",
  1556                "(Ljava/lang/String;Ljava/lang/String;"
  1557                "Ljava/lang/String;)I");
  1558   FIND_METHOD (rename_document, "renameDocument",
  1559                "(Ljava/lang/String;Ljava/lang/String;"
  1560                "Ljava/lang/String;Ljava/lang/String;)I");
  1561   FIND_METHOD (move_document, "moveDocument",
  1562                "(Ljava/lang/String;Ljava/lang/String;"
  1563                "Ljava/lang/String;Ljava/lang/String;"
  1564                "Ljava/lang/String;)Ljava/lang/String;");
  1565   FIND_METHOD (valid_authority, "validAuthority",
  1566                "(Ljava/lang/String;)Z");
  1567 #undef FIND_METHOD
  1568 }
  1569 
  1570 static void
  1571 android_init_emacs_pixmap (void)
  1572 {
  1573   jclass old;
  1574 
  1575   pixmap_class.class
  1576     = (*android_java_env)->FindClass (android_java_env,
  1577                                       "org/gnu/emacs/EmacsPixmap");
  1578   eassert (pixmap_class.class);
  1579 
  1580   old = pixmap_class.class;
  1581   pixmap_class.class
  1582     = (jclass) (*android_java_env)->NewGlobalRef (android_java_env,
  1583                                                   (jobject) old);
  1584   ANDROID_DELETE_LOCAL_REF (old);
  1585 
  1586   if (!pixmap_class.class)
  1587     emacs_abort ();
  1588 
  1589 #define FIND_METHOD(c_name, name, signature)                    \
  1590   pixmap_class.c_name                                           \
  1591     = (*android_java_env)->GetMethodID (android_java_env,       \
  1592                                         pixmap_class.class,     \
  1593                                         name, signature);       \
  1594   assert (pixmap_class.c_name);
  1595 
  1596   FIND_METHOD (constructor, "<init>", "(S[IIII)V");
  1597   FIND_METHOD (constructor_mutable, "<init>", "(SIII)V");
  1598 
  1599 #undef FIND_METHOD
  1600 }
  1601 
  1602 static void
  1603 android_init_graphics_point (void)
  1604 {
  1605   jclass old;
  1606 
  1607   point_class.class
  1608     = (*android_java_env)->FindClass (android_java_env,
  1609                                       "android/graphics/Point");
  1610   eassert (point_class.class);
  1611 
  1612   old = point_class.class;
  1613   point_class.class
  1614     = (jclass) (*android_java_env)->NewGlobalRef (android_java_env,
  1615                                                   (jobject) old);
  1616   ANDROID_DELETE_LOCAL_REF (old);
  1617 
  1618   if (!point_class.class)
  1619     emacs_abort ();
  1620 
  1621 #define FIND_METHOD(c_name, name, signature)                    \
  1622   point_class.c_name                                            \
  1623     = (*android_java_env)->GetMethodID (android_java_env,       \
  1624                                         point_class.class,      \
  1625                                         name, signature);       \
  1626   assert (point_class.c_name);
  1627 
  1628   FIND_METHOD (constructor, "<init>", "(II)V");
  1629 #undef FIND_METHOD
  1630 }
  1631 
  1632 static void
  1633 android_init_emacs_drawable (void)
  1634 {
  1635   jclass old;
  1636 
  1637   drawable_class.class
  1638     = (*android_java_env)->FindClass (android_java_env,
  1639                                       "org/gnu/emacs/EmacsDrawable");
  1640   eassert (drawable_class.class);
  1641 
  1642   old = drawable_class.class;
  1643   drawable_class.class
  1644     = (jclass) (*android_java_env)->NewGlobalRef (android_java_env,
  1645                                                   (jobject) old);
  1646   ANDROID_DELETE_LOCAL_REF (old);
  1647 
  1648   if (!drawable_class.class)
  1649     emacs_abort ();
  1650 
  1651 #define FIND_METHOD(c_name, name, signature)                    \
  1652   drawable_class.c_name                                         \
  1653     = (*android_java_env)->GetMethodID (android_java_env,       \
  1654                                         drawable_class.class,   \
  1655                                         name, signature);       \
  1656   assert (drawable_class.c_name);
  1657 
  1658   FIND_METHOD (get_bitmap, "getBitmap", "()Landroid/graphics/Bitmap;");
  1659   FIND_METHOD (damage_rect, "damageRect", "(Landroid/graphics/Rect;)V");
  1660 #undef FIND_METHOD
  1661 }
  1662 
  1663 static void
  1664 android_init_emacs_window (void)
  1665 {
  1666   jclass old;
  1667 
  1668   window_class.class
  1669     = (*android_java_env)->FindClass (android_java_env,
  1670                                       "org/gnu/emacs/EmacsWindow");
  1671   eassert (window_class.class);
  1672 
  1673   old = window_class.class;
  1674   window_class.class
  1675     = (jclass) (*android_java_env)->NewGlobalRef (android_java_env,
  1676                                                   (jobject) old);
  1677   ANDROID_DELETE_LOCAL_REF (old);
  1678 
  1679   if (!window_class.class)
  1680     emacs_abort ();
  1681 
  1682 #define FIND_METHOD(c_name, name, signature)                    \
  1683   window_class.c_name                                           \
  1684     = (*android_java_env)->GetMethodID (android_java_env,       \
  1685                                         window_class.class,     \
  1686                                         name, signature);       \
  1687   assert (window_class.c_name);
  1688 
  1689   FIND_METHOD (swap_buffers, "swapBuffers", "()V");
  1690   FIND_METHOD (toggle_on_screen_keyboard,
  1691                "toggleOnScreenKeyboard", "(Z)V");
  1692   FIND_METHOD (lookup_string, "lookupString", "(I)Ljava/lang/String;");
  1693   FIND_METHOD (set_fullscreen, "setFullscreen", "(Z)V");
  1694   FIND_METHOD (change_window_background, "changeWindowBackground",
  1695                "(I)V");
  1696   FIND_METHOD (reparent_to, "reparentTo",
  1697                "(Lorg/gnu/emacs/EmacsWindow;II)V");
  1698   FIND_METHOD (map_window, "mapWindow", "()V");
  1699   FIND_METHOD (unmap_window, "unmapWindow", "()V");
  1700   FIND_METHOD (resize_window, "resizeWindow", "(II)V");
  1701   FIND_METHOD (move_window, "moveWindow", "(II)V");
  1702   FIND_METHOD (make_input_focus, "makeInputFocus", "(J)V");
  1703   FIND_METHOD (raise, "raise", "()V");
  1704   FIND_METHOD (lower, "lower", "()V");
  1705   FIND_METHOD (get_window_geometry, "getWindowGeometry",
  1706                "()[I");
  1707   FIND_METHOD (translate_coordinates, "translateCoordinates",
  1708                "(II)[I");
  1709   FIND_METHOD (set_dont_focus_on_map, "setDontFocusOnMap", "(Z)V");
  1710   FIND_METHOD (set_dont_accept_focus, "setDontAcceptFocus", "(Z)V");
  1711   FIND_METHOD (define_cursor, "defineCursor",
  1712                "(Lorg/gnu/emacs/EmacsCursor;)V");
  1713 #undef FIND_METHOD
  1714 }
  1715 
  1716 static void
  1717 android_init_emacs_cursor (void)
  1718 {
  1719   jclass old;
  1720 
  1721   cursor_class.class
  1722     = (*android_java_env)->FindClass (android_java_env,
  1723                                       "org/gnu/emacs/EmacsCursor");
  1724   eassert (cursor_class.class);
  1725 
  1726   old = cursor_class.class;
  1727   cursor_class.class
  1728     = (jclass) (*android_java_env)->NewGlobalRef (android_java_env,
  1729                                                   (jobject) old);
  1730   ANDROID_DELETE_LOCAL_REF (old);
  1731 
  1732   if (!cursor_class.class)
  1733     emacs_abort ();
  1734 
  1735 #define FIND_METHOD(c_name, name, signature)                    \
  1736   cursor_class.c_name                                           \
  1737     = (*android_java_env)->GetMethodID (android_java_env,       \
  1738                                         cursor_class.class,     \
  1739                                         name, signature);       \
  1740   assert (cursor_class.c_name);
  1741 
  1742   FIND_METHOD (constructor, "<init>", "(SI)V");
  1743 #undef FIND_METHOD
  1744 }
  1745 
  1746 JNIEXPORT void JNICALL
  1747 NATIVE_NAME (initEmacs) (JNIEnv *env, jobject object, jarray argv,
  1748                          jobject dump_file_object)
  1749 {
  1750   /* android_emacs_init is not main, so GCC is not nice enough to add
  1751      the stack alignment prologue.
  1752 
  1753      Unfortunately for us, dalvik on Android 4.0.x calls native code
  1754      with a 4 byte aligned stack, so this prologue must be inserted
  1755      before each function exported via JNI.  */
  1756 
  1757   JNI_STACK_ALIGNMENT_PROLOGUE;
  1758 
  1759   char **c_argv;
  1760   jsize nelements, i;
  1761   jobject argument;
  1762   const char *c_argument;
  1763   char *dump_file;
  1764 
  1765   android_java_env = env;
  1766 
  1767   nelements = (*env)->GetArrayLength (env, argv);
  1768   c_argv = alloca (sizeof *c_argv * nelements);
  1769 
  1770   for (i = 0; i < nelements; ++i)
  1771     {
  1772       argument = (*env)->GetObjectArrayElement (env, argv, i);
  1773       c_argument = (*env)->GetStringUTFChars (env, (jstring) argument,
  1774                                               NULL);
  1775 
  1776       if (!c_argument)
  1777         emacs_abort ();
  1778 
  1779       /* Note that c_argument is in ``modified UTF-8 encoding'', but
  1780          we don't care as NUL bytes are not being specified inside.  */
  1781       c_argv[i] = alloca (strlen (c_argument) + 1);
  1782       strcpy (c_argv[i], c_argument);
  1783       (*env)->ReleaseStringUTFChars (env, (jstring) argument, c_argument);
  1784     }
  1785 
  1786   android_init_emacs_service ();
  1787   android_init_emacs_pixmap ();
  1788   android_init_graphics_point ();
  1789   android_init_emacs_drawable ();
  1790   android_init_emacs_window ();
  1791   android_init_emacs_cursor ();
  1792 
  1793   /* Set HOME to the app data directory.  */
  1794   setenv ("HOME", android_files_dir, 1);
  1795 
  1796   /* Set TMPDIR to the temporary files directory.  */
  1797   setenv ("TMPDIR", android_cache_dir, 1);
  1798 
  1799   /* And finally set "SHELL" to /system/bin/sh.  Otherwise, some
  1800      programs will look for /bin/sh, which is problematic.  */
  1801   setenv ("SHELL", "/system/bin/sh", 1);
  1802 
  1803   /* Set the cwd to that directory as well.  */
  1804   if (chdir (android_files_dir))
  1805     __android_log_print (ANDROID_LOG_WARN, __func__,
  1806                          "chdir: %s", strerror (errno));
  1807 
  1808   /* Initialize the Android GUI as long as the service object was
  1809      set.  */
  1810 
  1811   if (emacs_service)
  1812     android_init_gui = true;
  1813 
  1814   /* Now see if a dump file has been specified and should be used.  */
  1815   dump_file = NULL;
  1816 
  1817   if (dump_file_object)
  1818     {
  1819       c_argument
  1820         = (*env)->GetStringUTFChars (env, (jstring) dump_file_object,
  1821                                      NULL);
  1822 
  1823       /* Copy the Java string data once.  */
  1824       dump_file = strdup (c_argument);
  1825 
  1826       /* Release the Java string data.  */
  1827       (*env)->ReleaseStringUTFChars (env, (jstring) dump_file_object,
  1828                                      c_argument);
  1829     }
  1830 
  1831   /* Delete local references to objects that are no longer needed.  */
  1832   ANDROID_DELETE_LOCAL_REF (argv);
  1833   ANDROID_DELETE_LOCAL_REF (dump_file_object);
  1834 
  1835   /* Restore the signal mask at the time of startup if it was changed
  1836      to block unwanted signals from reaching system threads.  */
  1837 
  1838   if (signal_mask_changed_p)
  1839     pthread_sigmask (SIG_SETMASK, &startup_signal_mask, NULL);
  1840 
  1841   /* Now start Emacs proper.  */
  1842   android_emacs_init (nelements, c_argv, dump_file);
  1843 
  1844   /* android_emacs_init should never return.  */
  1845   emacs_abort ();
  1846 }
  1847 
  1848 JNIEXPORT void JNICALL
  1849 NATIVE_NAME (emacsAbort) (JNIEnv *env, jobject object)
  1850 {
  1851   JNI_STACK_ALIGNMENT_PROLOGUE;
  1852 
  1853   emacs_abort ();
  1854 }
  1855 
  1856 JNIEXPORT void JNICALL
  1857 NATIVE_NAME (quit) (JNIEnv *env, jobject object)
  1858 {
  1859   JNI_STACK_ALIGNMENT_PROLOGUE;
  1860 
  1861   __android_log_print (ANDROID_LOG_VERBOSE, __func__,
  1862                        "Sending SIGIO and setting Vquit_flag");
  1863 
  1864   /* Raise sigio to interrupt anything that could be reading
  1865      input.  */
  1866   Vquit_flag = Qt;
  1867   kill (getpid (), SIGIO);
  1868 }
  1869 
  1870 JNIEXPORT jlong JNICALL
  1871 NATIVE_NAME (sendConfigureNotify) (JNIEnv *env, jobject object,
  1872                                    jshort window, jlong time,
  1873                                    jint x, jint y, jint width,
  1874                                    jint height)
  1875 {
  1876   JNI_STACK_ALIGNMENT_PROLOGUE;
  1877 
  1878   union android_event event;
  1879 
  1880   event.xconfigure.type = ANDROID_CONFIGURE_NOTIFY;
  1881   event.xconfigure.serial = ++event_serial;
  1882   event.xconfigure.window = window;
  1883   event.xconfigure.time = time;
  1884   event.xconfigure.x = x;
  1885   event.xconfigure.y = y;
  1886   event.xconfigure.width = width;
  1887   event.xconfigure.height = height;
  1888 
  1889   android_write_event (&event);
  1890   return event_serial;
  1891 }
  1892 
  1893 JNIEXPORT jlong JNICALL
  1894 NATIVE_NAME (sendKeyPress) (JNIEnv *env, jobject object,
  1895                             jshort window, jlong time,
  1896                             jint state, jint keycode,
  1897                             jint unicode_char)
  1898 {
  1899   JNI_STACK_ALIGNMENT_PROLOGUE;
  1900 
  1901   union android_event event;
  1902 
  1903   event.xkey.type = ANDROID_KEY_PRESS;
  1904   event.xkey.serial = ++event_serial;
  1905   event.xkey.window = window;
  1906   event.xkey.time = time;
  1907   event.xkey.state = state;
  1908   event.xkey.keycode = keycode;
  1909   event.xkey.unicode_char = unicode_char;
  1910   event.xkey.counter = 0;
  1911 
  1912   android_write_event (&event);
  1913   return event_serial;
  1914 }
  1915 
  1916 JNIEXPORT jlong JNICALL
  1917 NATIVE_NAME (sendKeyRelease) (JNIEnv *env, jobject object,
  1918                               jshort window, jlong time,
  1919                               jint state, jint keycode,
  1920                               jint unicode_char)
  1921 {
  1922   JNI_STACK_ALIGNMENT_PROLOGUE;
  1923 
  1924   union android_event event;
  1925 
  1926   event.xkey.type = ANDROID_KEY_RELEASE;
  1927   event.xkey.serial = ++event_serial;
  1928   event.xkey.window = window;
  1929   event.xkey.time = time;
  1930   event.xkey.state = state;
  1931   event.xkey.keycode = keycode;
  1932   event.xkey.unicode_char = unicode_char;
  1933   event.xkey.counter = 0;
  1934 
  1935   android_write_event (&event);
  1936   return event_serial;
  1937 }
  1938 
  1939 JNIEXPORT jlong JNICALL
  1940 NATIVE_NAME (sendFocusIn) (JNIEnv *env, jobject object,
  1941                            jshort window, jlong time)
  1942 {
  1943   JNI_STACK_ALIGNMENT_PROLOGUE;
  1944 
  1945   union android_event event;
  1946 
  1947   event.xfocus.type = ANDROID_FOCUS_IN;
  1948   event.xfocus.serial = ++event_serial;
  1949   event.xfocus.window = window;
  1950   event.xfocus.time = time;
  1951 
  1952   android_write_event (&event);
  1953   return event_serial;
  1954 }
  1955 
  1956 JNIEXPORT jlong JNICALL
  1957 NATIVE_NAME (sendFocusOut) (JNIEnv *env, jobject object,
  1958                             jshort window, jlong time)
  1959 {
  1960   JNI_STACK_ALIGNMENT_PROLOGUE;
  1961 
  1962   union android_event event;
  1963 
  1964   event.xfocus.type = ANDROID_FOCUS_OUT;
  1965   event.xfocus.serial = ++event_serial;
  1966   event.xfocus.window = window;
  1967   event.xfocus.time = time;
  1968 
  1969   android_write_event (&event);
  1970   return ++event_serial;
  1971 }
  1972 
  1973 JNIEXPORT jlong JNICALL
  1974 NATIVE_NAME (sendWindowAction) (JNIEnv *env, jobject object,
  1975                                 jshort window, jint action)
  1976 {
  1977   JNI_STACK_ALIGNMENT_PROLOGUE;
  1978 
  1979   union android_event event;
  1980 
  1981   event.xaction.type = ANDROID_WINDOW_ACTION;
  1982   event.xaction.serial = ++event_serial;
  1983   event.xaction.window = window;
  1984   event.xaction.action = action;
  1985 
  1986   android_write_event (&event);
  1987   return event_serial;
  1988 }
  1989 
  1990 JNIEXPORT jlong JNICALL
  1991 NATIVE_NAME (sendEnterNotify) (JNIEnv *env, jobject object,
  1992                                jshort window, jint x, jint y,
  1993                                jlong time)
  1994 {
  1995   JNI_STACK_ALIGNMENT_PROLOGUE;
  1996 
  1997   union android_event event;
  1998 
  1999   event.xcrossing.type = ANDROID_ENTER_NOTIFY;
  2000   event.xcrossing.serial = ++event_serial;
  2001   event.xcrossing.window = window;
  2002   event.xcrossing.x = x;
  2003   event.xcrossing.y = y;
  2004   event.xcrossing.time = time;
  2005 
  2006   android_write_event (&event);
  2007   return event_serial;
  2008 }
  2009 
  2010 JNIEXPORT jlong JNICALL
  2011 NATIVE_NAME (sendLeaveNotify) (JNIEnv *env, jobject object,
  2012                                jshort window, jint x, jint y,
  2013                                jlong time)
  2014 {
  2015   JNI_STACK_ALIGNMENT_PROLOGUE;
  2016 
  2017   union android_event event;
  2018 
  2019   event.xcrossing.type = ANDROID_LEAVE_NOTIFY;
  2020   event.xcrossing.serial = ++event_serial;
  2021   event.xcrossing.window = window;
  2022   event.xcrossing.x = x;
  2023   event.xcrossing.y = y;
  2024   event.xcrossing.time = time;
  2025 
  2026   android_write_event (&event);
  2027   return event_serial;
  2028 }
  2029 
  2030 JNIEXPORT jlong JNICALL
  2031 NATIVE_NAME (sendMotionNotify) (JNIEnv *env, jobject object,
  2032                                 jshort window, jint x, jint y,
  2033                                 jlong time)
  2034 {
  2035   JNI_STACK_ALIGNMENT_PROLOGUE;
  2036 
  2037   union android_event event;
  2038 
  2039   event.xmotion.type = ANDROID_MOTION_NOTIFY;
  2040   event.xmotion.serial = ++event_serial;
  2041   event.xmotion.window = window;
  2042   event.xmotion.x = x;
  2043   event.xmotion.y = y;
  2044   event.xmotion.time = time;
  2045 
  2046   android_write_event (&event);
  2047   return event_serial;
  2048 }
  2049 
  2050 JNIEXPORT jlong JNICALL
  2051 NATIVE_NAME (sendButtonPress) (JNIEnv *env, jobject object,
  2052                                jshort window, jint x, jint y,
  2053                                jlong time, jint state,
  2054                                jint button)
  2055 {
  2056   JNI_STACK_ALIGNMENT_PROLOGUE;
  2057 
  2058   union android_event event;
  2059 
  2060   event.xbutton.type = ANDROID_BUTTON_PRESS;
  2061   event.xbutton.serial = ++event_serial;
  2062   event.xbutton.window = window;
  2063   event.xbutton.x = x;
  2064   event.xbutton.y = y;
  2065   event.xbutton.time = time;
  2066   event.xbutton.state = state;
  2067   event.xbutton.button = button;
  2068 
  2069   android_write_event (&event);
  2070   return event_serial;
  2071 }
  2072 
  2073 JNIEXPORT jlong JNICALL
  2074 NATIVE_NAME (sendButtonRelease) (JNIEnv *env, jobject object,
  2075                                  jshort window, jint x, jint y,
  2076                                  jlong time, jint state,
  2077                                  jint button)
  2078 {
  2079   JNI_STACK_ALIGNMENT_PROLOGUE;
  2080 
  2081   union android_event event;
  2082 
  2083   event.xbutton.type = ANDROID_BUTTON_RELEASE;
  2084   event.xbutton.serial = ++event_serial;
  2085   event.xbutton.window = window;
  2086   event.xbutton.x = x;
  2087   event.xbutton.y = y;
  2088   event.xbutton.time = time;
  2089   event.xbutton.state = state;
  2090   event.xbutton.button = button;
  2091 
  2092   android_write_event (&event);
  2093   return event_serial;
  2094 }
  2095 
  2096 JNIEXPORT jlong JNICALL
  2097 NATIVE_NAME (sendTouchDown) (JNIEnv *env, jobject object,
  2098                              jshort window, jint x, jint y,
  2099                              jlong time, jint pointer_id,
  2100                              jint flags)
  2101 {
  2102   JNI_STACK_ALIGNMENT_PROLOGUE;
  2103 
  2104   union android_event event;
  2105 
  2106   event.touch.type = ANDROID_TOUCH_DOWN;
  2107   event.touch.serial = ++event_serial;
  2108   event.touch.window = window;
  2109   event.touch.x = x;
  2110   event.touch.y = y;
  2111   event.touch.time = time;
  2112   event.touch.pointer_id = pointer_id;
  2113   event.touch.flags = flags;
  2114 
  2115   android_write_event (&event);
  2116   return event_serial;
  2117 }
  2118 
  2119 JNIEXPORT jlong JNICALL
  2120 NATIVE_NAME (sendTouchUp) (JNIEnv *env, jobject object,
  2121                            jshort window, jint x, jint y,
  2122                            jlong time, jint pointer_id,
  2123                            jint flags)
  2124 {
  2125   JNI_STACK_ALIGNMENT_PROLOGUE;
  2126 
  2127   union android_event event;
  2128 
  2129   event.touch.type = ANDROID_TOUCH_UP;
  2130   event.touch.serial = ++event_serial;
  2131   event.touch.window = window;
  2132   event.touch.x = x;
  2133   event.touch.y = y;
  2134   event.touch.time = time;
  2135   event.touch.pointer_id = pointer_id;
  2136   event.touch.flags = flags;
  2137 
  2138   android_write_event (&event);
  2139   return event_serial;
  2140 }
  2141 
  2142 JNIEXPORT jlong JNICALL
  2143 NATIVE_NAME (sendTouchMove) (JNIEnv *env, jobject object,
  2144                              jshort window, jint x, jint y,
  2145                              jlong time, jint pointer_id,
  2146                              jint flags)
  2147 {
  2148   JNI_STACK_ALIGNMENT_PROLOGUE;
  2149 
  2150   union android_event event;
  2151 
  2152   event.touch.type = ANDROID_TOUCH_MOVE;
  2153   event.touch.serial = ++event_serial;
  2154   event.touch.window = window;
  2155   event.touch.x = x;
  2156   event.touch.y = y;
  2157   event.touch.time = time;
  2158   event.touch.pointer_id = pointer_id;
  2159   event.touch.flags = flags;
  2160 
  2161   android_write_event (&event);
  2162   return event_serial;
  2163 }
  2164 
  2165 JNIEXPORT jlong JNICALL
  2166 NATIVE_NAME (sendWheel) (JNIEnv *env, jobject object,
  2167                          jshort window, jint x, jint y,
  2168                          jlong time, jint state,
  2169                          jfloat x_delta, jfloat y_delta)
  2170 {
  2171   JNI_STACK_ALIGNMENT_PROLOGUE;
  2172 
  2173   union android_event event;
  2174 
  2175   event.wheel.type = ANDROID_WHEEL;
  2176   event.wheel.serial = ++event_serial;
  2177   event.wheel.window = window;
  2178   event.wheel.x = x;
  2179   event.wheel.y = y;
  2180   event.wheel.time = time;
  2181   event.wheel.state = state;
  2182   event.wheel.x_delta = x_delta;
  2183   event.wheel.y_delta = y_delta;
  2184 
  2185   android_write_event (&event);
  2186   return event_serial;
  2187 }
  2188 
  2189 JNIEXPORT jlong JNICALL
  2190 NATIVE_NAME (sendIconified) (JNIEnv *env, jobject object,
  2191                              jshort window)
  2192 {
  2193   JNI_STACK_ALIGNMENT_PROLOGUE;
  2194 
  2195   union android_event event;
  2196 
  2197   event.iconified.type = ANDROID_ICONIFIED;
  2198   event.iconified.serial = ++event_serial;
  2199   event.iconified.window = window;
  2200 
  2201   android_write_event (&event);
  2202   return event_serial;
  2203 }
  2204 
  2205 JNIEXPORT jlong JNICALL
  2206 NATIVE_NAME (sendDeiconified) (JNIEnv *env, jobject object,
  2207                                jshort window)
  2208 {
  2209   JNI_STACK_ALIGNMENT_PROLOGUE;
  2210 
  2211   union android_event event;
  2212 
  2213   event.iconified.type = ANDROID_DEICONIFIED;
  2214   event.iconified.serial = ++event_serial;
  2215   event.iconified.window = window;
  2216 
  2217   android_write_event (&event);
  2218   return event_serial;
  2219 }
  2220 
  2221 JNIEXPORT jlong JNICALL
  2222 NATIVE_NAME (sendContextMenu) (JNIEnv *env, jobject object,
  2223                                jshort window, jint menu_event_id,
  2224                                jint menu_event_serial)
  2225 {
  2226   JNI_STACK_ALIGNMENT_PROLOGUE;
  2227 
  2228   union android_event event;
  2229 
  2230   event.menu.type = ANDROID_CONTEXT_MENU;
  2231   event.menu.serial = ++event_serial;
  2232   event.menu.window = window;
  2233   event.menu.menu_event_id = menu_event_id;
  2234   event.menu.menu_event_serial = menu_event_serial;
  2235 
  2236   android_write_event (&event);
  2237   return event_serial;
  2238 }
  2239 
  2240 JNIEXPORT jlong JNICALL
  2241 NATIVE_NAME (sendExpose) (JNIEnv *env, jobject object,
  2242                           jshort window, jint x, jint y,
  2243                           jint width, jint height)
  2244 {
  2245   JNI_STACK_ALIGNMENT_PROLOGUE;
  2246 
  2247   union android_event event;
  2248 
  2249   event.xexpose.type = ANDROID_EXPOSE;
  2250   event.xexpose.serial = ++event_serial;
  2251   event.xexpose.window = window;
  2252   event.xexpose.x = x;
  2253   event.xexpose.y = y;
  2254   event.xexpose.width = width;
  2255   event.xexpose.height = height;
  2256 
  2257   android_write_event (&event);
  2258   return event_serial;
  2259 }
  2260 
  2261 JNIEXPORT jboolean JNICALL
  2262 NATIVE_NAME (shouldForwardMultimediaButtons) (JNIEnv *env,
  2263                                               jobject object)
  2264 {
  2265   /* Yes, android_pass_multimedia_buttons_to_system is being
  2266      read from the UI thread.  */
  2267   return !android_pass_multimedia_buttons_to_system;
  2268 }
  2269 
  2270 JNIEXPORT void JNICALL
  2271 NATIVE_NAME (blitRect) (JNIEnv *env, jobject object,
  2272                         jobject src, jobject dest,
  2273                         jint x1, jint y1, jint x2, jint y2)
  2274 {
  2275   AndroidBitmapInfo src_info, dest_info;
  2276   unsigned char *src_data_1, *dest_data_1;
  2277   void *src_data, *dest_data;
  2278 
  2279   /* N.B. that X2 and Y2 represent the pixel past the edge of the
  2280      rectangle; thus, the width is x2 - x1 and the height is y2 -
  2281      y1.  */
  2282 
  2283   memset (&src_info, 0, sizeof src_info);
  2284   memset (&dest_info, 0, sizeof dest_info);
  2285   AndroidBitmap_getInfo (env, src, &src_info);
  2286   AndroidBitmap_getInfo (env, dest, &dest_info);
  2287 
  2288   /* If the stride is 0 after a call to `getInfo', assume it
  2289      failed.  */
  2290 
  2291   if (!src_info.stride || !dest_info.stride)
  2292     return;
  2293 
  2294   /* If formats differ, abort.  */
  2295   eassert (src_info.format == dest_info.format
  2296            && src_info.format == ANDROID_BITMAP_FORMAT_RGBA_8888);
  2297 
  2298   /* Lock the image data.  */
  2299   src_data = NULL;
  2300   AndroidBitmap_lockPixels (env, src, &src_data);
  2301 
  2302   if (!src_data)
  2303     return;
  2304 
  2305   dest_data = NULL;
  2306   AndroidBitmap_lockPixels (env, dest, &dest_data);
  2307 
  2308   if (!dest_data)
  2309     goto fail1;
  2310 
  2311   /* Now clip the rectangle to the bounds of the source and
  2312      destination bitmap.  */
  2313 
  2314   x1 = MAX (x1, 0);
  2315   y1 = MAX (y1, 0);
  2316   x2 = MAX (x2, 0);
  2317   y2 = MAX (y2, 0);
  2318 
  2319 
  2320   if (x1 >= src_info.width
  2321       || x1 >= dest_info.width)
  2322     x1 = MIN (dest_info.width - 1, src_info.width - 1);
  2323 
  2324   if (x2 > src_info.width
  2325       || x2 > dest_info.width)
  2326     x2 = MIN (src_info.width, dest_info.width);
  2327 
  2328   if (y1 >= src_info.height
  2329       || y1 >= dest_info.height)
  2330     y1 = MIN (dest_info.height - 1, src_info.height - 1);
  2331 
  2332   if (y2 > src_info.height
  2333       || y2 > dest_info.height)
  2334     y2 = MIN (src_info.height, dest_info.height);
  2335 
  2336   if (x1 >= x2 || y1 >= y2)
  2337     goto fail2;
  2338 
  2339   /* Determine the address of the first line to copy.  */
  2340 
  2341   src_data_1 = src_data;
  2342   dest_data_1 = dest_data;
  2343   src_data_1 += x1 * 4;
  2344   src_data_1 += y1 * src_info.stride;
  2345   dest_data_1 += x1 * 4;
  2346   dest_data_1 += y1 * dest_info.stride;
  2347 
  2348   /* Start copying each line.  */
  2349 
  2350   while (y1 != y2)
  2351     {
  2352       memcpy (dest_data_1, src_data_1, (x2 - x1) * 4);
  2353       src_data_1 += src_info.stride;
  2354       dest_data_1 += dest_info.stride;
  2355       y1++;
  2356     }
  2357 
  2358   /* Complete the copy and unlock the bitmap.  */
  2359 
  2360  fail2:
  2361   AndroidBitmap_unlockPixels (env, dest);
  2362  fail1:
  2363   AndroidBitmap_unlockPixels (env, src);
  2364 }
  2365 
  2366 JNIEXPORT void JNICALL
  2367 NATIVE_NAME (notifyPixelsChanged) (JNIEnv *env, jobject object,
  2368                                    jobject bitmap)
  2369 {
  2370   void *data;
  2371 
  2372   /* Lock and unlock the bitmap.  This calls
  2373      SkBitmap->notifyPixelsChanged.  */
  2374 
  2375   if (AndroidBitmap_lockPixels (env, bitmap, &data) < 0)
  2376     /* The return value is less than 0 if an error occurs.
  2377        Good luck finding this in the documentation.  */
  2378     return;
  2379 
  2380   AndroidBitmap_unlockPixels (env, bitmap);
  2381 }
  2382 
  2383 /* Forward declarations of deadlock prevention functions.  */
  2384 
  2385 static void android_begin_query (void);
  2386 static void android_end_query (void);
  2387 static void android_answer_query_spin (void);
  2388 
  2389 JNIEXPORT void JNICALL
  2390 NATIVE_NAME (beginSynchronous) (JNIEnv *env, jobject object)
  2391 {
  2392   JNI_STACK_ALIGNMENT_PROLOGUE;
  2393 
  2394   android_begin_query ();
  2395 }
  2396 
  2397 JNIEXPORT void JNICALL
  2398 NATIVE_NAME (endSynchronous) (JNIEnv *env, jobject object)
  2399 {
  2400   JNI_STACK_ALIGNMENT_PROLOGUE;
  2401 
  2402   android_end_query ();
  2403 }
  2404 
  2405 JNIEXPORT void JNICALL
  2406 NATIVE_NAME (answerQuerySpin) (JNIEnv *env, jobject object)
  2407 {
  2408   JNI_STACK_ALIGNMENT_PROLOGUE;
  2409 
  2410   android_answer_query_spin ();
  2411 }
  2412 
  2413 
  2414 
  2415 /* System thread setup.  Android doesn't always block signals Emacs is
  2416    interested in from being received by the UI or render threads,
  2417    which can lead to problems when those signals then interrupt one of
  2418    those threads.  */
  2419 
  2420 JNIEXPORT void JNICALL
  2421 NATIVE_NAME (setupSystemThread) (void)
  2422 {
  2423   sigset_t sigset;
  2424 
  2425   /* Block everything except for SIGSEGV and SIGBUS; those two are
  2426      used by the runtime.  */
  2427 
  2428   sigfillset (&sigset);
  2429   sigdelset (&sigset, SIGSEGV);
  2430   sigdelset (&sigset, SIGBUS);
  2431 
  2432   /* Save the signal mask that was previously used.  It will be
  2433      restored in `initEmacs'.  */
  2434 
  2435   if (pthread_sigmask (SIG_BLOCK, &sigset, &startup_signal_mask))
  2436     __android_log_print (ANDROID_LOG_WARN, __func__,
  2437                          "pthread_sigmask: %s", strerror (errno));
  2438   else
  2439     signal_mask_changed_p = true;
  2440 }
  2441 
  2442 #ifdef __clang__
  2443 #pragma clang diagnostic pop
  2444 #else
  2445 #pragma GCC diagnostic pop
  2446 #endif
  2447 
  2448 
  2449 
  2450 /* Java functions called by C.
  2451 
  2452    Because all C code runs in the native function initEmacs, ALL LOCAL
  2453    REFERENCES WILL PERSIST!
  2454 
  2455    This means that every local reference must be explicitly destroyed
  2456    with DeleteLocalRef.  A helper macro is provided to do this.  */
  2457 
  2458 struct android_handle_entry
  2459 {
  2460   /* The type.  */
  2461   enum android_handle_type type;
  2462 
  2463   /* The handle.  */
  2464   jobject handle;
  2465 };
  2466 
  2467 /* Table of handles MAX_HANDLE long.  */
  2468 struct android_handle_entry android_handles[USHRT_MAX];
  2469 
  2470 /* The largest handle ID currently known, but subject to
  2471    wraparound.  */
  2472 static android_handle max_handle;
  2473 
  2474 /* Allocate a new, unused, handle identifier.  If Emacs is out of
  2475    identifiers, return 0.  */
  2476 
  2477 static android_handle
  2478 android_alloc_id (void)
  2479 {
  2480   android_handle handle;
  2481 
  2482   /* 0 is never a valid handle ID.  */
  2483 
  2484   if (!max_handle)
  2485     max_handle++;
  2486 
  2487   /* See if the handle is already occupied.  */
  2488 
  2489   if (android_handles[max_handle].handle)
  2490     {
  2491       /* Look for a fresh unoccupied handle.  */
  2492 
  2493       handle = max_handle;
  2494       max_handle++;
  2495 
  2496       while (handle != max_handle)
  2497         {
  2498           ++max_handle;
  2499 
  2500           /* Make sure the handle is valid.  */
  2501           if (!max_handle)
  2502             ++max_handle;
  2503 
  2504           if (!android_handles[max_handle].handle)
  2505             return max_handle++;
  2506         }
  2507 
  2508       return ANDROID_NONE;
  2509     }
  2510 
  2511   return max_handle++;
  2512 }
  2513 
  2514 /* Destroy the specified handle and mark it as free on the Java side
  2515    as well.  */
  2516 
  2517 static void
  2518 android_destroy_handle (android_handle handle)
  2519 {
  2520   static jclass old, class;
  2521   static jmethodID method;
  2522 
  2523   if (!android_handles[handle].handle)
  2524     {
  2525       __android_log_print (ANDROID_LOG_ERROR, __func__,
  2526                            "Trying to destroy free handle!");
  2527       emacs_abort ();
  2528     }
  2529 
  2530   if (!class)
  2531     {
  2532       class
  2533         = (*android_java_env)->FindClass (android_java_env,
  2534                                           "org/gnu/emacs/EmacsHandleObject");
  2535       assert (class != NULL);
  2536 
  2537       method
  2538         = (*android_java_env)->GetMethodID (android_java_env, class,
  2539                                             "destroyHandle", "()V");
  2540       assert (method != NULL);
  2541 
  2542       old = class;
  2543       class
  2544         = (jclass) (*android_java_env)->NewGlobalRef (android_java_env,
  2545                                                       (jobject) class);
  2546       android_exception_check_1 (old);
  2547       ANDROID_DELETE_LOCAL_REF (old);
  2548     }
  2549 
  2550   (*android_java_env)->CallVoidMethod (android_java_env,
  2551                                        android_handles[handle].handle,
  2552                                        method);
  2553 
  2554   /* Just clear any exception thrown.  If destroying the handle
  2555      fails from an out-of-memory error, then Emacs loses some
  2556      resources, but that is not as big deal as signalling.  */
  2557   (*android_java_env)->ExceptionClear (android_java_env);
  2558 
  2559   /* Delete the global reference regardless of any error.  */
  2560   (*android_java_env)->DeleteGlobalRef (android_java_env,
  2561                                         android_handles[handle].handle);
  2562   android_handles[handle].handle = NULL;
  2563 }
  2564 
  2565 jobject
  2566 android_resolve_handle (android_handle handle,
  2567                         enum android_handle_type type)
  2568 {
  2569   if (!handle)
  2570     /* ANDROID_NONE.  */
  2571     return NULL;
  2572 
  2573   /* CheckJNI will normally ensure that the handle exists and is
  2574      the right type, but with a less informative error message.
  2575      Don't waste cycles doing our own checking here.  */
  2576 
  2577 #ifdef ENABLE_CHECKING
  2578 
  2579   if (!android_handles[handle].handle)
  2580     {
  2581       __android_log_print (ANDROID_LOG_ERROR, __func__,
  2582                            "Trying to resolve free handle!");
  2583       emacs_abort ();
  2584     }
  2585 
  2586   if (android_handles[handle].type != type)
  2587     {
  2588       __android_log_print (ANDROID_LOG_ERROR, __func__,
  2589                            "Handle has wrong type!");
  2590       emacs_abort ();
  2591     }
  2592 
  2593 #endif /* ENABLE_CHECKING */
  2594 
  2595   return android_handles[handle].handle;
  2596 }
  2597 
  2598 static jobject
  2599 android_resolve_handle2 (android_handle handle,
  2600                          enum android_handle_type type,
  2601                          enum android_handle_type type2)
  2602 {
  2603   if (!handle)
  2604     return NULL;
  2605 
  2606   /* CheckJNI will normally ensure that the handle exists and is
  2607      the right type, but with a less informative error message.
  2608      Don't waste cycles doing our own checking here.  */
  2609 
  2610 #ifdef ENABLE_CHECKING
  2611 
  2612   if (!android_handles[handle].handle)
  2613     {
  2614       __android_log_print (ANDROID_LOG_ERROR, __func__,
  2615                            "Trying to resolve free handle!");
  2616       emacs_abort ();
  2617     }
  2618 
  2619   if (android_handles[handle].type != type
  2620       && android_handles[handle].type != type2)
  2621     {
  2622       __android_log_print (ANDROID_LOG_ERROR, __func__,
  2623                            "Handle has wrong type!");
  2624       emacs_abort ();
  2625     }
  2626 
  2627 #endif /* ENABLE_CHECKING */
  2628 
  2629   return android_handles[handle].handle;
  2630 }
  2631 
  2632 void
  2633 android_change_window_attributes (android_window handle,
  2634                                   enum android_window_value_mask value_mask,
  2635                                   struct android_set_window_attributes *attrs)
  2636 {
  2637   jmethodID method;
  2638   jobject window;
  2639   jint pixel;
  2640 
  2641   window = android_resolve_handle (handle, ANDROID_HANDLE_WINDOW);
  2642 
  2643   if (value_mask & ANDROID_CW_BACK_PIXEL)
  2644     {
  2645       method = window_class.change_window_background;
  2646       pixel = (jint) attrs->background_pixel;
  2647       (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
  2648                                                      window,
  2649                                                      window_class.class,
  2650                                                      method, pixel);
  2651       android_exception_check ();
  2652     }
  2653 }
  2654 
  2655 /* Create a new window with the given width, height and
  2656    attributes.  */
  2657 
  2658 android_window
  2659 android_create_window (android_window parent, int x, int y,
  2660                        int width, int height,
  2661                        enum android_window_value_mask value_mask,
  2662                        struct android_set_window_attributes *attrs)
  2663 {
  2664   static jclass class;
  2665   static jmethodID constructor;
  2666   jobject object, parent_object, old;
  2667   android_window window;
  2668   android_handle prev_max_handle;
  2669   bool override_redirect;
  2670 
  2671   parent_object = android_resolve_handle (parent, ANDROID_HANDLE_WINDOW);
  2672 
  2673   prev_max_handle = max_handle;
  2674   window = android_alloc_id ();
  2675 
  2676   if (!window)
  2677     error ("Out of window handles!");
  2678 
  2679   if (!class)
  2680     {
  2681       class = (*android_java_env)->FindClass (android_java_env,
  2682                                               "org/gnu/emacs/EmacsWindow");
  2683       assert (class != NULL);
  2684 
  2685       constructor
  2686         = (*android_java_env)->GetMethodID (android_java_env, class, "<init>",
  2687                                             "(SLorg/gnu/emacs/EmacsWindow;"
  2688                                             "IIIIZ)V");
  2689       assert (constructor != NULL);
  2690 
  2691       old = class;
  2692       class = (*android_java_env)->NewGlobalRef (android_java_env, class);
  2693       android_exception_check_1 (old);
  2694       ANDROID_DELETE_LOCAL_REF (old);
  2695     }
  2696 
  2697   /* N.B. that ANDROID_CW_OVERRIDE_REDIRECT can only be set at window
  2698      creation time.  */
  2699   override_redirect = ((value_mask
  2700                         & ANDROID_CW_OVERRIDE_REDIRECT)
  2701                        && attrs->override_redirect);
  2702 
  2703   object = (*android_java_env)->NewObject (android_java_env, class,
  2704                                            constructor, (jshort) window,
  2705                                            parent_object, (jint) x, (jint) y,
  2706                                            (jint) width, (jint) height,
  2707                                            (jboolean) override_redirect);
  2708   if (!object)
  2709     {
  2710       (*android_java_env)->ExceptionClear (android_java_env);
  2711 
  2712       max_handle = prev_max_handle;
  2713       memory_full (0);
  2714     }
  2715 
  2716   android_handles[window].type = ANDROID_HANDLE_WINDOW;
  2717   android_handles[window].handle
  2718     = (*android_java_env)->NewGlobalRef (android_java_env,
  2719                                          object);
  2720   (*android_java_env)->ExceptionClear (android_java_env);
  2721   ANDROID_DELETE_LOCAL_REF (object);
  2722 
  2723   if (!android_handles[window].handle)
  2724     memory_full (0);
  2725 
  2726   android_change_window_attributes (window, value_mask, attrs);
  2727   return window;
  2728 }
  2729 
  2730 void
  2731 android_set_window_background (android_window window, unsigned long pixel)
  2732 {
  2733   struct android_set_window_attributes attrs;
  2734 
  2735   attrs.background_pixel = pixel;
  2736   android_change_window_attributes (window, ANDROID_CW_BACK_PIXEL,
  2737                                     &attrs);
  2738 }
  2739 
  2740 void
  2741 android_destroy_window (android_window window)
  2742 {
  2743   if (android_handles[window].type != ANDROID_HANDLE_WINDOW)
  2744     {
  2745       __android_log_print (ANDROID_LOG_ERROR, __func__,
  2746                            "Trying to destroy something not a window!");
  2747       emacs_abort ();
  2748     }
  2749 
  2750   android_destroy_handle (window);
  2751 }
  2752 
  2753 static void
  2754 android_init_android_rect_class (void)
  2755 {
  2756   jclass old;
  2757 
  2758   if (android_rect_class)
  2759     /* Already initialized.  */
  2760     return;
  2761 
  2762   android_rect_class
  2763     = (*android_java_env)->FindClass (android_java_env,
  2764                                       "android/graphics/Rect");
  2765   assert (android_rect_class);
  2766 
  2767   android_rect_constructor
  2768     = (*android_java_env)->GetMethodID (android_java_env, android_rect_class,
  2769                                         "<init>", "(IIII)V");
  2770   assert (emacs_gc_constructor);
  2771 
  2772   old = android_rect_class;
  2773   android_rect_class
  2774     = (jclass) (*android_java_env)->NewGlobalRef (android_java_env,
  2775                                                   (jobject) android_rect_class);
  2776   android_exception_check_1 (old);
  2777   ANDROID_DELETE_LOCAL_REF (old);
  2778 }
  2779 
  2780 static void
  2781 android_init_emacs_gc_class (void)
  2782 {
  2783   jclass old;
  2784 
  2785   if (emacs_gc_class)
  2786     /* Already initialized.  */
  2787     return;
  2788 
  2789   emacs_gc_class
  2790     = (*android_java_env)->FindClass (android_java_env,
  2791                                       "org/gnu/emacs/EmacsGC");
  2792   assert (emacs_gc_class);
  2793 
  2794   emacs_gc_constructor
  2795     = (*android_java_env)->GetMethodID (android_java_env,
  2796                                         emacs_gc_class,
  2797                                         "<init>", "(S)V");
  2798   assert (emacs_gc_constructor);
  2799 
  2800   emacs_gc_mark_dirty
  2801     = (*android_java_env)->GetMethodID (android_java_env,
  2802                                         emacs_gc_class,
  2803                                         "markDirty", "(Z)V");
  2804   assert (emacs_gc_mark_dirty);
  2805 
  2806   old = emacs_gc_class;
  2807   emacs_gc_class
  2808     = (jclass) (*android_java_env)->NewGlobalRef (android_java_env,
  2809                                                   (jobject) emacs_gc_class);
  2810   android_exception_check_1 (old);
  2811   ANDROID_DELETE_LOCAL_REF (old);
  2812 
  2813   emacs_gc_foreground
  2814     = (*android_java_env)->GetFieldID (android_java_env,
  2815                                        emacs_gc_class,
  2816                                        "foreground", "I");
  2817   emacs_gc_background
  2818     = (*android_java_env)->GetFieldID (android_java_env,
  2819                                        emacs_gc_class,
  2820                                        "background", "I");
  2821   emacs_gc_function
  2822     = (*android_java_env)->GetFieldID (android_java_env,
  2823                                        emacs_gc_class,
  2824                                        "function", "I");
  2825   emacs_gc_clip_rects
  2826     = (*android_java_env)->GetFieldID (android_java_env,
  2827                                        emacs_gc_class,
  2828                                        "clip_rects",
  2829                                        "[Landroid/graphics/Rect;");
  2830   emacs_gc_clip_x_origin
  2831     = (*android_java_env)->GetFieldID (android_java_env,
  2832                                        emacs_gc_class,
  2833                                        "clip_x_origin", "I");
  2834   emacs_gc_clip_y_origin
  2835     = (*android_java_env)->GetFieldID (android_java_env,
  2836                                        emacs_gc_class,
  2837                                        "clip_y_origin", "I");
  2838   emacs_gc_stipple
  2839     = (*android_java_env)->GetFieldID (android_java_env,
  2840                                        emacs_gc_class,
  2841                                        "stipple",
  2842                                        "Lorg/gnu/emacs/EmacsPixmap;");
  2843   emacs_gc_clip_mask
  2844     = (*android_java_env)->GetFieldID (android_java_env,
  2845                                        emacs_gc_class,
  2846                                        "clip_mask",
  2847                                        "Lorg/gnu/emacs/EmacsPixmap;");
  2848   emacs_gc_fill_style
  2849     = (*android_java_env)->GetFieldID (android_java_env,
  2850                                        emacs_gc_class,
  2851                                        "fill_style", "I");
  2852   emacs_gc_ts_origin_x
  2853     = (*android_java_env)->GetFieldID (android_java_env,
  2854                                        emacs_gc_class,
  2855                                        "ts_origin_x", "I");
  2856   emacs_gc_ts_origin_y
  2857     = (*android_java_env)->GetFieldID (android_java_env,
  2858                                        emacs_gc_class,
  2859                                        "ts_origin_y", "I");
  2860 }
  2861 
  2862 struct android_gc *
  2863 android_create_gc (enum android_gc_value_mask mask,
  2864                    struct android_gc_values *values)
  2865 {
  2866   struct android_gc *gc;
  2867   android_handle prev_max_handle;
  2868   jobject object;
  2869 
  2870   android_init_emacs_gc_class ();
  2871 
  2872   gc = xmalloc (sizeof *gc);
  2873   prev_max_handle = max_handle;
  2874   gc->gcontext = android_alloc_id ();
  2875   gc->foreground = 0;
  2876   gc->background = 0xffffff;
  2877   gc->clip_rects = NULL;
  2878 
  2879   /* This means to not apply any clipping.  */
  2880   gc->num_clip_rects = -1;
  2881 
  2882   /* Apply the other default values.  */
  2883   gc->function = ANDROID_GC_COPY;
  2884   gc->fill_style = ANDROID_FILL_SOLID;
  2885   gc->clip_x_origin = 0;
  2886   gc->clip_y_origin = 0;
  2887   gc->clip_mask = ANDROID_NONE;
  2888   gc->stipple = ANDROID_NONE;
  2889   gc->ts_x_origin = 0;
  2890   gc->ts_y_origin = 0;
  2891 
  2892   if (!gc->gcontext)
  2893     {
  2894       xfree (gc);
  2895       error ("Out of GContext handles!");
  2896     }
  2897 
  2898   object = (*android_java_env)->NewObject (android_java_env,
  2899                                            emacs_gc_class,
  2900                                            emacs_gc_constructor,
  2901                                            (jshort) gc->gcontext);
  2902 
  2903   if (!object)
  2904     {
  2905       (*android_java_env)->ExceptionClear (android_java_env);
  2906 
  2907       max_handle = prev_max_handle;
  2908       memory_full (0);
  2909     }
  2910 
  2911   android_handles[gc->gcontext].type = ANDROID_HANDLE_GCONTEXT;
  2912   android_handles[gc->gcontext].handle
  2913     = (*android_java_env)->NewGlobalRef (android_java_env, object);
  2914   (*android_java_env)->ExceptionClear (android_java_env);
  2915   ANDROID_DELETE_LOCAL_REF (object);
  2916 
  2917   if (!android_handles[gc->gcontext].handle)
  2918     memory_full (0);
  2919 
  2920   android_change_gc (gc, mask, values);
  2921   return gc;
  2922 }
  2923 
  2924 void
  2925 android_free_gc (struct android_gc *gc)
  2926 {
  2927   android_destroy_handle (gc->gcontext);
  2928 
  2929   xfree (gc->clip_rects);
  2930   xfree (gc);
  2931 }
  2932 
  2933 void
  2934 android_change_gc (struct android_gc *gc,
  2935                    enum android_gc_value_mask mask,
  2936                    struct android_gc_values *values)
  2937 {
  2938   jobject what, gcontext;
  2939   jboolean clip_changed;
  2940 
  2941   clip_changed = false;
  2942 
  2943   android_init_emacs_gc_class ();
  2944   gcontext = android_resolve_handle (gc->gcontext,
  2945                                      ANDROID_HANDLE_GCONTEXT);
  2946 
  2947   if (mask & ANDROID_GC_FOREGROUND)
  2948     {
  2949       (*android_java_env)->SetIntField (android_java_env,
  2950                                         gcontext,
  2951                                         emacs_gc_foreground,
  2952                                         values->foreground);
  2953       gc->foreground = values->foreground;
  2954     }
  2955 
  2956   if (mask & ANDROID_GC_BACKGROUND)
  2957     {
  2958       (*android_java_env)->SetIntField (android_java_env,
  2959                                         gcontext,
  2960                                         emacs_gc_background,
  2961                                         values->background);
  2962       gc->background = values->background;
  2963     }
  2964 
  2965   if (mask & ANDROID_GC_FUNCTION)
  2966     {
  2967       (*android_java_env)->SetIntField (android_java_env,
  2968                                         gcontext,
  2969                                         emacs_gc_function,
  2970                                         values->function);
  2971       gc->function = values->function;
  2972     }
  2973 
  2974   if (mask & ANDROID_GC_CLIP_X_ORIGIN)
  2975     {
  2976       (*android_java_env)->SetIntField (android_java_env,
  2977                                         gcontext,
  2978                                         emacs_gc_clip_x_origin,
  2979                                         values->clip_x_origin);
  2980       gc->clip_x_origin = values->clip_x_origin;
  2981       clip_changed = true;
  2982     }
  2983 
  2984   if (mask & ANDROID_GC_CLIP_Y_ORIGIN)
  2985     {
  2986       (*android_java_env)->SetIntField (android_java_env,
  2987                                         gcontext,
  2988                                         emacs_gc_clip_y_origin,
  2989                                         values->clip_y_origin);
  2990       gc->clip_y_origin = values->clip_y_origin;
  2991       clip_changed = true;
  2992     }
  2993 
  2994   if (mask & ANDROID_GC_CLIP_MASK)
  2995     {
  2996       what = android_resolve_handle (values->clip_mask,
  2997                                      ANDROID_HANDLE_PIXMAP);
  2998       (*android_java_env)->SetObjectField (android_java_env,
  2999                                            gcontext,
  3000                                            emacs_gc_clip_mask,
  3001                                            what);
  3002       gc->clip_mask = values->clip_mask;
  3003 
  3004       /* Changing GCClipMask also clears the clip rectangles.  */
  3005       (*android_java_env)->SetObjectField (android_java_env,
  3006                                            gcontext,
  3007                                            emacs_gc_clip_rects,
  3008                                            NULL);
  3009 
  3010       xfree (gc->clip_rects);
  3011       gc->clip_rects = NULL;
  3012       gc->num_clip_rects = -1;
  3013       clip_changed = true;
  3014     }
  3015 
  3016   if (mask & ANDROID_GC_STIPPLE)
  3017     {
  3018       what = android_resolve_handle (values->stipple,
  3019                                      ANDROID_HANDLE_PIXMAP);
  3020       (*android_java_env)->SetObjectField (android_java_env,
  3021                                            gcontext,
  3022                                            emacs_gc_stipple,
  3023                                            what);
  3024       gc->stipple = values->stipple;
  3025     }
  3026 
  3027   if (mask & ANDROID_GC_FILL_STYLE)
  3028     {
  3029       (*android_java_env)->SetIntField (android_java_env,
  3030                                         gcontext,
  3031                                         emacs_gc_fill_style,
  3032                                         values->fill_style);
  3033       gc->fill_style = values->fill_style;
  3034     }
  3035 
  3036   if (mask & ANDROID_GC_TILE_STIP_X_ORIGIN)
  3037     {
  3038       (*android_java_env)->SetIntField (android_java_env,
  3039                                         gcontext,
  3040                                         emacs_gc_ts_origin_x,
  3041                                         values->ts_x_origin);
  3042       gc->ts_x_origin = values->ts_x_origin;
  3043     }
  3044 
  3045   if (mask & ANDROID_GC_TILE_STIP_Y_ORIGIN)
  3046     {
  3047       (*android_java_env)->SetIntField (android_java_env,
  3048                                         gcontext,
  3049                                         emacs_gc_ts_origin_y,
  3050                                         values->ts_y_origin);
  3051       gc->ts_y_origin = values->ts_y_origin;
  3052     }
  3053 
  3054   if (mask)
  3055     {
  3056       (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
  3057                                                      gcontext,
  3058                                                      emacs_gc_class,
  3059                                                      emacs_gc_mark_dirty,
  3060                                                      (jboolean) clip_changed);
  3061       android_exception_check ();
  3062     }
  3063 }
  3064 
  3065 void
  3066 android_set_clip_rectangles (struct android_gc *gc, int clip_x_origin,
  3067                              int clip_y_origin,
  3068                              struct android_rectangle *clip_rects,
  3069                              int n_clip_rects)
  3070 {
  3071   jobjectArray array;
  3072   jobject rect, gcontext;
  3073   int i;
  3074 
  3075   android_init_android_rect_class ();
  3076   android_init_emacs_gc_class ();
  3077 
  3078   gcontext = android_resolve_handle (gc->gcontext,
  3079                                      ANDROID_HANDLE_GCONTEXT);
  3080 
  3081   array = (*android_java_env)->NewObjectArray (android_java_env,
  3082                                                n_clip_rects,
  3083                                                android_rect_class,
  3084                                                NULL);
  3085   android_exception_check ();
  3086 
  3087   for (i = 0; i < n_clip_rects; ++i)
  3088     {
  3089       rect = (*android_java_env)->NewObject (android_java_env,
  3090                                              android_rect_class,
  3091                                              android_rect_constructor,
  3092                                              (jint) clip_rects[i].x,
  3093                                              (jint) clip_rects[i].y,
  3094                                              (jint) (clip_rects[i].x
  3095                                                      + clip_rects[i].width),
  3096                                              (jint) (clip_rects[i].y
  3097                                                      + clip_rects[i].height));
  3098 
  3099       /* The meaning of this call is to check whether or not an
  3100          allocation error happened, and to delete ARRAY and signal an
  3101          out-of-memory error if that is the case.  */
  3102       android_exception_check_1 (array);
  3103 
  3104       (*android_java_env)->SetObjectArrayElement (android_java_env,
  3105                                                   array, i, rect);
  3106       ANDROID_DELETE_LOCAL_REF (rect);
  3107     }
  3108 
  3109   (*android_java_env)->SetObjectField (android_java_env,
  3110                                        gcontext,
  3111                                        emacs_gc_clip_rects,
  3112                                        (jobject) array);
  3113   ANDROID_DELETE_LOCAL_REF (array);
  3114 
  3115   (*android_java_env)->SetIntField (android_java_env,
  3116                                     gcontext,
  3117                                     emacs_gc_clip_x_origin,
  3118                                     clip_x_origin);
  3119   (*android_java_env)->SetIntField (android_java_env,
  3120                                     gcontext,
  3121                                     emacs_gc_clip_y_origin,
  3122                                     clip_y_origin);
  3123 
  3124   (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
  3125                                                  gcontext,
  3126                                                  emacs_gc_class,
  3127                                                  emacs_gc_mark_dirty,
  3128                                                  (jboolean) true);
  3129   android_exception_check ();
  3130 
  3131   /* Cache the clip rectangles on the C side for
  3132      sfntfont-android.c.  */
  3133   if (gc->clip_rects)
  3134     xfree (gc->clip_rects);
  3135 
  3136   /* If gc->num_clip_rects is 0, then no drawing will be performed at
  3137      all.  */
  3138   gc->clip_rects = xmalloc (sizeof *gc->clip_rects
  3139                             * n_clip_rects);
  3140   gc->num_clip_rects = n_clip_rects;
  3141   memcpy (gc->clip_rects, clip_rects,
  3142           n_clip_rects * sizeof *gc->clip_rects);
  3143 }
  3144 
  3145 void
  3146 android_reparent_window (android_window w, android_window parent_handle,
  3147                          int x, int y)
  3148 {
  3149   jobject window, parent;
  3150   jmethodID method;
  3151 
  3152   window = android_resolve_handle (w, ANDROID_HANDLE_WINDOW);
  3153   parent = android_resolve_handle (parent_handle,
  3154                                    ANDROID_HANDLE_WINDOW);
  3155 
  3156   method = window_class.reparent_to;
  3157   (*android_java_env)->CallNonvirtualVoidMethod (android_java_env, window,
  3158                                                  window_class.class, method,
  3159                                                  parent, (jint) x, (jint) y);
  3160   android_exception_check ();
  3161 }
  3162 
  3163 void
  3164 android_clear_window (android_window handle)
  3165 {
  3166   jobject window;
  3167 
  3168   window = android_resolve_handle (handle, ANDROID_HANDLE_WINDOW);
  3169 
  3170   (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
  3171                                                  emacs_service,
  3172                                                  service_class.class,
  3173                                                  service_class.clear_window,
  3174                                                  window);
  3175   android_exception_check ();
  3176 }
  3177 
  3178 void
  3179 android_map_window (android_window handle)
  3180 {
  3181   jobject window;
  3182   jmethodID map_window;
  3183 
  3184   window = android_resolve_handle (handle, ANDROID_HANDLE_WINDOW);
  3185   map_window = window_class.map_window;
  3186 
  3187   (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
  3188                                                  window,
  3189                                                  window_class.class,
  3190                                                  map_window);
  3191   android_exception_check ();
  3192 }
  3193 
  3194 void
  3195 android_unmap_window (android_window handle)
  3196 {
  3197   jobject window;
  3198   jmethodID unmap_window;
  3199 
  3200   window = android_resolve_handle (handle, ANDROID_HANDLE_WINDOW);
  3201   unmap_window = window_class.unmap_window;
  3202 
  3203   (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
  3204                                                  window,
  3205                                                  window_class.class,
  3206                                                  unmap_window);
  3207   android_exception_check ();
  3208 }
  3209 
  3210 void
  3211 android_resize_window (android_window handle, unsigned int width,
  3212                        unsigned int height)
  3213 {
  3214   jobject window;
  3215   jmethodID resize_window;
  3216 
  3217   window = android_resolve_handle (handle, ANDROID_HANDLE_WINDOW);
  3218   resize_window = window_class.resize_window;
  3219 
  3220   (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
  3221                                                  window,
  3222                                                  window_class.class,
  3223                                                  resize_window,
  3224                                                  (jint) width,
  3225                                                  (jint) height);
  3226   android_exception_check ();
  3227 }
  3228 
  3229 void
  3230 android_move_window (android_window handle, int x, int y)
  3231 {
  3232   jobject window;
  3233   jmethodID move_window;
  3234 
  3235   window = android_resolve_handle (handle, ANDROID_HANDLE_WINDOW);
  3236   move_window = window_class.move_window;
  3237 
  3238   (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
  3239                                                  window,
  3240                                                  window_class.class,
  3241                                                  move_window,
  3242                                                  (jint) x, (jint) y);
  3243   android_exception_check ();
  3244 }
  3245 
  3246 void
  3247 android_swap_buffers (struct android_swap_info *swap_info,
  3248                       int num_windows)
  3249 {
  3250   jobject window;
  3251   int i;
  3252 
  3253   for (i = 0; i < num_windows; ++i)
  3254     {
  3255       window = android_resolve_handle (swap_info[i].swap_window,
  3256                                        ANDROID_HANDLE_WINDOW);
  3257       (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
  3258                                                      window,
  3259                                                      window_class.class,
  3260                                                      window_class.swap_buffers);
  3261       android_exception_check ();
  3262     }
  3263 }
  3264 
  3265 void
  3266 android_get_gc_values (struct android_gc *gc,
  3267                        enum android_gc_value_mask mask,
  3268                        struct android_gc_values *values)
  3269 {
  3270   if (mask & ANDROID_GC_FOREGROUND)
  3271     /* GCs never have 32 bit colors, so we don't have to worry about
  3272        sign extension here.  */
  3273     values->foreground = gc->foreground;
  3274 
  3275   if (mask & ANDROID_GC_BACKGROUND)
  3276     values->background = gc->background;
  3277 
  3278   if (mask & ANDROID_GC_FUNCTION)
  3279     values->function = gc->function;
  3280 
  3281   if (mask & ANDROID_GC_CLIP_X_ORIGIN)
  3282     values->clip_x_origin = gc->clip_x_origin;
  3283 
  3284   if (mask & ANDROID_GC_CLIP_Y_ORIGIN)
  3285     values->clip_y_origin = gc->clip_y_origin;
  3286 
  3287   if (mask & ANDROID_GC_FILL_STYLE)
  3288     values->fill_style = gc->fill_style;
  3289 
  3290   if (mask & ANDROID_GC_TILE_STIP_X_ORIGIN)
  3291     values->ts_x_origin = gc->ts_x_origin;
  3292 
  3293   if (mask & ANDROID_GC_TILE_STIP_Y_ORIGIN)
  3294     values->ts_y_origin = gc->ts_y_origin;
  3295 
  3296   /* Fields involving handles are not used by Emacs, and thus not
  3297      implemented */
  3298 }
  3299 
  3300 void
  3301 android_set_foreground (struct android_gc *gc, unsigned long foreground)
  3302 {
  3303   struct android_gc_values gcv;
  3304 
  3305   gcv.foreground = foreground;
  3306   android_change_gc (gc, ANDROID_GC_FOREGROUND, &gcv);
  3307 }
  3308 
  3309 void
  3310 android_fill_rectangle (android_drawable handle, struct android_gc *gc,
  3311                         int x, int y, unsigned int width,
  3312                         unsigned int height)
  3313 {
  3314   jobject drawable, gcontext;
  3315 
  3316   drawable = android_resolve_handle2 (handle,
  3317                                       ANDROID_HANDLE_WINDOW,
  3318                                       ANDROID_HANDLE_PIXMAP);
  3319   gcontext = android_resolve_handle (gc->gcontext,
  3320                                      ANDROID_HANDLE_GCONTEXT);
  3321 
  3322   (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
  3323                                                  emacs_service,
  3324                                                  service_class.class,
  3325                                                  service_class.fill_rectangle,
  3326                                                  drawable,
  3327                                                  gcontext,
  3328                                                  (jint) x, (jint) y,
  3329                                                  (jint) width,
  3330                                                  (jint) height);
  3331 }
  3332 
  3333 android_pixmap
  3334 android_create_pixmap_from_bitmap_data (char *data, unsigned int width,
  3335                                         unsigned int height,
  3336                                         unsigned long foreground,
  3337                                         unsigned long background,
  3338                                         unsigned int depth)
  3339 {
  3340   android_handle prev_max_handle;
  3341   jobject object;
  3342   jintArray colors;
  3343   android_pixmap pixmap;
  3344   unsigned int x, y;
  3345   jint *region;
  3346 
  3347   USE_SAFE_ALLOCA;
  3348 
  3349   /* Create the color array holding the data.  */
  3350   colors = (*android_java_env)->NewIntArray (android_java_env,
  3351                                              width * height);
  3352   android_exception_check ();
  3353 
  3354   SAFE_NALLOCA (region, sizeof *region, width);
  3355 
  3356   for (y = 0; y < height; ++y)
  3357     {
  3358       for (x = 0; x < width; ++x)
  3359         {
  3360           if (depth == 24)
  3361             {
  3362               /* The alpha channels must be set, or otherwise, the
  3363                  pixmap will be created entirely transparent.  */
  3364 
  3365               if (data[x / 8] & (1 << (x % 8)))
  3366                 region[x] = foreground | 0xff000000;
  3367               else
  3368                 region[x] = background | 0xff000000;
  3369             }
  3370           else
  3371             {
  3372               if (data[x / 8] & (1 << (x % 8)))
  3373                 region[x] = foreground;
  3374               else
  3375                 region[x] = background;
  3376             }
  3377         }
  3378 
  3379       (*android_java_env)->SetIntArrayRegion (android_java_env,
  3380                                               colors,
  3381                                               width * y, width,
  3382                                               region);
  3383       data += width / 8;
  3384     }
  3385 
  3386   /* First, allocate the pixmap handle.  */
  3387   prev_max_handle = max_handle;
  3388   pixmap = android_alloc_id ();
  3389 
  3390   if (!pixmap)
  3391     {
  3392       ANDROID_DELETE_LOCAL_REF ((jobject) colors);
  3393       error ("Out of pixmap handles!");
  3394     }
  3395 
  3396   object = (*android_java_env)->NewObject (android_java_env,
  3397                                            pixmap_class.class,
  3398                                            pixmap_class.constructor,
  3399                                            (jshort) pixmap, colors,
  3400                                            (jint) width, (jint) height,
  3401                                            (jint) depth);
  3402   (*android_java_env)->ExceptionClear (android_java_env);
  3403   ANDROID_DELETE_LOCAL_REF ((jobject) colors);
  3404 
  3405   if (!object)
  3406     {
  3407       max_handle = prev_max_handle;
  3408       memory_full (0);
  3409     }
  3410 
  3411   android_handles[pixmap].type = ANDROID_HANDLE_PIXMAP;
  3412   android_handles[pixmap].handle
  3413     = (*android_java_env)->NewGlobalRef (android_java_env, object);
  3414   ANDROID_DELETE_LOCAL_REF (object);
  3415 
  3416   if (!android_handles[pixmap].handle)
  3417     memory_full (0);
  3418 
  3419   SAFE_FREE ();
  3420   return pixmap;
  3421 }
  3422 
  3423 void
  3424 android_set_clip_mask (struct android_gc *gc, android_pixmap pixmap)
  3425 {
  3426   struct android_gc_values gcv;
  3427 
  3428   gcv.clip_mask = pixmap;
  3429   android_change_gc (gc, ANDROID_GC_CLIP_MASK, &gcv);
  3430 }
  3431 
  3432 void
  3433 android_set_fill_style (struct android_gc *gc,
  3434                         enum android_fill_style fill_style)
  3435 {
  3436   struct android_gc_values gcv;
  3437 
  3438   gcv.fill_style = fill_style;
  3439   android_change_gc (gc, ANDROID_GC_FILL_STYLE, &gcv);
  3440 }
  3441 
  3442 
  3443 
  3444 /* Pixmap bit blit implementation.  This exists as `Canvas.drawBitmap'
  3445    seems to have trouble with copying bitmap data from one bitmap back
  3446    to itself on Android 8.0.  */
  3447 
  3448 /* Function called to actually perform the copy.  */
  3449 
  3450 typedef void (*android_blit_func) (int, int, int, int, int, int,
  3451                                    struct android_gc *,
  3452                                    unsigned char *, AndroidBitmapInfo *,
  3453                                    unsigned char *, AndroidBitmapInfo *,
  3454                                    unsigned char *, AndroidBitmapInfo *);
  3455 
  3456 
  3457 
  3458 #ifdef __aarch64__
  3459 
  3460 /* Copy N pixels from SRC to DST, using MASK as a depth 1 clip
  3461    mask.  */
  3462 
  3463 static void
  3464 android_neon_mask_line (unsigned int *src, unsigned int *dst,
  3465                         unsigned char *mask, int n)
  3466 {
  3467   uint32x4_t src_low, src_high, dst_low, dst_high;
  3468   int16x8_t vmask;
  3469   int32x4_t ext_mask_low, ext_mask_high, low, high;
  3470   int rem, i;
  3471 
  3472   /* Calculate the remainder.  */
  3473   rem = n & 7, n &= ~7;
  3474 
  3475   /* Process eight pixels at a time.  */
  3476 
  3477   if (n)
  3478     {
  3479     again:
  3480       /* Load the low and high four pixels from the source.  */
  3481       src_low = vld1q_u32 (src);
  3482       src_high = vld1q_u32 (src + 4);
  3483 
  3484       /* Do the same with the destination.  */
  3485       dst_low = vld1q_u32 (dst);
  3486       dst_high = vld1q_u32 (dst + 4);
  3487 
  3488       /* Load and sign extend the mask.  */
  3489       vmask = vmovl_s8 (vld1_u8 (mask));
  3490       ext_mask_low = vmovl_s16 (vget_low_s16 (vmask));
  3491       ext_mask_high = vmovl_s16 (vget_high_s16 (vmask));
  3492 
  3493       /* Reinterpret the mask.  */
  3494       low = vreinterpretq_u32_s32 (ext_mask_low);
  3495       high = vreinterpretq_u32_s32 (ext_mask_high);
  3496 
  3497       /* Apply the mask.  */
  3498       dst_low = vbicq_u32 (dst_low, low);
  3499       src_low = vandq_u32 (src_low, low);
  3500       dst_high = vbicq_u32 (dst_high, high);
  3501       src_high = vandq_u32 (src_high, high);
  3502 
  3503       /* Write the result after combining both masked vectors.  */
  3504       vst1q_u32 (dst, vorrq_u32 (dst_low, src_low));
  3505       vst1q_u32 (dst + 4, vorrq_u32 (dst_high, src_high));
  3506 
  3507       /* Adjust src, dst and mask.  */
  3508       dst += 8;
  3509       src += 8;
  3510       mask += 8;
  3511 
  3512       /* See if this loop should continue.  */
  3513       n -= 8;
  3514       if (n > 0)
  3515         goto again;
  3516     }
  3517 
  3518   /* Process the remaining pixels.  */
  3519 
  3520   for (i = 0; i < rem; ++i)
  3521     {
  3522       /* Sign extend the mask.  */
  3523       n = ((signed char *) mask)[i];
  3524 
  3525       /* Combine src and dst.  */
  3526       dst[i] = ((src[i] & n) | (dst[i] & ~n));
  3527     }
  3528 }
  3529 
  3530 #endif /* __aarch64__ */
  3531 
  3532 
  3533 
  3534 /* Copy a rectangle SRC_X, SRC_Y, WIDTH and HEIGHT from SRC, described
  3535    by SRC_INFO, to DST_X and DST_Y in DST, as described by DST_INFO.
  3536 
  3537    If MASK is set, mask the source data using MASK_INFO, translating
  3538    it by GC->clip_x_origin and GC->clip_y_origin.  MASK must be a
  3539    pixmap of depth 1.
  3540 
  3541    N.B. that currently only copies between bitmaps of depth 24 are
  3542    implemented.  */
  3543 
  3544 static void
  3545 android_blit_copy (int src_x, int src_y, int width, int height,
  3546                    int dst_x, int dst_y, struct android_gc *gc,
  3547                    unsigned char *src, AndroidBitmapInfo *src_info,
  3548                    unsigned char *dst, AndroidBitmapInfo *dst_info,
  3549                    unsigned char *mask, AndroidBitmapInfo *mask_info)
  3550 {
  3551   uintptr_t start, end;
  3552   int mask_offset;
  3553   size_t pixel, offset, offset1;
  3554   unsigned char *src_current, *dst_current;
  3555   unsigned char *mask_current;
  3556   int overflow, temp, i;
  3557 #ifndef __aarch64__
  3558   int j;
  3559 #endif /* __aarch64__ */
  3560   bool backwards;
  3561   unsigned int *long_src, *long_dst;
  3562 
  3563   /* Assert that the specified coordinates are within bounds.  */
  3564   eassert (src_x >= 0 && src_y >= 0
  3565            && dst_x >= 0 && dst_y >= 0);
  3566   eassert (src_x + width <= src_info->width);
  3567   eassert (src_y + height <= src_info->height);
  3568   eassert (dst_x + width <= dst_info->width);
  3569   eassert (dst_y + height <= dst_info->height);
  3570 
  3571   /* Now check that each bitmap has the correct format.  */
  3572   eassert (src_info->format == dst_info->format
  3573            && src_info->format == ANDROID_BITMAP_FORMAT_RGBA_8888);
  3574   pixel = sizeof (unsigned int);
  3575 
  3576   /* Android doesn't have A1 bitmaps, so A8 is used to represent
  3577      packed bitmaps of depth 1.  */
  3578   eassert (!mask || mask_info->format == ANDROID_BITMAP_FORMAT_A_8);
  3579 
  3580   /* Calculate the address of the first pixel of the first row to be
  3581      copied in both src and dst.  Compare them to determine the
  3582      direction in which the copy is to take place.  */
  3583 
  3584   overflow  = ckd_mul (&start, src_y, src_info->stride);
  3585   overflow |= ckd_mul (&end, src_x, pixel);
  3586   overflow |= ckd_add (&start, end, start);
  3587   overflow |= ckd_add (&start, (uintptr_t) src, start);
  3588 
  3589   if (overflow)
  3590     return;
  3591 
  3592   src_current = (unsigned char *) start;
  3593 
  3594   overflow  = ckd_mul (&start, dst_y, dst_info->stride);
  3595   overflow |= ckd_mul (&end, dst_x, pixel);
  3596   overflow |= ckd_add (&start, end, start);
  3597   overflow |= ckd_add (&start, (uintptr_t) dst, start);
  3598 
  3599   if (overflow)
  3600     return;
  3601 
  3602   dst_current = (unsigned char *) start;
  3603   backwards = false;
  3604 
  3605   /* Now see if copying should proceed from the bottom up.  */
  3606 
  3607   if (src == dst && dst_current >= src_current)
  3608     {
  3609       backwards = true;
  3610 
  3611       /* Walk src and dst from bottom to top, in order to avoid
  3612          overlap.  Calculate the coordinate of the last pixel of the
  3613          last row in both src and dst.  */
  3614 
  3615       overflow = ckd_mul (&start, src_y + height - 1,
  3616                           src_info->stride);
  3617 
  3618       if (mask)
  3619         /* If a mask is set, put the pointers before the end of the
  3620            row.  */
  3621         overflow |= ckd_mul (&end, src_x + width - 1, pixel);
  3622       else
  3623         end = src_x * pixel;
  3624 
  3625       overflow |= ckd_add (&start, start, end);
  3626       overflow |= ckd_add (&start, (uintptr_t) src, start);
  3627 
  3628       if (overflow)
  3629         return;
  3630 
  3631       src_current = (unsigned char *) start;
  3632 
  3633       overflow = ckd_mul (&start, dst_y + height - 1,
  3634                           dst_info->stride);
  3635 
  3636       if (mask)
  3637         /* If a mask is set, put the pointers before the end of the
  3638            row.  */
  3639         overflow |= ckd_mul (&end, dst_x + width - 1, pixel);
  3640       else
  3641         end = dst_x * pixel;
  3642 
  3643       overflow |= ckd_add (&start, start, end);
  3644       overflow |= ckd_add (&start, (uintptr_t) dst, start);
  3645 
  3646       if (overflow)
  3647         return;
  3648 
  3649       dst_current = (unsigned char *) start;
  3650     }
  3651 
  3652   if (!mask)
  3653     {
  3654       /* Change the direction of the copy depending on how SRC and DST
  3655          overlap.  */
  3656 
  3657       for (i = 0; i < height; ++i)
  3658         {
  3659           memmove (dst_current, src_current,
  3660                    width * pixel);
  3661 
  3662           if (backwards)
  3663             {
  3664               /* Proceed to the last row.  */
  3665               src_current -= src_info->stride;
  3666               dst_current -= dst_info->stride;
  3667             }
  3668           else
  3669             {
  3670               /* Proceed to the next row.  */
  3671               src_current += src_info->stride;
  3672               dst_current += dst_info->stride;
  3673             }
  3674         }
  3675     }
  3676   else
  3677     {
  3678       /* Adjust the source and destination Y.  The start is MAX
  3679          (dst_y, gc->clip_y_origin); the difference between that value
  3680          and dst_y is the offset to apply to src_y. */
  3681 
  3682       temp    = dst_y;
  3683       dst_y   = MAX (dst_y, gc->clip_y_origin);
  3684       src_y  += dst_y - temp;
  3685       height -= dst_y - temp;
  3686 
  3687       /* Verify that the bounds are correct.  */
  3688       eassert (dst_y + height
  3689                <= gc->clip_y_origin + mask_info->height);
  3690       eassert (dst_y >= gc->clip_y_origin);
  3691 
  3692       /* There is a mask.  For each scan line... */
  3693 
  3694       if (backwards)
  3695         {
  3696           /* Calculate the number of pixels at the end of the
  3697              mask.  */
  3698 
  3699           mask_offset  = dst_x + width;
  3700           mask_offset -= mask_info->width + gc->clip_x_origin;
  3701 
  3702           if (mask_offset < 0)
  3703             mask_offset = 0;
  3704 
  3705           /* Calculate the last column of the mask that will be
  3706              consulted.  */
  3707 
  3708           temp = dst_x - gc->clip_x_origin;
  3709           temp += MIN (mask_info->width - temp,
  3710                        width - mask_offset);
  3711 
  3712           if (temp < 0)
  3713             return;
  3714 
  3715           /* Now calculate the last row of the mask that will be
  3716              consulted.  */
  3717           i = dst_y - gc->clip_y_origin + height;
  3718 
  3719           /* Turn both into offsets.  */
  3720 
  3721           if (INT_MULTIPLY_WRAPV (temp, pixel, &offset)
  3722               || INT_MULTIPLY_WRAPV (i, mask_info->stride, &offset1)
  3723               || INT_ADD_WRAPV (offset, offset1, &offset)
  3724               || INT_ADD_WRAPV ((uintptr_t) mask, offset, &start))
  3725             return;
  3726 
  3727           if (height <= 0)
  3728             return;
  3729 
  3730           mask = mask_current = (unsigned char *) start;
  3731 
  3732           while (height--)
  3733             {
  3734               /* Skip backwards past the end of the mask.  */
  3735 
  3736               long_src = (unsigned int *) (src_current - mask_offset * pixel);
  3737               long_dst = (unsigned int *) (dst_current - mask_offset * pixel);
  3738               mask = mask_current;
  3739 
  3740               /* For each pixel covered by the mask... */
  3741               temp = MIN (mask_info->width - temp, width - mask_offset);
  3742               while (temp--)
  3743                 {
  3744                   /* Copy the destination it to the source, masked by
  3745                      the mask.  */
  3746 
  3747                   /* Sign extend the mask.  */
  3748                   i = *(signed char *) mask--;
  3749 
  3750                   /* Apply the mask.  */
  3751                   *long_dst = ((*long_src & i) | (*long_dst & ~i));
  3752 
  3753                   long_dst--;
  3754                   long_src--;
  3755                 }
  3756 
  3757               /* Return to the last row.  */
  3758               src_current -= src_info->stride;
  3759               dst_current -= dst_info->stride;
  3760               mask_current -= mask_info->stride;
  3761             }
  3762         }
  3763       else
  3764         {
  3765           /* Calculate the first column of the mask that will be
  3766              consulted.  */
  3767 
  3768           mask_offset = dst_x - gc->clip_x_origin;
  3769 
  3770           /* Adjust the mask by that much.  */
  3771 
  3772           if (mask_offset > 0)
  3773             mask += mask_offset;
  3774           else
  3775             {
  3776               /* Offset src and dst by the mask offset.  */
  3777               src_current += -mask_offset * pixel;
  3778               dst_current += -mask_offset * pixel;
  3779               width += mask_offset;
  3780             }
  3781 
  3782           /* Make sure it's not out of bounds.  */
  3783 
  3784           eassert (dst_y - gc->clip_y_origin >= 0);
  3785           if ((dst_y - gc->clip_y_origin) + height > mask_info->height
  3786               || width <= 0)
  3787             return;
  3788 
  3789           /* Now move mask to the position of the first row.  */
  3790 
  3791           mask += ((dst_y - gc->clip_y_origin)
  3792                    * mask_info->stride);
  3793 
  3794           /* Determine how many bytes need to be copied.  */
  3795 
  3796           if (mask_offset > 0)
  3797             temp = MIN (mask_info->width - mask_offset, width);
  3798           else
  3799             temp = MIN (mask_info->width, width);
  3800 
  3801           if (temp <= 0 || height <= 0)
  3802             return;
  3803 
  3804           /* Copy bytes according to the mask.  */
  3805 
  3806           while (height--)
  3807             {
  3808               long_src = (unsigned int *) src_current;
  3809               long_dst = (unsigned int *) dst_current;
  3810               mask_current = mask;
  3811 
  3812 #ifndef __aarch64__
  3813               for (j = 0; j < temp; ++j)
  3814                 {
  3815                   /* Sign extend the mask.  */
  3816                   i = *(signed char *) mask_current++;
  3817 
  3818                   /* Apply the mask.  */
  3819                   *long_dst = ((*long_src & i) | (*long_dst & ~i));
  3820                   long_dst++;
  3821                   long_src++;
  3822                 }
  3823 #else /* __aarch64__ */
  3824               android_neon_mask_line (long_src, long_dst, mask, temp);
  3825 #endif /* __aarch64__ */
  3826 
  3827               src_current += src_info->stride;
  3828               dst_current += dst_info->stride;
  3829               mask        += mask_info->stride;
  3830             }
  3831         }
  3832     }
  3833 }
  3834 
  3835 
  3836 /* Xor a rectangle SRC_X, SRC_Y, WIDTH and HEIGHT from SRC, described
  3837    by SRC_INFO, to DST_X and DST_Y in DST, as described by DST_INFO.
  3838 
  3839    Ignore the alpha channel when computing the exclusive-or of the
  3840    destination pixel.
  3841 
  3842    If MASK is set, mask the source data using MASK_INFO, translating
  3843    it by GC->clip_x_origin and GC->clip_y_origin.  MASK must be a
  3844    pixmap of depth 1.
  3845 
  3846    N.B. that currently only copies between bitmaps of depth 24 are
  3847    implemented.  */
  3848 
  3849 static void
  3850 android_blit_xor (int src_x, int src_y, int width, int height,
  3851                   int dst_x, int dst_y, struct android_gc *gc,
  3852                   unsigned char *src, AndroidBitmapInfo *src_info,
  3853                   unsigned char *dst, AndroidBitmapInfo *dst_info,
  3854                   unsigned char *mask, AndroidBitmapInfo *mask_info)
  3855 {
  3856 #if 0
  3857   uintptr_t start, end;
  3858   int mask_offset;
  3859   size_t pixel, offset, offset1;
  3860   unsigned char *src_current, *dst_current;
  3861   unsigned char *mask_current;
  3862   int overflow, temp, i;
  3863   bool backwards;
  3864   unsigned int *long_src, *long_dst;
  3865 #endif /* 0 */
  3866 
  3867   /* Note that this alu hasn't been tested -- it probably does not
  3868      work! */
  3869   emacs_abort ();
  3870 
  3871 #if 0
  3872   /* Assert that the specified coordinates are within bounds.  */
  3873   eassert (src_x >= 0 && src_y >= 0
  3874            && dst_x >= 0 && dst_y >= 0);
  3875   eassert (src_x + width <= src_info->width);
  3876   eassert (src_y + height <= src_info->height);
  3877   eassert (dst_x + width <= dst_info->width);
  3878   eassert (dst_y + height <= dst_info->height);
  3879 
  3880   /* Now check that each bitmap has the correct format.  */
  3881   eassert (src_info->format == dst_info->format
  3882            && src_info->format == ANDROID_BITMAP_FORMAT_RGBA_8888);
  3883   pixel = sizeof (unsigned int);
  3884 
  3885   /* Android doesn't have A1 bitmaps, so A8 is used to represent
  3886      packed bitmaps of depth 1.  */
  3887   eassert (!mask || mask_info->format == ANDROID_BITMAP_FORMAT_A_8);
  3888 
  3889   /* Calculate the address of the first pixel of the first row to be
  3890      copied in both src and dst.  Compare them to determine the
  3891      direction in which the copy is to take place.  */
  3892 
  3893   overflow  = ckd_mul (&start, src_y, src_info->stride);
  3894   overflow |= ckd_mul (&end, src_x, pixel);
  3895   overflow |= ckd_add (&start, (uintptr_t) src, start);
  3896 
  3897   if (overflow)
  3898     return;
  3899 
  3900   src_current = (unsigned char *) start;
  3901 
  3902   overflow  = ckd_mul (&start, dst_y, src_info->stride);
  3903   overflow |= ckd_mul (&end, dst_x, pixel);
  3904   overflow |= ckd_add (&start, (uintptr_t) dst, start);
  3905 
  3906   if (overflow)
  3907     return;
  3908 
  3909   dst_current = (unsigned char *) start;
  3910   backwards = false;
  3911 
  3912   /* Now see if copying should proceed from the bottom up.  */
  3913 
  3914   if (src == dst && dst_current >= src_current)
  3915     {
  3916       backwards = true;
  3917 
  3918       /* Walk src and dst from bottom to top, in order to avoid
  3919          overlap.  Calculate the coordinate of the last pixel of the
  3920          last row in both src and dst.  */
  3921 
  3922       overflow  = ckd_mul (&start, src_y + height - 1,
  3923                            src_info->stride);
  3924       if (mask) /* If a mask is set, put the pointers before the end
  3925                    of the row.  */
  3926         overflow |= ckd_mul (&end, src_x + width - 1, pixel);
  3927       else
  3928         overflow |= ckd_mul (&end, src_x, pixel);
  3929       overflow |= ckd_add (&start, start, end);
  3930       overflow |= ckd_add (&start, (uintptr_t) src, start);
  3931 
  3932       if (overflow)
  3933         return;
  3934 
  3935       src_current = (unsigned char *) start;
  3936 
  3937       overflow  = ckd_mul (&start, dst_y + height - 1,
  3938                            dst_info->stride);
  3939       if (mask) /* If a mask is set, put the pointers before the end
  3940                    of the row.  */
  3941         overflow |= ckd_mul (&end, dst_x + width - 1, pixel);
  3942       else
  3943         overflow |= ckd_mul (&end, dst_x, pixel);
  3944       overflow |= ckd_add (&start, start, end);
  3945       overflow |= ckd_add (&start, (uintptr_t) dst, start);
  3946 
  3947       if (overflow)
  3948         return;
  3949 
  3950       dst_current = (unsigned char *) start;
  3951     }
  3952 
  3953   if (!mask)
  3954     {
  3955       /* Change the direction of the copy depending on how SRC and DST
  3956          overlap.  */
  3957 
  3958       for (i = 0; i < height; ++i)
  3959         {
  3960           if (backwards)
  3961             {
  3962               for (i = width - 1; i <= 0; --i)
  3963                 (((unsigned int *) dst_current)[i])
  3964                   /* Keep the alpha channel intact.  */
  3965                   ^= (((unsigned int *) src_current)[i]) & 0xffffff;
  3966 
  3967               /* Proceed to the last row.  */
  3968               src_current -= src_info->stride;
  3969               dst_current -= dst_info->stride;
  3970             }
  3971           else
  3972             {
  3973               for (i = 0; i < width; ++i)
  3974                 (((unsigned int *) dst_current)[i])
  3975                   /* Keep the alpha channel intact.  */
  3976                   ^= (((unsigned int *) src_current)[i]) & 0xffffff;
  3977 
  3978               /* Proceed to the next row.  */
  3979               src_current += src_info->stride;
  3980               dst_current += dst_info->stride;
  3981             }
  3982         }
  3983     }
  3984   else
  3985     {
  3986       /* Adjust the source and destination Y.  The start is MAX
  3987          (dst_y, gc->clip_y_origin); the difference between that value
  3988          and dst_y is the offset to apply to src_y. */
  3989 
  3990       temp    = dst_y;
  3991       dst_y   = MAX (dst_y, gc->clip_y_origin);
  3992       src_y  += dst_y - temp;
  3993       height -= dst_y - temp;
  3994 
  3995       /* Verify that the bounds are correct.  */
  3996       eassert (dst_y + height
  3997                <= gc->clip_y_origin + mask_info->height);
  3998       eassert (dst_y >= gc->clip_y_origin);
  3999 
  4000       /* There is a mask.  For each scan line... */
  4001 
  4002       if (backwards)
  4003         {
  4004           /* Calculate the number of pixels at the end of the
  4005              mask.  */
  4006 
  4007           mask_offset  = dst_x + width;
  4008           mask_offset -= mask_info->width + gc->clip_x_origin;
  4009 
  4010           if (mask_info < 0)
  4011             mask_info = 0;
  4012 
  4013           /* Calculate the last column of the mask that will be
  4014              consulted.  */
  4015 
  4016           temp = dst_x - gc->clip_x_origin;
  4017           temp += MIN (mask_info->width - temp,
  4018                        width - mask_offset);
  4019 
  4020           if (temp < 0)
  4021             return;
  4022 
  4023           /* Now calculate the last row of the mask that will be
  4024              consulted.  */
  4025           i = dst_y - gc->clip_y_origin + height;
  4026 
  4027           /* Turn both into offsets.  */
  4028 
  4029           if (INT_MULTIPLY_WRAPV (temp, pixel, &offset)
  4030               || INT_MULTIPLY_WRAPV (i, mask_info->stride, &offset1)
  4031               || INT_ADD_WRAPV (offset, offset1, &offset)
  4032               || INT_ADD_WRAPV ((uintptr_t) mask, offset, &start))
  4033             return;
  4034 
  4035           mask = mask_current = (unsigned char *) start;
  4036 
  4037           for (i = 0; i < height; ++i)
  4038             {
  4039               /* Skip backwards past the end of the mask.  */
  4040 
  4041               long_src = (unsigned int *) (src_current - mask_offset * pixel);
  4042               long_dst = (unsigned int *) (dst_current - mask_offset * pixel);
  4043               mask = mask_current;
  4044 
  4045               /* For each pixel covered by the mask... */
  4046               temp = MIN (mask_info->width - temp, width - mask_offset);
  4047               while (temp--)
  4048                 /* XOR the source to the destination, masked by the
  4049                    mask.  */
  4050                 *long_dst-- ^= ((*(long_src--) & (0u - (*(mask--) & 1)))
  4051                                 & 0xffffff);
  4052 
  4053               /* Return to the last row.  */
  4054               src_current -= src_info->stride;
  4055               dst_current -= dst_info->stride;
  4056               mask_current -= mask_info->stride;
  4057             }
  4058         }
  4059       else
  4060         {
  4061           /* Calculate the first column of the mask that will be
  4062              consulted.  */
  4063 
  4064           mask_offset = dst_x - gc->clip_x_origin;
  4065 
  4066           /* Adjust the mask by that much.  */
  4067 
  4068           if (mask_offset > 0)
  4069             mask += mask_offset;
  4070           else
  4071             {
  4072               /* Offset src and dst by the mask offset.  */
  4073               src_current += -mask_offset * pixel;
  4074               dst_current += -mask_offset * pixel;
  4075               width -= mask_offset;
  4076             }
  4077 
  4078           /* Now move mask to the position of the first row.  */
  4079 
  4080           mask += gc->clip_y_origin * mask_info->stride;
  4081 
  4082           for (i = 0; i < height; ++i)
  4083             {
  4084               long_src = (unsigned int *) src_current;
  4085               long_dst = (unsigned int *) dst_current;
  4086               mask_current = mask;
  4087 
  4088               if (mask_offset > 0)
  4089                 {
  4090                   /* Copy bytes according to the mask.  */
  4091                   temp = MIN (mask_info->width - mask_offset, width);
  4092                   while (temp--)
  4093                     *long_dst++ ^= ((*(long_src++)
  4094                                      & (0u - (*(mask_current++) & 1)))
  4095                                     & 0xffffff);
  4096                 }
  4097               else
  4098                 {
  4099                   /* Copy bytes according to the mask.  */
  4100                   temp = MIN (mask_info->width, width);
  4101                   while (temp--)
  4102                     *long_dst++ = ((*(long_src++)
  4103                                     & (0u - (*(mask_current++) & 1)))
  4104                                    & 0xffffff);
  4105                 }
  4106 
  4107               src_current += src_info->stride;
  4108               dst_current += dst_info->stride;
  4109               mask        += mask_info->stride;
  4110             }
  4111         }
  4112     }
  4113 #endif /* 0 */
  4114 }
  4115 
  4116 void
  4117 android_copy_area (android_drawable src, android_drawable dest,
  4118                    struct android_gc *gc, int src_x, int src_y,
  4119                    unsigned int width, unsigned int height,
  4120                    int dest_x, int dest_y)
  4121 {
  4122   jobject src_object, dest_object, mask;
  4123   android_blit_func do_blit;
  4124   AndroidBitmapInfo src_info, dest_info, mask_info;
  4125   void *src_data, *dest_data, *mask_data;
  4126   int n_clip_rects, i;
  4127   bool flag;
  4128   struct android_rectangle bounds, rect, temp, *clip_rectangles;
  4129 
  4130   /* Perform the copy.  Loop over each clip rectangle, unless none are
  4131      set.  Also, obtain bitmaps for src and dst, and possibly the mask
  4132      as well if it is present.  */
  4133 
  4134   src_data = android_lock_bitmap (src, &src_info, &src_object);
  4135   if (!src_data)
  4136     return;
  4137 
  4138   mask_data = mask = NULL;
  4139 
  4140   if (src != dest)
  4141     {
  4142       dest_data = android_lock_bitmap (dest, &dest_info, &dest_object);
  4143       if (!dest_data)
  4144         goto fail;
  4145     }
  4146   else
  4147     {
  4148       dest_data = src_data;
  4149       dest_info = src_info;
  4150     }
  4151 
  4152   /* Obtain the bitmap for the mask if necessary.  */
  4153 
  4154   if (gc->clip_mask)
  4155     {
  4156       mask_data = android_lock_bitmap (gc->clip_mask,
  4157                                        &mask_info, &mask);
  4158       if (!mask_data)
  4159         goto fail1;
  4160     }
  4161 
  4162   /* Calculate the number of clip rectangles.  */
  4163   n_clip_rects = gc->num_clip_rects;
  4164 
  4165   /* If n_clip_rects is -1, then no clipping is in effect.  Set rect
  4166      to the bounds of the destination.  */
  4167 
  4168   flag = n_clip_rects == -1;
  4169   if (flag)
  4170     {
  4171       n_clip_rects = 1;
  4172       clip_rectangles = &rect;
  4173     }
  4174   else if (!n_clip_rects)
  4175     goto fail2;
  4176   else
  4177     clip_rectangles = gc->clip_rects;
  4178 
  4179   /* Set rect to the bounds of the destination.  */
  4180 
  4181   rect.x = 0;
  4182   rect.y = 0;
  4183   rect.width = dest_info.width;
  4184   rect.height = dest_info.height;
  4185 
  4186   if (mask_data)
  4187     {
  4188       /* Clip width and height to that of the mask.  */
  4189 
  4190       if (src_x + width > mask_info.width)
  4191         width = mask_info.width - src_x;
  4192 
  4193       if (src_y + height > mask_info.height)
  4194         height = mask_info.height - src_y;
  4195     }
  4196 
  4197   /* Clip width and height to that of the source.  */
  4198 
  4199   if (src_x + width > src_info.width)
  4200     width = src_info.width - src_x;
  4201 
  4202   if (src_y + height > src_info.height)
  4203     height = src_info.height - src_y;
  4204 
  4205   /* Return if the copy is outside the source.  */
  4206 
  4207   if (width <= 0 || height <= 0)
  4208     goto fail2;
  4209 
  4210   /* Look up the right function for the alu.  */
  4211 
  4212   switch (gc->function)
  4213     {
  4214     case ANDROID_GC_COPY:
  4215       do_blit = android_blit_copy;
  4216       break;
  4217 
  4218     case ANDROID_GC_XOR:
  4219       do_blit = android_blit_xor;
  4220       break;
  4221 
  4222     default:
  4223       emacs_abort ();
  4224     }
  4225 
  4226   /* Load the bounds of the destination rectangle.  */
  4227   bounds.x = dest_x;
  4228   bounds.y = dest_y;
  4229   bounds.width = width;
  4230   bounds.height = height;
  4231 
  4232   /* For each clip rectangle... */
  4233   for (i = 0; i < n_clip_rects; ++i)
  4234     {
  4235       /* Calculate its intersection with the destination
  4236          rectangle.  */
  4237 
  4238       if (!gui_intersect_rectangles (&clip_rectangles[i], &bounds,
  4239                                      &temp))
  4240         continue;
  4241 
  4242       /* And that of the destination itself.  */
  4243 
  4244       if (!flag && !gui_intersect_rectangles (&temp, &rect, &temp))
  4245         continue;
  4246 
  4247       /* Now perform the copy.  */
  4248       (*do_blit) (src_x + temp.x - dest_x,      /* temp.x relative to src_x */
  4249                   src_y + temp.y - dest_y,      /* temp.y relative to src_y */
  4250                   temp.width,                   /* Width of area to copy.  */
  4251                   temp.height,                  /* Height of area to copy.  */
  4252                   temp.x, temp.y,               /* Coordinates to copy to.  */
  4253                   gc,                           /* GC.  */
  4254                   src_data, &src_info,          /* Source drawable.  */
  4255                   dest_data, &dest_info,        /* Destination drawable.  */
  4256                   mask_data, &mask_info);       /* Mask drawable.  */
  4257     }
  4258 
  4259   /* Now damage the destination drawable accordingly, should it be a
  4260      window.  */
  4261 
  4262   if (android_handles[dest].type == ANDROID_HANDLE_WINDOW)
  4263     android_damage_window (dest, &bounds);
  4264 
  4265  fail2:
  4266   if (mask)
  4267     {
  4268       AndroidBitmap_unlockPixels (android_java_env, mask);
  4269       ANDROID_DELETE_LOCAL_REF (mask);
  4270     }
  4271  fail1:
  4272   if (src != dest)
  4273     {
  4274       AndroidBitmap_unlockPixels (android_java_env, dest_object);
  4275       ANDROID_DELETE_LOCAL_REF (dest_object);
  4276     }
  4277  fail:
  4278   AndroidBitmap_unlockPixels (android_java_env, src_object);
  4279   ANDROID_DELETE_LOCAL_REF (src_object);
  4280 }
  4281 
  4282 
  4283 
  4284 void
  4285 android_free_pixmap (android_pixmap pixmap)
  4286 {
  4287   android_destroy_handle (pixmap);
  4288 }
  4289 
  4290 void
  4291 android_set_background (struct android_gc *gc, unsigned long background)
  4292 {
  4293   struct android_gc_values gcv;
  4294 
  4295   gcv.background = background;
  4296   android_change_gc (gc, ANDROID_GC_BACKGROUND, &gcv);
  4297 }
  4298 
  4299 void
  4300 android_fill_polygon (android_drawable drawable, struct android_gc *gc,
  4301                       struct android_point *points, int npoints,
  4302                       enum android_shape shape, enum android_coord_mode mode)
  4303 {
  4304   jobjectArray array;
  4305   jobject point, drawable_object, gcontext;
  4306   int i;
  4307 
  4308   drawable_object = android_resolve_handle2 (drawable,
  4309                                              ANDROID_HANDLE_WINDOW,
  4310                                              ANDROID_HANDLE_PIXMAP);
  4311   gcontext = android_resolve_handle (gc->gcontext,
  4312                                      ANDROID_HANDLE_GCONTEXT);
  4313 
  4314   array = (*android_java_env)->NewObjectArray (android_java_env,
  4315                                                npoints,
  4316                                                point_class.class,
  4317                                                NULL);
  4318   android_exception_check ();
  4319 
  4320   for (i = 0; i < npoints; ++i)
  4321     {
  4322       point = (*android_java_env)->NewObject (android_java_env,
  4323                                               point_class.class,
  4324                                               point_class.constructor,
  4325                                               (jint) points[i].x,
  4326                                               (jint) points[i].y);
  4327       android_exception_check_1 (array);
  4328 
  4329       (*android_java_env)->SetObjectArrayElement (android_java_env,
  4330                                                   array, i, point);
  4331       ANDROID_DELETE_LOCAL_REF (point);
  4332     }
  4333 
  4334   (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
  4335                                                  emacs_service,
  4336                                                  service_class.class,
  4337                                                  service_class.fill_polygon,
  4338                                                  drawable_object,
  4339                                                  gcontext, array);
  4340   ANDROID_DELETE_LOCAL_REF (array);
  4341 }
  4342 
  4343 void
  4344 android_draw_rectangle (android_drawable handle, struct android_gc *gc,
  4345                         int x, int y, unsigned int width, unsigned int height)
  4346 {
  4347   jobject drawable, gcontext;
  4348 
  4349   drawable = android_resolve_handle2 (handle,
  4350                                       ANDROID_HANDLE_WINDOW,
  4351                                       ANDROID_HANDLE_PIXMAP);
  4352   gcontext = android_resolve_handle (gc->gcontext,
  4353                                      ANDROID_HANDLE_GCONTEXT);
  4354 
  4355   (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
  4356                                                  emacs_service,
  4357                                                  service_class.class,
  4358                                                  service_class.draw_rectangle,
  4359                                                  drawable, gcontext,
  4360                                                  (jint) x, (jint) y,
  4361                                                  (jint) width, (jint) height);
  4362 }
  4363 
  4364 void
  4365 android_draw_point (android_drawable handle, struct android_gc *gc,
  4366                     int x, int y)
  4367 {
  4368   jobject drawable, gcontext;
  4369 
  4370   drawable = android_resolve_handle2 (handle,
  4371                                       ANDROID_HANDLE_WINDOW,
  4372                                       ANDROID_HANDLE_PIXMAP);
  4373   gcontext = android_resolve_handle (gc->gcontext,
  4374                                      ANDROID_HANDLE_GCONTEXT);
  4375 
  4376   (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
  4377                                                  emacs_service,
  4378                                                  service_class.class,
  4379                                                  service_class.draw_point,
  4380                                                  drawable, gcontext,
  4381                                                  (jint) x, (jint) y);
  4382 }
  4383 
  4384 void
  4385 android_draw_line (android_drawable handle, struct android_gc *gc,
  4386                    int x, int y, int x2, int y2)
  4387 {
  4388   jobject drawable, gcontext;
  4389 
  4390   drawable = android_resolve_handle2 (handle,
  4391                                       ANDROID_HANDLE_WINDOW,
  4392                                       ANDROID_HANDLE_PIXMAP);
  4393   gcontext = android_resolve_handle (gc->gcontext,
  4394                                      ANDROID_HANDLE_GCONTEXT);
  4395 
  4396   (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
  4397                                                  emacs_service,
  4398                                                  service_class.class,
  4399                                                  service_class.draw_line,
  4400                                                  drawable, gcontext,
  4401                                                  (jint) x, (jint) y,
  4402                                                  (jint) x2, (jint) y2);
  4403 }
  4404 
  4405 android_pixmap
  4406 android_create_pixmap (unsigned int width, unsigned int height,
  4407                        int depth)
  4408 {
  4409   android_handle prev_max_handle;
  4410   jobject object;
  4411   android_pixmap pixmap;
  4412 
  4413   /* First, allocate the pixmap handle.  */
  4414   prev_max_handle = max_handle;
  4415   pixmap = android_alloc_id ();
  4416 
  4417   if (!pixmap)
  4418     error ("Out of pixmap handles!");
  4419 
  4420   object = (*android_java_env)->NewObject (android_java_env,
  4421                                            pixmap_class.class,
  4422                                            pixmap_class.constructor_mutable,
  4423                                            (jshort) pixmap,
  4424                                            (jint) width, (jint) height,
  4425                                            (jint) depth);
  4426 
  4427   if (!object)
  4428     {
  4429       (*android_java_env)->ExceptionClear (android_java_env);
  4430       max_handle = prev_max_handle;
  4431       memory_full (0);
  4432     }
  4433 
  4434   android_handles[pixmap].type = ANDROID_HANDLE_PIXMAP;
  4435   android_handles[pixmap].handle
  4436     = (*android_java_env)->NewGlobalRef (android_java_env, object);
  4437   (*android_java_env)->ExceptionClear (android_java_env);
  4438   ANDROID_DELETE_LOCAL_REF (object);
  4439 
  4440   if (!android_handles[pixmap].handle)
  4441     memory_full (0);
  4442 
  4443   return pixmap;
  4444 }
  4445 
  4446 void
  4447 android_set_ts_origin (struct android_gc *gc, int x, int y)
  4448 {
  4449   struct android_gc_values gcv;
  4450 
  4451   gcv.ts_x_origin = x;
  4452   gcv.ts_y_origin = y;
  4453   android_change_gc (gc, (ANDROID_GC_TILE_STIP_X_ORIGIN
  4454                           | ANDROID_GC_TILE_STIP_Y_ORIGIN),
  4455                      &gcv);
  4456 }
  4457 
  4458 void
  4459 android_clear_area (android_window handle, int x, int y,
  4460                     unsigned int width, unsigned int height)
  4461 {
  4462   jobject window;
  4463 
  4464   window = android_resolve_handle (handle, ANDROID_HANDLE_WINDOW);
  4465 
  4466   (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
  4467                                                  emacs_service,
  4468                                                  service_class.class,
  4469                                                  service_class.clear_area,
  4470                                                  window, (jint) x, (jint) y,
  4471                                                  (jint) width, (jint) height);
  4472 }
  4473 
  4474 android_pixmap
  4475 android_create_bitmap_from_data (char *bits, unsigned int width,
  4476                                  unsigned int height)
  4477 {
  4478   return android_create_pixmap_from_bitmap_data (bits, 1, 0,
  4479                                                  width, height, 1);
  4480 }
  4481 
  4482 struct android_image *
  4483 android_create_image (unsigned int depth, enum android_image_format format,
  4484                       char *data, unsigned int width, unsigned int height)
  4485 {
  4486   struct android_image *image;
  4487 
  4488   image = xmalloc (sizeof *image);
  4489 
  4490   /* Fill in the fields required by image.c.  N.B. that
  4491      android_destroy_image ostensibly will free data, but image.c
  4492      mostly sets and frees data itself.  */
  4493   image->width = width;
  4494   image->height = height;
  4495   image->data = data;
  4496   image->depth = depth;
  4497   image->format = format;
  4498 
  4499   /* Now fill in the image dimensions.  There are only two depths
  4500      supported by this function.  */
  4501 
  4502   if (depth == 1)
  4503     {
  4504       image->bytes_per_line = (width + 7) / 8;
  4505       image->bits_per_pixel = 1;
  4506     }
  4507   else if (depth == 24)
  4508     {
  4509       image->bytes_per_line = width * 4;
  4510       image->bits_per_pixel = 32;
  4511     }
  4512   else
  4513     emacs_abort ();
  4514 
  4515   return image;
  4516 }
  4517 
  4518 void
  4519 android_destroy_image (struct android_image *ximg)
  4520 {
  4521   /* If XIMG->data is NULL, then it has already been freed by
  4522      image.c.  */
  4523 
  4524   if (ximg->data)
  4525     xfree (ximg->data);
  4526   xfree (ximg);
  4527 }
  4528 
  4529 void
  4530 android_put_pixel (struct android_image *ximg, int x, int y,
  4531                    unsigned long pixel)
  4532 {
  4533   char *byte, *word;
  4534   unsigned int r, g, b;
  4535   unsigned int pixel_int;
  4536 
  4537   /* Ignore out-of-bounds accesses.  */
  4538 
  4539   if (x >= ximg->width || y >= ximg->height || x < 0 || y < 0)
  4540     return;
  4541 
  4542   switch (ximg->depth)
  4543     {
  4544     case 1:
  4545       byte = ximg->data + y * ximg->bytes_per_line + x / 8;
  4546 
  4547       if (pixel)
  4548         *byte |= (1 << x % 8);
  4549       else
  4550         *byte &= ~(1 << x % 8);
  4551       break;
  4552 
  4553     case 24:
  4554       /* Unaligned accesses are problematic on Android devices.  */
  4555       word = ximg->data + y * ximg->bytes_per_line + x * 4;
  4556 
  4557       /* Swizzle the pixel into ABGR format.  Android uses Skia's
  4558          ``native color type'', which is ABGR.  This is despite the
  4559          format being named ``ARGB'', and more confusingly
  4560          `ANDROID_BITMAP_FORMAT_RGBA_8888' in bitmap.h.  */
  4561       r = pixel & 0x00ff0000;
  4562       g = pixel & 0x0000ff00;
  4563       b = pixel & 0x000000ff;
  4564       pixel = (r >> 16) | g | (b << 16) | 0xff000000;
  4565 
  4566       pixel_int = pixel;
  4567       memcpy (word, &pixel_int, sizeof pixel_int);
  4568       break;
  4569     }
  4570 }
  4571 
  4572 unsigned long
  4573 android_get_pixel (struct android_image *ximg, int x, int y)
  4574 {
  4575   char *byte, *word;
  4576   unsigned int pixel, r, g, b;
  4577 
  4578   if (x >= ximg->width || y >= ximg->height
  4579       || x < 0 || y < 0)
  4580     return 0;
  4581 
  4582   switch (ximg->depth)
  4583     {
  4584     case 1:
  4585       byte = ximg->data + y * ximg->bytes_per_line + x / 8;
  4586       return (*byte & (1 << x % 8)) ? 1 : 0;
  4587 
  4588     case 24:
  4589       word = ximg->data + y * ximg->bytes_per_line + x * 4;
  4590       memcpy (&pixel, word, sizeof pixel);
  4591 
  4592       /* Convert the pixel back to RGB.  */
  4593       b = pixel & 0x00ff0000;
  4594       g = pixel & 0x0000ff00;
  4595       r = pixel & 0x000000ff;
  4596       pixel = ((r << 16) | g | (b >> 16)) & ~0xff000000;
  4597 
  4598       return pixel;
  4599     }
  4600 
  4601   emacs_abort ();
  4602 }
  4603 
  4604 struct android_image *
  4605 android_get_image (android_drawable handle,
  4606                    enum android_image_format format)
  4607 {
  4608   jobject drawable, bitmap;
  4609   AndroidBitmapInfo bitmap_info;
  4610   size_t byte_size;
  4611   void *data;
  4612   struct android_image *image;
  4613   unsigned char *data1, *data2;
  4614   int i, x;
  4615 
  4616   drawable = android_resolve_handle2 (handle, ANDROID_HANDLE_WINDOW,
  4617                                       ANDROID_HANDLE_PIXMAP);
  4618 
  4619   /* Look up the drawable and get the bitmap corresponding to it.
  4620      Then, lock the bitmap's bits.  */
  4621   bitmap = (*android_java_env)->CallObjectMethod (android_java_env,
  4622                                                   drawable,
  4623                                                   drawable_class.get_bitmap);
  4624   android_exception_check ();
  4625 
  4626   /* Clear the bitmap info structure.  */
  4627   memset (&bitmap_info, 0, sizeof bitmap_info);
  4628 
  4629   /* The NDK doc seems to imply this function can fail but doesn't say
  4630      what value it gives when it does! */
  4631   AndroidBitmap_getInfo (android_java_env, bitmap, &bitmap_info);
  4632 
  4633   if (!bitmap_info.stride)
  4634     {
  4635       ANDROID_DELETE_LOCAL_REF (bitmap);
  4636       memory_full (0);
  4637     }
  4638 
  4639   /* Compute how big the image data will be.  Fail if it would be too
  4640      big.  */
  4641 
  4642   if (bitmap_info.format != ANDROID_BITMAP_FORMAT_A_8)
  4643     {
  4644       if (INT_MULTIPLY_WRAPV ((size_t) bitmap_info.stride,
  4645                               (size_t) bitmap_info.height,
  4646                               &byte_size))
  4647         {
  4648           ANDROID_DELETE_LOCAL_REF (bitmap);
  4649           memory_full (0);
  4650         }
  4651     }
  4652   else
  4653     /* This A8 image will be packed into A1 later on.  */
  4654     byte_size = (bitmap_info.width + 7) / 8;
  4655 
  4656   /* Lock the image data.  Once again, the NDK documentation says the
  4657      call can fail, but does not say how to determine whether or not
  4658      it has failed, nor how the address is aligned.  */
  4659   data = NULL;
  4660   AndroidBitmap_lockPixels (android_java_env, bitmap, &data);
  4661 
  4662   if (!data)
  4663     {
  4664       /* Take a NULL pointer to mean that AndroidBitmap_lockPixels
  4665          failed.  */
  4666       ANDROID_DELETE_LOCAL_REF (bitmap);
  4667       memory_full (0);
  4668     }
  4669 
  4670   /* Copy the data into a new struct android_image.  */
  4671   image = xmalloc (sizeof *image);
  4672   image->width = bitmap_info.width;
  4673   image->height = bitmap_info.height;
  4674   image->data = malloc (byte_size);
  4675 
  4676   if (!image->data)
  4677     {
  4678       ANDROID_DELETE_LOCAL_REF (bitmap);
  4679       xfree (image);
  4680       memory_full (byte_size);
  4681     }
  4682 
  4683   /* Use the format of the bitmap to determine the image depth.  */
  4684   switch (bitmap_info.format)
  4685     {
  4686     case ANDROID_BITMAP_FORMAT_RGBA_8888:
  4687       image->depth = 24;
  4688       image->bits_per_pixel = 32;
  4689       break;
  4690 
  4691       /* A8 images are used by Emacs to represent bitmaps.  They have
  4692          to be packed manually.  */
  4693     case ANDROID_BITMAP_FORMAT_A_8:
  4694       image->depth = 1;
  4695       image->bits_per_pixel = 1;
  4696       break;
  4697 
  4698       /* Other formats are currently not supported.  */
  4699     default:
  4700       emacs_abort ();
  4701     }
  4702 
  4703   image->format = format;
  4704 
  4705   if (image->depth == 24)
  4706     {
  4707       image->bytes_per_line = bitmap_info.stride;
  4708 
  4709       /* Copy the bitmap data over.  */
  4710       memcpy (image->data, data, byte_size);
  4711     }
  4712   else
  4713     {
  4714       /* Pack the A8 image data into bits manually.  */
  4715       image->bytes_per_line = (image->width + 7) / 8;
  4716 
  4717       data1 = (unsigned char *) image->data;
  4718       data2 = data;
  4719 
  4720       for (i = 0; i < image->height; ++i)
  4721         {
  4722           for (x = 0; x < image->width; ++x)
  4723             /* Some bits in data1 might be initialized at this point,
  4724                but they will all be set properly later.  */
  4725             data1[x / 8] = (data2[x]
  4726                             ? (data1[x / 8] | (1 << (x % 8)))
  4727                             : (data1[x / 8] & ~(1 << (x % 8))));
  4728 
  4729           data1 += image->bytes_per_line;
  4730           data2 += bitmap_info.stride;
  4731         }
  4732     }
  4733 
  4734   /* Unlock the bitmap pixels.  */
  4735   AndroidBitmap_unlockPixels (android_java_env, bitmap);
  4736 
  4737   /* Delete the bitmap reference.  */
  4738   ANDROID_DELETE_LOCAL_REF (bitmap);
  4739   return image;
  4740 }
  4741 
  4742 void
  4743 android_put_image (android_pixmap handle, struct android_image *image)
  4744 {
  4745   jobject drawable, bitmap;
  4746   AndroidBitmapInfo bitmap_info;
  4747   void *data;
  4748   unsigned char *data_1, *data_2;
  4749   int i, x;
  4750 
  4751   drawable = android_resolve_handle (handle, ANDROID_HANDLE_PIXMAP);
  4752 
  4753   /* Look up the drawable and get the bitmap corresponding to it.
  4754      Then, lock the bitmap's bits.  */
  4755   bitmap = (*android_java_env)->CallObjectMethod (android_java_env,
  4756                                                   drawable,
  4757                                                   drawable_class.get_bitmap);
  4758   android_exception_check ();
  4759 
  4760   /* Clear the bitmap info structure.  */
  4761   memset (&bitmap_info, 0, sizeof bitmap_info);
  4762 
  4763   /* The NDK doc seems to imply this function can fail but doesn't say
  4764      what value it gives when it does! */
  4765   AndroidBitmap_getInfo (android_java_env, bitmap, &bitmap_info);
  4766 
  4767   if (!bitmap_info.stride)
  4768     {
  4769       ANDROID_DELETE_LOCAL_REF (bitmap);
  4770       memory_full (0);
  4771     }
  4772 
  4773   if (bitmap_info.width != image->width
  4774       || bitmap_info.height != image->height)
  4775     /* This is not yet supported.  */
  4776     emacs_abort ();
  4777 
  4778   /* Make sure the bitmap formats are compatible with each other.  */
  4779 
  4780   if ((image->depth == 24
  4781        && bitmap_info.format != ANDROID_BITMAP_FORMAT_RGBA_8888)
  4782       || (image->depth == 1
  4783           && bitmap_info.format != ANDROID_BITMAP_FORMAT_A_8))
  4784     emacs_abort ();
  4785 
  4786   /* Lock the image data.  Once again, the NDK documentation says the
  4787      call can fail, but does not say how to determine whether or not
  4788      it has failed, nor how the address is aligned.  */
  4789   data = NULL;
  4790   AndroidBitmap_lockPixels (android_java_env, bitmap, &data);
  4791 
  4792   if (!data)
  4793     {
  4794       /* Take a NULL pointer to mean that AndroidBitmap_lockPixels
  4795          failed.  */
  4796       ANDROID_DELETE_LOCAL_REF (bitmap);
  4797       memory_full (0);
  4798     }
  4799 
  4800   data_1 = data;
  4801   data_2 = (unsigned char *) image->data;
  4802 
  4803   /* Copy the bitmap data over scanline-by-scanline.  */
  4804   for (i = 0; i < image->height; ++i)
  4805     {
  4806       if (image->depth != 1)
  4807         memcpy (data_1, data_2,
  4808                 image->width * (image->bits_per_pixel / 8));
  4809       else
  4810         {
  4811           /* Android internally uses a 1 byte-per-pixel format for
  4812              ALPHA_8 images.  Expand the image from the 1
  4813              bit-per-pixel X format correctly.  */
  4814 
  4815           for (x = 0; x < image->width; ++x)
  4816             data_1[x] = (data_2[x / 8] & (1 << x % 8)) ? 0xff : 0;
  4817         }
  4818 
  4819       data_1 += bitmap_info.stride;
  4820       data_2 += image->bytes_per_line;
  4821     }
  4822 
  4823   /* Unlock the bitmap pixels.  */
  4824   AndroidBitmap_unlockPixels (android_java_env, bitmap);
  4825 
  4826   /* Delete the bitmap reference.  */
  4827   ANDROID_DELETE_LOCAL_REF (bitmap);
  4828 }
  4829 
  4830 void
  4831 android_bell (void)
  4832 {
  4833   (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
  4834                                                  emacs_service,
  4835                                                  service_class.class,
  4836                                                  service_class.ring_bell);
  4837   android_exception_check ();
  4838 }
  4839 
  4840 void
  4841 android_set_input_focus (android_window handle, unsigned long time)
  4842 {
  4843   jobject window;
  4844   jmethodID make_input_focus;
  4845 
  4846   window = android_resolve_handle (handle, ANDROID_HANDLE_WINDOW);
  4847   make_input_focus = window_class.make_input_focus;
  4848 
  4849   (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
  4850                                                  window,
  4851                                                  window_class.class,
  4852                                                  make_input_focus,
  4853                                                  (jlong) time);
  4854   android_exception_check ();
  4855 }
  4856 
  4857 void
  4858 android_raise_window (android_window handle)
  4859 {
  4860   jobject window;
  4861   jmethodID raise;
  4862 
  4863   window = android_resolve_handle (handle, ANDROID_HANDLE_WINDOW);
  4864   raise = window_class.raise;
  4865 
  4866   (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
  4867                                                  window,
  4868                                                  window_class.class,
  4869                                                  raise);
  4870   android_exception_check ();
  4871 }
  4872 
  4873 void
  4874 android_lower_window (android_window handle)
  4875 {
  4876   jobject window;
  4877   jmethodID lower;
  4878 
  4879   window = android_resolve_handle (handle, ANDROID_HANDLE_WINDOW);
  4880   lower = window_class.lower;
  4881 
  4882   (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
  4883                                                  window,
  4884                                                  window_class.class,
  4885                                                  lower);
  4886   android_exception_check ();
  4887 }
  4888 
  4889 int
  4890 android_query_tree (android_window handle, android_window *root_return,
  4891                     android_window *parent_return,
  4892                     android_window **children_return,
  4893                     unsigned int *nchildren_return)
  4894 {
  4895   jobject window, array;
  4896   jsize nelements, i;
  4897   android_window *children;
  4898   jshort *shorts;
  4899 
  4900   window = android_resolve_handle (handle, ANDROID_HANDLE_WINDOW);
  4901 
  4902   /* window can be NULL, so this is a service method.  */
  4903   array
  4904     = (*android_java_env)->CallObjectMethod (android_java_env,
  4905                                              emacs_service,
  4906                                              service_class.query_tree,
  4907                                              window);
  4908   android_exception_check ();
  4909 
  4910   /* The first element of the array is the parent window.  The rest
  4911      are the children.  */
  4912   nelements = (*android_java_env)->GetArrayLength (android_java_env,
  4913                                                    array);
  4914   eassert (nelements);
  4915 
  4916   /* Now fill in the children.  */
  4917   children = xnmalloc (nelements - 1, sizeof *children);
  4918 
  4919   shorts
  4920     = (*android_java_env)->GetShortArrayElements (android_java_env, array,
  4921                                                   NULL);
  4922   android_exception_check_nonnull (shorts, array);
  4923 
  4924   for (i = 1; i < nelements; ++i)
  4925     /* Subtract one from the index into children, since the parent is
  4926        not included.  */
  4927     children[i - 1] = shorts[i];
  4928 
  4929   /* Finally, return the parent and other values.  */
  4930   *root_return = 0;
  4931   *parent_return = shorts[0];
  4932   *children_return = children;
  4933   *nchildren_return = nelements - 1;
  4934 
  4935   /* Release the array contents.  */
  4936   (*android_java_env)->ReleaseShortArrayElements (android_java_env, array,
  4937                                                   shorts, JNI_ABORT);
  4938 
  4939   ANDROID_DELETE_LOCAL_REF (array);
  4940   return 1;
  4941 }
  4942 
  4943 void
  4944 android_get_geometry (android_window handle,
  4945                       android_window *root_return,
  4946                       int *x_return, int *y_return,
  4947                       unsigned int *width_return,
  4948                       unsigned int *height_return,
  4949                       unsigned int *border_width_return)
  4950 {
  4951   jobject window;
  4952   jarray window_geometry;
  4953   jmethodID get_geometry;
  4954   jint *ints;
  4955 
  4956   window = android_resolve_handle (handle, ANDROID_HANDLE_WINDOW);
  4957   get_geometry = window_class.get_window_geometry;
  4958 
  4959   window_geometry
  4960     = (*android_java_env)->CallObjectMethod (android_java_env,
  4961                                              window,
  4962                                              get_geometry);
  4963   android_exception_check ();
  4964 
  4965   /* window_geometry is an array containing x, y, width and
  4966      height.  border_width is always 0 on Android.  */
  4967   eassert ((*android_java_env)->GetArrayLength (android_java_env,
  4968                                                 window_geometry)
  4969            == 4);
  4970 
  4971   *root_return = 0;
  4972   *border_width_return = 0;
  4973 
  4974   ints
  4975     = (*android_java_env)->GetIntArrayElements (android_java_env,
  4976                                                 window_geometry,
  4977                                                 NULL);
  4978   android_exception_check_nonnull (ints, window_geometry);
  4979 
  4980   *x_return = ints[0];
  4981   *y_return = ints[1];
  4982   *width_return = ints[2];
  4983   *height_return = ints[3];
  4984 
  4985   (*android_java_env)->ReleaseIntArrayElements (android_java_env,
  4986                                                 window_geometry,
  4987                                                 ints, JNI_ABORT);
  4988 
  4989   /* Now free the local reference.  */
  4990   ANDROID_DELETE_LOCAL_REF (window_geometry);
  4991 }
  4992 
  4993 void
  4994 android_move_resize_window (android_window window, int x, int y,
  4995                             unsigned int width, unsigned int height)
  4996 {
  4997   android_move_window (window, x, y);
  4998   android_resize_window (window, width, height);
  4999 }
  5000 
  5001 void
  5002 android_map_raised (android_window window)
  5003 {
  5004   android_raise_window (window);
  5005   android_map_window (window);
  5006 }
  5007 
  5008 void
  5009 android_translate_coordinates (android_window src, int x,
  5010                                int y, int *root_x, int *root_y)
  5011 {
  5012   jobject window;
  5013   jarray coordinates;
  5014   jmethodID method;
  5015   jint *ints;
  5016 
  5017   window = android_resolve_handle (src, ANDROID_HANDLE_WINDOW);
  5018   method = window_class.translate_coordinates;
  5019   coordinates
  5020     = (*android_java_env)->CallObjectMethod (android_java_env,
  5021                                              window, method,
  5022                                              (jint) x, (jint) y);
  5023   android_exception_check ();
  5024 
  5025   /* The array must contain two elements: X, Y translated to the root
  5026      window.  */
  5027   eassert ((*android_java_env)->GetArrayLength (android_java_env,
  5028                                                 coordinates)
  5029            == 2);
  5030 
  5031   /* Obtain the coordinates from the array.  */
  5032   ints = (*android_java_env)->GetIntArrayElements (android_java_env,
  5033                                                    coordinates, NULL);
  5034   android_exception_check_nonnull (ints, coordinates);
  5035 
  5036   *root_x = ints[0];
  5037   *root_y = ints[1];
  5038 
  5039   /* Release the coordinates.  */
  5040   (*android_java_env)->ReleaseIntArrayElements (android_java_env,
  5041                                                 coordinates, ints,
  5042                                                 JNI_ABORT);
  5043 
  5044   /* And free the local reference.  */
  5045   ANDROID_DELETE_LOCAL_REF (coordinates);
  5046 }
  5047 
  5048 int
  5049 android_wc_lookup_string (android_key_pressed_event *event,
  5050                           wchar_t *buffer_return, int wchars_buffer,
  5051                           int *keysym_return,
  5052                           enum android_lookup_status *status_return)
  5053 {
  5054   enum android_lookup_status status;
  5055   int rc;
  5056   jobject window, string;
  5057   const jchar *characters;
  5058   jsize size;
  5059   size_t i;
  5060 
  5061   status = ANDROID_LOOKUP_NONE;
  5062   rc = 0;
  5063 
  5064   /* See if an actual lookup has to be made.  Note that while
  5065      BUFFER_RETURN is wchar_t, the returned characters are always in
  5066      UCS.  */
  5067 
  5068   if (event->unicode_char != (uint32_t) -1)
  5069     {
  5070       if (event->unicode_char)
  5071         {
  5072           if (wchars_buffer < 1)
  5073             {
  5074               *status_return = ANDROID_BUFFER_OVERFLOW;
  5075               return 0;
  5076             }
  5077           else
  5078             {
  5079               buffer_return[0] = event->unicode_char;
  5080               status = ANDROID_LOOKUP_CHARS;
  5081               rc = 1;
  5082             }
  5083         }
  5084 
  5085       *keysym_return = event->keycode;
  5086 
  5087       if (status == ANDROID_LOOKUP_CHARS)
  5088         status = ANDROID_LOOKUP_BOTH;
  5089       else
  5090         {
  5091           status = ANDROID_LOOKUP_KEYSYM;
  5092           rc = 0;
  5093         }
  5094 
  5095       *status_return = status;
  5096 
  5097       return rc;
  5098     }
  5099 
  5100   /* Now look up the window.  */
  5101   rc = 0;
  5102 
  5103   if (!android_handles[event->window].handle
  5104       || (android_handles[event->window].type
  5105           != ANDROID_HANDLE_WINDOW))
  5106     status = ANDROID_LOOKUP_NONE;
  5107   else
  5108     {
  5109       window = android_handles[event->window].handle;
  5110       string
  5111         = (*android_java_env)->CallObjectMethod (android_java_env, window,
  5112                                                  window_class.lookup_string,
  5113                                                  (jint) event->serial);
  5114       android_exception_check ();
  5115 
  5116       if (!string)
  5117         status = ANDROID_LOOKUP_NONE;
  5118       else
  5119         {
  5120           /* Now return this input method string.  */
  5121           characters = (*android_java_env)->GetStringChars (android_java_env,
  5122                                                             string, NULL);
  5123           android_exception_check_nonnull ((void *) characters, string);
  5124 
  5125           /* Figure out how big the string is.  */
  5126           size = (*android_java_env)->GetStringLength (android_java_env,
  5127                                                        string);
  5128 
  5129           /* Copy over the string data.  */
  5130           for (i = 0; i < MIN ((unsigned int) wchars_buffer, size); ++i)
  5131             buffer_return[i] = characters[i];
  5132 
  5133           if (i < size)
  5134             status = ANDROID_BUFFER_OVERFLOW;
  5135           else
  5136             status = ANDROID_LOOKUP_CHARS;
  5137 
  5138           /* Return the number of characters that should have been
  5139              written.  */
  5140 
  5141           if (size > INT_MAX)
  5142             rc = INT_MAX;
  5143           else
  5144             rc = size;
  5145 
  5146           (*android_java_env)->ReleaseStringChars (android_java_env, string,
  5147                                                    characters);
  5148           ANDROID_DELETE_LOCAL_REF (string);
  5149         }
  5150     }
  5151 
  5152   *status_return = status;
  5153   return rc;
  5154 }
  5155 
  5156 
  5157 
  5158 /* Low level drawing primitives.  */
  5159 
  5160 /* Lock the bitmap corresponding to the drawable DRAWABLE.  Return the
  5161    bitmap data upon success, and store the bitmap object in
  5162    BITMAP_RETURN.  Value is NULL upon failure.
  5163 
  5164    The caller must take care to unlock the bitmap data afterwards.  */
  5165 
  5166 unsigned char *
  5167 android_lock_bitmap (android_window drawable,
  5168                      AndroidBitmapInfo *bitmap_info,
  5169                      jobject *bitmap_return)
  5170 {
  5171   jobject object, bitmap;
  5172   void *data;
  5173 
  5174   object = android_resolve_handle2 (drawable, ANDROID_HANDLE_WINDOW,
  5175                                     ANDROID_HANDLE_PIXMAP);
  5176 
  5177   /* Look up the drawable and get the bitmap corresponding to it.
  5178      Then, lock the bitmap's bits.  */
  5179   bitmap = (*android_java_env)->CallObjectMethod (android_java_env,
  5180                                                   object,
  5181                                                   drawable_class.get_bitmap);
  5182   if (!bitmap)
  5183     /* NULL is returned when the bitmap does not currently exist due
  5184        to ongoing reconfiguration on the main thread.  */
  5185     return NULL;
  5186 
  5187   memset (bitmap_info, 0, sizeof *bitmap_info);
  5188 
  5189   /* Get the bitmap info.  */
  5190   AndroidBitmap_getInfo (android_java_env, bitmap, bitmap_info);
  5191 
  5192   if (!bitmap_info->stride)
  5193     {
  5194       ANDROID_DELETE_LOCAL_REF (bitmap);
  5195       return NULL;
  5196     }
  5197 
  5198   /* Now lock the image data.  */
  5199   data = NULL;
  5200   AndroidBitmap_lockPixels (android_java_env, bitmap, &data);
  5201 
  5202   if (!data)
  5203     {
  5204       ANDROID_DELETE_LOCAL_REF (bitmap);
  5205       return NULL;
  5206     }
  5207 
  5208   /* Give the bitmap to the caller.  */
  5209   *bitmap_return = bitmap;
  5210 
  5211   /* The bitmap data is now locked.  */
  5212   return data;
  5213 }
  5214 
  5215 /* Damage the window HANDLE by the given damage rectangle.  */
  5216 
  5217 void
  5218 android_damage_window (android_drawable handle,
  5219                        struct android_rectangle *damage)
  5220 {
  5221   jobject drawable, rect;
  5222 
  5223   drawable = android_resolve_handle (handle, ANDROID_HANDLE_WINDOW);
  5224 
  5225   /* Now turn DAMAGE into a Java rectangle.  */
  5226   rect = (*android_java_env)->NewObject (android_java_env,
  5227                                          android_rect_class,
  5228                                          android_rect_constructor,
  5229                                          (jint) damage->x,
  5230                                          (jint) damage->y,
  5231                                          (jint) (damage->x
  5232                                                  + damage->width),
  5233                                          (jint) (damage->y
  5234                                                  + damage->height));
  5235   android_exception_check ();
  5236 
  5237   /* Post the damage to the drawable.  */
  5238   (*android_java_env)->CallVoidMethod (android_java_env,
  5239                                        drawable,
  5240                                        drawable_class.damage_rect,
  5241                                        rect);
  5242   android_exception_check_1 (rect);
  5243   ANDROID_DELETE_LOCAL_REF (rect);
  5244 }
  5245 
  5246 
  5247 
  5248 /* Other misc system routines.  */
  5249 
  5250 int
  5251 android_get_screen_width (void)
  5252 {
  5253   int rc;
  5254   jmethodID method;
  5255 
  5256   method = service_class.get_screen_width;
  5257   rc = (*android_java_env)->CallNonvirtualIntMethod (android_java_env,
  5258                                                      emacs_service,
  5259                                                      service_class.class,
  5260                                                      method,
  5261                                                      (jboolean) false);
  5262   android_exception_check ();
  5263   return rc;
  5264 }
  5265 
  5266 int
  5267 android_get_screen_height (void)
  5268 {
  5269   int rc;
  5270   jmethodID method;
  5271 
  5272   method = service_class.get_screen_height;
  5273   rc = (*android_java_env)->CallNonvirtualIntMethod (android_java_env,
  5274                                                      emacs_service,
  5275                                                      service_class.class,
  5276                                                      method,
  5277                                                      (jboolean) false);
  5278   android_exception_check ();
  5279   return rc;
  5280 }
  5281 
  5282 int
  5283 android_get_mm_width (void)
  5284 {
  5285   int rc;
  5286   jmethodID method;
  5287 
  5288   method = service_class.get_screen_width;
  5289   rc = (*android_java_env)->CallNonvirtualIntMethod (android_java_env,
  5290                                                      emacs_service,
  5291                                                      service_class.class,
  5292                                                      method,
  5293                                                      (jboolean) true);
  5294   android_exception_check ();
  5295   return rc;
  5296 }
  5297 
  5298 int
  5299 android_get_mm_height (void)
  5300 {
  5301   int rc;
  5302   jmethodID method;
  5303 
  5304   method = service_class.get_screen_height;
  5305   rc = (*android_java_env)->CallNonvirtualIntMethod (android_java_env,
  5306                                                      emacs_service,
  5307                                                      service_class.class,
  5308                                                      method,
  5309                                                      (jboolean) true);
  5310   android_exception_check ();
  5311   return rc;
  5312 }
  5313 
  5314 bool
  5315 android_detect_mouse (void)
  5316 {
  5317   bool rc;
  5318   jmethodID method;
  5319 
  5320   method = service_class.detect_mouse;
  5321   rc = (*android_java_env)->CallNonvirtualBooleanMethod (android_java_env,
  5322                                                          emacs_service,
  5323                                                          service_class.class,
  5324                                                          method);
  5325   android_exception_check ();
  5326   return rc;
  5327 }
  5328 
  5329 void
  5330 android_set_dont_focus_on_map (android_window handle,
  5331                                bool no_focus_on_map)
  5332 {
  5333   jmethodID method;
  5334   jobject window;
  5335 
  5336   window = android_resolve_handle (handle, ANDROID_HANDLE_WINDOW);
  5337   method = window_class.set_dont_focus_on_map;
  5338 
  5339   (*android_java_env)->CallNonvirtualVoidMethod (android_java_env, window,
  5340                                                  window_class.class,
  5341                                                  method,
  5342                                                  (jboolean) no_focus_on_map);
  5343   android_exception_check ();
  5344 }
  5345 
  5346 void
  5347 android_set_dont_accept_focus (android_window handle,
  5348                                bool no_accept_focus)
  5349 {
  5350   jmethodID method;
  5351   jobject window;
  5352 
  5353   window = android_resolve_handle (handle, ANDROID_HANDLE_WINDOW);
  5354   method = window_class.set_dont_accept_focus;
  5355 
  5356   (*android_java_env)->CallNonvirtualVoidMethod (android_java_env, window,
  5357                                                  window_class.class,
  5358                                                  method,
  5359                                                  (jboolean) no_accept_focus);
  5360   android_exception_check ();
  5361 }
  5362 
  5363 void
  5364 android_get_keysym_name (int keysym, char *name_return, size_t size)
  5365 {
  5366   jobject string;
  5367   const char *buffer;
  5368 
  5369   string = (*android_java_env)->CallObjectMethod (android_java_env,
  5370                                                   emacs_service,
  5371                                                   service_class.name_keysym,
  5372                                                   (jint) keysym);
  5373   android_exception_check ();
  5374 
  5375   buffer = (*android_java_env)->GetStringUTFChars (android_java_env,
  5376                                                    (jstring) string,
  5377                                                    NULL);
  5378   android_exception_check_nonnull ((void *) buffer, string);
  5379   strncpy (name_return, buffer, size - 1);
  5380   name_return[size] = '\0';
  5381 
  5382   (*android_java_env)->ReleaseStringUTFChars (android_java_env,
  5383                                               (jstring) string,
  5384                                               buffer);
  5385   ANDROID_DELETE_LOCAL_REF (string);
  5386 }
  5387 
  5388 /* Display the on screen keyboard on window WINDOW, or hide it if SHOW
  5389    is false.  Ask the system to bring up or hide the on-screen
  5390    keyboard on behalf of WINDOW.  The request may be rejected by the
  5391    system, especially when the window does not have the input
  5392    focus.  */
  5393 
  5394 void
  5395 android_toggle_on_screen_keyboard (android_window window, bool show)
  5396 {
  5397   jobject object;
  5398   jmethodID method;
  5399 
  5400   object = android_resolve_handle (window, ANDROID_HANDLE_WINDOW);
  5401   method = window_class.toggle_on_screen_keyboard;
  5402 
  5403   /* Now display the on screen keyboard.  */
  5404   (*android_java_env)->CallNonvirtualVoidMethod (android_java_env, object,
  5405                                                  window_class.class,
  5406                                                  method, (jboolean) show);
  5407 
  5408   /* Check for out of memory errors.  */
  5409   android_exception_check ();
  5410 }
  5411 
  5412 
  5413 
  5414 /* emacs_abort implementation for Android.  This logs a stack
  5415    trace.  */
  5416 
  5417 void
  5418 emacs_abort (void)
  5419 {
  5420   volatile char *foo;
  5421 
  5422   __android_log_print (ANDROID_LOG_FATAL, __func__,
  5423                        "emacs_abort called, please review the ensuing"
  5424                        " stack trace");
  5425 
  5426   /* Cause a NULL pointer dereference to make debuggerd generate a
  5427      tombstone.  */
  5428   foo = NULL;
  5429   *foo = '\0';
  5430 
  5431   abort ();
  5432 }
  5433 
  5434 
  5435 
  5436 /* Return whether or not TEXT, a string without multibyte
  5437    characters, has no bytes with the 8th bit set.  */
  5438 
  5439 static bool
  5440 android_check_string (Lisp_Object text)
  5441 {
  5442   ptrdiff_t i;
  5443 
  5444   for (i = 0; i < SBYTES (text); ++i)
  5445     {
  5446       if (SREF (text, i) & 128)
  5447         return false;
  5448     }
  5449 
  5450   return true;
  5451 }
  5452 
  5453 /* Verify that the specified NULL-terminated STRING is a valid JNI
  5454    ``UTF-8'' string.  Return 0 if so, 1 otherwise.
  5455 
  5456    Do not perform GC, enabling NAME to be a direct reference to string
  5457    data.
  5458 
  5459    The native coding system used by the JVM to store strings derives
  5460    from UTF-8, but deviates from it in two aspects in an attempt to
  5461    better represent the UCS-16 based Java String format, and to let
  5462    strings contain NULL characters while remaining valid C strings:
  5463    NULL bytes are encoded as two-byte sequences, and Unicode surrogate
  5464    pairs encoded as two-byte sequences are prefered to four-byte
  5465    sequences when encoding characters above the BMP.  */
  5466 
  5467 int
  5468 android_verify_jni_string (const char *name)
  5469 {
  5470   const unsigned char *chars;
  5471 
  5472   chars = (unsigned char *) name;
  5473   while (*chars)
  5474     {
  5475       /* Switch on the high 4 bits.  */
  5476 
  5477       switch (*chars++ >> 4)
  5478         {
  5479         case 0 ... 7:
  5480           /* The 8th bit is clean, so this is a regular C
  5481              character.  */
  5482           break;
  5483 
  5484         case 8 ... 0xb:
  5485           /* Invalid starting byte! */
  5486           return 1;
  5487 
  5488         case 0xf:
  5489           /* The start of a four byte sequence.  These aren't allowed
  5490              in Java.  */
  5491           return 1;
  5492 
  5493         case 0xe:
  5494           /* The start of a three byte sequence.  Verify that its
  5495              continued.  */
  5496 
  5497           if ((*chars++ & 0xc0) != 0x80)
  5498             return 1;
  5499 
  5500           FALLTHROUGH;
  5501 
  5502         case 0xc ... 0xd:
  5503           /* The start of a two byte sequence.  Verify that the
  5504              next byte exists and has its high bit set.  */
  5505 
  5506           if ((*chars++ & 0xc0) != 0x80)
  5507             return 1;
  5508 
  5509           break;
  5510         }
  5511     }
  5512 
  5513   return 0;
  5514 }
  5515 
  5516 /* Given a Lisp string TEXT, return a local reference to an equivalent
  5517    Java string.  */
  5518 
  5519 jstring
  5520 android_build_string (Lisp_Object text)
  5521 {
  5522   Lisp_Object encoded;
  5523   jstring string;
  5524   size_t nchars;
  5525   jchar *characters;
  5526   USE_SAFE_ALLOCA;
  5527 
  5528   /* Directly encode TEXT if it contains no non-ASCII characters, or
  5529      is multibyte and a valid Modified UTF-8 string.  This is okay
  5530      because the Java extended UTF format is compatible with
  5531      ASCII.  */
  5532 
  5533   if ((SBYTES (text) == SCHARS (text)
  5534        && android_check_string (text))
  5535       /* If TEXT is a multibyte string, then it's using Emacs's
  5536          internal UTF-8 coding system, a significant subset of which
  5537          is compatible with JNI.  */
  5538       || (STRING_MULTIBYTE (text)
  5539           && !android_verify_jni_string (SSDATA (text))))
  5540     {
  5541       string = (*android_java_env)->NewStringUTF (android_java_env,
  5542                                                   SSDATA (text));
  5543       android_exception_check ();
  5544       SAFE_FREE ();
  5545 
  5546       return string;
  5547     }
  5548 
  5549   encoded = code_convert_string_norecord (text, Qutf_16le,
  5550                                           true);
  5551   nchars = (SBYTES (encoded) / sizeof (jchar));
  5552 
  5553   /* Encode the string as UTF-16 prior to creating the string.
  5554      Copy the string to a separate buffer in order to preserve
  5555      alignment.  */
  5556 
  5557   characters = SAFE_ALLOCA (SBYTES (encoded));
  5558   memcpy (characters, SDATA (encoded), SBYTES (encoded));
  5559 
  5560   /* Create the string.  */
  5561   string
  5562     = (*android_java_env)->NewString (android_java_env,
  5563                                       characters, nchars);
  5564   android_exception_check ();
  5565 
  5566   SAFE_FREE ();
  5567   return string;
  5568 }
  5569 
  5570 /* Do the same, except TEXT is constant string data in ASCII or
  5571    UTF-8 containing no characters outside the Basic Multilingual
  5572    Plane.  */
  5573 
  5574 jstring
  5575 android_build_jstring (const char *text)
  5576 {
  5577   jstring string;
  5578 
  5579   /* Note that Java expects this string to be in ``modified UTF
  5580      encoding'', which is actually UTF-8, except with NUL
  5581      encoded as a two-byte sequence, and surrogate pairs encoded
  5582      in the three-byte extended encoding.  The only consequence
  5583      of passing an actual UTF-8 string is that NUL bytes and
  5584      characters requiring surrogate pairs cannot be represented,
  5585      which is not really of consequence.  */
  5586 
  5587   string = (*android_java_env)->NewStringUTF (android_java_env,
  5588                                               text);
  5589   android_exception_check ();
  5590 
  5591   return string;
  5592 }
  5593 
  5594 
  5595 
  5596 /* Exception checking functions.  Most JNI functions which allocate
  5597    memory return NULL upon failure; they also set the JNI
  5598    environment's pending exception to an OutOfMemoryError.
  5599 
  5600    These functions check for such errors and call memory_full wherever
  5601    appropriate.  Three variants are provided: one which releases no
  5602    local references, one which releases a single local reference
  5603    before calling memory_full, and one which releases two local
  5604    references.
  5605 
  5606    Typically, you use these functions by calling them immediately
  5607    after a JNI function which allocates memory, passing it any local
  5608    references that are already valid but should be deleted after
  5609    leaving the current scope.  For example, to allocate foo, make
  5610    global_foo its global reference, and then release foo, you write:
  5611 
  5612      jobject foo, global_foo;
  5613 
  5614      foo = (*android_java_env)->New...;
  5615      android_exception_check ();
  5616 
  5617      global_foo = (*android_java_env)->NewGlobalRef (..., foo);
  5618      android_exception_check_1 (foo);
  5619      ANDROID_DELETE_LOCAL_REF (foo);
  5620 
  5621    where the first android_exception_check ensures that foo has been
  5622    allocated correctly, while the call to android_exception_check_1,
  5623    and the call to ANDROID_DELETE_LOCAL_REF afterwards, together
  5624    ensure the same of global_foo, and also that foo is released both
  5625    if global_foo cannot be allocated, and after the global reference
  5626    is created.  */
  5627 
  5628 #if __GNUC__ >= 3
  5629 #define likely(cond)    __builtin_expect ((cond), 1)
  5630 #else /* __GNUC__ < 3 */
  5631 #define likely(cond)    (cond)
  5632 #endif /* __GNUC__ >= 3 */
  5633 
  5634 /* Check for JNI exceptions and call memory_full in that
  5635    situation.  */
  5636 
  5637 void
  5638 android_exception_check (void)
  5639 {
  5640   if (likely (!(*android_java_env)->ExceptionCheck (android_java_env)))
  5641     return;
  5642 
  5643   __android_log_print (ANDROID_LOG_WARN, __func__,
  5644                        "Possible out of memory error. "
  5645                        " The Java exception follows:  ");
  5646   /* Describe exactly what went wrong.  */
  5647   (*android_java_env)->ExceptionDescribe (android_java_env);
  5648   (*android_java_env)->ExceptionClear (android_java_env);
  5649   memory_full (0);
  5650 }
  5651 
  5652 /* Check for JNI exceptions.  If there is one such exception, clear
  5653    it, then delete the local reference to OBJECT and call
  5654    memory_full.  */
  5655 
  5656 void
  5657 android_exception_check_1 (jobject object)
  5658 {
  5659   if (likely (!(*android_java_env)->ExceptionCheck (android_java_env)))
  5660     return;
  5661 
  5662   __android_log_print (ANDROID_LOG_WARN, __func__,
  5663                        "Possible out of memory error. "
  5664                        " The Java exception follows:  ");
  5665   /* Describe exactly what went wrong.  */
  5666   (*android_java_env)->ExceptionDescribe (android_java_env);
  5667   (*android_java_env)->ExceptionClear (android_java_env);
  5668   ANDROID_DELETE_LOCAL_REF (object);
  5669   memory_full (0);
  5670 }
  5671 
  5672 /* Like android_exception_check_1, except it takes more than one local
  5673    reference argument.  */
  5674 
  5675 void
  5676 android_exception_check_2 (jobject object, jobject object1)
  5677 {
  5678   if (likely (!(*android_java_env)->ExceptionCheck (android_java_env)))
  5679     return;
  5680 
  5681   __android_log_print (ANDROID_LOG_WARN, __func__,
  5682                        "Possible out of memory error. "
  5683                        " The Java exception follows:  ");
  5684   /* Describe exactly what went wrong.  */
  5685   (*android_java_env)->ExceptionDescribe (android_java_env);
  5686   (*android_java_env)->ExceptionClear (android_java_env);
  5687   ANDROID_DELETE_LOCAL_REF (object);
  5688   ANDROID_DELETE_LOCAL_REF (object1);
  5689   memory_full (0);
  5690 }
  5691 
  5692 /* Like android_exception_check_2, except it takes more than two local
  5693    reference arguments.  */
  5694 
  5695 void
  5696 android_exception_check_3 (jobject object, jobject object1,
  5697                            jobject object2)
  5698 {
  5699   if (likely (!(*android_java_env)->ExceptionCheck (android_java_env)))
  5700     return;
  5701 
  5702   __android_log_print (ANDROID_LOG_WARN, __func__,
  5703                        "Possible out of memory error. "
  5704                        " The Java exception follows:  ");
  5705   /* Describe exactly what went wrong.  */
  5706   (*android_java_env)->ExceptionDescribe (android_java_env);
  5707   (*android_java_env)->ExceptionClear (android_java_env);
  5708   ANDROID_DELETE_LOCAL_REF (object);
  5709   ANDROID_DELETE_LOCAL_REF (object1);
  5710   ANDROID_DELETE_LOCAL_REF (object2);
  5711   memory_full (0);
  5712 }
  5713 
  5714 /* Like android_exception_check_3, except it takes more than three
  5715    local reference arguments.  */
  5716 
  5717 void
  5718 android_exception_check_4 (jobject object, jobject object1,
  5719                            jobject object2, jobject object3)
  5720 {
  5721   if (likely (!(*android_java_env)->ExceptionCheck (android_java_env)))
  5722     return;
  5723 
  5724   __android_log_print (ANDROID_LOG_WARN, __func__,
  5725                        "Possible out of memory error. "
  5726                        " The Java exception follows:  ");
  5727   /* Describe exactly what went wrong.  */
  5728   (*android_java_env)->ExceptionDescribe (android_java_env);
  5729   (*android_java_env)->ExceptionClear (android_java_env);
  5730   ANDROID_DELETE_LOCAL_REF (object);
  5731   ANDROID_DELETE_LOCAL_REF (object1);
  5732   ANDROID_DELETE_LOCAL_REF (object2);
  5733   ANDROID_DELETE_LOCAL_REF (object3);
  5734   memory_full (0);
  5735 }
  5736 
  5737 /* Check for JNI problems based on the value of OBJECT.
  5738 
  5739    Signal out of memory if OBJECT is NULL.  OBJECT1 means the
  5740    same as in `android_exception_check_1'.
  5741 
  5742    This function is useful when checking for errors from JNI
  5743    functions that do not set exceptions on failure, such as
  5744    `GetIntArrayElements'.  */
  5745 
  5746 void
  5747 android_exception_check_nonnull (void *object, jobject object1)
  5748 {
  5749   if (likely (object != NULL))
  5750     return;
  5751 
  5752   if (object1)
  5753     ANDROID_DELETE_LOCAL_REF (object1);
  5754 
  5755   memory_full (0);
  5756 }
  5757 
  5758 /* Check for JNI problems based on the value of OBJECT.
  5759 
  5760    Signal out of memory if OBJECT is NULL.  OBJECT1 and OBJECT2 mean
  5761    the same as in `android_exception_check_2'.  */
  5762 
  5763 void
  5764 android_exception_check_nonnull_1 (void *object, jobject object1,
  5765                                    jobject object2)
  5766 {
  5767   if (likely (object != NULL))
  5768     return;
  5769 
  5770   if (object1)
  5771     ANDROID_DELETE_LOCAL_REF (object1);
  5772 
  5773   if (object2)
  5774     ANDROID_DELETE_LOCAL_REF (object2);
  5775 
  5776   memory_full (0);
  5777 }
  5778 
  5779 
  5780 
  5781 /* Native image transforms.  */
  5782 
  5783 /* Transform the coordinates X and Y by the specified affine
  5784    transformation MATRIX.  Place the result in *XOUT and *YOUT.  */
  5785 
  5786 static void
  5787 android_transform_coordinates (int x, int y,
  5788                                struct android_transform *transform,
  5789                                float *xout, float *yout)
  5790 {
  5791   /* Apply the specified affine transformation.
  5792      A transform looks like:
  5793 
  5794        M1 M2 M3     X
  5795        M4 M5 M6   * Y
  5796 
  5797        =
  5798 
  5799        M1*X + M2*Y + M3*1 = X1
  5800        M4*X + M5*Y + M6*1 = Y1
  5801 
  5802      (In most transforms, there is another row at the bottom for
  5803      mathematical reasons.  Since Z1 is always 1.0, the row is simply
  5804      implied to be 0 0 1, because 0 * x + 0 * y + 1 * 1 = 1.0.  See
  5805      the definition of matrix3x3 in image.c for some more explanations
  5806      about this.) */
  5807 
  5808   *xout = transform->m1 * x + transform->m2 * y + transform->m3;
  5809   *yout = transform->m4 * x + transform->m5 * y + transform->m6;
  5810 }
  5811 
  5812 /* Return the interpolation of the four pixels TL, TR, BL, and BR,
  5813    according to the weights DISTX and DISTY.  */
  5814 
  5815 static unsigned int
  5816 android_four_corners_bilinear (unsigned int tl, unsigned int tr,
  5817                                unsigned int bl, unsigned int br,
  5818                                int distx, int disty)
  5819 {
  5820   int distxy, distxiy, distixy, distixiy;
  5821   uint32_t f, r;
  5822 
  5823   distxy = distx * disty;
  5824   distxiy = (distx << 8) - distxy;
  5825   distixy = (disty << 8) - distxy;
  5826   distixiy = (256 * 256 - (disty << 8)
  5827               - (distx << 8) + distxy);
  5828 
  5829   /* Red */
  5830   r = ((tl & 0x000000ff) * distixiy + (tr & 0x000000ff) * distxiy
  5831        + (bl & 0x000000ff) * distixy  + (br & 0x000000ff) * distxy);
  5832 
  5833   /* Green */
  5834   f = ((tl & 0x0000ff00) * distixiy + (tr & 0x0000ff00) * distxiy
  5835        + (bl & 0x0000ff00) * distixy  + (br & 0x0000ff00) * distxy);
  5836   r |= f & 0xff000000;
  5837 
  5838   /* Now do the upper two components.  */
  5839   tl >>= 16;
  5840   tr >>= 16;
  5841   bl >>= 16;
  5842   br >>= 16;
  5843   r >>= 16;
  5844 
  5845   /* Blue */
  5846   f = ((tl & 0x000000ff) * distixiy + (tr & 0x000000ff) * distxiy
  5847        + (bl & 0x000000ff) * distixy  + (br & 0x000000ff) * distxy);
  5848   r |= f & 0x00ff0000;
  5849 
  5850   /* Alpha */
  5851   f = ((tl & 0x0000ff00) * distixiy + (tr & 0x0000ff00) * distxiy
  5852        + (bl & 0x0000ff00) * distixy  + (br & 0x0000ff00) * distxy);
  5853   r |= f & 0xff000000;
  5854 
  5855   return r;
  5856 }
  5857 
  5858 /* Return the interpolation of the four pixels closest to at X, Y in
  5859    IMAGE, according to weights in both axes computed from X and Y.
  5860    IMAGE must be depth 24, or the behavior is undefined.  */
  5861 
  5862 static unsigned int
  5863 android_fetch_pixel_bilinear (struct android_image *image,
  5864                               float x, float y)
  5865 {
  5866   int x1, y1, x2, y2;
  5867   float distx, disty;
  5868   unsigned int top_left, top_right;
  5869   unsigned int bottom_left, bottom_right;
  5870   char *word;
  5871 
  5872   /* Compute the four closest corners to X and Y.  */
  5873   x1 = (int) x;
  5874   x2 = x1 + 1;
  5875   y1 = (int) y;
  5876   y2 = y1 + 1;
  5877 
  5878   /* Make sure all four corners are within range.  */
  5879   x1 = MAX (0, MIN (image->width - 1, x1));
  5880   y1 = MAX (0, MIN (image->height - 1, y1));
  5881   x2 = MAX (0, MIN (image->width - 1, x2));
  5882   y2 = MAX (0, MIN (image->height - 1, y2));
  5883 
  5884   /* Compute the X and Y biases.  These are numbers between 0f and
  5885      1f.  */
  5886   distx = x - x1;
  5887   disty = y - y1;
  5888 
  5889   /* Fetch the four closest pixels.  */
  5890   word = image->data + y1 * image->bytes_per_line + x1 * 4;
  5891   memcpy (&top_left, word, sizeof top_left);
  5892   word = image->data + y1 * image->bytes_per_line + x2 * 4;
  5893   memcpy (&top_right, word, sizeof top_right);
  5894   word = image->data + y2 * image->bytes_per_line + x1 * 4;
  5895   memcpy (&bottom_left, word, sizeof bottom_left);
  5896   word = image->data + y2 * image->bytes_per_line + x2 * 4;
  5897   memcpy (&bottom_right, word, sizeof bottom_right);
  5898 
  5899   /* Do the interpolation.  */
  5900   return android_four_corners_bilinear (top_left, top_right, bottom_left,
  5901                                         bottom_right, distx * 256,
  5902                                         disty * 256);
  5903 }
  5904 
  5905 /* Transform the depth 24 image IMAGE by the 3x2 affine transformation
  5906    matrix MATRIX utilizing a bilinear filter.  Place the result in
  5907    OUT.  The matrix maps from the coordinate space of OUT to
  5908    IMAGE.  */
  5909 
  5910 void
  5911 android_project_image_bilinear (struct android_image *image,
  5912                                 struct android_image *out,
  5913                                 struct android_transform *transform)
  5914 {
  5915   int x, y;
  5916   unsigned int pixel;
  5917   float xout, yout;
  5918   char *word;
  5919 
  5920   /* Loop through each pixel in OUT.  Transform it by TRANSFORM, then
  5921      interpolate it to IMAGE, and place the result back in OUT.  */
  5922 
  5923   for (y = 0; y < out->height; ++y)
  5924     {
  5925       for (x = 0; x < out->width; ++x)
  5926         {
  5927           /* Transform the coordinates by TRANSFORM.  */
  5928           android_transform_coordinates (x, y, transform,
  5929                                          &xout, &yout);
  5930 
  5931           /* Interpolate back to IMAGE.  */
  5932           pixel = android_fetch_pixel_bilinear (image, xout, yout);
  5933 
  5934           /* Put the pixel back in OUT.  */
  5935           word = out->data + y * out->bytes_per_line + x * 4;
  5936           memcpy (word, &pixel, sizeof pixel);
  5937         }
  5938     }
  5939 }
  5940 
  5941 /* Return the interpolation of X, Y to IMAGE, a depth 24 image.  */
  5942 
  5943 static unsigned int
  5944 android_fetch_pixel_nearest_24 (struct android_image *image, float x,
  5945                                 float y)
  5946 {
  5947   int x1, y1;
  5948   char *word;
  5949   unsigned int pixel;
  5950 
  5951   x1 = MAX (0, MIN (image->width - 1, (int) roundf (x)));
  5952   y1 = MAX (0, MIN (image->height - 1, (int) roundf (y)));
  5953 
  5954   word = image->data + y1 * image->bytes_per_line + x1 * 4;
  5955   memcpy (&pixel, word, sizeof pixel);
  5956 
  5957   return pixel;
  5958 }
  5959 
  5960 /* Return the interpolation of X, Y to IMAGE, a depth 1 image.  */
  5961 
  5962 static unsigned int
  5963 android_fetch_pixel_nearest_1 (struct android_image *image, float x,
  5964                                float y)
  5965 {
  5966   int x1, y1;
  5967   char *byte;
  5968 
  5969   x1 = MAX (0, MIN (image->width - 1, (int) roundf (x)));
  5970   y1 = MAX (0, MIN (image->height - 1, (int) roundf (y)));
  5971 
  5972   byte = image->data + y1 * image->bytes_per_line;
  5973   return (byte[x1 / 8] & (1 << x1 % 8)) ? 1 : 0;
  5974 }
  5975 
  5976 /* Transform the depth 24 or 1 image IMAGE by the 3x2 affine
  5977    transformation matrix MATRIX.  Place the result in OUT.  The matrix
  5978    maps from the coordinate space of OUT to IMAGE.  Use a
  5979    nearest-neighbor filter.  */
  5980 
  5981 void
  5982 android_project_image_nearest (struct android_image *image,
  5983                                struct android_image *out,
  5984                                struct android_transform *transform)
  5985 {
  5986   int x, y;
  5987   unsigned int pixel;
  5988   float xout, yout;
  5989   char *word, *byte;
  5990 
  5991   if (image->depth == 1)
  5992     {
  5993       for (y = 0; y < out->height; ++y)
  5994         {
  5995           for (x = 0; x < out->width; ++x)
  5996             {
  5997               /* Transform the coordinates by TRANSFORM.  */
  5998               android_transform_coordinates (x, y, transform,
  5999                                              &xout, &yout);
  6000 
  6001               /* Interpolate back to IMAGE.  */
  6002               pixel = android_fetch_pixel_nearest_1 (image, xout, yout);
  6003 
  6004               /* Put the pixel back in OUT.  */
  6005               byte = out->data + y * out->bytes_per_line + x / 8;
  6006 
  6007               if (pixel)
  6008                 *byte |= (1 << x % 8);
  6009               else
  6010                 *byte &= ~(1 << x % 8);
  6011             }
  6012         }
  6013 
  6014       return;
  6015     }
  6016 
  6017   for (y = 0; y < out->height; ++y)
  6018     {
  6019       for (x = 0; x < out->width; ++x)
  6020         {
  6021           /* Transform the coordinates by TRANSFORM.  */
  6022           android_transform_coordinates (x, y, transform,
  6023                                          &xout, &yout);
  6024 
  6025           /* Interpolate back to IMAGE.  */
  6026           pixel = android_fetch_pixel_nearest_24 (image, xout, yout);
  6027 
  6028           /* Put the pixel back in OUT.  */
  6029           word = out->data + y * out->bytes_per_line + x * 4;
  6030           memcpy (word, &pixel, sizeof pixel);
  6031         }
  6032     }
  6033 }
  6034 
  6035 
  6036 
  6037 /* Other miscellaneous functions.  */
  6038 
  6039 /* Ask the system to start browsing the specified URL.  Upon failure,
  6040    return a string describing the error.  Else, value is nil.  URL
  6041    should be encoded unless SEND.
  6042 
  6043    If SEND, open the URL with applications that can ``send'' or
  6044    ``share'' the URL (through mail, for example.)  */
  6045 
  6046 Lisp_Object
  6047 android_browse_url (Lisp_Object url, Lisp_Object send)
  6048 {
  6049   jobject value, string;
  6050   Lisp_Object tem;
  6051   const char *buffer;
  6052 
  6053   string = android_build_string (url);
  6054   value = (*android_java_env)->CallObjectMethod (android_java_env,
  6055                                                  emacs_service,
  6056                                                  service_class.browse_url,
  6057                                                  string,
  6058                                                  (jboolean) !NILP (send));
  6059   android_exception_check ();
  6060 
  6061   ANDROID_DELETE_LOCAL_REF (string);
  6062 
  6063   /* If no string was returned, return Qnil.  */
  6064   if (!value)
  6065     return Qnil;
  6066 
  6067   buffer = (*android_java_env)->GetStringUTFChars (android_java_env,
  6068                                                    (jstring) value,
  6069                                                    NULL);
  6070   android_exception_check_1 (string);
  6071 
  6072   /* Otherwise, build the string describing the error.  */
  6073   tem = build_string_from_utf8 (buffer);
  6074 
  6075   (*android_java_env)->ReleaseStringUTFChars (android_java_env,
  6076                                               (jstring) value,
  6077                                               buffer);
  6078 
  6079   /* And return it.  */
  6080   ANDROID_DELETE_LOCAL_REF (value);
  6081   return tem;
  6082 }
  6083 
  6084 /* Tell the system to restart Emacs in a short amount of time, and
  6085    then kill Emacs.  Never return.  This is used to implement
  6086    `restart-emacs'.  */
  6087 
  6088 _Noreturn void
  6089 android_restart_emacs (void)
  6090 {
  6091   /* Try to call the Java side function.  Normally, this should call
  6092      System.exit to terminate this process.  */
  6093   (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
  6094                                                  emacs_service,
  6095                                                  service_class.class,
  6096                                                  service_class.restart_emacs);
  6097 
  6098   /* Exit anyway, in case EmacsService did not do so.  */
  6099   exit (0);
  6100 }
  6101 
  6102 /* Return a number from 1 to 33 describing the version of Android
  6103    Emacs is running on.
  6104 
  6105    This is different from __ANDROID_API__, as that describes the
  6106    minimum version of Android this build of Emacs will run on, and in
  6107    turn which APIs Emacs can safely use.  */
  6108 
  6109 int
  6110 (android_get_current_api_level) (void)
  6111 {
  6112   return android_api_level;
  6113 }
  6114 
  6115 /* Query the status of the battery, and place it in *STATUS.
  6116    Value is 1 upon failure, else 0.  */
  6117 
  6118 int
  6119 android_query_battery (struct android_battery_state *status)
  6120 {
  6121   jlongArray array;
  6122   jlong *longs;
  6123 
  6124   array = (*android_java_env)->CallObjectMethod (android_java_env,
  6125                                                  emacs_service,
  6126                                                  service_class.query_battery);
  6127   android_exception_check ();
  6128 
  6129   /* A NULL return with no exception means that battery information
  6130      could not be obtained.  */
  6131 
  6132   if (!array)
  6133     return 1;
  6134 
  6135   longs = (*android_java_env)->GetLongArrayElements (android_java_env,
  6136                                                      array, NULL);
  6137   android_exception_check_nonnull (longs, array);
  6138 
  6139   status->capacity = longs[0];
  6140   status->charge_counter = longs[1];
  6141   status->current_average = longs[2];
  6142   status->current_now = longs[3];
  6143   status->remaining = longs[4];
  6144   status->status = longs[5];
  6145   status->plugged = longs[6];
  6146   status->temperature = longs[7];
  6147 
  6148   (*android_java_env)->ReleaseLongArrayElements (android_java_env,
  6149                                                  array, longs,
  6150                                                  JNI_ABORT);
  6151   ANDROID_DELETE_LOCAL_REF (array);
  6152 
  6153   return 0;
  6154 }
  6155 
  6156 /* Display a file panel and grant Emacs access to the SAF directory
  6157    within it.  Value is 1 upon failure and 0 upon success (which only
  6158    indicates that the panel has been displayed successfully; the panel
  6159    may still be dismissed without a file being selected.)  */
  6160 
  6161 int
  6162 android_request_directory_access (void)
  6163 {
  6164   jint rc;
  6165   jmethodID method;
  6166 
  6167   method = service_class.request_directory_access;
  6168   rc = (*android_java_env)->CallNonvirtualIntMethod (android_java_env,
  6169                                                      emacs_service,
  6170                                                      service_class.class,
  6171                                                      method);
  6172   android_exception_check ();
  6173 
  6174   return rc;
  6175 }
  6176 
  6177 
  6178 
  6179 /* The thread from which a query against a thread is currently being
  6180    made, if any.  Value is 0 if no query is in progress, 1 if a query
  6181    is being made from the UI thread to the main thread, and 2 if a
  6182    query is being made the other way around.  */
  6183 static char android_servicing_query;
  6184 
  6185 /* Function that is waiting to be run in the Emacs thread.  */
  6186 static void (*android_query_function) (void *);
  6187 
  6188 /* Context for that function.  */
  6189 static void *android_query_context;
  6190 
  6191 /* Deadlock protection.  The UI thread and the Emacs thread must
  6192    sometimes make synchronous queries to each other, which are
  6193    normally answered inside each thread's respective event loop.
  6194    Deadlocks can happen when both threads simultaneously make such
  6195    synchronous queries and block waiting for each others responses.
  6196 
  6197    The Emacs thread can be interrupted to service any queries made by
  6198    the UI thread, but is not possible the other way around.
  6199 
  6200    To avoid such deadlocks, an atomic counter is provided.  This
  6201    counter is set to two every time a query starts from the main
  6202    thread, and is set to zero every time one ends.  If the UI thread
  6203    tries to make a query and sees that the counter is two, it simply
  6204    returns so that its event loop can proceed to perform and respond
  6205    to the query.  If the Emacs thread sees that the counter is one,
  6206    then it stops to service all queries being made by the input
  6207    method, then proceeds to make its query with the counter set to
  6208    2.
  6209 
  6210    The memory synchronization is simple: all writes to
  6211    `android_query_context' and `android_query_function' are depended
  6212    on by writes to the atomic counter.  Loads of the new value from
  6213    the counter are then guaranteed to make those writes visible.  The
  6214    separate flag `android_urgent_query' does not depend on anything
  6215    itself; however, the input signal handler executes a memory fence
  6216    to ensure that all query related writes become visible.  */
  6217 
  6218 /* Run any function that the UI thread has asked to run, and then
  6219    signal its completion.  */
  6220 
  6221 static void
  6222 android_check_query (void)
  6223 {
  6224   void (*proc) (void *);
  6225   void *closure;
  6226 
  6227   if (!__atomic_load_n (&android_servicing_query, __ATOMIC_ACQUIRE))
  6228     return;
  6229 
  6230   /* First, load the procedure and closure.  */
  6231   closure = android_query_context;
  6232   proc = android_query_function;
  6233 
  6234   if (!proc)
  6235     return;
  6236 
  6237   proc (closure);
  6238 
  6239   /* Finish the query.  */
  6240   android_query_context = NULL;
  6241   android_query_function = NULL;
  6242   __atomic_store_n (&android_servicing_query, 0, __ATOMIC_RELEASE);
  6243   __atomic_clear (&android_urgent_query, __ATOMIC_RELEASE);
  6244 
  6245   /* Signal completion.  */
  6246   sem_post (&android_query_sem);
  6247 }
  6248 
  6249 /* Run any function that the UI thread has asked to run, if the UI
  6250    thread has been waiting for more than two seconds.
  6251 
  6252    Call this from `process_pending_signals' to ensure that the UI
  6253    thread always receives an answer within a reasonable amount of
  6254    time.  */
  6255 
  6256 void
  6257 android_check_query_urgent (void)
  6258 {
  6259   void (*proc) (void *);
  6260   void *closure;
  6261 
  6262   if (!__atomic_load_n (&android_urgent_query, __ATOMIC_ACQUIRE))
  6263     return;
  6264 
  6265   __android_log_print (ANDROID_LOG_VERBOSE, __func__,
  6266                        "Responding to urgent query...");
  6267 
  6268   if (!__atomic_load_n (&android_servicing_query, __ATOMIC_ACQUIRE))
  6269     return;
  6270 
  6271   /* First, load the procedure and closure.  */
  6272   closure = android_query_context;
  6273   proc = android_query_function;
  6274 
  6275   if (!proc)
  6276     return;
  6277 
  6278   proc (closure);
  6279 
  6280   /* Finish the query.  Don't clear `android_urgent_query'; instead,
  6281      do that the next time Emacs enters the keyboard loop.  */
  6282 
  6283   android_query_context = NULL;
  6284   android_query_function = NULL;
  6285   __atomic_store_n (&android_servicing_query, 0, __ATOMIC_RELEASE);
  6286 
  6287   /* Signal completion.  */
  6288   sem_post (&android_query_sem);
  6289 }
  6290 
  6291 /* Run the function that the UI thread has asked to run, and then
  6292    signal its completion.  Do not change `android_servicing_query'
  6293    after it completes.  */
  6294 
  6295 static void
  6296 android_answer_query (void)
  6297 {
  6298   void (*proc) (void *);
  6299   void *closure;
  6300 
  6301   eassert (__atomic_load_n (&android_servicing_query,
  6302                             __ATOMIC_ACQUIRE)
  6303            == 1);
  6304 
  6305   /* First, load the procedure and closure.  */
  6306   closure = android_query_context;
  6307   proc = android_query_function;
  6308 
  6309   if (!proc)
  6310     return;
  6311 
  6312   proc (closure);
  6313 
  6314   /* Finish the query.  */
  6315   android_query_context = NULL;
  6316   android_query_function = NULL;
  6317   __atomic_clear (&android_urgent_query, __ATOMIC_RELEASE);
  6318 
  6319   /* Signal completion.  */
  6320   sem_post (&android_query_sem);
  6321 }
  6322 
  6323 /* Like `android_answer_query'.  However, the query may not have
  6324    begun; spin until it has.  */
  6325 
  6326 static void
  6327 android_answer_query_spin (void)
  6328 {
  6329   int n;
  6330 
  6331   while (!(n = __atomic_load_n (&android_servicing_query,
  6332                                 __ATOMIC_ACQUIRE)))
  6333     eassert (!n);
  6334 
  6335   /* Note that this function is supposed to be called before
  6336      `android_begin_query' starts, so clear the service flag.  */
  6337   android_check_query ();
  6338 }
  6339 
  6340 /* Notice that the Emacs thread will start blocking waiting for a
  6341    response from the UI thread.  Process any pending queries from the
  6342    UI thread.
  6343 
  6344    This function may be called from Java.  */
  6345 
  6346 static void
  6347 android_begin_query (void)
  6348 {
  6349   char old;
  6350 
  6351   /* Load the previous value of `android_servicing_query' and then set
  6352      it to 2.  */
  6353 
  6354   old = __atomic_exchange_n (&android_servicing_query,
  6355                              2, __ATOMIC_ACQ_REL);
  6356 
  6357   /* See if a query was previously in progress.  */
  6358   if (old == 1)
  6359     {
  6360       /* Answer the query that is currently being made.  */
  6361       assert (android_query_function != NULL);
  6362       android_answer_query ();
  6363     }
  6364 
  6365   /* `android_servicing_query' is now 2.  */
  6366 }
  6367 
  6368 /* Notice that a query has stopped.  This function may be called from
  6369    Java.  */
  6370 
  6371 static void
  6372 android_end_query (void)
  6373 {
  6374   __atomic_store_n (&android_servicing_query, 0, __ATOMIC_RELEASE);
  6375   __atomic_clear (&android_urgent_query, __ATOMIC_RELEASE);
  6376 }
  6377 
  6378 /* Synchronously ask the Emacs thread to run the specified PROC with
  6379    the given CLOSURE.  Return if this fails, or once PROC is run.
  6380 
  6381    PROC may be run from inside maybe_quit.
  6382 
  6383    It is not okay to run Lisp code which signals or performs non
  6384    trivial tasks inside PROC.
  6385 
  6386    Return 1 if the Emacs thread is currently waiting for the UI thread
  6387    to respond and PROC could not be run, or 0 otherwise.  */
  6388 
  6389 int
  6390 android_run_in_emacs_thread (void (*proc) (void *), void *closure)
  6391 {
  6392   union android_event event;
  6393   char old;
  6394   int rc;
  6395   struct timespec timeout;
  6396 
  6397   event.xaction.type = ANDROID_WINDOW_ACTION;
  6398   event.xaction.serial = ++event_serial;
  6399   event.xaction.window = 0;
  6400   event.xaction.action = 0;
  6401 
  6402   /* Set android_query_function and android_query_context.  */
  6403   android_query_context = closure;
  6404   android_query_function = proc;
  6405 
  6406   /* Don't allow deadlocks to happen; make sure the Emacs thread is
  6407      not waiting for something to be done (in that case,
  6408      `android_query_context' is 2.)  */
  6409 
  6410   old = 0;
  6411   if (!__atomic_compare_exchange_n (&android_servicing_query, &old,
  6412                                     1, false, __ATOMIC_ACQ_REL,
  6413                                     __ATOMIC_ACQUIRE))
  6414     {
  6415       android_query_context = NULL;
  6416       android_query_function = NULL;
  6417 
  6418       /* The two variables above may still be non-NULL from the POV of
  6419          the main thread, as no happens-before constraint is placed on
  6420          those stores wrt a future load from `android_servicing_query'.  */
  6421 
  6422       return 1;
  6423     }
  6424 
  6425   /* Send a dummy event.  `android_check_query' will be called inside
  6426      wait_reading_process_output after the event arrives.
  6427 
  6428      Otherwise, android_select will call android_check_thread the next
  6429      time it is entered.  */
  6430   android_write_event (&event);
  6431 
  6432   /* Start waiting for the function to be executed.  First, wait two
  6433      seconds for the query to execute normally.  */
  6434 
  6435   timeout.tv_sec = 2;
  6436   timeout.tv_nsec = 0;
  6437   timeout = timespec_add (current_timespec (), timeout);
  6438 
  6439   /* See if an urgent query was recently answered without entering the
  6440      keyboard loop in between.  When that happens, raise SIGIO to
  6441      continue processing queries as soon as possible.  */
  6442 
  6443   if (__atomic_load_n (&android_urgent_query, __ATOMIC_ACQUIRE))
  6444     kill (getpid (), SIGIO);
  6445 
  6446  again:
  6447   rc = sem_timedwait (&android_query_sem, &timeout);
  6448 
  6449   if (rc < 0)
  6450     {
  6451       if (errno == EINTR)
  6452         goto again;
  6453 
  6454       eassert (errno == ETIMEDOUT);
  6455 
  6456       __android_log_print (ANDROID_LOG_VERBOSE, __func__,
  6457                            "Timed out waiting for response"
  6458                            " from main thread...");
  6459 
  6460       /* The query timed out.  At this point, set
  6461          `android_urgent_query' to true.  */
  6462       __atomic_store_n (&android_urgent_query, true,
  6463                         __ATOMIC_RELEASE);
  6464 
  6465     kill_again:
  6466 
  6467       /* And raise SIGIO.  Now that the query is considered urgent,
  6468          the main thread will reply while reading async input.
  6469 
  6470          Normally, the main thread waits for the keyboard loop to be
  6471          entered before responding, in order to avoid responding with
  6472          inaccurate results taken during command executioon.  */
  6473       kill (getpid (), SIGIO);
  6474 
  6475       /* Wait for the query to complete.  `android_urgent_query' is
  6476          only cleared by either `android_select' or
  6477          `android_check_query', so there's no need to worry about the
  6478          flag being cleared before the query is processed.
  6479 
  6480          Send SIGIO again periodically until the query is answered, on
  6481          the off chance that SIGIO arrived too late to preempt a
  6482          system call, but too early for it to return EINTR.  */
  6483 
  6484       timeout.tv_sec = 4;
  6485       timeout.tv_nsec = 0;
  6486       timeout = timespec_add (current_timespec (), timeout);
  6487 
  6488       while (sem_timedwait (&android_query_sem, &timeout) < 0)
  6489         {
  6490           /* If waiting timed out, send SIGIO to the main thread
  6491              again.  */
  6492 
  6493           if (errno == ETIMEDOUT)
  6494             goto kill_again;
  6495 
  6496           /* Otherwise, continue waiting.  */
  6497           eassert (errno == EINTR);
  6498         }
  6499     }
  6500 
  6501   /* At this point, `android_servicing_query' should either be zero if
  6502      the query was answered or two if the main thread has started a
  6503      query.  */
  6504 
  6505   eassert (!__atomic_load_n (&android_servicing_query,
  6506                              __ATOMIC_ACQUIRE)
  6507            || (__atomic_load_n (&android_servicing_query,
  6508                                 __ATOMIC_ACQUIRE) == 2));
  6509 
  6510   return 0;
  6511 }
  6512 
  6513 
  6514 
  6515 /* Input method related functions.  */
  6516 
  6517 /* Change WINDOW's active selection to the characters between
  6518    SELECTION_START and SELECTION_END.
  6519 
  6520    Also, update the composing region to COMPOSING_REGION_START and
  6521    COMPOSING_REGION_END.
  6522 
  6523    If any value cannot fit in jint, then the behavior of the input
  6524    method is undefined.  */
  6525 
  6526 void
  6527 android_update_ic (android_window window, ptrdiff_t selection_start,
  6528                    ptrdiff_t selection_end, ptrdiff_t composing_region_start,
  6529                    ptrdiff_t composing_region_end)
  6530 {
  6531   jobject object;
  6532 
  6533   object = android_resolve_handle (window, ANDROID_HANDLE_WINDOW);
  6534 
  6535   (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
  6536                                                  emacs_service,
  6537                                                  service_class.class,
  6538                                                  service_class.update_ic,
  6539                                                  object,
  6540                                                  (jint) selection_start,
  6541                                                  (jint) selection_end,
  6542                                                  (jint) composing_region_start,
  6543                                                  (jint) composing_region_end);
  6544   android_exception_check ();
  6545 }
  6546 
  6547 /* Reinitialize any ongoing input method connection on WINDOW.
  6548 
  6549    Any input method that is connected to WINDOW will invalidate its
  6550    cache of the buffer contents.
  6551 
  6552    MODE controls certain aspects of the input method's behavior:
  6553 
  6554      - If MODE is ANDROID_IC_MODE_NULL, the input method will be
  6555        deactivated, and an ASCII only keyboard will be displayed
  6556        instead.
  6557 
  6558      - If MODE is ANDROID_IC_MODE_ACTION, the input method will
  6559        edit text normally, but send ``return'' as a key event.
  6560        This is useful inside the mini buffer.
  6561 
  6562      - If MODE is ANDROID_IC_MODE_TEXT, the input method is free
  6563        to behave however it wants.  */
  6564 
  6565 void
  6566 android_reset_ic (android_window window, enum android_ic_mode mode)
  6567 {
  6568   jobject object;
  6569 
  6570   object = android_resolve_handle (window, ANDROID_HANDLE_WINDOW);
  6571 
  6572   (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
  6573                                                  emacs_service,
  6574                                                  service_class.class,
  6575                                                  service_class.reset_ic,
  6576                                                  object, (jint) mode);
  6577   android_exception_check ();
  6578 }
  6579 
  6580 /* Make updates to extracted text known to the input method on
  6581    WINDOW.  TEXT should be a local reference to the new
  6582    extracted text.  TOKEN should be the token specified by the
  6583    input method.  */
  6584 
  6585 void
  6586 android_update_extracted_text (android_window window, void *text,
  6587                                int token)
  6588 {
  6589   jobject object;
  6590   jmethodID method;
  6591 
  6592   object = android_resolve_handle (window, ANDROID_HANDLE_WINDOW);
  6593   method = service_class.update_extracted_text;
  6594 
  6595   (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
  6596                                                  emacs_service,
  6597                                                  service_class.class,
  6598                                                  method, object,
  6599                                                  /* N.B. that text is
  6600                                                     not jobject,
  6601                                                     because that type
  6602                                                     is not available
  6603                                                     in
  6604                                                     androidgui.h.  */
  6605                                                  (jobject) text,
  6606                                                  (jint) token);
  6607   android_exception_check_1 (text);
  6608 }
  6609 
  6610 /* Report the position of the cursor to the input method connection on
  6611    WINDOW.
  6612 
  6613    X is the horizontal position of the end of the insertion marker.  Y
  6614    is the top of the insertion marker.  Y_BASELINE is the baseline of
  6615    the row containing the insertion marker, and Y_BOTTOM is the bottom
  6616    of the insertion marker.  */
  6617 
  6618 void
  6619 android_update_cursor_anchor_info (android_window window, float x,
  6620                                    float y, float y_baseline,
  6621                                    float y_bottom)
  6622 {
  6623   jobject object;
  6624   jmethodID method;
  6625 
  6626   object = android_resolve_handle (window, ANDROID_HANDLE_WINDOW);
  6627   method = service_class.update_cursor_anchor_info;
  6628 
  6629   (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
  6630                                                  emacs_service,
  6631                                                  service_class.class,
  6632                                                  method,
  6633                                                  object,
  6634                                                  (jfloat) x,
  6635                                                  (jfloat) y,
  6636                                                  (jfloat) y_baseline,
  6637                                                  (jfloat) y_bottom);
  6638   android_exception_check ();
  6639 }
  6640 
  6641 
  6642 
  6643 /* Window decoration management functions.  */
  6644 
  6645 /* Make the specified WINDOW fullscreen, i.e. obscure all of the
  6646    system navigation and status bars.  If not FULLSCREEN, make it
  6647    maximized instead.
  6648 
  6649    Value is 1 if the system does not support this, else 0.  */
  6650 
  6651 int
  6652 android_set_fullscreen (android_window window, bool fullscreen)
  6653 {
  6654   jobject object;
  6655 
  6656   /* Android 4.0 and earlier don't support fullscreen windows.  */
  6657 
  6658   if (android_api_level < 16)
  6659     return 1;
  6660 
  6661   object = android_resolve_handle (window, ANDROID_HANDLE_WINDOW);
  6662 
  6663   (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
  6664                                                  object,
  6665                                                  window_class.class,
  6666                                                  window_class.set_fullscreen,
  6667                                                  (jboolean) fullscreen);
  6668   android_exception_check ();
  6669   return 0;
  6670 }
  6671 
  6672 
  6673 
  6674 /* Window cursor support.  */
  6675 
  6676 android_cursor
  6677 android_create_font_cursor (enum android_cursor_shape shape)
  6678 {
  6679   android_cursor id;
  6680   short prev_max_handle;
  6681   jobject object;
  6682 
  6683   /* First, allocate the cursor handle.  */
  6684   prev_max_handle = max_handle;
  6685   id = android_alloc_id ();
  6686 
  6687   if (!id)
  6688     error ("Out of cursor handles!");
  6689 
  6690   /* Next, create the cursor.  */
  6691   object = (*android_java_env)->NewObject (android_java_env,
  6692                                            cursor_class.class,
  6693                                            cursor_class.constructor,
  6694                                            (jshort) id,
  6695                                            (jint) shape);
  6696   if (!object)
  6697     {
  6698       (*android_java_env)->ExceptionClear (android_java_env);
  6699       max_handle = prev_max_handle;
  6700       memory_full (0);
  6701     }
  6702 
  6703   android_handles[id].type = ANDROID_HANDLE_CURSOR;
  6704   android_handles[id].handle
  6705     = (*android_java_env)->NewGlobalRef (android_java_env, object);
  6706   (*android_java_env)->ExceptionClear (android_java_env);
  6707   ANDROID_DELETE_LOCAL_REF (object);
  6708 
  6709   if (!android_handles[id].handle)
  6710     memory_full (0);
  6711 
  6712   return id;
  6713 }
  6714 
  6715 void
  6716 android_define_cursor (android_window window, android_cursor cursor)
  6717 {
  6718   jobject window1, cursor1;
  6719   jmethodID method;
  6720 
  6721   window1 = android_resolve_handle (window, ANDROID_HANDLE_WINDOW);
  6722   cursor1 = android_resolve_handle (cursor, ANDROID_HANDLE_CURSOR);
  6723   method = window_class.define_cursor;
  6724 
  6725   (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
  6726                                                  window1,
  6727                                                  window_class.class,
  6728                                                  method, cursor1);
  6729   android_exception_check ();
  6730 }
  6731 
  6732 void
  6733 android_free_cursor (android_cursor cursor)
  6734 {
  6735   if (android_handles[cursor].type != ANDROID_HANDLE_CURSOR)
  6736     {
  6737       __android_log_print (ANDROID_LOG_ERROR, __func__,
  6738                            "Trying to destroy something not a CURSOR!");
  6739       emacs_abort ();
  6740     }
  6741 
  6742   android_destroy_handle (cursor);
  6743 }
  6744 
  6745 
  6746 
  6747 /* Process execution.
  6748 
  6749    Newer Android systems use SELinux to restrict user programs from
  6750    executing programs installed in the application data directory for
  6751    security reasons.  Emacs uses a `loader' binary installed in the
  6752    application data directory to manually load executables and replace
  6753    the `execve' system call.  */
  6754 
  6755 enum
  6756   {
  6757     /* Maximum number of arguments available.  */
  6758     MAXARGS = 1024,
  6759   };
  6760 
  6761 /* Rewrite the command line given in *ARGV to utilize the `exec1'
  6762    bootstrap binary if necessary.
  6763 
  6764    Value is 0 upon success, else 1.  Set errno upon failure.
  6765 
  6766    ARGV holds a pointer to a NULL-terminated array of arguments given
  6767    to `emacs_spawn'.  */
  6768 
  6769 int
  6770 android_rewrite_spawn_argv (const char ***argv)
  6771 {
  6772   static const char *new_args[MAXARGS];
  6773   static char exec1_name[PATH_MAX], loader_name[PATH_MAX];
  6774   size_t i, nargs;
  6775 
  6776   /* This isn't required on Android 9 or earlier.  */
  6777 
  6778   if (android_api_level < 29 || !android_use_exec_loader)
  6779     return 0;
  6780 
  6781   /* Get argv[0]; this should never be NULL.
  6782      Then, verify that it exists and is executable.  */
  6783 
  6784   eassert (**argv);
  6785   if (access (**argv, R_OK | X_OK))
  6786     return 1;
  6787 
  6788   /* Count the number of arguments in *argv.  */
  6789 
  6790   nargs = 0;
  6791   while ((*argv)[nargs])
  6792     ++nargs;
  6793 
  6794   /* nargs now holds the number of arguments in argv.  If it's larger
  6795      than MAXARGS, return failure.  */
  6796 
  6797   if (nargs + 2 > MAXARGS)
  6798     {
  6799       errno = E2BIG;
  6800       return 1;
  6801     }
  6802 
  6803   /* Fill in the name of `libexec1.so'.  */
  6804   snprintf (exec1_name, PATH_MAX, "%s/libexec1.so",
  6805             android_lib_dir);
  6806 
  6807   /* And libloader.so.  */
  6808   snprintf (loader_name, PATH_MAX, "%s/libloader.so",
  6809             android_lib_dir);
  6810 
  6811   /* Now fill in the first two arguments.  */
  6812   new_args[0] = exec1_name;
  6813   new_args[1] = loader_name;
  6814 
  6815   /* And insert the rest, including the trailing NULL.  */
  6816   for (i = 0; i < nargs + 1; ++i)
  6817     new_args[i + 2] = (*argv)[i];
  6818 
  6819   /* Replace argv.  */
  6820   *argv = new_args;
  6821 
  6822   /* Return success.  */
  6823   return 0;
  6824 }
  6825 
  6826 
  6827 
  6828 #else /* ANDROID_STUBIFY */
  6829 
  6830 /* X emulation functions for Android.  */
  6831 
  6832 struct android_gc *
  6833 android_create_gc (enum android_gc_value_mask mask,
  6834                    struct android_gc_values *values)
  6835 {
  6836   /* This function should never be called when building stubs.  */
  6837   emacs_abort ();
  6838 }
  6839 
  6840 void
  6841 android_free_gc (struct android_gc *gc)
  6842 {
  6843   /* This function should never be called when building stubs.  */
  6844   emacs_abort ();
  6845 }
  6846 
  6847 struct android_image *
  6848 android_create_image (unsigned int depth, enum android_image_format format,
  6849                       char *data, unsigned int width, unsigned int height)
  6850 {
  6851   emacs_abort ();
  6852 }
  6853 
  6854 void
  6855 android_destroy_image (struct android_image *ximg)
  6856 {
  6857   emacs_abort ();
  6858 }
  6859 
  6860 void
  6861 android_put_pixel (struct android_image *ximg, int x, int y,
  6862                    unsigned long pixel)
  6863 {
  6864   emacs_abort ();
  6865 }
  6866 
  6867 unsigned long
  6868 android_get_pixel (struct android_image *ximg, int x, int y)
  6869 {
  6870   emacs_abort ();
  6871 }
  6872 
  6873 struct android_image *
  6874 android_get_image (android_drawable drawable,
  6875                    enum android_image_format format)
  6876 {
  6877   emacs_abort ();
  6878 }
  6879 
  6880 void
  6881 android_put_image (android_pixmap pixmap,
  6882                    struct android_image *image)
  6883 {
  6884   emacs_abort ();
  6885 }
  6886 
  6887 void
  6888 android_project_image_bilinear (struct android_image *image,
  6889                                 struct android_image *out,
  6890                                 struct android_transform *transform)
  6891 {
  6892   emacs_abort ();
  6893 }
  6894 
  6895 void
  6896 android_project_image_nearest (struct android_image *image,
  6897                                struct android_image *out,
  6898                                struct android_transform *transform)
  6899 {
  6900   emacs_abort ();
  6901 }
  6902 
  6903 #endif /* !ANDROID_STUBIFY */

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