aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2023-01-02 21:38:19 +0800
committerPo Lu2023-01-02 21:38:19 +0800
commita32963e11f9f8e5d22b0d754d34a867f3b178ed2 (patch)
tree898f12248beb2feb63ed4295f9de40c89053ae19 /src
parentfd074f3133a348dd1d3b7ee569f0fc046223efb9 (diff)
downloademacs-a32963e11f9f8e5d22b0d754d34a867f3b178ed2.tar.gz
emacs-a32963e11f9f8e5d22b0d754d34a867f3b178ed2.zip
Update Android port
* Makefile.in (java): Depend on info. (MAKEFILE_NAME): (config.status): Remove unneeded changes. * configure.ac (BUILD_DETAILS, ANDROID_STUBIFY): Don't require a C++ compiler on Android. * java/AndroidManifest.xml: <EmacsActivity>: Set launchMode appropriately. <EmacsMultitaskActivity>: New activity. * java/Makefile.in (CROSS_BINS): Add EmacsClient. * java/org/gnu/emacs/EmacsActivity.java (EmacsActivity) (onCreate): Use the window attachment manager. * java/org/gnu/emacs/EmacsCopyArea.java (EmacsCopyArea) (paintTo): Implement clip masks correctly. * java/org/gnu/emacs/EmacsDrawRectangle.java (getRect, paintTo): Fix damage tracking rectangles. * java/org/gnu/emacs/EmacsFontDriver.java (FontSpec, toString): New function. (FontMetrics, EmacsFontDriver): Fix signature of textExtents. * java/org/gnu/emacs/EmacsMultitaskActivity.java (EmacsMultitaskActivity): New file. * java/org/gnu/emacs/EmacsNative.java (EmacsNative): New functions sendFocusIn, sendFocusOut, sendWindowAction. * java/org/gnu/emacs/EmacsPaintQueue.java (run): Fix clipping handling. * java/org/gnu/emacs/EmacsPixmap.java (EmacsPixmap): Add constructor for mutable pixmaps. * java/org/gnu/emacs/EmacsSdk23FontDriver.java (EmacsSdk23FontDriver): New file. * java/org/gnu/emacs/EmacsSdk7FontDriver.java (EmacsSdk7FontDriver, Sdk7Typeface, Sdk7FontEntity, Sdk7FontObject) (checkMatch, hasChar, encodeChar): Implement text display and fix font metrics semantics. * java/org/gnu/emacs/EmacsService.java (EmacsService): Remove availableChildren. (getLibraryDirectory, onCreate): Pass pixel density to Emacs. (clearArea): Fix arguments. Switch to using the window attachment manager. * java/org/gnu/emacs/EmacsSurfaceView.java (surfaceChanged) (surfaceCreated): Flip buffers on surface attachment. * java/org/gnu/emacs/EmacsView.java (EmacsView, swapBuffers): New argument FORCE. Always swap if it is true. (onKeyMultiple, onFocusChanged): New functions. * java/org/gnu/emacs/EmacsWindow.java (EmacsWindow, destroyHandle) (run): Switch to using the window attachment manager. * java/org/gnu/emacs/EmacsWindowAttachmentManager.java (EmacsWindowAttachmentManager): New file. * lisp/cus-edit.el (custom-button, custom-button-mouse) (custom-button-pressed): * lisp/faces.el (tool-bar): Define faces correctly on Android. * src/android.c (struct android_emacs_pixmap): Add mutable constructor. (struct android_emacs_drawable): New structure. (android_write_event): Check if event queue hasn't yet been initialized. (android_select): Set errno to EINTR if pselect fails. (android_close): Remove unused debugging code. (android_get_home_directory): New function. (Java_org_gnu_emacs_EmacsNative_setEmacsParams): Set pixel density and compute game path. (android_init_emacs_drawable): New function. (Java_org_gnu_emacs_EmacsNative_sendKeyPress): New argument `unicode_char'. Pass it in events. (Java_org_gnu_emacs_EmacsNative_sendKeyRelease): Likewise. (Java_org_gnu_emacs_EmacsNative_sendFocusIn) (Java_org_gnu_emacs_EmacsNative_sendFocusOut) (Java_org_gnu_emacs_EmacsNative_sendWindowAction): New functions. (android_resolve_handle): Export function. (android_change_gc): Clear clip rects under the right circumstances. Set right clip mask field. (android_create_pixmap_from_bitmap_data): Use correct alpha channels. (android_create_pixmap): Create mutable pixmap and avoid redundant color array allocation. (android_create_bitmap_from_data, android_create_image) (android_destroy_image, android_put_pixel, android_get_pixel) (android_get_image, android_put_image, faccessat): New functions. * src/android.h: Update prototypes. * src/androidfns.c (android_default_font_parameter): Prefer monospace to Droid Sans Mono. * src/androidfont.c (struct android_emacs_font_driver): New method `draw'. (struct android_emacs_font_spec): New field `dpi'. (struct androidfont_info): Add font metrics cache. (android_init_font_driver, android_init_font_spec): Adjust accordingly. (androidfont_from_lisp, androidfont_from_java): Handle new fields. (androidfont_draw): Implement function. (androidfont_open_font): Set pixel size correctly. (androidfont_close_font): Free metrics cache. (androidfont_cache_text_extents) (androidfont_check_cached_extents): New functions. (androidfont_text_extents): Cache glyph metrics somewhere for future use. (androidfont_list_family): Implement function. * src/androidgui.h (enum android_event_type): New focus and window action events. (enum android_modifier_mask): New masks. (struct android_key_event): New field `unicode_char'. (ANDROID_IS_MODIFIER_KEY): Newmacro. (struct android_focus_event, struct android_window_action_event): New structs. (union android_event): Add new fields. (enum android_image_format, struct android_image): New enums and structs. * src/androidterm.c (android_android_to_emacs_modifiers) (android_emacs_to_android_modifiers, android_lower_frame) (android_raise_frame, android_new_focus_frame) (android_focus_changed, android_detect_focus_change): New functions. (handle_one_android_event): Implement focus and key event handling. (android_frame_rehighlight): New function. (android_frame_raise_lower): Implement accordingly. (android_make_frame_invisible): Clear highlight_frame if required. (android_free_frame_resources): Clear x_focus_event_frame if required. (android_draw_fringe_bitmap, android_draw_image_foreground) (android_draw_image_foreground_1) (android_draw_image_glyph_string): Remove unnecessary code. (android_create_terminal, android_term_init): Set the baud rate to something sensible. * src/androidterm.h (struct android_bitmap_record): Make structure the same as on X. (struct android_display_info): New focus tracking fields. (struct android_output): Likewise. * src/dispextern.h (struct image): Add ximg and mask_img on Android. * src/emacs.c (android_emacs_init): Fix argc sorting iteration. * src/fileio.c (user_homedir): (get_homedir): Implement correctly on Android. * src/font.h (PT_PER_INCH): Define correctly on Android. * src/fringe.c (X, swap_nibble, init_fringe_bitmap): Swap fringe bitmaps correctly on Android. * src/image.c (GET_PIXEL, image_create_bitmap_from_data) (image_create_bitmap_from_file, free_bitmap_record) (image_unget_x_image_or_dc, struct image_type) (prepare_image_for_display, image_clear_image_1) (image_size_in_bytes, x_check_image_size) (x_create_x_image_and_pixmap, x_destroy_x_image) (image_check_image_size, image_create_x_image_and_pixmap_1) (image_destroy_x_image, gui_put_x_image, image_put_x_image) (image_get_x_image, image_unget_x_image) (Create_Pixmap_From_Bitmap_Data, image_pixmap_draw_cross) (MaskForeground, image_types, syms_of_image): Implement all of the above on Android in terms of an API very similar to X. * src/keyboard.c (FUNCTION_KEY_OFFSET, lispy_function_keys): Define on Android to something sensible. * src/lread.c (build_load_history): Fix problem.
Diffstat (limited to 'src')
-rw-r--r--src/android.c627
-rw-r--r--src/android.h15
-rw-r--r--src/androidfns.c5
-rw-r--r--src/androidfont.c270
-rw-r--r--src/androidgui.h81
-rw-r--r--src/androidterm.c544
-rw-r--r--src/androidterm.h30
-rw-r--r--src/dispextern.h11
-rw-r--r--src/emacs.c5
-rw-r--r--src/fileio.c9
-rw-r--r--src/font.h6
-rw-r--r--src/fringe.c23
-rw-r--r--src/image.c249
-rw-r--r--src/keyboard.c53
-rw-r--r--src/lread.c20
15 files changed, 1518 insertions, 430 deletions
diff --git a/src/android.c b/src/android.c
index dd841cf383a..db12e244275 100644
--- a/src/android.c
+++ b/src/android.c
@@ -24,6 +24,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
24#include <limits.h> 24#include <limits.h>
25#include <signal.h> 25#include <signal.h>
26#include <semaphore.h> 26#include <semaphore.h>
27#include <dlfcn.h>
27 28
28#include <sys/stat.h> 29#include <sys/stat.h>
29#include <sys/mman.h> 30#include <sys/mman.h>
@@ -46,6 +47,7 @@ bool android_init_gui;
46 47
47#include <android/asset_manager.h> 48#include <android/asset_manager.h>
48#include <android/asset_manager_jni.h> 49#include <android/asset_manager_jni.h>
50#include <android/bitmap.h>
49#include <android/log.h> 51#include <android/log.h>
50 52
51#include <linux/ashmem.h> 53#include <linux/ashmem.h>
@@ -86,6 +88,7 @@ struct android_emacs_pixmap
86{ 88{
87 jclass class; 89 jclass class;
88 jmethodID constructor; 90 jmethodID constructor;
91 jmethodID constructor_mutable;
89}; 92};
90 93
91struct android_graphics_point 94struct android_graphics_point
@@ -94,6 +97,12 @@ struct android_graphics_point
94 jmethodID constructor; 97 jmethodID constructor;
95}; 98};
96 99
100struct android_emacs_drawable
101{
102 jclass class;
103 jmethodID get_bitmap;
104};
105
97/* The asset manager being used. */ 106/* The asset manager being used. */
98static AAssetManager *asset_manager; 107static AAssetManager *asset_manager;
99 108
@@ -106,6 +115,12 @@ char *android_site_load_path;
106/* The path used to store native libraries. */ 115/* The path used to store native libraries. */
107char *android_lib_dir; 116char *android_lib_dir;
108 117
118/* The path used to store game files. */
119char *android_game_path;
120
121/* The display's pixel densities. */
122double android_pixel_density_x, android_pixel_density_y;
123
109/* The Android application data directory. */ 124/* The Android application data directory. */
110static char *android_files_dir; 125static char *android_files_dir;
111 126
@@ -149,6 +164,9 @@ static struct android_emacs_pixmap pixmap_class;
149/* Various methods associated with the Point class. */ 164/* Various methods associated with the Point class. */
150static struct android_graphics_point point_class; 165static struct android_graphics_point point_class;
151 166
167/* Various methods associated with the EmacsDrawable class. */
168static struct android_emacs_drawable drawable_class;
169
152 170
153 171
154/* Event handling functions. Events are stored on a (circular) queue 172/* Event handling functions. Events are stored on a (circular) queue
@@ -383,6 +401,10 @@ android_write_event (union android_event *event)
383 if (!container) 401 if (!container)
384 return; 402 return;
385 403
404 /* If the event queue hasn't been initialized yet, return false. */
405 if (!event_queue.events.next)
406 return;
407
386 pthread_mutex_lock (&event_queue.mutex); 408 pthread_mutex_lock (&event_queue.mutex);
387 409
388 /* The event queue is full, wait for events to be read. */ 410 /* The event queue is full, wait for events to be read. */
@@ -451,6 +473,10 @@ android_select (int nfds, fd_set *readfds, fd_set *writefds,
451 /* Unlock the event queue mutex. */ 473 /* Unlock the event queue mutex. */
452 pthread_mutex_unlock (&event_queue.mutex); 474 pthread_mutex_unlock (&event_queue.mutex);
453 475
476 /* This is to shut up process.c when pselect gets EINTR. */
477 if (nfds_return < 0)
478 errno = EINTR;
479
454 return nfds_return; 480 return nfds_return;
455} 481}
456 482
@@ -793,16 +819,20 @@ android_close (int fd)
793{ 819{
794 if (fd < ANDROID_MAX_ASSET_FD 820 if (fd < ANDROID_MAX_ASSET_FD
795 && (android_table[fd].flags & ANDROID_FD_TABLE_ENTRY_IS_VALID)) 821 && (android_table[fd].flags & ANDROID_FD_TABLE_ENTRY_IS_VALID))
796 { 822 android_table[fd].flags = 0;
797 __android_log_print (ANDROID_LOG_INFO, __func__,
798 "closing android file descriptor %d",
799 fd);
800 android_table[fd].flags = 0;
801 }
802 823
803 return close (fd); 824 return close (fd);
804} 825}
805 826
827/* Return the current user's ``home'' directory, which is actually the
828 app data directory on Android. */
829
830const char *
831android_get_home_directory (void)
832{
833 return android_files_dir;
834}
835
806 836
807 837
808/* JNI functions called by Java. */ 838/* JNI functions called by Java. */
@@ -814,6 +844,8 @@ JNIEXPORT void JNICALL
814NATIVE_NAME (setEmacsParams) (JNIEnv *env, jobject object, 844NATIVE_NAME (setEmacsParams) (JNIEnv *env, jobject object,
815 jobject local_asset_manager, 845 jobject local_asset_manager,
816 jobject files_dir, jobject libs_dir, 846 jobject files_dir, jobject libs_dir,
847 jfloat pixel_density_x,
848 jfloat pixel_density_y,
817 jobject emacs_service_object) 849 jobject emacs_service_object)
818{ 850{
819 int pipefd[2]; 851 int pipefd[2];
@@ -829,6 +861,9 @@ NATIVE_NAME (setEmacsParams) (JNIEnv *env, jobject object,
829 return; 861 return;
830 } 862 }
831 863
864 android_pixel_density_x = pixel_density_x;
865 android_pixel_density_y = pixel_density_y;
866
832 __android_log_print (ANDROID_LOG_INFO, __func__, 867 __android_log_print (ANDROID_LOG_INFO, __func__,
833 "Initializing "PACKAGE_STRING"...\nPlease report bugs to " 868 "Initializing "PACKAGE_STRING"...\nPlease report bugs to "
834 PACKAGE_BUGREPORT". Thanks.\n"); 869 PACKAGE_BUGREPORT". Thanks.\n");
@@ -891,15 +926,23 @@ NATIVE_NAME (setEmacsParams) (JNIEnv *env, jobject object,
891 if (!android_site_load_path) 926 if (!android_site_load_path)
892 emacs_abort (); 927 emacs_abort ();
893 928
929 android_game_path = malloc (PATH_MAX + 1);
930
931 if (!android_game_path)
932 emacs_abort ();
933
894 snprintf (android_site_load_path, PATH_MAX, "%s/site-lisp", 934 snprintf (android_site_load_path, PATH_MAX, "%s/site-lisp",
895 android_files_dir); 935 android_files_dir);
936 snprintf (android_game_path, PATH_MAX, "%s/scores", android_files_dir);
937
896 __android_log_print (ANDROID_LOG_INFO, __func__, 938 __android_log_print (ANDROID_LOG_INFO, __func__,
897 "Site-lisp directory: %s\n" 939 "Site-lisp directory: %s\n"
898 "Files directory: %s\n" 940 "Files directory: %s\n"
899 "Native code directory: %s", 941 "Native code directory: %s\n"
942 "Game score path: %s\n",
900 android_site_load_path, 943 android_site_load_path,
901 android_files_dir, 944 android_files_dir,
902 android_lib_dir); 945 android_lib_dir, android_game_path);
903 946
904 /* Make a reference to the Emacs service. */ 947 /* Make a reference to the Emacs service. */
905 emacs_service = (*env)->NewGlobalRef (env, emacs_service_object); 948 emacs_service = (*env)->NewGlobalRef (env, emacs_service_object);
@@ -997,6 +1040,7 @@ android_init_emacs_pixmap (void)
997 assert (pixmap_class.c_name); 1040 assert (pixmap_class.c_name);
998 1041
999 FIND_METHOD (constructor, "<init>", "(S[IIII)V"); 1042 FIND_METHOD (constructor, "<init>", "(S[IIII)V");
1043 FIND_METHOD (constructor_mutable, "<init>", "(SIII)V");
1000 1044
1001#undef FIND_METHOD 1045#undef FIND_METHOD
1002} 1046}
@@ -1031,6 +1075,36 @@ android_init_graphics_point (void)
1031#undef FIND_METHOD 1075#undef FIND_METHOD
1032} 1076}
1033 1077
1078static void
1079android_init_emacs_drawable (void)
1080{
1081 jclass old;
1082
1083 drawable_class.class
1084 = (*android_java_env)->FindClass (android_java_env,
1085 "org/gnu/emacs/EmacsDrawable");
1086 eassert (drawable_class.class);
1087
1088 old = drawable_class.class;
1089 drawable_class.class
1090 = (jclass) (*android_java_env)->NewGlobalRef (android_java_env,
1091 (jobject) old);
1092 ANDROID_DELETE_LOCAL_REF (old);
1093
1094 if (!drawable_class.class)
1095 emacs_abort ();
1096
1097#define FIND_METHOD(c_name, name, signature) \
1098 drawable_class.c_name \
1099 = (*android_java_env)->GetMethodID (android_java_env, \
1100 drawable_class.class, \
1101 name, signature); \
1102 assert (drawable_class.c_name);
1103
1104 FIND_METHOD (get_bitmap, "getBitmap", "()Landroid/graphics/Bitmap;");
1105#undef FIND_METHOD
1106}
1107
1034extern JNIEXPORT void JNICALL 1108extern JNIEXPORT void JNICALL
1035NATIVE_NAME (initEmacs) (JNIEnv *env, jobject object, jarray argv) 1109NATIVE_NAME (initEmacs) (JNIEnv *env, jobject object, jarray argv)
1036{ 1110{
@@ -1063,6 +1137,15 @@ NATIVE_NAME (initEmacs) (JNIEnv *env, jobject object, jarray argv)
1063 android_init_emacs_service (); 1137 android_init_emacs_service ();
1064 android_init_emacs_pixmap (); 1138 android_init_emacs_pixmap ();
1065 android_init_graphics_point (); 1139 android_init_graphics_point ();
1140 android_init_emacs_drawable ();
1141
1142 /* Set HOME to the app data directory. */
1143 setenv ("HOME", android_files_dir, 1);
1144
1145 /* Set the cwd to that directory as well. */
1146 if (chdir (android_files_dir))
1147 __android_log_print (ANDROID_LOG_WARN, __func__,
1148 "chdir: %s", strerror (errno));
1066 1149
1067 /* Initialize the Android GUI. */ 1150 /* Initialize the Android GUI. */
1068 android_init_gui = true; 1151 android_init_gui = true;
@@ -1099,7 +1182,8 @@ NATIVE_NAME (sendConfigureNotify) (JNIEnv *env, jobject object,
1099extern JNIEXPORT void JNICALL 1182extern JNIEXPORT void JNICALL
1100NATIVE_NAME (sendKeyPress) (JNIEnv *env, jobject object, 1183NATIVE_NAME (sendKeyPress) (JNIEnv *env, jobject object,
1101 jshort window, jlong time, 1184 jshort window, jlong time,
1102 jint state, jint keycode) 1185 jint state, jint keycode,
1186 jint unicode_char)
1103{ 1187{
1104 union android_event event; 1188 union android_event event;
1105 1189
@@ -1108,6 +1192,7 @@ NATIVE_NAME (sendKeyPress) (JNIEnv *env, jobject object,
1108 event.xkey.time = time; 1192 event.xkey.time = time;
1109 event.xkey.state = state; 1193 event.xkey.state = state;
1110 event.xkey.keycode = keycode; 1194 event.xkey.keycode = keycode;
1195 event.xkey.unicode_char = unicode_char;
1111 1196
1112 android_write_event (&event); 1197 android_write_event (&event);
1113} 1198}
@@ -1115,7 +1200,8 @@ NATIVE_NAME (sendKeyPress) (JNIEnv *env, jobject object,
1115extern JNIEXPORT void JNICALL 1200extern JNIEXPORT void JNICALL
1116NATIVE_NAME (sendKeyRelease) (JNIEnv *env, jobject object, 1201NATIVE_NAME (sendKeyRelease) (JNIEnv *env, jobject object,
1117 jshort window, jlong time, 1202 jshort window, jlong time,
1118 jint state, jint keycode) 1203 jint state, jint keycode,
1204 jint unicode_char)
1119{ 1205{
1120 union android_event event; 1206 union android_event event;
1121 1207
@@ -1124,6 +1210,46 @@ NATIVE_NAME (sendKeyRelease) (JNIEnv *env, jobject object,
1124 event.xkey.time = time; 1210 event.xkey.time = time;
1125 event.xkey.state = state; 1211 event.xkey.state = state;
1126 event.xkey.keycode = keycode; 1212 event.xkey.keycode = keycode;
1213 event.xkey.unicode_char = unicode_char;
1214
1215 android_write_event (&event);
1216}
1217
1218extern JNIEXPORT void JNICALL
1219NATIVE_NAME (sendFocusIn) (JNIEnv *env, jobject object,
1220 jshort window, jlong time)
1221{
1222 union android_event event;
1223
1224 event.xkey.type = ANDROID_FOCUS_IN;
1225 event.xkey.window = window;
1226 event.xkey.time = time;
1227
1228 android_write_event (&event);
1229}
1230
1231extern JNIEXPORT void JNICALL
1232NATIVE_NAME (sendFocusOut) (JNIEnv *env, jobject object,
1233 jshort window, jlong time)
1234{
1235 union android_event event;
1236
1237 event.xkey.type = ANDROID_FOCUS_OUT;
1238 event.xkey.window = window;
1239 event.xkey.time = time;
1240
1241 android_write_event (&event);
1242}
1243
1244extern JNIEXPORT void JNICALL
1245NATIVE_NAME (sendWindowAction) (JNIEnv *env, jobject object,
1246 jshort window, jint action)
1247{
1248 union android_event event;
1249
1250 event.xaction.type = ANDROID_WINDOW_ACTION;
1251 event.xaction.window = window;
1252 event.xaction.action = action;
1127 1253
1128 android_write_event (&event); 1254 android_write_event (&event);
1129} 1255}
@@ -1142,13 +1268,6 @@ NATIVE_NAME (sendKeyRelease) (JNIEnv *env, jobject object,
1142 1268
1143#define MAX_HANDLE 65535 1269#define MAX_HANDLE 65535
1144 1270
1145enum android_handle_type
1146 {
1147 ANDROID_HANDLE_WINDOW,
1148 ANDROID_HANDLE_GCONTEXT,
1149 ANDROID_HANDLE_PIXMAP,
1150 };
1151
1152struct android_handle_entry 1271struct android_handle_entry
1153{ 1272{
1154 /* The type. */ 1273 /* The type. */
@@ -1245,7 +1364,7 @@ android_destroy_handle (android_handle handle)
1245 android_handles[handle].handle = NULL; 1364 android_handles[handle].handle = NULL;
1246} 1365}
1247 1366
1248static jobject 1367jobject
1249android_resolve_handle (android_handle handle, 1368android_resolve_handle (android_handle handle,
1250 enum android_handle_type type) 1369 enum android_handle_type type)
1251{ 1370{
@@ -1625,14 +1744,15 @@ android_change_gc (struct android_gc *gc,
1625 ANDROID_HANDLE_PIXMAP); 1744 ANDROID_HANDLE_PIXMAP);
1626 (*android_java_env)->SetObjectField (android_java_env, 1745 (*android_java_env)->SetObjectField (android_java_env,
1627 gcontext, 1746 gcontext,
1628 emacs_gc_stipple, 1747 emacs_gc_clip_mask,
1629 what); 1748 what);
1630 1749
1631 /* Clearing GCClipMask also clears the clip rectangles. */ 1750 /* Clearing GCClipMask also clears the clip rectangles. */
1632 (*android_java_env)->SetObjectField (android_java_env, 1751 if (!what)
1633 gcontext, 1752 (*android_java_env)->SetObjectField (android_java_env,
1634 emacs_gc_clip_rects, 1753 gcontext,
1635 NULL); 1754 emacs_gc_clip_rects,
1755 NULL);
1636 } 1756 }
1637 1757
1638 if (mask & ANDROID_GC_STIPPLE) 1758 if (mask & ANDROID_GC_STIPPLE)
@@ -2008,10 +2128,23 @@ android_create_pixmap_from_bitmap_data (char *data, unsigned int width,
2008 { 2128 {
2009 for (x = 0; x < width; ++x) 2129 for (x = 0; x < width; ++x)
2010 { 2130 {
2011 if (data[y / 8] & (1 << (x % 8))) 2131 if (depth == 24)
2012 region[x] = foreground; 2132 {
2133 /* The alpha channels must be set, or otherwise, the
2134 pixmap will be created entirely transparent. */
2135
2136 if (data[y * (width + 7) / 8 + x / 8] & (1 << (x % 8)))
2137 region[x] = foreground | 0xff000000;
2138 else
2139 region[x] = background | 0xff000000;
2140 }
2013 else 2141 else
2014 region[x] = background; 2142 {
2143 if (data[y * (width + 7) / 8 + x / 8] & (1 << (x % 8)))
2144 region[x] = foreground;
2145 else
2146 region[x] = background;
2147 }
2015 } 2148 }
2016 2149
2017 (*android_java_env)->SetIntArrayRegion (android_java_env, 2150 (*android_java_env)->SetIntArrayRegion (android_java_env,
@@ -2236,36 +2369,21 @@ android_create_pixmap (unsigned int width, unsigned int height,
2236{ 2369{
2237 android_handle prev_max_handle; 2370 android_handle prev_max_handle;
2238 jobject object; 2371 jobject object;
2239 jintArray colors;
2240 android_pixmap pixmap; 2372 android_pixmap pixmap;
2241 2373
2242 /* Create the color array holding the data. */
2243 colors = (*android_java_env)->NewIntArray (android_java_env,
2244 width * height);
2245
2246 if (!colors)
2247 {
2248 (*android_java_env)->ExceptionClear (android_java_env);
2249 memory_full (0);
2250 }
2251
2252 /* First, allocate the pixmap handle. */ 2374 /* First, allocate the pixmap handle. */
2253 prev_max_handle = max_handle; 2375 prev_max_handle = max_handle;
2254 pixmap = android_alloc_id (); 2376 pixmap = android_alloc_id ();
2255 2377
2256 if (!pixmap) 2378 if (!pixmap)
2257 { 2379 error ("Out of pixmap handles!");
2258 ANDROID_DELETE_LOCAL_REF ((jobject) colors);
2259 error ("Out of pixmap handles!");
2260 }
2261 2380
2262 object = (*android_java_env)->NewObject (android_java_env, 2381 object = (*android_java_env)->NewObject (android_java_env,
2263 pixmap_class.class, 2382 pixmap_class.class,
2264 pixmap_class.constructor, 2383 pixmap_class.constructor_mutable,
2265 (jshort) pixmap, colors, 2384 (jshort) pixmap,
2266 (jint) width, (jint) height, 2385 (jint) width, (jint) height,
2267 (jint) depth); 2386 (jint) depth);
2268 ANDROID_DELETE_LOCAL_REF ((jobject) colors);
2269 2387
2270 if (!object) 2388 if (!object)
2271 { 2389 {
@@ -2313,6 +2431,387 @@ android_clear_area (android_window handle, int x, int y,
2313 (jint) width, (jint) height); 2431 (jint) width, (jint) height);
2314} 2432}
2315 2433
2434android_pixmap
2435android_create_bitmap_from_data (char *bits, unsigned int width,
2436 unsigned int height)
2437{
2438 return android_create_pixmap_from_bitmap_data (bits, 1, 0,
2439 width, height, 1);
2440}
2441
2442struct android_image *
2443android_create_image (unsigned int depth, enum android_image_format format,
2444 char *data, unsigned int width, unsigned int height)
2445{
2446 struct android_image *image;
2447
2448 image = xmalloc (sizeof *image);
2449
2450 /* Fill in the fields required by image.c. N.B. that
2451 android_destroy_image ostensibly will free data, but image.c
2452 mostly sets and frees data itself. */
2453 image->width = width;
2454 image->height = height;
2455 image->data = data;
2456 image->depth = depth;
2457 image->format = format;
2458
2459 /* Now fill in the image dimensions. There are only two depths
2460 supported by this function. */
2461
2462 if (depth == 1)
2463 {
2464 image->bytes_per_line = (width + 7) / 8;
2465 image->bits_per_pixel = 1;
2466 }
2467 else if (depth == 24)
2468 {
2469 image->bytes_per_line = width * 4;
2470 image->bits_per_pixel = 32;
2471 }
2472 else
2473 emacs_abort ();
2474
2475 return image;
2476}
2477
2478void
2479android_destroy_image (struct android_image *ximg)
2480{
2481 /* If XIMG->data is NULL, then it has already been freed by
2482 image.c. */
2483
2484 if (ximg->data)
2485 xfree (ximg->data);
2486 xfree (ximg);
2487}
2488
2489void
2490android_put_pixel (struct android_image *ximg, int x, int y,
2491 unsigned long pixel)
2492{
2493 char *byte, *word;
2494 unsigned int r, g, b;
2495
2496 /* Ignore out-of-bounds accesses. */
2497
2498 if (x >= ximg->width || y >= ximg->height || x < 0 || y < 0)
2499 return;
2500
2501 switch (ximg->depth)
2502 {
2503 case 1:
2504 byte = ximg->data + y * ximg->bytes_per_line + x / 8;
2505
2506 if (pixel)
2507 *byte |= (1 << x % 8);
2508 else
2509 *byte &= ~(1 << x % 8);
2510 break;
2511
2512 case 24:
2513 /* Unaligned accesses are problematic on Android devices. */
2514 word = ximg->data + y * ximg->bytes_per_line + x * 4;
2515
2516 /* Swizzle the pixel into ABGR format. Android uses Skia's
2517 ``native color type'', which is ABGR. This is despite the
2518 format being named ``ARGB'', and more confusingly
2519 `ANDROID_BITMAP_FORMAT_RGBA_8888' in bitmap.h. */
2520 r = pixel & 0x00ff0000;
2521 g = pixel & 0x0000ff00;
2522 b = pixel & 0x000000ff;
2523 pixel = (r >> 16) | g | (b << 16) | 0xff000000;
2524
2525 memcpy (word, &pixel, sizeof pixel);
2526 break;
2527 }
2528}
2529
2530unsigned long
2531android_get_pixel (struct android_image *ximg, int x, int y)
2532{
2533 char *byte, *word;
2534 unsigned int pixel, r, g, b;
2535
2536 if (x >= ximg->width || y >= ximg->height
2537 || x < 0 || y < 0)
2538 return 0;
2539
2540 switch (ximg->depth)
2541 {
2542 case 1:
2543 byte = ximg->data + y * ximg->bytes_per_line + x / 8;
2544 return (*byte & (1 << x % 8)) ? 1 : 0;
2545
2546 case 24:
2547 word = ximg->data + y * ximg->bytes_per_line + x * 4;
2548 memcpy (&pixel, word, sizeof pixel);
2549
2550 /* Convert the pixel back to RGB. */
2551 b = pixel & 0x00ff0000;
2552 g = pixel & 0x0000ff00;
2553 r = pixel & 0x000000ff;
2554 pixel = ((r << 16) | g | (b >> 16)) & ~0xff000000;
2555
2556 return pixel;
2557 }
2558
2559 emacs_abort ();
2560}
2561
2562struct android_image *
2563android_get_image (android_drawable handle,
2564 enum android_image_format format)
2565{
2566 jobject drawable, bitmap;
2567 AndroidBitmapInfo bitmap_info;
2568 size_t byte_size;
2569 void *data;
2570 struct android_image *image;
2571 unsigned char *data1, *data2;
2572 int i, x;
2573
2574 /* N.B. that supporting windows requires some more work to make
2575 EmacsDrawable.getBitmap thread safe. */
2576 drawable = android_resolve_handle2 (handle, ANDROID_HANDLE_WINDOW,
2577 ANDROID_HANDLE_PIXMAP);
2578
2579 /* Look up the drawable and get the bitmap corresponding to it.
2580 Then, lock the bitmap's bits. */
2581 bitmap = (*android_java_env)->CallObjectMethod (android_java_env,
2582 drawable,
2583 drawable_class.get_bitmap);
2584 if (!bitmap)
2585 {
2586 (*android_java_env)->ExceptionClear (android_java_env);
2587 memory_full (0);
2588 }
2589
2590 memset (&bitmap_info, 0, sizeof bitmap_info);
2591
2592 /* The NDK doc seems to imply this function can fail but doesn't say
2593 what value it gives when it does! */
2594 AndroidBitmap_getInfo (android_java_env, bitmap, &bitmap_info);
2595
2596 if (!bitmap_info.stride)
2597 {
2598 ANDROID_DELETE_LOCAL_REF (bitmap);
2599 memory_full (0);
2600 }
2601
2602 /* Compute how big the image data will be. Fail if it would be too
2603 big. */
2604
2605 if (bitmap_info.format != ANDROID_BITMAP_FORMAT_A_8)
2606 {
2607 if (INT_MULTIPLY_WRAPV ((size_t) bitmap_info.stride,
2608 (size_t) bitmap_info.height,
2609 &byte_size))
2610 {
2611 ANDROID_DELETE_LOCAL_REF (bitmap);
2612 memory_full (0);
2613 }
2614 }
2615 else
2616 /* This A8 image will be packed into A1 later on. */
2617 byte_size = (bitmap_info.width + 7) / 8;
2618
2619 /* Lock the image data. Once again, the NDK documentation says the
2620 call can fail, but does not say how to determine whether or not
2621 it has failed, nor how the address is aligned. */
2622 data = NULL;
2623 AndroidBitmap_lockPixels (android_java_env, bitmap, &data);
2624
2625 if (!data)
2626 {
2627 /* Take a NULL pointer to mean that AndroidBitmap_lockPixels
2628 failed. */
2629 ANDROID_DELETE_LOCAL_REF (bitmap);
2630 memory_full (0);
2631 }
2632
2633 /* Copy the data into a new struct android_image. */
2634 image = xmalloc (sizeof *image);
2635 image->width = bitmap_info.width;
2636 image->height = bitmap_info.height;
2637 image->data = malloc (byte_size);
2638
2639 if (!image->data)
2640 {
2641 ANDROID_DELETE_LOCAL_REF (bitmap);
2642 xfree (image);
2643 memory_full (byte_size);
2644 }
2645
2646 /* Use the format of the bitmap to determine the image depth. */
2647 switch (bitmap_info.format)
2648 {
2649 case ANDROID_BITMAP_FORMAT_RGBA_8888:
2650 image->depth = 24;
2651 image->bits_per_pixel = 32;
2652 break;
2653
2654 /* A8 images are used by Emacs to represent bitmaps. They have
2655 to be packed manually. */
2656 case ANDROID_BITMAP_FORMAT_A_8:
2657 image->depth = 1;
2658 image->bits_per_pixel = 1;
2659 break;
2660
2661 /* Other formats are currently not supported. */
2662 default:
2663 emacs_abort ();
2664 }
2665
2666 image->format = format;
2667
2668 if (image->depth == 24)
2669 {
2670 image->bytes_per_line = bitmap_info.stride;
2671
2672 /* Copy the bitmap data over. */
2673 memcpy (image->data, data, byte_size);
2674 }
2675 else
2676 {
2677 /* Pack the A8 image data into bits manually. */
2678 image->bytes_per_line = (image->width + 7) / 8;
2679
2680 data1 = (unsigned char *) image->data;
2681 data2 = data;
2682
2683 for (i = 0; i < image->height; ++i)
2684 {
2685 for (x = 0; x < image->width; ++x)
2686 /* Some bits in data1 might be initialized at this point,
2687 but they will all be set properly later. */
2688 data1[x / 8] = (data2[x]
2689 ? (data1[x / 8] | (1 << (x % 8)))
2690 : (data1[x / 8] & ~(1 << (x % 8))));
2691
2692 data1 += image->bytes_per_line;
2693 data2 += bitmap_info.stride;
2694 }
2695 }
2696
2697 /* Unlock the bitmap pixels. */
2698 AndroidBitmap_unlockPixels (android_java_env, bitmap);
2699
2700 /* Delete the bitmap reference. */
2701 ANDROID_DELETE_LOCAL_REF (bitmap);
2702 return image;
2703}
2704
2705void
2706android_put_image (android_pixmap handle, struct android_image *image)
2707{
2708 jobject drawable, bitmap;
2709 AndroidBitmapInfo bitmap_info;
2710 void *data;
2711 unsigned char *data_1, *data_2;
2712 int i, x;
2713
2714 drawable = android_resolve_handle (handle, ANDROID_HANDLE_PIXMAP);
2715
2716 /* Look up the drawable and get the bitmap corresponding to it.
2717 Then, lock the bitmap's bits. */
2718 bitmap = (*android_java_env)->CallObjectMethod (android_java_env,
2719 drawable,
2720 drawable_class.get_bitmap);
2721 if (!bitmap)
2722 {
2723 (*android_java_env)->ExceptionClear (android_java_env);
2724 memory_full (0);
2725 }
2726
2727 memset (&bitmap_info, 0, sizeof bitmap_info);
2728
2729 /* The NDK doc seems to imply this function can fail but doesn't say
2730 what value it gives when it does! */
2731 AndroidBitmap_getInfo (android_java_env, bitmap, &bitmap_info);
2732
2733 if (!bitmap_info.stride)
2734 {
2735 ANDROID_DELETE_LOCAL_REF (bitmap);
2736 memory_full (0);
2737 }
2738
2739 if (bitmap_info.width != image->width
2740 || bitmap_info.height != image->height)
2741 /* This is not yet supported. */
2742 emacs_abort ();
2743
2744 /* Make sure the bitmap formats are compatible with each other. */
2745
2746 if ((image->depth == 24
2747 && bitmap_info.format != ANDROID_BITMAP_FORMAT_RGBA_8888)
2748 || (image->depth == 1
2749 && bitmap_info.format != ANDROID_BITMAP_FORMAT_A_8))
2750 emacs_abort ();
2751
2752 /* Lock the image data. Once again, the NDK documentation says the
2753 call can fail, but does not say how to determine whether or not
2754 it has failed, nor how the address is aligned. */
2755 data = NULL;
2756 AndroidBitmap_lockPixels (android_java_env, bitmap, &data);
2757
2758 if (!data)
2759 {
2760 /* Take a NULL pointer to mean that AndroidBitmap_lockPixels
2761 failed. */
2762 ANDROID_DELETE_LOCAL_REF (bitmap);
2763 memory_full (0);
2764 }
2765
2766 data_1 = data;
2767 data_2 = (unsigned char *) image->data;
2768
2769 /* Copy the bitmap data over scanline-by-scanline. */
2770 for (i = 0; i < image->height; ++i)
2771 {
2772 if (image->depth != 1)
2773 memcpy (data_1, data_2,
2774 image->width * (image->bits_per_pixel / 8));
2775 else
2776 {
2777 /* Android internally uses a 1 byte-per-pixel format for
2778 ALPHA_8 images. Expand the image from the 1
2779 bit-per-pixel X format correctly. */
2780
2781 for (x = 0; x < image->width; ++x)
2782 data_1[x] = (data_2[x / 8] & (1 << x % 8)) ? 0xff : 0;
2783 }
2784
2785 data_1 += bitmap_info.stride;
2786 data_2 += image->bytes_per_line;
2787 }
2788
2789 /* Unlock the bitmap pixels. */
2790 AndroidBitmap_unlockPixels (android_java_env, bitmap);
2791
2792 /* Delete the bitmap reference. */
2793 ANDROID_DELETE_LOCAL_REF (bitmap);
2794}
2795
2796
2797
2798#undef faccessat
2799
2800/* Replace the system faccessat with one which understands AT_EACCESS.
2801 Android's faccessat simply fails upon using AT_EACCESS, so repalce
2802 it with zero here. This isn't caught during configuration. */
2803
2804int
2805faccessat (int dirfd, const char *pathname, int mode, int flags)
2806{
2807 static int (*real_faccessat) (int, const char *, int, int);
2808
2809 if (!real_faccessat)
2810 real_faccessat = dlsym (RTLD_NEXT, "faccessat");
2811
2812 return real_faccessat (dirfd, pathname, mode, flags & ~AT_EACCESS);
2813}
2814
2316#else /* ANDROID_STUBIFY */ 2815#else /* ANDROID_STUBIFY */
2317 2816
2318/* X emulation functions for Android. */ 2817/* X emulation functions for Android. */
@@ -2332,4 +2831,44 @@ android_free_gc (struct android_gc *gc)
2332 emacs_abort (); 2831 emacs_abort ();
2333} 2832}
2334 2833
2834struct android_image *
2835android_create_image (unsigned int depth, enum android_image_format format,
2836 char *data, unsigned int width, unsigned int height)
2837{
2838 emacs_abort ();
2839}
2840
2841void
2842android_destroy_image (struct android_image *ximg)
2843{
2844 emacs_abort ();
2845}
2846
2847void
2848android_put_pixel (struct android_image *ximg, int x, int y,
2849 unsigned long pixel)
2850{
2851 emacs_abort ();
2852}
2853
2854unsigned long
2855android_get_pixel (struct android_image *ximg, int x, int y)
2856{
2857 emacs_abort ();
2858}
2859
2860struct android_image *
2861android_get_image (android_drawable drawable,
2862 enum android_image_format format)
2863{
2864 emacs_abort ();
2865}
2866
2867void
2868android_put_image (android_pixmap pixmap,
2869 struct android_image *image)
2870{
2871 emacs_abort ();
2872}
2873
2335#endif 2874#endif
diff --git a/src/android.h b/src/android.h
index 6bdcd38ed68..4d702fe2079 100644
--- a/src/android.h
+++ b/src/android.h
@@ -28,6 +28,8 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
28#include <jni.h> 28#include <jni.h>
29#include <pwd.h> 29#include <pwd.h>
30#include <sys/stat.h> 30#include <sys/stat.h>
31
32#include "androidgui.h"
31#endif 33#endif
32 34
33/* This must be used in every symbol declaration to export it to the 35/* This must be used in every symbol declaration to export it to the
@@ -49,6 +51,19 @@ extern int android_fstat (int, struct stat *);
49extern int android_fstatat (int, const char *restrict, 51extern int android_fstatat (int, const char *restrict,
50 struct stat *restrict, int); 52 struct stat *restrict, int);
51extern int android_close (int); 53extern int android_close (int);
54extern const char *android_get_home_directory (void);
55
56extern double android_pixel_density_x, android_pixel_density_y;
57
58enum android_handle_type
59 {
60 ANDROID_HANDLE_WINDOW,
61 ANDROID_HANDLE_GCONTEXT,
62 ANDROID_HANDLE_PIXMAP,
63 };
64
65extern jobject android_resolve_handle (android_handle,
66 enum android_handle_type);
52 67
53#endif 68#endif
54 69
diff --git a/src/androidfns.c b/src/androidfns.c
index e9e1ae3d52e..a78b35fc8ff 100644
--- a/src/androidfns.c
+++ b/src/androidfns.c
@@ -531,9 +531,10 @@ android_default_font_parameter (struct frame *f, Lisp_Object parms)
531 if (! FONTP (font) && ! STRINGP (font)) 531 if (! FONTP (font) && ! STRINGP (font))
532 { 532 {
533 const char *names[] = { 533 const char *names[] = {
534 /* This will find the normal font. */ 534 /* This will find the normal font. The default font size on
535 "DroidSansMono", 535 Android is 8. */
536 "monospace", 536 "monospace",
537 "DroidSansMono",
537 NULL 538 NULL
538 }; 539 };
539 int i; 540 int i;
diff --git a/src/androidfont.c b/src/androidfont.c
index e312e55c54a..b2c83201b06 100644
--- a/src/androidfont.c
+++ b/src/androidfont.c
@@ -49,6 +49,7 @@ struct android_emacs_font_driver
49 jmethodID has_char; 49 jmethodID has_char;
50 jmethodID text_extents; 50 jmethodID text_extents;
51 jmethodID encode_char; 51 jmethodID encode_char;
52 jmethodID draw;
52 53
53 /* Static methods. */ 54 /* Static methods. */
54 jmethodID create_font_driver; 55 jmethodID create_font_driver;
@@ -67,6 +68,7 @@ struct android_emacs_font_spec
67 jfieldID size; 68 jfieldID size;
68 jfieldID spacing; 69 jfieldID spacing;
69 jfieldID avgwidth; 70 jfieldID avgwidth;
71 jfieldID dpi;
70}; 72};
71 73
72struct android_emacs_font_metrics 74struct android_emacs_font_metrics
@@ -113,6 +115,9 @@ struct androidfont_info
113 115
114 /* The Java-side font. */ 116 /* The Java-side font. */
115 jobject object; 117 jobject object;
118
119 /* Cached glyph metrics arranged in a two dimensional array. */
120 struct font_metrics **metrics;
116}; 121};
117 122
118struct androidfont_entity 123struct androidfont_entity
@@ -197,9 +202,11 @@ android_init_font_driver (void)
197 FIND_METHOD (has_char, "hasChar", "(Lorg/gnu/emacs/EmacsFontDriver$Font" 202 FIND_METHOD (has_char, "hasChar", "(Lorg/gnu/emacs/EmacsFontDriver$Font"
198 "Spec;C)I"); 203 "Spec;C)I");
199 FIND_METHOD (text_extents, "textExtents", "(Lorg/gnu/emacs/EmacsFontDriver" 204 FIND_METHOD (text_extents, "textExtents", "(Lorg/gnu/emacs/EmacsFontDriver"
200 "$FontObject;[I[Lorg/gnu/emacs/EmacsFontDriver$FontMetrics;)V"); 205 "$FontObject;[ILorg/gnu/emacs/EmacsFontDriver$FontMetrics;)V");
201 FIND_METHOD (encode_char, "encodeChar", "(Lorg/gnu/emacs/EmacsFontDriver" 206 FIND_METHOD (encode_char, "encodeChar", "(Lorg/gnu/emacs/EmacsFontDriver"
202 "$FontObject;C)I"); 207 "$FontObject;C)I");
208 FIND_METHOD (draw, "draw", "(Lorg/gnu/emacs/EmacsFontDriver$FontObject;"
209 "Lorg/gnu/emacs/EmacsGC;Lorg/gnu/emacs/EmacsDrawable;[IIIIZ)I");
203 210
204 font_driver_class.create_font_driver 211 font_driver_class.create_font_driver
205 = (*android_java_env)->GetStaticMethodID (android_java_env, 212 = (*android_java_env)->GetStaticMethodID (android_java_env,
@@ -252,6 +259,7 @@ android_init_font_spec (void)
252 FIND_FIELD (size, "size", "Ljava/lang/Integer;"); 259 FIND_FIELD (size, "size", "Ljava/lang/Integer;");
253 FIND_FIELD (spacing, "spacing", "Ljava/lang/Integer;"); 260 FIND_FIELD (spacing, "spacing", "Ljava/lang/Integer;");
254 FIND_FIELD (avgwidth, "avgwidth", "Ljava/lang/Integer;"); 261 FIND_FIELD (avgwidth, "avgwidth", "Ljava/lang/Integer;");
262 FIND_FIELD (dpi, "dpi", "Ljava/lang/Integer;");
255#undef FIND_FIELD 263#undef FIND_FIELD
256} 264}
257 265
@@ -449,6 +457,9 @@ androidfont_from_lisp (Lisp_Object font)
449 DO_CARDINAL_FIELD (avgwidth, (FIXNUMP (AREF (font, FONT_AVGWIDTH_INDEX)) 457 DO_CARDINAL_FIELD (avgwidth, (FIXNUMP (AREF (font, FONT_AVGWIDTH_INDEX))
450 ? XFIXNUM (AREF (font, FONT_AVGWIDTH_INDEX)) 458 ? XFIXNUM (AREF (font, FONT_AVGWIDTH_INDEX))
451 : -1)); 459 : -1));
460 DO_CARDINAL_FIELD (dpi, (FIXNUMP (AREF (font, FONT_DPI_INDEX))
461 ? XFIXNUM (AREF (font, FONT_DPI_INDEX))
462 : -1));
452 463
453#undef DO_CARDINAL_FIELD 464#undef DO_CARDINAL_FIELD
454 465
@@ -507,6 +518,8 @@ androidfont_from_java (jobject spec, Lisp_Object entity)
507 DO_CARDINAL_FIELD (size, FONT_SIZE_INDEX, false); 518 DO_CARDINAL_FIELD (size, FONT_SIZE_INDEX, false);
508 DO_CARDINAL_FIELD (spacing, FONT_SPACING_INDEX, false); 519 DO_CARDINAL_FIELD (spacing, FONT_SPACING_INDEX, false);
509 DO_CARDINAL_FIELD (avgwidth, FONT_AVGWIDTH_INDEX, false); 520 DO_CARDINAL_FIELD (avgwidth, FONT_AVGWIDTH_INDEX, false);
521 DO_CARDINAL_FIELD (dpi, FONT_DPI_INDEX, false);
522
510#undef DO_CARDINAL_FIELD 523#undef DO_CARDINAL_FIELD
511} 524}
512 525
@@ -613,49 +626,98 @@ static int
613androidfont_draw (struct glyph_string *s, int from, int to, 626androidfont_draw (struct glyph_string *s, int from, int to,
614 int x, int y, bool with_background) 627 int x, int y, bool with_background)
615{ 628{
616 return 0; 629 struct androidfont_info *info;
630 jarray chars;
631 int rc;
632 jobject gcontext, drawable;
633
634 verify (sizeof (unsigned int) == sizeof (jint));
635 info = (struct androidfont_info *) s->font;
636
637 gcontext = android_resolve_handle (s->gc->gcontext,
638 ANDROID_HANDLE_GCONTEXT);
639 drawable = android_resolve_handle (FRAME_ANDROID_WINDOW (s->f),
640 ANDROID_HANDLE_WINDOW);
641 chars = (*android_java_env)->NewIntArray (android_java_env,
642 to - from);
643
644 if (!chars)
645 {
646 (*android_java_env)->ExceptionClear (android_java_env);
647 memory_full (0);
648 }
649
650 (*android_java_env)->SetIntArrayRegion (android_java_env, chars,
651 0, to - from,
652 (jint *) s->char2b + from);
653
654 info = (struct androidfont_info *) s->font;
655 prepare_face_for_display (s->f, s->face);
656
657 rc = (*android_java_env)->CallIntMethod (android_java_env,
658 font_driver,
659 font_driver_class.draw,
660 info->object,
661 gcontext, drawable,
662 chars, (jint) x, (jint) y,
663 (jint) s->width,
664 (jboolean) with_background);
665 (*android_java_env)->ExceptionClear (android_java_env);
666 ANDROID_DELETE_LOCAL_REF (chars);
667
668 return rc;
617} 669}
618 670
619static Lisp_Object 671static Lisp_Object
620androidfont_open_font (struct frame *f, Lisp_Object font_entity, int x) 672androidfont_open_font (struct frame *f, Lisp_Object font_entity,
673 int pixel_size)
621{ 674{
622 struct androidfont_info *font_info; 675 struct androidfont_info *font_info;
623 struct androidfont_entity *entity; 676 struct androidfont_entity *entity;
624 struct font *font; 677 struct font *font;
625 Lisp_Object font_object, tem; 678 Lisp_Object font_object;
626 jobject old; 679 jobject old;
627 jint value; 680 jint value;
628 681
629 if (x <= 0) 682 if (XFIXNUM (AREF (font_entity, FONT_SIZE_INDEX)) != 0)
683 pixel_size = XFIXNUM (AREF (font_entity, FONT_SIZE_INDEX));
684 else if (pixel_size == 0)
630 { 685 {
631 /* Get pixel size from frame instead. */ 686 /* This bit was copied from xfont.c. The values might need
632 tem = get_frame_param (f, Qfontsize); 687 adjustment. */
633 x = NILP (tem) ? 0 : XFIXNAT (tem); 688
689 if (FRAME_FONT (f))
690 pixel_size = FRAME_FONT (f)->pixel_size;
691 else
692 pixel_size = 12;
634 } 693 }
635 694
636 __android_log_print (ANDROID_LOG_DEBUG, __func__, 695 __android_log_print (ANDROID_LOG_DEBUG, __func__,
637 "opening font entity %"pI"x:%d", 696 "opening font entity %"pI"x:%d",
638 (EMACS_INT) font_entity, x); 697 (EMACS_INT) font_entity, pixel_size);
639 698
640 entity = (struct androidfont_entity *) XFONT_ENTITY (font_entity); 699 entity = (struct androidfont_entity *) XFONT_ENTITY (font_entity);
641 700
642 block_input (); 701 block_input ();
643 font_object = font_make_object (VECSIZE (struct androidfont_info), 702 font_object = font_make_object (VECSIZE (struct androidfont_info),
644 font_entity, x); 703 font_entity, pixel_size);
645 ASET (font_object, FONT_TYPE_INDEX, Qandroid); 704 ASET (font_object, FONT_TYPE_INDEX, Qandroid);
646 font_info = (struct androidfont_info *) XFONT_OBJECT (font_object); 705 font_info = (struct androidfont_info *) XFONT_OBJECT (font_object);
647 font = &font_info->font; 706 font = &font_info->font;
648 font->driver = &androidfont_driver; 707 font->driver = &androidfont_driver;
649 708
650 /* Clear font_info->object early in case GC happens later on! */ 709 /* Clear font_info->object and font_info->metrics early in case GC
710 happens later on! */
651 font_info->object = NULL; 711 font_info->object = NULL;
712 font_info->metrics = NULL;
652 unblock_input (); 713 unblock_input ();
653 714
654 font_info->object 715 font_info->object
655 = (*android_java_env)->CallObjectMethod (android_java_env, 716 = (*android_java_env)->CallObjectMethod (android_java_env,
656 font_driver, 717 font_driver,
657 font_driver_class.open_font, 718 font_driver_class.open_font,
658 entity->object, (jint) x); 719 entity->object,
720 (jint) pixel_size);
659 if (!font_info->object) 721 if (!font_info->object)
660 { 722 {
661 (*android_java_env)->ExceptionClear (android_java_env); 723 (*android_java_env)->ExceptionClear (android_java_env);
@@ -710,9 +772,19 @@ static void
710androidfont_close_font (struct font *font) 772androidfont_close_font (struct font *font)
711{ 773{
712 struct androidfont_info *info; 774 struct androidfont_info *info;
775 int i;
713 776
714 info = (struct androidfont_info *) font; 777 info = (struct androidfont_info *) font;
715 778
779 /* Free the font metrics cache if it exists. */
780
781 if (info->metrics)
782 {
783 for (i = 0; i < 256; ++i)
784 xfree (info->metrics[i]);
785 xfree (info->metrics);
786 }
787
716 /* If info->object is NULL, then FONT was unsuccessfully created, 788 /* If info->object is NULL, then FONT was unsuccessfully created,
717 and there is no global reference that has to be deleted. */ 789 and there is no global reference that has to be deleted. */
718 790
@@ -763,17 +835,64 @@ androidfont_encode_char (struct font *font, int c)
763} 835}
764 836
765static void 837static void
838androidfont_cache_text_extents (struct androidfont_info *info,
839 unsigned int glyph,
840 struct font_metrics *metrics)
841{
842 int i;
843
844 /* Glyphs larger than 65535 can't be cached. */
845 if (glyph >= 256 * 256)
846 return;
847
848 if (!info->metrics)
849 info->metrics = xzalloc (256 * sizeof *info->metrics);
850
851 if (!info->metrics[glyph / 256])
852 {
853 info->metrics[glyph / 256]
854 = xnmalloc (256, sizeof **info->metrics);
855
856 /* Now, all the metrics in that array as invalid by setting
857 lbearing to SHRT_MAX. */
858 for (i = 0; i < 256; ++i)
859 info->metrics[glyph / 256][i].lbearing = SHRT_MAX;
860 }
861
862 /* Finally, cache the glyph. */
863 info->metrics[glyph / 256][glyph % 256] = *metrics;
864}
865
866static bool
867androidfont_check_cached_extents (struct androidfont_info *info,
868 unsigned int glyph,
869 struct font_metrics *metrics)
870{
871 if (info->metrics && info->metrics[glyph / 256]
872 && info->metrics[glyph / 256][glyph % 256].lbearing != SHRT_MAX)
873 {
874 *metrics = info->metrics[glyph / 256][glyph % 256];
875 return true;
876 }
877
878 return false;
879}
880
881static void
766androidfont_text_extents (struct font *font, const unsigned int *code, 882androidfont_text_extents (struct font *font, const unsigned int *code,
767 int nglyphs, struct font_metrics *metrics) 883 int nglyphs, struct font_metrics *metrics)
768{ 884{
769 struct androidfont_info *info; 885 struct androidfont_info *info;
770 jarray codepoint_array, metrics_array; 886 jarray codepoint_array;
771 jobject metrics_object; 887 jobject metrics_object;
772 int i;
773 short value; 888 short value;
774 889
775 info = (struct androidfont_info *) font; 890 info = (struct androidfont_info *) font;
776 891
892 if (nglyphs == 1
893 && androidfont_check_cached_extents (info, *code, metrics))
894 return;
895
777 /* Allocate the arrays of code points and font metrics. */ 896 /* Allocate the arrays of code points and font metrics. */
778 codepoint_array 897 codepoint_array
779 = (*android_java_env)->NewIntArray (android_java_env, 898 = (*android_java_env)->NewIntArray (android_java_env,
@@ -784,92 +903,103 @@ androidfont_text_extents (struct font *font, const unsigned int *code,
784 memory_full (0); 903 memory_full (0);
785 } 904 }
786 905
787 metrics_array 906 verify (sizeof (unsigned int) == sizeof (jint));
788 = (*android_java_env)->NewObjectArray (android_java_env,
789 nglyphs,
790 font_metrics_class.class,
791 NULL);
792 if (!metrics_array)
793 {
794 (*android_java_env)->ExceptionClear (android_java_env);
795 ANDROID_DELETE_LOCAL_REF (metrics_array);
796 memory_full (0);
797 }
798
799 if (sizeof (unsigned int) == sizeof (jint))
800 /* Always true on every Android device. */
801 (*android_java_env)->SetIntArrayRegion (android_java_env,
802 codepoint_array,
803 0, nglyphs,
804 (jint *) code);
805 else
806 emacs_abort ();
807
808 for (i = 0; i < nglyphs; ++i)
809 {
810 metrics_object
811 = (*android_java_env)->AllocObject (android_java_env,
812 font_metrics_class.class);
813 907
814 if (!metrics_object) 908 /* Always true on every Android device. */
815 { 909 (*android_java_env)->SetIntArrayRegion (android_java_env,
816 (*android_java_env)->ExceptionClear (android_java_env); 910 codepoint_array,
817 ANDROID_DELETE_LOCAL_REF (metrics_array); 911 0, nglyphs,
818 ANDROID_DELETE_LOCAL_REF (codepoint_array); 912 (jint *) code);
819 memory_full (0);
820 }
821 913
822 (*android_java_env)->SetObjectArrayElement (android_java_env, 914 metrics_object
823 metrics_array, i, 915 = (*android_java_env)->AllocObject (android_java_env,
824 metrics_object); 916 font_metrics_class.class);
825 ANDROID_DELETE_LOCAL_REF (metrics_object);
826 }
827 917
828 (*android_java_env)->CallVoidMethod (android_java_env, 918 (*android_java_env)->CallVoidMethod (android_java_env,
829 font_driver, 919 font_driver,
830 font_driver_class.text_extents, 920 font_driver_class.text_extents,
831 info->object, codepoint_array, 921 info->object, codepoint_array,
832 metrics_array); 922 metrics_object);
833 923
834 if ((*android_java_env)->ExceptionCheck (android_java_env)) 924 if ((*android_java_env)->ExceptionCheck (android_java_env))
835 { 925 {
836 (*android_java_env)->ExceptionClear (android_java_env); 926 (*android_java_env)->ExceptionClear (android_java_env);
837 ANDROID_DELETE_LOCAL_REF (metrics_array); 927 ANDROID_DELETE_LOCAL_REF (metrics_object);
838 ANDROID_DELETE_LOCAL_REF (codepoint_array); 928 ANDROID_DELETE_LOCAL_REF (codepoint_array);
839 memory_full (0); 929 memory_full (0);
840 } 930 }
841 931
842 for (i = 0; i < nglyphs; ++i)
843 {
844 metrics_object
845 = (*android_java_env)->GetObjectArrayElement (android_java_env,
846 metrics_array, i);
847#define DO_CARDINAL_FIELD(field) \ 932#define DO_CARDINAL_FIELD(field) \
848 value \ 933 value \
849 = (*android_java_env)->GetShortField (android_java_env, \ 934 = (*android_java_env)->GetShortField (android_java_env, \
850 metrics_object, \ 935 metrics_object, \
851 font_metrics_class.field); \ 936 font_metrics_class.field); \
852 metrics[i].field = value; 937 metrics->field = value;
853 938
854 DO_CARDINAL_FIELD (lbearing); 939 DO_CARDINAL_FIELD (lbearing);
855 DO_CARDINAL_FIELD (rbearing); 940 DO_CARDINAL_FIELD (rbearing);
856 DO_CARDINAL_FIELD (width); 941 DO_CARDINAL_FIELD (width);
857 DO_CARDINAL_FIELD (ascent); 942 DO_CARDINAL_FIELD (ascent);
858 DO_CARDINAL_FIELD (descent); 943 DO_CARDINAL_FIELD (descent);
859 944
860#undef DO_CARDINAL_FIELD 945#undef DO_CARDINAL_FIELD
861 946
862 ANDROID_DELETE_LOCAL_REF (metrics_object); 947 ANDROID_DELETE_LOCAL_REF (metrics_object);
863 }
864
865 ANDROID_DELETE_LOCAL_REF (metrics_array);
866 ANDROID_DELETE_LOCAL_REF (codepoint_array); 948 ANDROID_DELETE_LOCAL_REF (codepoint_array);
949
950 /* Emacs spends a lot of time in androidfont_text_extents, which
951 makes calling JNI too slow. Cache the metrics for this single
952 glyph. */
953
954 if (nglyphs == 1)
955 androidfont_cache_text_extents (info, *code, metrics);
867} 956}
868 957
869static Lisp_Object 958static Lisp_Object
870androidfont_list_family (struct frame *f) 959androidfont_list_family (struct frame *f)
871{ 960{
872 return Qnil; 961 Lisp_Object families;
962 jarray family_array;
963 jobject string;
964 jsize i, length;
965 const char *family;
966
967 family_array
968 = (*android_java_env)->CallObjectMethod (android_java_env,
969 font_driver,
970 font_driver_class.list_families);
971 if (!family_array)
972 {
973 (*android_java_env)->ExceptionClear (android_java_env);
974 memory_full (0);
975 }
976
977 length = (*android_java_env)->GetArrayLength (android_java_env,
978 family_array);
979 families = Qnil;
980
981 for (i = 0; i < length; ++i)
982 {
983 string = (*android_java_env)->GetObjectArrayElement (android_java_env,
984 family_array, i);
985 family = (*android_java_env)->GetStringUTFChars (android_java_env,
986 (jstring) string, NULL);
987
988 if (!family)
989 {
990 ANDROID_DELETE_LOCAL_REF (string);
991 ANDROID_DELETE_LOCAL_REF (family_array);
992 }
993
994 families = Fcons (build_string_from_utf8 (string), families);
995 (*android_java_env)->ReleaseStringUTFChars (android_java_env,
996 (jstring) string,
997 family);
998 ANDROID_DELETE_LOCAL_REF (string);
999 }
1000
1001 ANDROID_DELETE_LOCAL_REF (family_array);
1002 return Fnreverse (families);
873} 1003}
874 1004
875struct font_driver androidfont_driver = 1005struct font_driver androidfont_driver =
diff --git a/src/androidgui.h b/src/androidgui.h
index 43ccc86e5c7..b0ea820cfdf 100644
--- a/src/androidgui.h
+++ b/src/androidgui.h
@@ -201,6 +201,9 @@ enum android_event_type
201 ANDROID_KEY_PRESS, 201 ANDROID_KEY_PRESS,
202 ANDROID_KEY_RELEASE, 202 ANDROID_KEY_RELEASE,
203 ANDROID_CONFIGURE_NOTIFY, 203 ANDROID_CONFIGURE_NOTIFY,
204 ANDROID_FOCUS_IN,
205 ANDROID_FOCUS_OUT,
206 ANDROID_WINDOW_ACTION,
204 }; 207 };
205 208
206struct android_any_event 209struct android_any_event
@@ -209,6 +212,13 @@ struct android_any_event
209 android_window window; 212 android_window window;
210}; 213};
211 214
215enum android_modifier_mask
216 {
217 ANDROID_SHIFT_MASK = 193,
218 ANDROID_CONTROL_MASK = 4096,
219 ANDROID_ALT_MASK = 2,
220 };
221
212struct android_key_event 222struct android_key_event
213{ 223{
214 enum android_event_type type; 224 enum android_event_type type;
@@ -216,8 +226,18 @@ struct android_key_event
216 android_time time; 226 android_time time;
217 unsigned int state; 227 unsigned int state;
218 unsigned int keycode; 228 unsigned int keycode;
229 unsigned int unicode_char;
219}; 230};
220 231
232/* These hard coded values are Android modifier keycodes derived
233 through experimentation. */
234
235#define ANDROID_IS_MODIFIER_KEY(key) \
236 ((key) == 57 || (key) == 58 || (key) == 113 || (key) == 114 \
237 || (key) == 119 || (key) == 117 || (key) == 118 || (key) == 78 \
238 || (key) == 94 || (key) == 59 || (key) == 60 || (key) == 95 \
239 || (key) == 63)
240
221struct android_configure_event 241struct android_configure_event
222{ 242{
223 enum android_event_type type; 243 enum android_event_type type;
@@ -227,12 +247,35 @@ struct android_configure_event
227 int width, height; 247 int width, height;
228}; 248};
229 249
250struct android_focus_event
251{
252 enum android_event_type type;
253 android_window window;
254 android_time time;
255};
256
257struct android_window_action_event
258{
259 enum android_event_type type;
260
261 /* The window handle. This can be ANDROID_NONE. */
262 android_window window;
263
264 /* Numerical identifier for this action. If 0 and WINDOW is set,
265 then it means the frame associated with that window has been
266 destroyed. Otherwise, it means Emacs should create a new
267 frame. */
268 unsigned int action;
269};
270
230union android_event 271union android_event
231{ 272{
232 enum android_event_type type; 273 enum android_event_type type;
233 struct android_any_event xany; 274 struct android_any_event xany;
234 struct android_key_event xkey; 275 struct android_key_event xkey;
235 struct android_configure_event xconfigure; 276 struct android_configure_event xconfigure;
277 struct android_focus_event xfocus;
278 struct android_window_action_event xaction;
236}; 279};
237 280
238extern int android_pending (void); 281extern int android_pending (void);
@@ -303,9 +346,47 @@ extern android_pixmap android_create_pixmap (unsigned int, unsigned int,
303extern void android_set_ts_origin (struct android_gc *, int, int); 346extern void android_set_ts_origin (struct android_gc *, int, int);
304extern void android_clear_area (android_window, int, int, unsigned int, 347extern void android_clear_area (android_window, int, int, unsigned int,
305 unsigned int); 348 unsigned int);
349extern android_pixmap android_create_bitmap_from_data (char *, unsigned int,
350 unsigned int);
306 351
307#endif 352#endif
308 353
354
355
356/* Image support. Keep the API as similar to XImage as possible. To
357 avoid leaving a huge mess of "#ifndef ANDROID_STUBIFY" in image.c,
358 stubs should be defined for all functions. */
359
360enum android_image_format
361 {
362 ANDROID_Z_PIXMAP,
363 };
364
365struct android_image
366{
367 int width, height;
368 enum android_image_format format;
369 char *data;
370 int depth;
371 int bytes_per_line;
372 int bits_per_pixel;
373};
374
375extern struct android_image *android_create_image (unsigned int,
376 enum android_image_format,
377 char *, unsigned int,
378 unsigned int);
379extern void android_destroy_image (struct android_image *);
380
381extern void android_put_pixel (struct android_image *, int, int,
382 unsigned long);
383extern unsigned long android_get_pixel (struct android_image *, int, int);
384extern struct android_image *android_get_image (android_drawable,
385 enum android_image_format);
386extern void android_put_image (android_pixmap, struct android_image *);
387
388
389
309/* X emulation stuff also needed while building stubs. */ 390/* X emulation stuff also needed while building stubs. */
310 391
311extern struct android_gc *android_create_gc (enum android_gc_value_mask, 392extern struct android_gc *android_create_gc (enum android_gc_value_mask,
diff --git a/src/androidterm.c b/src/androidterm.c
index bb3c2a29737..0279da4f58d 100644
--- a/src/androidterm.c
+++ b/src/androidterm.c
@@ -39,6 +39,8 @@ struct android_display_info *x_display_list;
39 39
40#ifndef ANDROID_STUBIFY 40#ifndef ANDROID_STUBIFY
41 41
42#include <android/log.h>
43
42enum 44enum
43 { 45 {
44 ANDROID_EVENT_NORMAL, 46 ANDROID_EVENT_NORMAL,
@@ -141,6 +143,124 @@ android_flush_dirty_back_buffer_on (struct frame *f)
141 show_back_buffer (f); 143 show_back_buffer (f);
142} 144}
143 145
146/* Convert between the modifier bits Android uses and the modifier
147 bits Emacs uses. */
148
149static int
150android_android_to_emacs_modifiers (struct android_display_info *dpyinfo,
151 int state)
152{
153 return ((state & ANDROID_CONTROL_MASK) ? ctrl_modifier : 0
154 | (state & ANDROID_SHIFT_MASK) ? shift_modifier : 0
155 | (state & ANDROID_ALT_MASK) ? meta_modifier : 0);
156}
157
158static int
159android_emacs_to_android_modifiers (struct android_display_info *dpyinfo,
160 intmax_t state)
161{
162 return ((state & ctrl_modifier) ? ANDROID_CONTROL_MASK : 0
163 | (state & shift_modifier) ? ANDROID_SHIFT_MASK : 0
164 | (state & meta_modifier) ? ANDROID_ALT_MASK : 0);
165}
166
167static void android_frame_rehighlight (struct android_display_info *);
168
169static void
170android_lower_frame (struct frame *f)
171{
172 /* TODO. */
173}
174
175static void
176android_raise_frame (struct frame *f)
177{
178 /* TODO. */
179}
180
181static void
182android_new_focus_frame (struct android_display_info *dpyinfo,
183 struct frame *frame)
184{
185 struct frame *old_focus;
186
187 old_focus = dpyinfo->focus_frame;
188
189 if (frame != dpyinfo->focus_frame)
190 {
191 /* Set this before calling other routines, so that they see
192 the correct value of x_focus_frame. */
193 dpyinfo->focus_frame = frame;
194
195 if (old_focus && old_focus->auto_lower)
196 android_lower_frame (old_focus);
197
198 if (dpyinfo->focus_frame && dpyinfo->focus_frame->auto_raise)
199 dpyinfo->pending_autoraise_frame = dpyinfo->focus_frame;
200 else
201 dpyinfo->pending_autoraise_frame = NULL;
202 }
203
204 android_frame_rehighlight (dpyinfo);
205}
206
207static void
208android_focus_changed (int type, int state,
209 struct android_display_info *dpyinfo,
210 struct frame *frame, struct input_event *bufp)
211{
212 if (type == ANDROID_FOCUS_IN)
213 {
214 if (dpyinfo->x_focus_event_frame != frame)
215 {
216 android_new_focus_frame (dpyinfo, frame);
217 dpyinfo->x_focus_event_frame = frame;
218 bufp->kind = FOCUS_IN_EVENT;
219 XSETFRAME (bufp->frame_or_window, frame);
220 }
221
222 frame->output_data.android->focus_state |= state;
223 }
224 else if (type == ANDROID_FOCUS_OUT)
225 {
226 frame->output_data.android->focus_state &= ~state;
227
228 if (dpyinfo->x_focus_event_frame == frame)
229 {
230 dpyinfo->x_focus_event_frame = 0;
231 android_new_focus_frame (dpyinfo, 0);
232
233 bufp->kind = FOCUS_OUT_EVENT;
234 XSETFRAME (bufp->frame_or_window, frame);
235 }
236
237 if (frame->pointer_invisible)
238 android_toggle_invisible_pointer (frame, false);
239 }
240}
241
242static void
243android_detect_focus_change (struct android_display_info *dpyinfo,
244 struct frame *frame,
245 union android_event *event,
246 struct input_event *bufp)
247{
248 if (!frame)
249 return;
250
251 switch (event->type)
252 {
253 case ANDROID_FOCUS_IN:
254 case ANDROID_FOCUS_OUT:
255 android_focus_changed (event->type, FOCUS_EXPLICIT,
256 dpyinfo, frame, bufp);
257 break;
258
259 default:
260 break;
261 }
262}
263
144static int 264static int
145handle_one_android_event (struct android_display_info *dpyinfo, 265handle_one_android_event (struct android_display_info *dpyinfo,
146 union android_event *event, int *finish, 266 union android_event *event, int *finish,
@@ -149,11 +269,20 @@ handle_one_android_event (struct android_display_info *dpyinfo,
149 union android_event configureEvent; 269 union android_event configureEvent;
150 struct frame *f, *any, *mouse_frame; 270 struct frame *f, *any, *mouse_frame;
151 Mouse_HLInfo *hlinfo; 271 Mouse_HLInfo *hlinfo;
272 union buffered_input_event inev;
273 int modifiers, count;
274
275 /* It is okay for this to not resemble handle_one_xevent so much.
276 Differences in event handling code are much less nasty than
277 stuble differences in the graphics code. */
152 278
279 count = 0;
153 hlinfo = &dpyinfo->mouse_highlight; 280 hlinfo = &dpyinfo->mouse_highlight;
154 *finish = ANDROID_EVENT_NORMAL; 281 *finish = ANDROID_EVENT_NORMAL;
155 any = android_window_to_frame (dpyinfo, event->xany.window); 282 any = android_window_to_frame (dpyinfo, event->xany.window);
156 283
284 EVENT_INIT (inev.ie);
285
157 switch (event->type) 286 switch (event->type)
158 { 287 {
159 case ANDROID_CONFIGURE_NOTIFY: 288 case ANDROID_CONFIGURE_NOTIFY:
@@ -192,12 +321,15 @@ handle_one_android_event (struct android_display_info *dpyinfo,
192 321
193 case ANDROID_KEY_PRESS: 322 case ANDROID_KEY_PRESS:
194 323
324 /* Set f to any. There are no ``outer windows'' on Android. */
325 f = any;
326
195 /* If mouse-highlight is an integer, input clears out 327 /* If mouse-highlight is an integer, input clears out
196 mouse highlighting. */ 328 mouse highlighting. */
197 if (!hlinfo->mouse_face_hidden && FIXNUMP (Vmouse_highlight) 329 if (!hlinfo->mouse_face_hidden && FIXNUMP (Vmouse_highlight)
198 && (any == 0 330 && (any == 0
199 || !EQ (f->tool_bar_window, hlinfo->mouse_face_window) 331 || !EQ (any->tool_bar_window, hlinfo->mouse_face_window)
200 || !EQ (f->tab_bar_window, hlinfo->mouse_face_window))) 332 || !EQ (any->tab_bar_window, hlinfo->mouse_face_window)))
201 { 333 {
202 mouse_frame = hlinfo->mouse_face_mouse_frame; 334 mouse_frame = hlinfo->mouse_face_mouse_frame;
203 335
@@ -208,13 +340,90 @@ handle_one_android_event (struct android_display_info *dpyinfo,
208 android_flush_dirty_back_buffer_on (mouse_frame); 340 android_flush_dirty_back_buffer_on (mouse_frame);
209 } 341 }
210 342
343 event->xkey.state
344 |= android_emacs_to_android_modifiers (dpyinfo,
345 extra_keyboard_modifiers);
346 modifiers = event->xkey.state;
347
348 /* Common for all keysym input events. */
349 XSETFRAME (inev.ie.frame_or_window, any);
350 inev.ie.modifiers
351 = android_android_to_emacs_modifiers (dpyinfo, modifiers);
352 inev.ie.timestamp = event->xkey.time;
353
354 /* First deal with keysyms which have defined translations to
355 characters. */
356
357 if (event->xkey.unicode_char >= 32
358 && event->xkey.unicode_char < 128)
359 {
360 inev.ie.kind = ASCII_KEYSTROKE_EVENT;
361 inev.ie.code = event->xkey.unicode_char;
362 }
363 else if (event->xkey.unicode_char < 32)
364 {
365 /* If the key is a modifier key, just return. */
366 if (ANDROID_IS_MODIFIER_KEY (event->xkey.keycode))
367 goto done_keysym;
368
369 /* Next, deal with special ``characters'' by giving the
370 keycode to keyboard.c. */
371 inev.ie.kind = NON_ASCII_KEYSTROKE_EVENT;
372 inev.ie.code = event->xkey.keycode;
373 }
374 else
375 {
376 /* Finally, deal with Unicode characters. */
377 inev.ie.kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
378 inev.ie.code = event->xkey.unicode_char;
379 }
380
381 goto done_keysym;
382
383 done_keysym:
384 goto OTHER;
385
386 case ANDROID_FOCUS_IN:
387 case ANDROID_FOCUS_OUT:
388 android_detect_focus_change (dpyinfo, any, event, &inev.ie);
389 goto OTHER;
390
391 case ANDROID_WINDOW_ACTION:
392
393 f = any;
394
395 if (event->xaction.action == 0)
396 {
397 /* Action 0 either means to destroy a frame or to create a
398 new frame, depending on whether or not
399 event->xaction.window exists. */
400
401 if (event->xaction.window)
402 {
403 if (!f)
404 goto OTHER;
405
406 inev.ie.kind = DELETE_WINDOW_EVENT;
407 XSETFRAME (inev.ie.frame_or_window, f);
408 }
409 else
410 /* A new frame must be created. */;
411 }
412
413 goto OTHER;
414
211 default: 415 default:
212 goto OTHER; 416 goto OTHER;
213 } 417 }
214 418
215 OTHER: 419 OTHER:
420 if (inev.ie.kind != NO_EVENT)
421 {
422 kbd_buffer_store_buffered_event (&inev, hold_quit);
423 count++;
424 }
216 425
217 return 0; 426 return count;
218} 427}
219 428
220static int 429static int
@@ -378,15 +587,52 @@ android_focus_frame (struct frame *f, bool noactivate)
378} 587}
379 588
380static void 589static void
381android_frame_rehighlight (struct frame *f) 590android_frame_rehighlight (struct android_display_info *dpyinfo)
382{ 591{
383 /* TODO */ 592 struct frame *old_highlight;
593
594 old_highlight = dpyinfo->highlight_frame;
595
596 if (dpyinfo->focus_frame)
597 {
598 dpyinfo->highlight_frame
599 = ((FRAMEP (FRAME_FOCUS_FRAME (dpyinfo->focus_frame)))
600 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo->focus_frame))
601 : dpyinfo->focus_frame);
602 if (!FRAME_LIVE_P (dpyinfo->highlight_frame))
603 {
604 fset_focus_frame (dpyinfo->focus_frame, Qnil);
605 dpyinfo->highlight_frame = dpyinfo->focus_frame;
606 }
607 }
608 else
609 dpyinfo->highlight_frame = 0;
610
611 if (dpyinfo->highlight_frame != old_highlight)
612 {
613 /* This is not yet required on Android. */
614#if 0
615 if (old_highlight)
616 android_frame_unhighlight (old_highlight);
617 if (dpyinfo->highlight_frame)
618 android_frame_highlight (dpyinfo->highlight_frame);
619#endif
620 }
621}
622
623static void
624android_frame_rehighlight_hook (struct frame *f)
625{
626 android_frame_rehighlight (FRAME_DISPLAY_INFO (f));
384} 627}
385 628
386static void 629static void
387android_frame_raise_lower (struct frame *f, bool raise_flag) 630android_frame_raise_lower (struct frame *f, bool raise_flag)
388{ 631{
389 /* TODO */ 632 if (raise_flag)
633 android_raise_frame (f);
634 else
635 android_lower_frame (f);
390} 636}
391 637
392void 638void
@@ -401,6 +647,10 @@ android_make_frame_visible (struct frame *f)
401void 647void
402android_make_frame_invisible (struct frame *f) 648android_make_frame_invisible (struct frame *f)
403{ 649{
650 /* Don't keep the highlight on an invisible frame. */
651 if (FRAME_DISPLAY_INFO (f)->highlight_frame == f)
652 FRAME_DISPLAY_INFO (f)->highlight_frame = 0;
653
404 android_unmap_window (FRAME_ANDROID_WINDOW (f)); 654 android_unmap_window (FRAME_ANDROID_WINDOW (f));
405 655
406 SET_FRAME_VISIBLE (f, false); 656 SET_FRAME_VISIBLE (f, false);
@@ -584,6 +834,8 @@ android_free_frame_resources (struct frame *f)
584 834
585 if (f == dpyinfo->focus_frame) 835 if (f == dpyinfo->focus_frame)
586 dpyinfo->focus_frame = 0; 836 dpyinfo->focus_frame = 0;
837 if (f == dpyinfo->x_focus_event_frame)
838 dpyinfo->x_focus_event_frame = 0;
587 if (f == dpyinfo->highlight_frame) 839 if (f == dpyinfo->highlight_frame)
588 dpyinfo->highlight_frame = 0; 840 dpyinfo->highlight_frame = 0;
589 if (f == hlinfo->mouse_face_mouse_frame) 841 if (f == hlinfo->mouse_face_mouse_frame)
@@ -783,7 +1035,7 @@ android_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
783 if (p->overlay_p) 1035 if (p->overlay_p)
784 { 1036 {
785 clipmask = android_create_pixmap_from_bitmap_data (bits, p->wd, p->h, 1037 clipmask = android_create_pixmap_from_bitmap_data (bits, p->wd, p->h,
786 1, 0, 0); 1038 1, 0, 1);
787 1039
788 gcv.clip_mask = clipmask; 1040 gcv.clip_mask = clipmask;
789 gcv.clip_x_origin = p->x; 1041 gcv.clip_x_origin = p->x;
@@ -1606,158 +1858,47 @@ android_draw_image_foreground (struct glyph_string *s)
1606 1858
1607 if (s->img->pixmap) 1859 if (s->img->pixmap)
1608 { 1860 {
1609 if (s->img->mask) 1861 unsigned long mask = (ANDROID_GC_CLIP_MASK
1610 { 1862 | ANDROID_GC_CLIP_X_ORIGIN
1611 unsigned long mask = (ANDROID_GC_CLIP_MASK 1863 | ANDROID_GC_CLIP_Y_ORIGIN
1612 | ANDROID_GC_CLIP_X_ORIGIN 1864 | ANDROID_GC_FUNCTION);
1613 | ANDROID_GC_CLIP_Y_ORIGIN 1865 struct android_gc_values xgcv;
1614 | ANDROID_GC_FUNCTION); 1866 struct android_rectangle clip_rect, image_rect, r;
1615 struct android_gc_values xgcv; 1867
1616 struct android_rectangle clip_rect, image_rect, r; 1868 xgcv.clip_mask = s->img->mask;
1617 1869 xgcv.clip_x_origin = x - s->slice.x;
1618 xgcv.clip_mask = s->img->mask; 1870 xgcv.clip_y_origin = y - s->slice.y;
1619 xgcv.clip_x_origin = x - s->slice.x; 1871 xgcv.function = ANDROID_GC_COPY;
1620 xgcv.clip_y_origin = y - s->slice.y; 1872 android_change_gc (s->gc, mask, &xgcv);
1621 xgcv.function = ANDROID_GC_COPY; 1873
1622 android_change_gc (s->gc, mask, &xgcv); 1874 get_glyph_string_clip_rect (s, &clip_rect);
1623 1875 image_rect.x = x;
1624 get_glyph_string_clip_rect (s, &clip_rect); 1876 image_rect.y = y;
1625 image_rect.x = x; 1877 image_rect.width = s->slice.width;
1626 image_rect.y = y; 1878 image_rect.height = s->slice.height;
1627 image_rect.width = s->slice.width; 1879
1628 image_rect.height = s->slice.height; 1880 if (gui_intersect_rectangles (&clip_rect, &image_rect, &r))
1629 1881 android_copy_area (s->img->pixmap,
1630 if (gui_intersect_rectangles (&clip_rect, &image_rect, &r)) 1882 FRAME_ANDROID_WINDOW (s->f),
1631 android_copy_area (s->img->pixmap, FRAME_ANDROID_WINDOW (s->f), 1883 s->gc, s->slice.x + r.x - x,
1632 s->gc, s->slice.x + r.x - x, 1884 s->slice.y + r.y - y,
1633 s->slice.y + r.y - y, 1885 r.width, r.height, r.x, r.y);
1634 r.x, r.y, r.width, r.height); 1886
1635 } 1887 /* When the image has a mask, we can expect that at least part
1636 else 1888 of a mouse highlight or a block cursor will be visible. If
1889 the image doesn't have a mask, make a block cursor visible by
1890 drawing a rectangle around the image. I believe it's looking
1891 better if we do nothing here for mouse-face. */
1892 if (s->hl == DRAW_CURSOR && !s->img->mask)
1637 { 1893 {
1638 unsigned long mask = (ANDROID_GC_CLIP_MASK 1894 int relief = eabs (s->img->relief);
1639 | ANDROID_GC_CLIP_X_ORIGIN 1895 android_draw_rectangle (FRAME_ANDROID_WINDOW (s->f), s->gc,
1640 | ANDROID_GC_CLIP_Y_ORIGIN 1896 x - relief, y - relief,
1641 | ANDROID_GC_FUNCTION); 1897 s->slice.width + relief*2 - 1,
1642 struct android_gc_values xgcv; 1898 s->slice.height + relief*2 - 1);
1643 struct android_rectangle clip_rect, image_rect, r;
1644
1645 xgcv.clip_mask = s->img->mask;
1646 xgcv.clip_x_origin = x - s->slice.x;
1647 xgcv.clip_y_origin = y - s->slice.y;
1648 xgcv.function = ANDROID_GC_COPY;
1649 android_change_gc (s->gc, mask, &xgcv);
1650
1651 get_glyph_string_clip_rect (s, &clip_rect);
1652 image_rect.x = x;
1653 image_rect.y = y;
1654 image_rect.width = s->slice.width;
1655 image_rect.height = s->slice.height;
1656
1657 if (gui_intersect_rectangles (&clip_rect, &image_rect, &r))
1658 android_copy_area (s->img->pixmap,
1659 FRAME_ANDROID_WINDOW (s->f),
1660 s->gc, s->slice.x + r.x - x,
1661 s->slice.y + r.y - y,
1662 r.x, r.y, r.width, r.height);
1663
1664 /* When the image has a mask, we can expect that at
1665 least part of a mouse highlight or a block cursor will
1666 be visible. If the image doesn't have a mask, make
1667 a block cursor visible by drawing a rectangle around
1668 the image. I believe it's looking better if we do
1669 nothing here for mouse-face. */
1670 if (s->hl == DRAW_CURSOR)
1671 {
1672 int relief = eabs (s->img->relief);
1673 android_draw_rectangle (FRAME_ANDROID_WINDOW (s->f), s->gc,
1674 x - relief, y - relief,
1675 s->slice.width + relief*2 - 1,
1676 s->slice.height + relief*2 - 1);
1677 }
1678 } 1899 }
1679 }
1680 else
1681 /* Draw a rectangle if image could not be loaded. */
1682 android_draw_rectangle (FRAME_ANDROID_WINDOW (s->f), s->gc, x, y,
1683 s->slice.width - 1, s->slice.height - 1);
1684}
1685
1686/* Draw the foreground of image glyph string S to PIXMAP. */
1687
1688static void
1689android_draw_image_foreground_1 (struct glyph_string *s,
1690 android_pixmap pixmap)
1691{
1692 int x = 0;
1693 int y = s->ybase - s->y - image_ascent (s->img, s->face, &s->slice);
1694
1695 /* If first glyph of S has a left box line, start drawing it to the
1696 right of that line. */
1697 if (s->face->box != FACE_NO_BOX
1698 && s->first_glyph->left_box_line_p
1699 && s->slice.x == 0)
1700 x += max (s->face->box_vertical_line_width, 0);
1701
1702 /* If there is a margin around the image, adjust x- and y-position
1703 by that margin. */
1704 if (s->slice.x == 0)
1705 x += s->img->hmargin;
1706 if (s->slice.y == 0)
1707 y += s->img->vmargin;
1708 1900
1709 if (s->img->pixmap) 1901 android_set_clip_mask (s->gc, ANDROID_NONE);
1710 {
1711 if (s->img->mask)
1712 {
1713 unsigned long mask = (ANDROID_GC_CLIP_MASK
1714 | ANDROID_GC_CLIP_X_ORIGIN
1715 | ANDROID_GC_CLIP_Y_ORIGIN
1716 | ANDROID_GC_FUNCTION);
1717 struct android_gc_values xgcv;
1718 struct android_rectangle clip_rect, image_rect, r;
1719
1720 xgcv.clip_mask = s->img->mask;
1721 xgcv.clip_x_origin = x - s->slice.x;
1722 xgcv.clip_y_origin = y - s->slice.y;
1723 xgcv.function = ANDROID_GC_COPY;
1724 android_change_gc (s->gc, mask, &xgcv);
1725
1726 get_glyph_string_clip_rect (s, &clip_rect);
1727 image_rect.x = x;
1728 image_rect.y = y;
1729 image_rect.width = s->slice.width;
1730 image_rect.height = s->slice.height;
1731
1732 if (gui_intersect_rectangles (&clip_rect, &image_rect, &r))
1733 android_copy_area (s->img->pixmap, pixmap, s->gc,
1734 s->slice.x + r.x - x,
1735 s->slice.y + r.y - y,
1736 r.x, r.y, r.width, r.height);
1737
1738 android_set_clip_mask (s->gc, ANDROID_NONE);
1739 }
1740 else
1741 {
1742 android_copy_area (s->img->pixmap, pixmap, s->gc,
1743 s->slice.x, s->slice.y,
1744 s->slice.width, s->slice.height, x, y);
1745
1746 /* When the image has a mask, we can expect that at
1747 least part of a mouse highlight or a block cursor will
1748 be visible. If the image doesn't have a mask, make
1749 a block cursor visible by drawing a rectangle around
1750 the image. I believe it's looking better if we do
1751 nothing here for mouse-face. */
1752 if (s->hl == DRAW_CURSOR)
1753 {
1754 int r = eabs (s->img->relief);
1755 android_draw_rectangle (FRAME_ANDROID_WINDOW (s->f),
1756 s->gc, x - r, y - r,
1757 s->slice.width + r*2 - 1,
1758 s->slice.height + r*2 - 1);
1759 }
1760 }
1761 } 1902 }
1762 else 1903 else
1763 /* Draw a rectangle if image could not be loaded. */ 1904 /* Draw a rectangle if image could not be loaded. */
@@ -1771,7 +1912,6 @@ android_draw_image_glyph_string (struct glyph_string *s)
1771 int box_line_hwidth = max (s->face->box_vertical_line_width, 0); 1912 int box_line_hwidth = max (s->face->box_vertical_line_width, 0);
1772 int box_line_vwidth = max (s->face->box_horizontal_line_width, 0); 1913 int box_line_vwidth = max (s->face->box_horizontal_line_width, 0);
1773 int height; 1914 int height;
1774 android_pixmap pixmap = ANDROID_NONE;
1775 1915
1776 height = s->height; 1916 height = s->height;
1777 if (s->slice.y == 0) 1917 if (s->slice.y == 0)
@@ -1793,79 +1933,27 @@ android_draw_image_glyph_string (struct glyph_string *s)
1793 if (s->stippled_p) 1933 if (s->stippled_p)
1794 s->row->stipple_p = true; 1934 s->row->stipple_p = true;
1795 1935
1796 if (s->img->mask) 1936 int x = s->x;
1797 { 1937 int y = s->y;
1798 /* Create a pixmap as large as the glyph string. Fill it 1938 int width = s->background_width;
1799 with the background color. Copy the image to it, using
1800 its mask. Copy the temporary pixmap to the display. */
1801 int depth = FRAME_DISPLAY_INFO (s->f)->n_planes;
1802
1803 /* Create a pixmap as large as the glyph string. */
1804 pixmap = android_create_pixmap (s->background_width,
1805 s->height, depth);
1806
1807 /* Don't clip in the following because we're working on the
1808 pixmap. */
1809 android_set_clip_mask (s->gc, ANDROID_NONE);
1810
1811 /* Fill the pixmap with the background color/stipple. */
1812 if (s->stippled_p)
1813 {
1814 /* Fill background with a stipple pattern. */
1815 android_set_fill_style (s->gc, ANDROID_FILL_OPAQUE_STIPPLED);
1816 android_set_ts_origin (s->gc, - s->x, - s->y);
1817 android_fill_rectangle (pixmap, s->gc,
1818 0, 0, s->background_width, s->height);
1819 android_set_fill_style (s->gc, ANDROID_FILL_OPAQUE_STIPPLED);
1820 android_set_ts_origin (s->gc, 0, 0);
1821 }
1822 else
1823 {
1824 struct android_gc_values xgcv;
1825 1939
1826 android_get_gc_values (s->gc, (ANDROID_GC_FOREGROUND 1940 if (s->first_glyph->left_box_line_p
1827 | ANDROID_GC_BACKGROUND), 1941 && s->slice.x == 0)
1828 &xgcv);
1829 android_set_foreground (s->gc, xgcv.background);
1830 android_fill_rectangle (pixmap, s->gc,
1831 0, 0, s->background_width, s->height);
1832 android_set_background (s->gc, xgcv.foreground);
1833 }
1834 }
1835 else
1836 { 1942 {
1837 int x = s->x; 1943 x += box_line_hwidth;
1838 int y = s->y; 1944 width -= box_line_hwidth;
1839 int width = s->background_width; 1945 }
1840 1946
1841 if (s->first_glyph->left_box_line_p 1947 if (s->slice.y == 0)
1842 && s->slice.x == 0) 1948 y += box_line_vwidth;
1843 {
1844 x += box_line_hwidth;
1845 width -= box_line_hwidth;
1846 }
1847 1949
1848 if (s->slice.y == 0) 1950 android_draw_glyph_string_bg_rect (s, x, y, width, height);
1849 y += box_line_vwidth;
1850
1851 android_draw_glyph_string_bg_rect (s, x, y, width, height);
1852 }
1853 1951
1854 s->background_filled_p = true; 1952 s->background_filled_p = true;
1855 } 1953 }
1856 1954
1857 /* Draw the foreground. */ 1955 /* Draw the foreground. */
1858 if (pixmap != ANDROID_NONE) 1956 android_draw_image_foreground (s);
1859 {
1860 android_draw_image_foreground_1 (s, pixmap);
1861 android_set_glyph_string_clipping (s);
1862 android_copy_area (pixmap, FRAME_ANDROID_WINDOW (s->f), s->gc,
1863 0, 0, s->background_width, s->height, s->x,
1864 s->y);
1865 android_free_pixmap (pixmap);
1866 }
1867 else
1868 android_draw_image_foreground (s);
1869 1957
1870 /* If we must draw a relief around the image, do it. */ 1958 /* If we must draw a relief around the image, do it. */
1871 if (s->img->relief 1959 if (s->img->relief
@@ -3047,7 +3135,7 @@ android_create_terminal (struct android_display_info *dpyinfo)
3047 terminal->mouse_position_hook = android_mouse_position; 3135 terminal->mouse_position_hook = android_mouse_position;
3048 terminal->get_focus_frame = android_get_focus_frame; 3136 terminal->get_focus_frame = android_get_focus_frame;
3049 terminal->focus_frame_hook = android_focus_frame; 3137 terminal->focus_frame_hook = android_focus_frame;
3050 terminal->frame_rehighlight_hook = android_frame_rehighlight; 3138 terminal->frame_rehighlight_hook = android_frame_rehighlight_hook;
3051 terminal->frame_raise_lower_hook = android_frame_raise_lower; 3139 terminal->frame_raise_lower_hook = android_frame_raise_lower;
3052 terminal->frame_visible_invisible_hook 3140 terminal->frame_visible_invisible_hook
3053 = android_make_frame_visible_invisible; 3141 = android_make_frame_visible_invisible;
@@ -3117,9 +3205,12 @@ android_term_init (void)
3117 3205
3118 dpyinfo->color_map = color_map; 3206 dpyinfo->color_map = color_map;
3119 3207
3120 /* TODO! */ 3208#ifndef ANDROID_STUBIFY
3121 dpyinfo->resx = 96.0; 3209
3122 dpyinfo->resy = 96.0; 3210 dpyinfo->resx = android_pixel_density_x;
3211 dpyinfo->resy = android_pixel_density_y;
3212
3213#endif
3123 3214
3124 /* https://lists.gnu.org/r/emacs-devel/2015-11/msg00194.html */ 3215 /* https://lists.gnu.org/r/emacs-devel/2015-11/msg00194.html */
3125 dpyinfo->smallest_font_height = 1; 3216 dpyinfo->smallest_font_height = 1;
@@ -3130,6 +3221,9 @@ android_term_init (void)
3130 /* The display "connection" is now set up, and it must never go 3221 /* The display "connection" is now set up, and it must never go
3131 away. */ 3222 away. */
3132 terminal->reference_count = 30000; 3223 terminal->reference_count = 30000;
3224
3225 /* Set the baud rate to the same value it gets set to on X. */
3226 baud_rate = 19200;
3133} 3227}
3134 3228
3135 3229
diff --git a/src/androidterm.h b/src/androidterm.h
index 3a0c9f60555..c834ffb70e5 100644
--- a/src/androidterm.h
+++ b/src/androidterm.h
@@ -28,8 +28,8 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
28 28
29struct android_bitmap_record 29struct android_bitmap_record
30{ 30{
31 /* The image backing the bitmap. */ 31 /* The image backing the bitmap and its mask. */
32 Emacs_Pixmap img; 32 android_pixmap pixmap, mask;
33 33
34 /* The file from which it comes. */ 34 /* The file from which it comes. */
35 char *file; 35 char *file;
@@ -37,8 +37,11 @@ struct android_bitmap_record
37 /* The number of references to it. */ 37 /* The number of references to it. */
38 int refcount; 38 int refcount;
39 39
40 /* The height and width. */ 40 /* The height and width and the depth. */
41 int height, width; 41 int height, width, depth;
42
43 /* Whether or not there is a mask. */
44 bool have_mask;
42}; 45};
43 46
44struct android_display_info 47struct android_display_info
@@ -95,6 +98,9 @@ struct android_display_info
95 /* The frame currently with the input focus. */ 98 /* The frame currently with the input focus. */
96 struct frame *focus_frame; 99 struct frame *focus_frame;
97 100
101 /* The last frame mentioned in a focus event. */
102 struct frame *x_focus_event_frame;
103
98 /* The frame which currently has the visual highlight, and should 104 /* The frame which currently has the visual highlight, and should
99 get keyboard input. It points to the focus frame's selected 105 get keyboard input. It points to the focus frame's selected
100 window's frame, but can differ. */ 106 window's frame, but can differ. */
@@ -206,8 +212,24 @@ struct android_output
206 /* The background for which the above relief GCs were set up. 212 /* The background for which the above relief GCs were set up.
207 They are changed only when a different background is involved. */ 213 They are changed only when a different background is involved. */
208 unsigned long relief_background; 214 unsigned long relief_background;
215
216 /* Focus state. Only present for consistency with X; it is actually
217 a boolean. */
218 int focus_state;
209}; 219};
210 220
221enum
222 {
223 /* Values for focus_state, used as bit mask. EXPLICIT means we
224 received a FocusIn for the frame and know it has the focus.
225 IMPLICIT means we received an EnterNotify and the frame may
226 have the focus if no window manager is running. FocusOut and
227 LeaveNotify clears EXPLICIT/IMPLICIT. */
228 FOCUS_NONE = 0,
229 FOCUS_IMPLICIT = 1,
230 FOCUS_EXPLICIT = 2
231 };
232
211/* Return the Android output data for frame F. */ 233/* Return the Android output data for frame F. */
212#define FRAME_ANDROID_OUTPUT(f) ((f)->output_data.android) 234#define FRAME_ANDROID_OUTPUT(f) ((f)->output_data.android)
213#define FRAME_OUTPUT_DATA(f) ((f)->output_data.android) 235#define FRAME_OUTPUT_DATA(f) ((f)->output_data.android)
diff --git a/src/dispextern.h b/src/dispextern.h
index e521dffc37c..c9b3495934b 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -160,8 +160,8 @@ typedef Emacs_Pixmap Emacs_Pix_Context;
160#ifdef HAVE_ANDROID 160#ifdef HAVE_ANDROID
161#include "androidgui.h" 161#include "androidgui.h"
162typedef struct android_display_info Display_Info; 162typedef struct android_display_info Display_Info;
163typedef Emacs_Pixmap Emacs_Pix_Container; 163typedef struct android_image *Emacs_Pix_Container;
164typedef Emacs_Pixmap Emacs_Pix_Context; 164typedef struct android_image *Emacs_Pix_Context;
165#endif 165#endif
166 166
167#ifdef HAVE_WINDOW_SYSTEM 167#ifdef HAVE_WINDOW_SYSTEM
@@ -3119,6 +3119,13 @@ struct image
3119 int original_width, original_height; 3119 int original_width, original_height;
3120# endif 3120# endif
3121#endif /* HAVE_X_WINDOWS */ 3121#endif /* HAVE_X_WINDOWS */
3122#ifdef HAVE_ANDROID
3123 /* Android images of the image, corresponding to the above Pixmaps.
3124 Non-NULL means it and its Pixmap counterpart may be out of sync
3125 and the latter is outdated. NULL means the X image has been
3126 synchronized to Pixmap. */
3127 struct android_image *ximg, *mask_img;
3128#endif /* HAVE_ANDROID */
3122#ifdef HAVE_NTGUI 3129#ifdef HAVE_NTGUI
3123 XFORM xform; 3130 XFORM xform;
3124#endif 3131#endif
diff --git a/src/emacs.c b/src/emacs.c
index 9ef58ca412e..d3c53dd8051 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -1440,9 +1440,8 @@ main (int argc, char **argv)
1440 bool only_version = false; 1440 bool only_version = false;
1441 sort_args (argc, argv); 1441 sort_args (argc, argv);
1442 old_argc = argc, argc = 0; 1442 old_argc = argc, argc = 0;
1443 while (argv[argc] 1443 /* Don't allow going past argv. */
1444 /* Don't allow going past argv. */ 1444 while (argc < old_argc && argv[argc]) argc++;
1445 && argc < old_argc) argc++;
1446 1445
1447 skip_args = 0; 1446 skip_args = 0;
1448 if (argmatch (argv, argc, "-version", "--version", 3, NULL, &skip_args)) 1447 if (argmatch (argv, argc, "-version", "--version", 3, NULL, &skip_args))
diff --git a/src/fileio.c b/src/fileio.c
index 1d22c51ebaa..0f205283d7e 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -898,6 +898,10 @@ user_homedir (char const *name)
898 p[length] = 0; 898 p[length] = 0;
899 struct passwd *pw = getpwnam (p); 899 struct passwd *pw = getpwnam (p);
900 SAFE_FREE (); 900 SAFE_FREE ();
901#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
902 if (pw && !pw->pw_dir && pw->pw_uid == getuid ())
903 return (char *) android_get_home_directory ();
904#endif
901 if (!pw || (pw->pw_dir && !IS_ABSOLUTE_FILE_NAME (pw->pw_dir))) 905 if (!pw || (pw->pw_dir && !IS_ABSOLUTE_FILE_NAME (pw->pw_dir)))
902 return NULL; 906 return NULL;
903 return pw->pw_dir; 907 return pw->pw_dir;
@@ -1888,6 +1892,11 @@ get_homedir (void)
1888 pw = getpwuid (getuid ()); 1892 pw = getpwuid (getuid ());
1889 if (pw) 1893 if (pw)
1890 home = pw->pw_dir; 1894 home = pw->pw_dir;
1895
1896#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
1897 if (!home && pw && pw->pw_uid == getuid ())
1898 return android_get_home_directory ();
1899#endif
1891 if (!home) 1900 if (!home)
1892 return ""; 1901 return "";
1893 } 1902 }
diff --git a/src/font.h b/src/font.h
index c1ab26b87cb..1db94a9f3f8 100644
--- a/src/font.h
+++ b/src/font.h
@@ -547,8 +547,14 @@ CHECK_FONT_GET_OBJECT (Lisp_Object x)
547 return XFONT_OBJECT (x); 547 return XFONT_OBJECT (x);
548} 548}
549 549
550#ifndef HAVE_ANDROID
550/* Number of pt per inch (from the TeXbook). */ 551/* Number of pt per inch (from the TeXbook). */
551#define PT_PER_INCH 72.27 552#define PT_PER_INCH 72.27
553#else
554/* Android uses this value instead to compensate for different device
555 dimensions. */
556#define PT_PER_INCH 160.00
557#endif
552 558
553/* Return a pixel size (integer) corresponding to POINT size (double) 559/* Return a pixel size (integer) corresponding to POINT size (double)
554 on resolution DPI. */ 560 on resolution DPI. */
diff --git a/src/fringe.c b/src/fringe.c
index 5d7c8dca998..f10bc424239 100644
--- a/src/fringe.c
+++ b/src/fringe.c
@@ -1422,25 +1422,30 @@ If BITMAP overrides a standard fringe bitmap, the original bitmap is restored.
1422 On X, we bit-swap the built-in bitmaps and reduce bitmap 1422 On X, we bit-swap the built-in bitmaps and reduce bitmap
1423 from short to char array if width is <= 8 bits. 1423 from short to char array if width is <= 8 bits.
1424 1424
1425 The Android port tries to follow X as closely as possible, so do
1426 that there too.
1427
1425 On MAC with big-endian CPU, we need to byte-swap each short. 1428 On MAC with big-endian CPU, we need to byte-swap each short.
1426 1429
1427 On W32 and MAC (little endian), there's no need to do this. 1430 On W32 and MAC (little endian), there's no need to do this.
1428*/ 1431*/
1429 1432
1430#if defined (HAVE_X_WINDOWS) || defined (HAVE_PGTK) 1433#if defined (HAVE_X_WINDOWS) || defined (HAVE_PGTK) || defined (HAVE_ANDROID)
1431static const unsigned char swap_nibble[16] = { 1434static const unsigned char swap_nibble[16] =
1432 0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */ 1435 {
1433 0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */ 1436 0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */
1434 0x1, 0x9, 0x5, 0xd, /* 0001 1001 0101 1101 */ 1437 0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */
1435 0x3, 0xb, 0x7, 0xf}; /* 0011 1011 0111 1111 */ 1438 0x1, 0x9, 0x5, 0xd, /* 0001 1001 0101 1101 */
1436#endif /* HAVE_X_WINDOWS */ 1439 0x3, 0xb, 0x7, 0xf, /* 0011 1011 0111 1111 */
1440 };
1441#endif
1437 1442
1438static void 1443static void
1439init_fringe_bitmap (int which, struct fringe_bitmap *fb, int once_p) 1444init_fringe_bitmap (int which, struct fringe_bitmap *fb, int once_p)
1440{ 1445{
1441 if (once_p || fb->dynamic) 1446 if (once_p || fb->dynamic)
1442 { 1447 {
1443#if defined (HAVE_X_WINDOWS) 1448#if defined (HAVE_X_WINDOWS) || defined (HAVE_ANDROID)
1444 unsigned short *bits = fb->bits; 1449 unsigned short *bits = fb->bits;
1445 int j; 1450 int j;
1446 1451
@@ -1488,7 +1493,7 @@ init_fringe_bitmap (int which, struct fringe_bitmap *fb, int once_p)
1488 } 1493 }
1489 } 1494 }
1490#endif /* not USE_CAIRO */ 1495#endif /* not USE_CAIRO */
1491#endif /* HAVE_X_WINDOWS */ 1496#endif /* HAVE_X_WINDOWS || HAVE_ANDROID */
1492 1497
1493#if !defined(HAVE_X_WINDOWS) && defined (HAVE_PGTK) 1498#if !defined(HAVE_X_WINDOWS) && defined (HAVE_PGTK)
1494 unsigned short *bits = fb->bits; 1499 unsigned short *bits = fb->bits;
diff --git a/src/image.c b/src/image.c
index 986dd7aada4..08d092e2c6e 100644
--- a/src/image.c
+++ b/src/image.c
@@ -177,11 +177,14 @@ typedef struct haiku_bitmap_record Bitmap_Record;
177 177
178#ifdef HAVE_ANDROID 178#ifdef HAVE_ANDROID
179#include "androidterm.h" 179#include "androidterm.h"
180
180typedef struct android_bitmap_record Bitmap_Record; 181typedef struct android_bitmap_record Bitmap_Record;
181 182
182/* TODO: implement images on Android. */ 183typedef struct android_image XImage;
183#define GET_PIXEL(ximg, x, y) 0 184typedef android_pixmap Pixmap;
184#define PUT_PIXEL(ximg, x, y, pixel) ((void) (pixel)) 185
186#define GET_PIXEL(ximg, x, y) android_get_pixel (ximg, x, y)
187#define PUT_PIXEL(ximg, x, y, pixel) android_put_pixel (ximg, x, y, pixel)
185#define NO_PIXMAP 0 188#define NO_PIXMAP 0
186 189
187#define PIX_MASK_RETAIN 0 190#define PIX_MASK_RETAIN 0
@@ -507,6 +510,18 @@ image_create_bitmap_from_data (struct frame *f, char *bits,
507 return -1; 510 return -1;
508#endif /* HAVE_X_WINDOWS */ 511#endif /* HAVE_X_WINDOWS */
509 512
513#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
514 android_pixmap bitmap;
515
516 bitmap = android_create_bitmap_from_data (bits, width, height);
517
518 if (!bitmap)
519 return -1;
520#else
521 ((void) dpyinfo);
522 emacs_abort ();
523#endif
524
510#ifdef HAVE_NTGUI 525#ifdef HAVE_NTGUI
511 Lisp_Object frame UNINIT; /* The value is not used. */ 526 Lisp_Object frame UNINIT; /* The value is not used. */
512 Emacs_Pixmap bitmap; 527 Emacs_Pixmap bitmap;
@@ -619,14 +634,14 @@ image_create_bitmap_from_data (struct frame *f, char *bits,
619 dpyinfo->bitmaps[id - 1].width = width; 634 dpyinfo->bitmaps[id - 1].width = width;
620 dpyinfo->bitmaps[id - 1].refcount = 1; 635 dpyinfo->bitmaps[id - 1].refcount = 1;
621 636
622#ifdef HAVE_X_WINDOWS 637#if defined HAVE_X_WINDOWS && defined HAVE_ANDROID
623 dpyinfo->bitmaps[id - 1].pixmap = bitmap; 638 dpyinfo->bitmaps[id - 1].pixmap = bitmap;
624 dpyinfo->bitmaps[id - 1].have_mask = false; 639 dpyinfo->bitmaps[id - 1].have_mask = false;
625 dpyinfo->bitmaps[id - 1].depth = 1; 640 dpyinfo->bitmaps[id - 1].depth = 1;
626#ifdef USE_CAIRO 641#ifdef USE_CAIRO
627 dpyinfo->bitmaps[id - 1].stipple = NULL; 642 dpyinfo->bitmaps[id - 1].stipple = NULL;
628#endif /* USE_CAIRO */ 643#endif /* USE_CAIRO */
629#endif /* HAVE_X_WINDOWS */ 644#endif /* HAVE_X_WINDOWS || HAVE_ANDROID */
630 645
631#ifdef HAVE_NTGUI 646#ifdef HAVE_NTGUI
632 dpyinfo->bitmaps[id - 1].pixmap = bitmap; 647 dpyinfo->bitmaps[id - 1].pixmap = bitmap;
@@ -637,7 +652,7 @@ image_create_bitmap_from_data (struct frame *f, char *bits,
637 return id; 652 return id;
638} 653}
639 654
640#if defined HAVE_HAIKU || defined HAVE_NS 655#if defined HAVE_HAIKU || defined HAVE_NS || defined HAVE_ANDROID
641static char *slurp_file (int, ptrdiff_t *); 656static char *slurp_file (int, ptrdiff_t *);
642static Lisp_Object image_find_image_fd (Lisp_Object, int *); 657static Lisp_Object image_find_image_fd (Lisp_Object, int *);
643static bool xbm_read_bitmap_data (struct frame *, char *, char *, 658static bool xbm_read_bitmap_data (struct frame *, char *, char *,
@@ -861,8 +876,62 @@ image_create_bitmap_from_file (struct frame *f, Lisp_Object file)
861 /* This function should never be called when building stubs. */ 876 /* This function should never be called when building stubs. */
862 emacs_abort (); 877 emacs_abort ();
863#else 878#else
864 /* you lose, not yet implemented TODO */ 879 ptrdiff_t id, size;
865 return 0; 880 int fd, width, height, rc;
881 char *contents, *data;
882 Lisp_Object found;
883 android_pixmap bitmap;
884
885 /* Look for an existing bitmap with the same name. */
886 for (id = 0; id < dpyinfo->bitmaps_last; ++id)
887 {
888 if (dpyinfo->bitmaps[id].refcount
889 && dpyinfo->bitmaps[id].file
890 && !strcmp (dpyinfo->bitmaps[id].file, SSDATA (file)))
891 {
892 ++dpyinfo->bitmaps[id].refcount;
893 return id + 1;
894 }
895 }
896
897 /* Search bitmap-file-path for the file, if appropriate. */
898 if (openp (Vx_bitmap_file_path, file, Qnil, &found,
899 make_fixnum (R_OK), false, false)
900 < 0)
901 return -1;
902
903 if (!STRINGP (image_find_image_fd (file, &fd))
904 && !STRINGP (image_find_image_fd (found, &fd)))
905 return -1;
906
907 contents = slurp_file (fd, &size);
908
909 if (!contents)
910 return -1;
911
912 rc = xbm_read_bitmap_data (f, contents, contents + size,
913 &width, &height, &data, 0);
914
915 if (!rc)
916 {
917 xfree (contents);
918 return -1;
919 }
920
921 xfree (contents);
922 bitmap = android_create_bitmap_from_data (data, width, height);
923 xfree (data);
924
925 id = image_allocate_bitmap_record (f);
926 dpyinfo->bitmaps[id - 1].pixmap = bitmap;
927 dpyinfo->bitmaps[id - 1].have_mask = false;
928 dpyinfo->bitmaps[id - 1].refcount = 1;
929 dpyinfo->bitmaps[id - 1].file = xlispstrdup (file);
930 dpyinfo->bitmaps[id - 1].depth = 1;
931 dpyinfo->bitmaps[id - 1].height = height;
932 dpyinfo->bitmaps[id - 1].width = width;
933
934 return id;
866#endif 935#endif
867#endif 936#endif
868} 937}
@@ -882,6 +951,13 @@ free_bitmap_record (Display_Info *dpyinfo, Bitmap_Record *bm)
882#endif /* USE_CAIRO */ 951#endif /* USE_CAIRO */
883#endif /* HAVE_X_WINDOWS */ 952#endif /* HAVE_X_WINDOWS */
884 953
954#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
955 android_free_pixmap (bm->pixmap);
956
957 if (bm->have_mask)
958 android_free_pixmap (bm->pixmap);
959#endif
960
885#ifdef HAVE_NTGUI 961#ifdef HAVE_NTGUI
886 DeleteObject (bm->pixmap); 962 DeleteObject (bm->pixmap);
887#endif /* HAVE_NTGUI */ 963#endif /* HAVE_NTGUI */
@@ -969,7 +1045,7 @@ static void image_unget_x_image (struct image *, bool, Emacs_Pix_Container);
969 image_unget_x_image (img, mask_p, ximg) 1045 image_unget_x_image (img, mask_p, ximg)
970#endif 1046#endif
971 1047
972#ifdef HAVE_X_WINDOWS 1048#if defined HAVE_X_WINDOWS || defined HAVE_ANDROID
973 1049
974#ifndef USE_CAIRO 1050#ifndef USE_CAIRO
975static void image_sync_to_pixmaps (struct frame *, struct image *); 1051static void image_sync_to_pixmaps (struct frame *, struct image *);
@@ -983,6 +1059,8 @@ static bool x_create_x_image_and_pixmap (struct frame *, int, int, int,
983 XImage **, Pixmap *); 1059 XImage **, Pixmap *);
984static void x_destroy_x_image (XImage *); 1060static void x_destroy_x_image (XImage *);
985 1061
1062#if defined HAVE_X_WINDOWS
1063
986/* Create a mask of a bitmap. Note is this not a perfect mask. 1064/* Create a mask of a bitmap. Note is this not a perfect mask.
987 It's nicer with some borders in this context */ 1065 It's nicer with some borders in this context */
988 1066
@@ -1079,7 +1157,9 @@ x_create_bitmap_mask (struct frame *f, ptrdiff_t id)
1079 x_destroy_x_image (mask_img); 1157 x_destroy_x_image (mask_img);
1080} 1158}
1081 1159
1082#endif /* HAVE_X_WINDOWS */ 1160#endif
1161
1162#endif /* HAVE_X_WINDOWS || defined HAVE_ANDROID*/
1083 1163
1084/*********************************************************************** 1164/***********************************************************************
1085 Image types 1165 Image types
@@ -1113,7 +1193,7 @@ struct image_type
1113#if defined HAVE_RSVG || defined HAVE_PNG || defined HAVE_GIF || \ 1193#if defined HAVE_RSVG || defined HAVE_PNG || defined HAVE_GIF || \
1114 defined HAVE_TIFF || defined HAVE_JPEG || defined HAVE_XPM || \ 1194 defined HAVE_TIFF || defined HAVE_JPEG || defined HAVE_XPM || \
1115 defined HAVE_NS || defined HAVE_HAIKU || defined HAVE_PGTK || \ 1195 defined HAVE_NS || defined HAVE_HAIKU || defined HAVE_PGTK || \
1116 defined HAVE_WEBP 1196 defined HAVE_WEBP || defined HAVE_ANDROID
1117# ifdef WINDOWSNT 1197# ifdef WINDOWSNT
1118# define IMAGE_TYPE_INIT(f) f 1198# define IMAGE_TYPE_INIT(f) f
1119# else 1199# else
@@ -1615,7 +1695,7 @@ prepare_image_for_display (struct frame *f, struct image *img)
1615 } 1695 }
1616 unblock_input (); 1696 unblock_input ();
1617 } 1697 }
1618#elif defined HAVE_X_WINDOWS 1698#elif defined HAVE_X_WINDOWS || defined HAVE_ANDROID
1619 if (!img->load_failed_p) 1699 if (!img->load_failed_p)
1620 { 1700 {
1621 block_input (); 1701 block_input ();
@@ -1822,7 +1902,7 @@ image_clear_image_1 (struct frame *f, struct image *img, int flags)
1822 /* NOTE (HAVE_NS): background color is NOT an indexed color! */ 1902 /* NOTE (HAVE_NS): background color is NOT an indexed color! */
1823 img->background_valid = 0; 1903 img->background_valid = 0;
1824 } 1904 }
1825#if defined HAVE_X_WINDOWS && !defined USE_CAIRO 1905#if (defined HAVE_X_WINDOWS || defined HAVE_ANDROID) && !defined USE_CAIRO
1826 if (img->ximg) 1906 if (img->ximg)
1827 { 1907 {
1828 image_destroy_x_image (img->ximg); 1908 image_destroy_x_image (img->ximg);
@@ -1840,7 +1920,7 @@ image_clear_image_1 (struct frame *f, struct image *img, int flags)
1840 img->mask = NO_PIXMAP; 1920 img->mask = NO_PIXMAP;
1841 img->background_transparent_valid = 0; 1921 img->background_transparent_valid = 0;
1842 } 1922 }
1843#if defined HAVE_X_WINDOWS && !defined USE_CAIRO 1923#if (defined HAVE_X_WINDOWS || defined HAVE_ANDROID) && !defined USE_CAIRO
1844 if (img->mask_img) 1924 if (img->mask_img)
1845 { 1925 {
1846 image_destroy_x_image (img->mask_img); 1926 image_destroy_x_image (img->mask_img);
@@ -2212,11 +2292,11 @@ image_size_in_bytes (struct image *img)
2212 if (msk) 2292 if (msk)
2213 size += msk->height * msk->bytes_per_line; 2293 size += msk->height * msk->bytes_per_line;
2214 2294
2215#elif defined HAVE_X_WINDOWS 2295#elif defined HAVE_X_WINDOWS || defined HAVE_ANDROID
2216 /* Use a nominal depth of 24 bpp for pixmap and 1 bpp for mask, 2296 /* Use a nominal depth of 24 and a bpp of 32 for pixmap and 1 bpp
2217 to avoid having to query the server. */ 2297 for mask, to avoid having to query the server. */
2218 if (img->pixmap != NO_PIXMAP) 2298 if (img->pixmap != NO_PIXMAP)
2219 size += img->width * img->height * 3; 2299 size += img->width * img->height * 4;
2220 if (img->mask != NO_PIXMAP) 2300 if (img->mask != NO_PIXMAP)
2221 size += img->width * img->height / 8; 2301 size += img->width * img->height / 8;
2222 2302
@@ -3195,9 +3275,12 @@ mark_image_cache (struct image_cache *c)
3195 3275
3196/*********************************************************************** 3276/***********************************************************************
3197 X / NS / W32 support code 3277 X / NS / W32 support code
3278 Most of this code is shared with Android to make
3279 it easier to maintain.
3198 ***********************************************************************/ 3280 ***********************************************************************/
3199 3281
3200#ifdef HAVE_X_WINDOWS 3282#if defined HAVE_X_WINDOWS || defined HAVE_ANDROID
3283
3201static bool 3284static bool
3202x_check_image_size (XImage *ximg, int width, int height) 3285x_check_image_size (XImage *ximg, int width, int height)
3203{ 3286{
@@ -3213,7 +3296,11 @@ x_check_image_size (XImage *ximg, int width, int height)
3213 int bitmap_pad, depth, bytes_per_line; 3296 int bitmap_pad, depth, bytes_per_line;
3214 if (ximg) 3297 if (ximg)
3215 { 3298 {
3299#ifndef HAVE_ANDROID
3216 bitmap_pad = ximg->bitmap_pad; 3300 bitmap_pad = ximg->bitmap_pad;
3301#else
3302 bitmap_pad = (ximg->depth == 1 ? 8 : 32);
3303#endif
3217 depth = ximg->depth; 3304 depth = ximg->depth;
3218 bytes_per_line = ximg->bytes_per_line; 3305 bytes_per_line = ximg->bytes_per_line;
3219 } 3306 }
@@ -3231,16 +3318,23 @@ static bool
3231x_create_x_image_and_pixmap (struct frame *f, int width, int height, int depth, 3318x_create_x_image_and_pixmap (struct frame *f, int width, int height, int depth,
3232 XImage **ximg, Pixmap *pixmap) 3319 XImage **ximg, Pixmap *pixmap)
3233{ 3320{
3321#ifndef HAVE_ANDROID
3234 Display *display = FRAME_X_DISPLAY (f); 3322 Display *display = FRAME_X_DISPLAY (f);
3235 Drawable drawable = FRAME_X_DRAWABLE (f); 3323 Drawable drawable = FRAME_X_DRAWABLE (f);
3324#endif
3236 3325
3237 eassert (input_blocked_p ()); 3326 eassert (input_blocked_p ());
3238 3327
3239 if (depth <= 0) 3328 if (depth <= 0)
3240 depth = FRAME_DISPLAY_INFO (f)->n_planes; 3329 depth = FRAME_DISPLAY_INFO (f)->n_planes;
3330#ifndef HAVE_ANDROID
3241 *ximg = XCreateImage (display, FRAME_X_VISUAL (f), 3331 *ximg = XCreateImage (display, FRAME_X_VISUAL (f),
3242 depth, ZPixmap, 0, NULL, width, height, 3332 depth, ZPixmap, 0, NULL, width, height,
3243 depth > 16 ? 32 : depth > 8 ? 16 : 8, 0); 3333 depth > 16 ? 32 : depth > 8 ? 16 : 8, 0);
3334#else
3335 *ximg = android_create_image (depth, ANDROID_Z_PIXMAP, NULL, width,
3336 height);
3337#endif
3244 if (*ximg == NULL) 3338 if (*ximg == NULL)
3245 { 3339 {
3246 image_error ("Unable to allocate X image"); 3340 image_error ("Unable to allocate X image");
@@ -3260,7 +3354,15 @@ x_create_x_image_and_pixmap (struct frame *f, int width, int height, int depth,
3260 (*ximg)->data = xmalloc ((*ximg)->bytes_per_line * height); 3354 (*ximg)->data = xmalloc ((*ximg)->bytes_per_line * height);
3261 3355
3262 /* Allocate a pixmap of the same size. */ 3356 /* Allocate a pixmap of the same size. */
3357#ifndef HAVE_ANDROID
3263 *pixmap = XCreatePixmap (display, drawable, width, height, depth); 3358 *pixmap = XCreatePixmap (display, drawable, width, height, depth);
3359#else
3360#ifndef ANDROID_STUBIFY
3361 *pixmap = android_create_pixmap (width, height, depth);
3362#else
3363 emacs_abort ();
3364#endif
3365#endif
3264 if (*pixmap == NO_PIXMAP) 3366 if (*pixmap == NO_PIXMAP)
3265 { 3367 {
3266 x_destroy_x_image (*ximg); 3368 x_destroy_x_image (*ximg);
@@ -3281,7 +3383,11 @@ x_destroy_x_image (XImage *ximg)
3281 ximg->data = NULL; 3383 ximg->data = NULL;
3282 } 3384 }
3283 3385
3386#ifndef HAVE_ANDROID
3284 XDestroyImage (ximg); 3387 XDestroyImage (ximg);
3388#else
3389 android_destroy_image (ximg);
3390#endif
3285} 3391}
3286 3392
3287# if !defined USE_CAIRO && defined HAVE_XRENDER 3393# if !defined USE_CAIRO && defined HAVE_XRENDER
@@ -3348,7 +3454,7 @@ x_create_xrender_picture (struct frame *f, Emacs_Pixmap pixmap, int depth)
3348static bool 3454static bool
3349image_check_image_size (Emacs_Pix_Container ximg, int width, int height) 3455image_check_image_size (Emacs_Pix_Container ximg, int width, int height)
3350{ 3456{
3351#if defined HAVE_X_WINDOWS && !defined USE_CAIRO 3457#if (defined HAVE_X_WINDOWS || defined HAVE_ANDROID) && !defined USE_CAIRO
3352 return x_check_image_size (ximg, width, height); 3458 return x_check_image_size (ximg, width, height);
3353#else 3459#else
3354 /* FIXME: Implement this check for the HAVE_NS and HAVE_NTGUI cases. 3460 /* FIXME: Implement this check for the HAVE_NS and HAVE_NTGUI cases.
@@ -3372,16 +3478,6 @@ image_create_x_image_and_pixmap_1 (struct frame *f, int width, int height, int d
3372 Emacs_Pix_Container *pimg, 3478 Emacs_Pix_Container *pimg,
3373 Emacs_Pixmap *pixmap, Picture *picture) 3479 Emacs_Pixmap *pixmap, Picture *picture)
3374{ 3480{
3375#ifdef HAVE_ANDROID
3376#ifdef ANDROID_STUBIFY
3377 /* This function should never be called when building stubs. */
3378 emacs_abort ();
3379#else
3380 /* you lose, not yet implemented TODO */
3381 return false;
3382#endif
3383#endif
3384
3385#ifdef USE_CAIRO 3481#ifdef USE_CAIRO
3386 eassert (input_blocked_p ()); 3482 eassert (input_blocked_p ());
3387 3483
@@ -3396,7 +3492,7 @@ image_create_x_image_and_pixmap_1 (struct frame *f, int width, int height, int d
3396 3492
3397 *pimg = *pixmap; 3493 *pimg = *pixmap;
3398 return 1; 3494 return 1;
3399#elif defined HAVE_X_WINDOWS 3495#elif defined HAVE_X_WINDOWS || defined HAVE_ANDROID
3400 if (!x_create_x_image_and_pixmap (f, width, height, depth, pimg, pixmap)) 3496 if (!x_create_x_image_and_pixmap (f, width, height, depth, pimg, pixmap))
3401 return 0; 3497 return 0;
3402# ifdef HAVE_XRENDER 3498# ifdef HAVE_XRENDER
@@ -3542,7 +3638,7 @@ image_create_x_image_and_pixmap_1 (struct frame *f, int width, int height, int d
3542static void 3638static void
3543image_destroy_x_image (Emacs_Pix_Container pimg) 3639image_destroy_x_image (Emacs_Pix_Container pimg)
3544{ 3640{
3545#if defined HAVE_X_WINDOWS && !defined USE_CAIRO 3641#if (defined HAVE_X_WINDOWS || defined HAVE_ANDROID) && !defined USE_CAIRO
3546 x_destroy_x_image (pimg); 3642 x_destroy_x_image (pimg);
3547#else 3643#else
3548 eassert (input_blocked_p ()); 3644 eassert (input_blocked_p ());
@@ -3581,7 +3677,9 @@ gui_put_x_image (struct frame *f, Emacs_Pix_Container pimg,
3581 XPutImage (FRAME_X_DISPLAY (f), pixmap, gc, pimg, 0, 0, 0, 0, 3677 XPutImage (FRAME_X_DISPLAY (f), pixmap, gc, pimg, 0, 0, 0, 0,
3582 pimg->width, pimg->height); 3678 pimg->width, pimg->height);
3583 XFreeGC (FRAME_X_DISPLAY (f), gc); 3679 XFreeGC (FRAME_X_DISPLAY (f), gc);
3584#endif /* HAVE_X_WINDOWS */ 3680#elif defined HAVE_ANDROID
3681 android_put_image (pixmap, pimg);
3682#endif
3585 3683
3586#ifdef HAVE_NS 3684#ifdef HAVE_NS
3587 eassert (pimg == pixmap); 3685 eassert (pimg == pixmap);
@@ -3618,7 +3716,7 @@ static void
3618image_put_x_image (struct frame *f, struct image *img, Emacs_Pix_Container ximg, 3716image_put_x_image (struct frame *f, struct image *img, Emacs_Pix_Container ximg,
3619 bool mask_p) 3717 bool mask_p)
3620{ 3718{
3621#if defined HAVE_X_WINDOWS && !defined USE_CAIRO 3719#if (defined HAVE_X_WINDOWS || defined HAVE_ANDROID) && !defined USE_CAIRO
3622 if (!mask_p) 3720 if (!mask_p)
3623 { 3721 {
3624 eassert (img->ximg == NULL); 3722 eassert (img->ximg == NULL);
@@ -3636,7 +3734,7 @@ image_put_x_image (struct frame *f, struct image *img, Emacs_Pix_Container ximg,
3636#endif 3734#endif
3637} 3735}
3638 3736
3639#if defined HAVE_X_WINDOWS && !defined USE_CAIRO 3737#if (defined HAVE_X_WINDOWS || defined HAVE_ANDROID) && !defined USE_CAIRO
3640/* Put the X images recorded in IMG on frame F into pixmaps, then free 3738/* Put the X images recorded in IMG on frame F into pixmaps, then free
3641 the X images and their buffers. */ 3739 the X images and their buffers. */
3642 3740
@@ -3690,19 +3788,9 @@ image_unget_x_image_or_dc (struct image *img, bool mask_p,
3690static Emacs_Pix_Container 3788static Emacs_Pix_Container
3691image_get_x_image (struct frame *f, struct image *img, bool mask_p) 3789image_get_x_image (struct frame *f, struct image *img, bool mask_p)
3692{ 3790{
3693#ifdef HAVE_ANDROID
3694#ifdef ANDROID_STUBIFY
3695 /* This function should never be called when building stubs. */
3696 emacs_abort ();
3697#else
3698 /* you lose, not yet implemented TODO */
3699 return 0;
3700#endif
3701#endif
3702
3703#if defined USE_CAIRO || defined (HAVE_HAIKU) 3791#if defined USE_CAIRO || defined (HAVE_HAIKU)
3704 return !mask_p ? img->pixmap : img->mask; 3792 return !mask_p ? img->pixmap : img->mask;
3705#elif defined HAVE_X_WINDOWS 3793#elif defined HAVE_X_WINDOWS || defined HAVE_ANDROID
3706 XImage *ximg_in_img = !mask_p ? img->ximg : img->mask_img; 3794 XImage *ximg_in_img = !mask_p ? img->ximg : img->mask_img;
3707 3795
3708 if (ximg_in_img) 3796 if (ximg_in_img)
@@ -3712,9 +3800,15 @@ image_get_x_image (struct frame *f, struct image *img, bool mask_p)
3712 return XGetImage (FRAME_X_DISPLAY (f), !mask_p ? img->pixmap : img->mask, 3800 return XGetImage (FRAME_X_DISPLAY (f), !mask_p ? img->pixmap : img->mask,
3713 0, 0, img->original_width, img->original_height, ~0, ZPixmap); 3801 0, 0, img->original_width, img->original_height, ~0, ZPixmap);
3714#endif 3802#endif
3803#ifndef HAVE_ANDROID
3715 else 3804 else
3716 return XGetImage (FRAME_X_DISPLAY (f), !mask_p ? img->pixmap : img->mask, 3805 return XGetImage (FRAME_X_DISPLAY (f), !mask_p ? img->pixmap : img->mask,
3717 0, 0, img->width, img->height, ~0, ZPixmap); 3806 0, 0, img->width, img->height, ~0, ZPixmap);
3807#else
3808 else
3809 return android_get_image (!mask_p ? img->pixmap : img->mask,
3810 ANDROID_Z_PIXMAP);
3811#endif
3718#elif defined (HAVE_NS) 3812#elif defined (HAVE_NS)
3719 Emacs_Pix_Container pixmap = !mask_p ? img->pixmap : img->mask; 3813 Emacs_Pix_Container pixmap = !mask_p ? img->pixmap : img->mask;
3720 3814
@@ -3727,13 +3821,18 @@ static void
3727image_unget_x_image (struct image *img, bool mask_p, Emacs_Pix_Container ximg) 3821image_unget_x_image (struct image *img, bool mask_p, Emacs_Pix_Container ximg)
3728{ 3822{
3729#ifdef USE_CAIRO 3823#ifdef USE_CAIRO
3730#elif defined HAVE_X_WINDOWS 3824#elif defined HAVE_X_WINDOWS || defined HAVE_ANDROID
3731 XImage *ximg_in_img = !mask_p ? img->ximg : img->mask_img; 3825 XImage *ximg_in_img = !mask_p ? img->ximg : img->mask_img;
3732 3826
3733 if (ximg_in_img) 3827 if (ximg_in_img)
3734 eassert (ximg == ximg_in_img); 3828 eassert (ximg == ximg_in_img);
3829#ifdef HAVE_ANDROID
3830 else
3831 android_destroy_image (ximg);
3832#else
3735 else 3833 else
3736 XDestroyImage (ximg); 3834 XDestroyImage (ximg);
3835#endif
3737#elif defined (HAVE_NS) 3836#elif defined (HAVE_NS)
3738 ns_release_object (ximg); 3837 ns_release_object (ximg);
3739#endif 3838#endif
@@ -4256,6 +4355,15 @@ Create_Pixmap_From_Bitmap_Data (struct frame *f, struct image *img, char *data,
4256 img->picture = x_create_xrender_picture (f, img->pixmap, 0); 4355 img->picture = x_create_xrender_picture (f, img->pixmap, 0);
4257# endif 4356# endif
4258 4357
4358#elif defined HAVE_ANDROID
4359#ifndef ANDROID_STUBIFY
4360 img->pixmap
4361 = android_create_pixmap_from_bitmap_data (data, img->width, img->height,
4362 fg, bg,
4363 FRAME_DISPLAY_INFO (f)->n_planes);
4364#else
4365 emacs_abort ();
4366#endif
4259#elif defined HAVE_NTGUI 4367#elif defined HAVE_NTGUI
4260 img->pixmap 4368 img->pixmap
4261 = w32_create_pixmap_from_bitmap_data (img->width, img->height, data); 4369 = w32_create_pixmap_from_bitmap_data (img->width, img->height, data);
@@ -4686,7 +4794,8 @@ xbm_load (struct frame *f, struct image *img)
4686 XPM images 4794 XPM images
4687 ***********************************************************************/ 4795 ***********************************************************************/
4688 4796
4689#if defined (HAVE_XPM) || defined (HAVE_NS) || defined (HAVE_PGTK) 4797#if defined (HAVE_XPM) || defined (HAVE_NS) || defined (HAVE_PGTK) \
4798 || defined (HAVE_ANDROID)
4690 4799
4691static bool xpm_image_p (Lisp_Object object); 4800static bool xpm_image_p (Lisp_Object object);
4692static bool xpm_load (struct frame *f, struct image *img); 4801static bool xpm_load (struct frame *f, struct image *img);
@@ -4716,7 +4825,8 @@ static bool xpm_load (struct frame *f, struct image *img);
4716#endif /* not HAVE_NTGUI */ 4825#endif /* not HAVE_NTGUI */
4717#endif /* HAVE_XPM */ 4826#endif /* HAVE_XPM */
4718 4827
4719#if defined HAVE_XPM || defined USE_CAIRO || defined HAVE_NS || defined HAVE_HAIKU 4828#if defined HAVE_XPM || defined USE_CAIRO || defined HAVE_NS \
4829 || defined HAVE_HAIKU || defined HAVE_ANDROID
4720 4830
4721/* Indices of image specification fields in xpm_format, below. */ 4831/* Indices of image specification fields in xpm_format, below. */
4722 4832
@@ -4736,7 +4846,8 @@ enum xpm_keyword_index
4736 XPM_LAST 4846 XPM_LAST
4737}; 4847};
4738 4848
4739#if defined HAVE_XPM || defined HAVE_NS || defined HAVE_HAIKU || defined HAVE_PGTK 4849#if defined HAVE_XPM || defined HAVE_NS || defined HAVE_HAIKU \
4850 || defined HAVE_PGTK || defined HAVE_ANDROID
4740/* Vector of image_keyword structures describing the format 4851/* Vector of image_keyword structures describing the format
4741 of valid XPM image specifications. */ 4852 of valid XPM image specifications. */
4742 4853
@@ -4978,7 +5089,8 @@ init_xpm_functions (void)
4978 5089
4979#endif /* WINDOWSNT */ 5090#endif /* WINDOWSNT */
4980 5091
4981#if defined HAVE_XPM || defined HAVE_NS || defined HAVE_HAIKU || defined HAVE_PGTK 5092#if defined HAVE_XPM || defined HAVE_NS || defined HAVE_HAIKU \
5093 || defined HAVE_PGTK || defined HAVE_ANDROID
4982/* Value is true if COLOR_SYMBOLS is a valid color symbols list 5094/* Value is true if COLOR_SYMBOLS is a valid color symbols list
4983 for XPM images. Such a list must consist of conses whose car and 5095 for XPM images. Such a list must consist of conses whose car and
4984 cdr are strings. */ 5096 cdr are strings. */
@@ -5014,9 +5126,9 @@ xpm_image_p (Lisp_Object object)
5014 && (! fmt[XPM_COLOR_SYMBOLS].count 5126 && (! fmt[XPM_COLOR_SYMBOLS].count
5015 || xpm_valid_color_symbols_p (fmt[XPM_COLOR_SYMBOLS].value))); 5127 || xpm_valid_color_symbols_p (fmt[XPM_COLOR_SYMBOLS].value)));
5016} 5128}
5017#endif /* HAVE_XPM || HAVE_NS || HAVE_HAIKU || HAVE_PGTK */ 5129#endif /* HAVE_XPM || HAVE_NS || HAVE_HAIKU || HAVE_PGTK || HAVE_ANDROID */
5018 5130
5019#endif /* HAVE_XPM || USE_CAIRO || HAVE_NS || HAVE_HAIKU */ 5131#endif /* HAVE_XPM || USE_CAIRO || HAVE_NS || HAVE_HAIKU || HAVE_ANDROID */
5020 5132
5021#if defined HAVE_XPM && defined HAVE_X_WINDOWS && !defined USE_GTK 5133#if defined HAVE_XPM && defined HAVE_X_WINDOWS && !defined USE_GTK
5022ptrdiff_t 5134ptrdiff_t
@@ -5389,10 +5501,12 @@ xpm_load (struct frame *f, struct image *img)
5389#if (defined USE_CAIRO && defined HAVE_XPM) \ 5501#if (defined USE_CAIRO && defined HAVE_XPM) \
5390 || (defined HAVE_NS && !defined HAVE_XPM) \ 5502 || (defined HAVE_NS && !defined HAVE_XPM) \
5391 || (defined HAVE_HAIKU && !defined HAVE_XPM) \ 5503 || (defined HAVE_HAIKU && !defined HAVE_XPM) \
5392 || (defined HAVE_PGTK && !defined HAVE_XPM) 5504 || (defined HAVE_PGTK && !defined HAVE_XPM) \
5505 || (defined HAVE_ANDROID && !defined HAVE_XPM)
5393 5506
5394/* XPM support functions for NS and Haiku where libxpm is not available, and for 5507/* XPM support functions for NS, Haiku and Android where libxpm is not
5395 Cairo. Only XPM version 3 (without any extensions) is supported. */ 5508 available, and for Cairo. Only XPM version 3 (without any
5509 extensions) is supported. */
5396 5510
5397static void xpm_put_color_table_v (Lisp_Object, const char *, 5511static void xpm_put_color_table_v (Lisp_Object, const char *,
5398 int, Lisp_Object); 5512 int, Lisp_Object);
@@ -6492,11 +6606,16 @@ image_pixmap_draw_cross (struct frame *f, Emacs_Pixmap pixmap,
6492#elif HAVE_HAIKU 6606#elif HAVE_HAIKU
6493 be_draw_cross_on_pixmap (pixmap, x, y, width, height, color); 6607 be_draw_cross_on_pixmap (pixmap, x, y, width, height, color);
6494#elif HAVE_ANDROID 6608#elif HAVE_ANDROID
6495#ifdef ANDROID_STUBIFY 6609#ifndef ANDROID_STUBIFY
6496 /* This function should never be called when building stubs. */ 6610 struct android_gc *gc;
6497 emacs_abort (); 6611
6612 gc = android_create_gc (0, NULL);
6613 android_set_foreground (gc, color);
6614 android_draw_line (pixmap, gc, x, y, x + width - 1, y + height - 1);
6615 android_draw_line (pixmap, gc, x, y + height - 1, x + width - 1, y);
6616 android_free_gc (gc);
6498#else 6617#else
6499 /* you lose, not yet implemented TODO */ 6618 emacs_abort ();
6500#endif 6619#endif
6501#endif 6620#endif
6502} 6621}
@@ -6552,7 +6671,7 @@ image_disable_image (struct frame *f, struct image *img)
6552#define MaskForeground(f) PIX_MASK_DRAW 6671#define MaskForeground(f) PIX_MASK_DRAW
6553#endif /* USE_CAIRO || HAVE_HAIKU */ 6672#endif /* USE_CAIRO || HAVE_HAIKU */
6554 6673
6555#if !defined USE_CAIRO && !defined HAVE_HAIKU && !defined HAVE_ANDROID 6674#if !defined USE_CAIRO && !defined HAVE_HAIKU
6556 image_sync_to_pixmaps (f, img); 6675 image_sync_to_pixmaps (f, img);
6557#endif /* !USE_CAIRO && !HAVE_HAIKU */ 6676#endif /* !USE_CAIRO && !HAVE_HAIKU */
6558 image_pixmap_draw_cross (f, img->pixmap, 0, 0, img->width, img->height, 6677 image_pixmap_draw_cross (f, img->pixmap, 0, 0, img->width, img->height,
@@ -12079,7 +12198,8 @@ static struct image_type const image_types[] =
12079 { SYMBOL_INDEX (Qjpeg), jpeg_image_p, jpeg_load, image_clear_image, 12198 { SYMBOL_INDEX (Qjpeg), jpeg_image_p, jpeg_load, image_clear_image,
12080 IMAGE_TYPE_INIT (init_jpeg_functions) }, 12199 IMAGE_TYPE_INIT (init_jpeg_functions) },
12081#endif 12200#endif
12082#if defined HAVE_XPM || defined HAVE_NS || defined HAVE_HAIKU || defined HAVE_PGTK 12201#if defined HAVE_XPM || defined HAVE_NS || defined HAVE_HAIKU \
12202 || defined HAVE_PGTK || defined HAVE_ANDROID
12083 { SYMBOL_INDEX (Qxpm), xpm_image_p, xpm_load, image_clear_image, 12203 { SYMBOL_INDEX (Qxpm), xpm_image_p, xpm_load, image_clear_image,
12084 IMAGE_TYPE_INIT (init_xpm_functions) }, 12204 IMAGE_TYPE_INIT (init_xpm_functions) },
12085#endif 12205#endif
@@ -12138,7 +12258,7 @@ syms_of_image (void)
12138 DEFVAR_LISP ("image-types", Vimage_types, 12258 DEFVAR_LISP ("image-types", Vimage_types,
12139 doc: /* List of potentially supported image types. 12259 doc: /* List of potentially supported image types.
12140Each element of the list is a symbol for an image type, like `jpeg' or `png'. 12260Each element of the list is a symbol for an image type, like `jpeg' or `png'.
12141To check whether it is really supported, use `image-type-available-p'. */); 12261 check whether it is really supported, use `image-type-available-p'. */);
12142 Vimage_types = Qnil; 12262 Vimage_types = Qnil;
12143 12263
12144 DEFVAR_LISP ("max-image-size", Vmax_image_size, 12264 DEFVAR_LISP ("max-image-size", Vmax_image_size,
@@ -12241,7 +12361,8 @@ non-numeric, there is no explicit limit on the size of images. */);
12241 add_image_type (Qxbm); 12361 add_image_type (Qxbm);
12242 12362
12243#if defined (HAVE_XPM) || defined (HAVE_NS) \ 12363#if defined (HAVE_XPM) || defined (HAVE_NS) \
12244 || defined (HAVE_HAIKU) || defined (HAVE_PGTK) 12364 || defined (HAVE_HAIKU) || defined (HAVE_PGTK) \
12365 || defined (HAVE_ANDROID)
12245 DEFSYM (Qxpm, "xpm"); 12366 DEFSYM (Qxpm, "xpm");
12246 add_image_type (Qxpm); 12367 add_image_type (Qxpm);
12247#endif 12368#endif
diff --git a/src/keyboard.c b/src/keyboard.c
index 7bf89ac7d4b..8eec833a9ca 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -4909,7 +4909,58 @@ static const char *const lispy_accent_keys[] =
4909 "dead-horn", 4909 "dead-horn",
4910}; 4910};
4911 4911
4912#ifdef HAVE_NTGUI 4912#ifdef HAVE_ANDROID
4913#define FUNCTION_KEY_OFFSET 0
4914
4915const char *const lispy_function_keys[] =
4916 {
4917 /* All elements in this array default to 0, except for the few
4918 function keys that Emacs recognizes. */
4919 [111] = "escape",
4920 [121] = "break",
4921 [122] = "home",
4922 [123] = "end",
4923 [124] = "insert",
4924 [131] = "f1",
4925 [132] = "f2",
4926 [133] = "f3",
4927 [134] = "f4",
4928 [135] = "f5",
4929 [136] = "f6",
4930 [137] = "f7",
4931 [138] = "f8",
4932 [139] = "f9",
4933 [140] = "f10",
4934 [141] = "f11",
4935 [142] = "f12",
4936 [160] = "kp-ret",
4937 [19] = "up",
4938 [20] = "down",
4939 [213] = "muhenkan",
4940 [214] = "henkan",
4941 [215] = "hiragana-katakana",
4942 [218] = "kana",
4943 [21] = "left",
4944 [22] = "right",
4945 [259] = "help",
4946 [268] = "kp-up-left",
4947 [269] = "kp-down-left",
4948 [270] = "kp-up-right",
4949 [271] = "kp-down-right",
4950 [277] = "cut",
4951 [278] = "copy",
4952 [279] = "paste",
4953 [28] = "clear",
4954 [4] = "back",
4955 [61] = "tab",
4956 [66] = "return",
4957 [67] = "backspace",
4958 [82] = "menu",
4959 [92] = "page-up",
4960 [93] = "page-down",
4961 };
4962
4963#elif defined HAVE_NTGUI
4913#define FUNCTION_KEY_OFFSET 0x0 4964#define FUNCTION_KEY_OFFSET 0x0
4914 4965
4915const char *const lispy_function_keys[] = 4966const char *const lispy_function_keys[] =
diff --git a/src/lread.c b/src/lread.c
index eb029f01623..15273ad34fa 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -2073,7 +2073,7 @@ static void
2073build_load_history (Lisp_Object filename, bool entire) 2073build_load_history (Lisp_Object filename, bool entire)
2074{ 2074{
2075 Lisp_Object tail, prev, newelt; 2075 Lisp_Object tail, prev, newelt;
2076 Lisp_Object tem, tem2; 2076 Lisp_Object tem, tem2, association;
2077 bool foundit = 0; 2077 bool foundit = 0;
2078 2078
2079 tail = Vload_history; 2079 tail = Vload_history;
@@ -2088,7 +2088,7 @@ build_load_history (Lisp_Object filename, bool entire)
2088 { 2088 {
2089 foundit = 1; 2089 foundit = 1;
2090 2090
2091 /* If we're loading the entire file, remove old data. */ 2091 /* If we're loading the entire file, remove old data. */
2092 if (entire) 2092 if (entire)
2093 { 2093 {
2094 if (NILP (prev)) 2094 if (NILP (prev))
@@ -2096,8 +2096,8 @@ build_load_history (Lisp_Object filename, bool entire)
2096 else 2096 else
2097 Fsetcdr (prev, XCDR (tail)); 2097 Fsetcdr (prev, XCDR (tail));
2098 } 2098 }
2099 2099 /* Otherwise, cons on new symbols that are not already
2100 /* Otherwise, cons on new symbols that are not already members. */ 2100 members. */
2101 else 2101 else
2102 { 2102 {
2103 tem2 = Vcurrent_load_list; 2103 tem2 = Vcurrent_load_list;
@@ -2122,8 +2122,16 @@ build_load_history (Lisp_Object filename, bool entire)
2122 front of load-history, the most-recently-loaded position. Also 2122 front of load-history, the most-recently-loaded position. Also
2123 do this if we didn't find an existing member for the file. */ 2123 do this if we didn't find an existing member for the file. */
2124 if (entire || !foundit) 2124 if (entire || !foundit)
2125 Vload_history = Fcons (Fnreverse (Vcurrent_load_list), 2125 {
2126 Vload_history); 2126 association = Fnreverse (Vcurrent_load_list);
2127
2128 if (!NILP (association) && STRINGP (XCAR (association)))
2129 /* readevalloop can be called with SOURCENAME set to some
2130 nonsense value, meaning the car of ASSOCIATION will be nil
2131 (or worse something else), leading to an invalid
2132 Vload_history. Ignore such invalid entries. */
2133 Vload_history = Fcons (association, Vload_history);
2134 }
2127} 2135}
2128 2136
2129static void 2137static void