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

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