aboutsummaryrefslogtreecommitdiffstats
path: root/java/README
diff options
context:
space:
mode:
authorPo Lu2023-08-07 08:51:11 +0800
committerPo Lu2023-08-07 08:51:11 +0800
commitc71a520d1da636a722cf87b46534ca3b5aafbc7b (patch)
tree95a3099c065800f60602e0a403b551a6d6dba139 /java/README
parent18e7bc87521e3c48b819cfe4a113f532ba905561 (diff)
parent9a9f73041d09d2da7ed562c7ffae0d9519562fba (diff)
downloademacs-c71a520d1da636a722cf87b46534ca3b5aafbc7b.tar.gz
emacs-c71a520d1da636a722cf87b46534ca3b5aafbc7b.zip
Introduce an Android window system port for GNU Emacs
* src/xterm.h: New fields `quit_keysym' and `quit_keysym_time'. * src/xterm.c (handle_one_xevent): Check for the quit keysym, and set Vquit_flag upon witnessing two clicks in rapid succession. (x_term_init): Set `quit_keysym'. (init_xterm): Fix typo in name of `register_textconv_interface'. (syms_of_xterm) <Vx_toolkit_scroll_bars>: Describe its default value on android. * src/xfns.c (xic_string_conversion_callback): Pass `0' as the last argument to textconv_query. (Fx_server_vendor, Fx_server_version): Document return values on Android. * src/xfaces.c (Fx_family_fonts, set_lface_from_font): Use FRAME_RES instead of FRAME_RES_Y, respecting user preferences on window systems that have distinct display and font scaling factors. (Fx_load_color_file): Call `emacs_fclose', not fclose. * src/xdisp.c (tab_bar_item_info): Allow `close_p' to be NULL. (get_tab_bar_item): Update commentary to reflect that change. (get_tab_bar_item_kbd): New function, resembling get_tab_bar_item. (build_desired_tool_bar_string): Clear `f->tool_bar_wraps_p'; insert new line characters if a QCwrap item is encountered, and set f->tool_bar_wrap_p. Replace characters beyond the end of the tool bar with spaces. (display_tool_bar_line): Move iterator to the next line if in contact with an explicit line-wrap item. (redisplay_internal): If there are newline characters in the tool bar, refrain from coercing each row into being identically tall. Don't call `set_tty_color_mode' on Android. (mark_window_display_accurate_1): Report changes to the point and mark to input methods. (display_menu_bar): Adjust ifdefs to allow non-X window systems to use the built-in menu bar. (draw_row_with_mouse_face): Don't call TTY functions on Android. (note_mouse_highlight): Call `popup_activated' on Android. (expose_frame): Correctly work on the menu bar window. (gui_union_rectangles): New function. * src/window.h (struct window): New fields for recording the last window and point positions, along with an ephemeral position used during IM text conversion. (WINDOW_MENU_BAR_P): Correct definition for non-X window systems without external menu bars. * src/window.c (replace_buffer_in_windows): Call Qreplace_buffer_in_windows only when bound. * src/w32proc.c (sys_spawnve): Pass extra argument to openp. * src/w32font.c (fill_in_logfont): Use font scaling factor, not the display scaling factor. * src/w32.c (check_windows_init_file): Pass extra argument to openp. * src/verbose.mk.in (AM_V_JAVAC, AM_V_DX, AM_V_AAPT) (AM_V_ZIPALIGN, AM_V_SILENT): New variables. * src/textconv.h (struct textconv_interface): New `point_changed', `compose_region_changed' and `notify_conversion'. Add declarations for new functions. * src/textconv.c (TEXTCONV_DEBUG): New macro. (suppress_conversion_count): New variable. (enum textconv_batch_edit_flags): New flag. (copy_buffer): Don't overwrite text before the gap with the text after. (get_mark, select_window): New functions. (textconv_query): New argument FLAGS. Contingent upon its value, use the previous point or mark or skip the conversion region. (sync_overlay, record_buffer_change, reset_frame_state) (detect_conversion_events, restore_selected_window) (really_commit_text, really_finish_composing_text) (really_set_composing_region, really_delete_composing_text) (really_request_point_update, really_set_point_and_mark) (complete_edit): New functions. (struct complete_edit_check_context): New structure; store in it the result of editing operations. (complete_edit_check, handle_pending_conversion_events_1) (decrement_inside, handle_pending_conversion_events) (start_batch_edit, end_batch_edit, commit_text) (set_composing_text, textconv_set_point_and_mark) (request_point_update, textconv_barrier, get_extracted_text) (get_surrounding_text, conversion_disabled_p) (report_selected_window_change, report_point_change) (disable_text_conversion, resume_text_conversion) (register_textconv_interface, check_postponed_buffers) (postponed_buffers, Fset_text_conversion_style) (syms_of_textconv) <Qaction, Qtext_conversion, Qpush_mark, Qunderline, Qoverriding_text_conversion_style, Vtext_conversion_edits, Voverriding_text_conversion_style, Vtext_conversion_face>: New functions, symbols and variables. * src/terminal.c (Fterminal_live_p): Return Qandroid if type is output_android. * src/termhooks.h (enum output_method): Add `output_android'. (struct terminal) <display_info>: Add union constituent field for `android'. <query_colors>: Define on Android as well. (TERMINAL_FONT_CACHE) [HAVE_ANDROID]: Return the inappropriately named font cache field on Android. * src/term.c (string_cost, string_cost_one_line, per_line_cost) (calculate_costs, produce_glyphs, produce_glyphs, tty_capable_p) (tty_capable_p, device, init_tty, maybe_fatal) (delete_tty) [HAVE_ANDROID]: Exclude or turn these functions into vestiges. (Fsuspend_tty, Fresume_tty): Call `emacs_fclose' and always signal on Android. (Fresume_tty): Call `emacs_fdopen'. (Ftty__set_output_buffer_size) [HAVE_ANDROID]: Remove this function. (encode_terminal_code): Replace with a stub. (init_tty, delete_tty, maybe_fatal): Call `emacs_fclose'. (syms_of_term): Remove most unnecessary code on Android. <system_uses_terminfo>: Always set this option on Android. * src/sysdep.c (init_standard_fds): Call emacs_fopen. (reset_sigio, widen_foreground_group): Define out on Android. (reset_sys_modes): Don't call either function on Android. (init_sigbus, handle_sigbus): New functions. (init_signals): Don't add user signals on Android. Register signal handlers for SIGBUS, and refrain from handling SIGSEGV. (emacs_fstatat): Wrap android_fstatat on Android. (sys_fstat, sys_faccessat): New function. (emacs_openat): Exclude this function when building libemacs.so. (emacs_open, emacs_open_noquit, emacs_fopen, emacs_close): Wrap functions defined in the Android filesystem emulation code. (emacs_fdopen, emacs_fclose, emacs_unlink, emacs_symlink) (emacs_rmdir, emacs_mkdir, emacs_renameat_noreplace, emacs_rename) (emacs_fchmodat): New wrappers for more of those functions. (close_output_streams): Placate the file descriptor sanitizer that's included with android. * src/sound.c (Fplay_sound_internal): Pass extra argument to openp. * src/sfntfont.h: * src/sfntfont.c: * src/sfntfont-android.c: * src/sfnt.h: * src/sfnt.c: New files. * src/scroll.c: Exclude the entire file on Android. * src/process.c: (allocate_pty): Call sys_faccessat, not faccessat. (Fmake_process): Call openp with an extra argument. (wait_reading_process_output): Call android_select. (Fprocess_send_eof): Don't call tcdrain if not present. (handle_child_signal): Write a comment describing a small, seldom encountered issue. * src/print.c (print_vectorlike): Don't print FONT_EXTRA_INDEX for font entities. * src/pdumper.c (Fdump_emacs_portable): Allow dumping in interactive Emacs's on Android, as this is performed within loadup.el. (dump_discard_mem): Use madvise if posix_advise is not present. (pdumper_load): Call sys_fstat, not fstat. (syms_of_pdumper) <Vpdumper_fingerprint>: Calculate the fingerprint for this Emacs executable and store it there. * src/menu.c (have_boxes): Android has boxes. (push_submenu_start, push_submenu_end): Define on Android. (single_menu_item): Produce submenus on Android as well. (x_popup_menu_1): Call EVENT_START, in contrast to duplicating its old functionality with calls to Fcar and XCDR. (Fx_popup_menu): Update documentation to reflect that touch screen events are now accepted as POSITION. * src/marker.c (set_marker_internal): Redisplay buffers when their mark changes, enabling changes to be reported to the IME. * src/lread.c (lread_fd, lread_fd_cmp, lread_fd_p, lread_close) (lread_fstat, lread_read_quit, lread_lseek, file_stream) (file_seek, file_stream_valid_p, file_stream_close) (file_stream_invalid, getc): New macros. Define to an implementation with file descriptors and file streams on systems other than Android 2.3+, and one using Android file descriptors on those systems. (USE_ANDROID_ASSETS): Define on Android 2.3+; (file_get_char): New function. (infile, skip_dyn_bytes, skip_dyn_eof, readbyte_from_stdio) (read_filtered_event, safe_to_load_version, close_infile_unwind): Implement in terms of those macros. (close_file_unwind_android_fd): New function. (Fload): Pass extra argument to `openp' and use Android file descriptors where possible. (Flocate_file_internal): Pass extra argument to `openp'. (maybe_swap_for_eln1): Call sys_fstat, not fstat. (openp): New arg PLATFORM; if supplied and opening a platform-specific file descriptor replacement is possible, place one there. (build_load_history): Fix typos in comments. (skip_lazy_string): Implement in terms of the aformentioned macros. * src/lisp.h: Add declarations for new functions. * src/keyboard.h (reading_key_sequence): Declare here. (EVENT_START): Treat touch screen events specially by returning the posn of their touch point. * src/keyboard.c (reading_key_sequence, menu_bar_touch_id): New variables. (command_loop_1): (read_menu_command): Pass false to read_key_sequence. (read_char): Update commentary. (readable_events): If text conversion events (edits from an input method) are queued, return 1. (kbd_buffer_get_event): If text conversion events exist, carry out the edits contained within. Then, generate a Qtext_conversion event. (lispy_function_keys, FUNCTION_KEY_OFFSET): Define function key array on Android. (coords_in_tab_bar_window): New function. (make_lispy_event) <TOUCHSCREEN_BEGIN_EVENT>: Keep track of touches that fall into the confines of the tab bar, and include the tab bar item in their position lists. Moreover, retain and track the touch in C code if it's taking place within the menu bar. <TOUCHSCREEN_END_EVENT>: Likewise for the tab bar; generate menu bar events if the touch ends on a menu item and was previously singled out for tracking. <TOUCHSCREEN_UPDATE_EVENT>: Don't deliver this event if the frame is dead, or if it was identified for tracking since the only touch sequence that changed begun inside the menu bar. (handle_async_input): Call android_check_query_urgent. (handle_input_available_signal): Add memory fence. (parse_tool_bar_item): Handle `wrap' properties within tool bar items moving subsequent items onto a new row. (access_keymap_keyremap): New arguments START, END, KEYBUF. Set Qcurrent_key_remap_sequence around calls to the remap function. (keyremap_step): Pass the necessary information to access_keymap_keyremap. (restore_reading_key_sequence): New function. (read_key_sequence): Set `reading_key_sequence'. New arg DISABLE_TEXT_CONVERSION_P, which causes text conversion to be disabled as long as the key sequence is being read. Disable text conversion as well if a menu or function key prefix is read, insert imaginary prefix keys before touchscreen events within special areas of a frame. Don't insert prefix keys if input is being mocked, which transpires if the input is in actuality originating from a key translation map. (read_key_sequence_vs): New argument DISABLE_TEXT_CONVERSION. (Fread_key_sequence): New argument DISABLE_TEXT_CONVERSION. (Fopen_dribble_file): Use emacs_fclose. (head_table): Make touchscreen-begin and touchscreen-end events touchscreen events. (syms_of_keyboard) <QCwrap, Qtouchscreen, Qtext_conversion>: New symbols. <disable_inhibit_text_conversion, Vcurrent_key_remap_sequence>: New variables. * src/inotify.c (Finotify_add_watch): Detect and avoid watching special files that don't exist from the POV of inotify. * src/image.c (image_create_bitmap_from_data) (image_create_bitmap_from_file, free_bitmap_record) (prepare_image_for_display, image_clear_image_1) (image_clear_image_1, image_size_in_bytes, image_set_transform): (Create_Pixmap_From_Bitmap_Data, lookup_rgb_color) (image_to_emacs_colors, image_from_emacs_colors) (image_pixmap_draw_cross, image_disable_image): Implement on Android, reusing much of the X11 code. (matrix_identity, matrix_rotate, matrix_mirror_horizontal) (matrix_translate): New functions. (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_get_x_image, image_unget_x_image): Implement on Android. (image_find_image_fd): Return an Android file descriptor if possible. (close_android_fd): New function. (slurp_file): Accept `image_fds', defined to Android file descriptors. (xpm_load): Enable built-in XPM support on Android. (xbm_load, pbm_load, png_load_body, jpeg_load_body, gif_load) (webp_load, imagemagick_load_image, svg_load): Use image file descriptors on Android; these file descriptors may in fact represent compressed asset streams, and obviate the necessity of creating a new file descriptor for each asset image opened. (Fimage_transforms_p): Report rotate90 on Android. (image_types, syms_of_image): Enable built-in XPM support on Android. * src/fringe.c (init_fringe_bitmap): Bit swap bitmaps on Android, as on X. * src/frame.h (enum text_conversion_operation): New enumerator. (struct text_conversion_action, struct text_conversion_state): New variable. (struct frame): New fields `tool_bar_wraps_p' and `conversion'. Increase the width of `output_method'. <output_data>: Add `android' field. <wait_event_type>: Define on Android as well. (fset_menu_bar_window): Define correctly, so that it's declared on non-X builds without external menu bars. (FRAME_ANDROID_P): Define macro. (FRAME_WINDOW_P) [HAVE_ANDROID]: Define to FRAME_ANDROID_P. (FRAME_RES): New macro. (MOUSE_HL_INFO): Define without referencing tty output data on Android, which doesn't have them. * src/frame.c (Fframep): Return `android' on Android systems. (Fwindow_system): Likewise. (make_frame): Clear text conversion state and `tool_bar_wraps_p'. (Fmake_terminal_frame): Signal that Android doesn't support text terminals. (delete_frame): Reset text conversion state prior to deleting the frame. (gui_display_get_resource): Don't call the resource hook on Android. (Fx_parse_geometry): Pacify compiler warning. (make_monitor_attribute_list): Don't always use SOURCE if nil. (syms_of_frame) <Qandroid>: New symbol. <Vdefault_frame_scroll_bars>: Don't default scroll bars to an enabled state on Android. * src/fontset.c (fontset_find_font): Tackle an unusual problem. * src/font.h (struct font_entity): New field `is_android'. (PT_PER_INCH): Define to 160.00 on Android. * src/font.c (font_make_entity): New function. (font_make_entity_android): New variant that sets `is_android' to true. (font_pixel_size, font_find_for_lface, font_open_for_lface) (Ffont_face_attributes, Fopen_font): Respect the distinction between frame text and display scales. * src/fns.c (Flocale_info): Silence compiler warning. * src/filelock.c (BOOT_TIME): Undefine BOOT_TIME when building libemacs.so (get_boot_time, rename_lock_file, create_lock_file) (current_lock_owner, make_lock_file_name, unlock_file): Employ wrappers for Android filesystem operations. * src/fileio.c (emacs_fd, emacs_fd_open, emacs_fd_close) (emacs_fd_read, emacs_fd_lseek, emacs_fd_fstat, emacs_fd_valid_p): New type and macros; define them to suitable values, akin to those in lread.c (check_vfs_filename): New function. (file_access_p): Call `sys_faccessat'. (close_file_unwind_emacs_fd): New function. (fclose_unwind): Call `emacs_fclose', not fclose. (file_name_directory): Export this function. (user_homedir): If PW->pw_dir is not set and its uid is the current user, call `android_get_home_directory'. (get_homedir): Call `android_get_home_directory' if PW->pw_dir is not set. (Fcopy_file, Fmake_directory_internal, Fdelete_directory_internal) (Fdelete_file, Frename_file, Fmake_symbolic_link, Faccess_file) (file_directory_p, file_accessible_directory_p, Fset_file_modes) (Fset_file_times, Ffile_newer_than_file_p, read_non_regular) (Finsert_file_contents, write_region) (Fverify_visited_file_modtime, Fset_visited_file_modtime) (do_auto_save_unwind): Make use of Android filesystem wrappers and file descriptors where possible. (Fadd_name_to_file): Prohibit creating links to and from files residing on Android special directories. (Ffile_system_info): Avoid compilation failure on Android, where Gnulib can't find out how to implement statfs. * src/epaths.in [HAVE_ANDROID && !ANDROID_STUBIFY]: Deface this file, so Makefile cannot change the hard-coded values within. * src/emacs.c (using_utf8): Correctly initialize mbstate_t on Android. (init_cmdargs): Pass extra argument to openp. (load_pdump): When building libemacs.so, use solely the file provided on the command line or as an argument to `android_emacs_init'. (load_seccomp): Call sys_fstat, not fstat. (main, android_emacs_init): Name `main' `android_emacs_init' when building libemacs.so, and accept an argument designating the dump file. (main): Initialize text conversion and Android. Don't presume that argv is NULL terminated. (Fkill_emacs, shut_down_emacs): Properly implement RESTART on Android. (syms_of_emacs) <Vsystem_type>: Describe the possible value `android'. * src/emacs-module.c (MODULE_HANDLE_NONLOCAL_EXIT): Cease relying on GCC clean-up attribute extension. (MODULE_INTERNAL_CLEANUP): New macro. (module_make_global_ref, module_free_global_ref) (module_make_function, module_get_function_finalizer) (module_make_interactive, module_funcall, module_extract_integer) (module_extract_float, module_copy_string_contents) (module_get_user_ptr, module_set_user_ptr) (module_get_user_finalizer, module_set_user_finalizer) (module_vec_set, module_vec_size, module_process_input) (module_extract_big_integer, module_make_big_integer): Carry out necessary clean-up tasks using MODULE_HANDLE_NONLOCAL_EXIT. * src/editfns.c (Fuser_full_name): Call `android_user_full_name', as USER_FULL_NAME doesn't always work. * src/doc.c (doc_fd, doc_fd_p, doc_open, doc_read_quit) (doc_lseek): New types and macros, resembling those in lread.c. (get_doc_string, Fsnarf_documentation): Implement in terms of those macros, so as to use Android asset streams directly. * src/dispnew.c (clear_current_matrices, clear_desired_matrices) (allocate_matrices_for_window_redisplay, free_glyphs) (redraw_frame, update_frame, scrolling, update_frame_line): Disable support for text terminals when building for Android. (Fopen_termscript): Use emacs_fclose. (init_display_interactive): Set Vinitial_window_system to Qandroid, and lose if Emacs needs to create a text terminal. * src/dispextern.h (No_Cursor, Emacs_Rectangle, struct gui_box): New definitions. (struct glyph_string) <gc>: Define to the Android GC type. (HAVE_NATIVE_TRANSPHORMS): Define on Android. (struct image): New fields `ximg', `mask_img', as on X. (enum tool_bar_item_idx): New tool bar item property TOOL_BAR_ITEM_WRAP. * src/dired.c (emacs_dir, emacs_closedir, emacs_readdir): New typedef and definitions. (open_directory): Return emacs_dir; use android_opendir on Android, instead of at-funcs. (directory_files_internal_unwind): Call emacs_closedir. (read_dirent): Call emacs_readdir. (directory_files_internal, file_name_completion) (file_name_completion_dirp): Use Android wrappers for directories and files. (file_attributes): Abstain from openat on Android. * src/conf_post.h (MB_CUR_MAX): Define to REPLACEMENT_MB_CUR_MAX if necessary to counteract inept LLVM headers. * src/coding.h (from_unicode_buffer): Define if HAVE_ANDROID as well. * src/coding.c (from_unicode_buffer): Define on Android, creating a variant that understands UCS-16 extended into wchar_t. (syms_of_coding) <Qutf_16le>: Define on Android. * src/charset.c (load_charset_map_from_file): Supply extra argument to openp, and call Emacs wrappers for fdopen and fclose. * src/callproc.c (get_current_directory): Return the home directory if ENCODED is a special directory. (delete_temp_file): Call emacs_unlink in lieu of unlink. (call_process): Use openp. (emacs_spawn): Use Android executable loader binary if needed and enabled. (init_callproc): Set Vshell_file_name to /system/bin/sh if libemacs.so. (syms_of_callproc) <Vctags_program_name, Vetags_program_name, Vhexl_program_name, Vemacsclient_program_name, Vmovemail_program_name>: New variables. Define to the names of the programs they respectively stand for. * src/callint.c (Fcall_interactively): Supply new argument in calls to Fread_key_sequence and Fread_key_sequence_vector. * src/buffer.h (struct buffer) <text_conversion_style_>: New bvar. (bset_text_conversion_style): New bvar setter. * src/buffer.c (init_buffer_once): Set the text conversion style. (syms_of_buffer) <BVAR (current_buffer, text_conversion_style)>: Define new BLV. * src/androidvfs.c: * src/androidterm.h: * src/androidterm.c: * src/androidselect.c: * src/androidmenu.c: * src/androidgui.h: * src/androidfont.c: * src/androidfns.c: * src/android.h: * src/android.c: * src/android-emacs.c: * src/android-asset.h: New function. * src/alloc.c (cleanup_vector): Finalize Android font entities. (find_string_data_in_pure) [__i386__ && !__clang__]: On Android, compensate for a bug in the latest NDK GCC. (mark_pinned_symbols, android_make_lisp_symbol): Elude another bug in debuginfo generation with an almost nonsensical fix. (garbage_collect): Mark androidterm and sfntfont. (mark_frame): Mark text conversion actions and info. * src/Makefile.in (XCONFIGURE): New variable. If set, add srcdir to vpath. (hostlib): New variable, always defined to libgnu.a on the build machine. (GIF_CFLAGS, JPEG_CFLAGS, TIFF_CFLAGS, SQLITE3_CFLAGS) (LIBSELINUX_CFLAGS, ANDROID_OBJ, ANDROID_LIBS, ANDROID_LDFLAGS) (ANDROID_BUILD_CFLAGS, LIBGMP_CFLAGS): New variables. (CM_OBJ): Update commentary. (EMACS_CFLAGS): Add new compiler flags variables. (base_obj): Add ANDROID_OBJ. (SOME_MACHINE_OBJECTS): Add Android-related objects. (lisp.mk): Generate from its absolute file name. ($(lispsource)/international/charprop.el): Don't generate when building libemacs.so. ($(libsrc)/make-docfile$(EXEEXT) $(libsrc)/make-fingerprint$(EXEEXT)): Depend on libgnu.a on the build machine. (mostlyclean): Remove libemacs.so. (build-counter.c, libemacs.so, android-emacs): New targets. These targets are made from this Makefile copied to a subdirectory of `cross', and provide the Emacs library and an ancillary binary used by the Android port. * nt/mingw-cfg.site: * nt/gnulib-cfg.mk: Impede building Gnulib's vasnprintf* code. * msdos/sedlibmk.inp: * msdos/sedlibcf.inp: * msdos/sed3v2.inp: * msdos/sed1v2.inp: Fix the DJGPP build. * make-dist (possibly_non_vc_files): Add exec/configure and exec/config.h.in. * m4/ndk-build.m4: New file. * m4/getline.m4: * m4/getdelim.m4: * m4/asm-underscore.m4: Update from Gnulib. * lisp/wid-edit.el (widget-event-point): Treat touch screen events correctly. (widget-keymap): Map touchscreen-begin to widget-button-click. (widget-event-start): New function. (widget-button--check-and-call-button): (widget-button-click): Behave correctly when confronted by touch screen events. * lisp/version.el (android-read-build-system) (android_read_build_time): New functions. (emacs-build-system, emacs-repository-version-android) (emacs-repository-get-version): (emacs-repository-get-branch): Implement properly on Android, by reading a file generated during the packaging process. * lisp/touch-screen.el: New file, supplying support for translating raw touch screen events into gestures. * lisp/tool-bar.el (secondary-tool-bar-map): New defvar. (tool-bar--cache-key, tool-bar--secondary-cache-key): Make defsubsts. (tool-bar--flush-key): Flush caches for the secondary tool bar as well. (tool-bar-make-keymap, tool-bar-make-keymap-1): Append the secondary tool bar map below the primary tool bar map. (modifier-bar-modifier-list): New variable. (tool-bar-apply-modifiers, modifier-bar-button) (tool-bar-event-apply-alt-modifier) (tool-bar-event-apply-super-modifier) (tool-bar-event-apply-hyper-modifier) (tool-bar-event-apply-shift-modifier) (tool-bar-event-apply-control-modifier) (tool-bar-event-apply-meta-modifier, modifier-bar-available-p) (modifier-bar-mode): New functions. * lisp/textmodes/text-mode.el (text-mode): Set text-conversion-style to t. * lisp/textmodes/reftex-global.el (reftex-create-tags-file): Use etags-program-name to provide the name of the etags program. * lisp/textmodes/conf-mode.el (conf-mode-initialize): Enable text conversion. * lisp/textmodes/artist.el (artist-figlet-get-font-list): Use /system/bin/sh on Android. * lisp/term/android-win.el: New file. * lisp/term.el (term-mode): Always display the on screen keyboard. (term-exec-1): Use /system/bin/sh on Android. * lisp/tab-line.el (tab-line-tab-map) (tab-line-new-tab) (tab-line-select-tab) (tab-line-close-tab) (tab-line-track-tap) (tab-line-event-start): Improve support for touch screen events. * lisp/tab-bar.el (tab-bar-mouse-context-menu): (tab-bar-map): Likewise. (tab-bar-handle-timeout, tab-bar-touchscreen-begin): New functions. * lisp/subr.el (event-start): Don't return nonsense if EVENT is a touchscreen event. (event-end): Likewise. (read-key): Disable text conversion within read-key-sequence-vector. (read-char-choice-with-read-key): Display the on screen keyboard. (read-char-from-minibuffer): Disable text conversion. (use-dialog-box-p): Prefer dialog boxes on Android. (y-or-n-p): Disable text conversion properly under all three modes of operation. * lisp/startup.el (android-fonts-enumerated): New variable. (normal-top-level): Load system fonts on Android. * lisp/speedbar.el (speedbar-fetch-etags-command): Use etags-program-name instead of hard-coding `etags'. * lisp/simple.el (normal-erase-is-backspace-setup-frame): Return true on Android. (event-apply-modifier): Correctly apply Shift and Control modifiers to keys with other modifiers. (undo-auto-amalgamate): Mention analyze-text-conversion wrt being an amalgamating command. * lisp/shell.el (shell--command-completion-data): Don't lose if PATH contains an inaccessible directory. * lisp/progmodes/prog-mode.el (prog-mode): Enable text conversion. * lisp/progmodes/cperl-mode.el (cperl-etags): Don't hard-code etags, employ etags-program-name instead. * lisp/progmodes/cc-mode.el (c-initialize-cc-mode): Initialize text conversion hook. * lisp/progmodes/cc-cmds.el (c-post-text-conversion): New function. Do electric characters. * lisp/play/gamegrid.el (gamegrid-setup-default-font): Don't crash if the display resolution is too high. * lisp/play/dunnet.el (text-conversion-style): * lisp/play/doctor.el (doctor-mode): Enable text conversion. * lisp/pixel-scroll.el (pixel-scroll-precision-scroll-down-page) (pixel-scroll-precision-scroll-Up-page): Make autoloads. * lisp/org/org-ctags.el (org-ctags-path-to-ctags): Use ctags-program-name, not ctags. * lisp/obsolete/terminal.el (terminal-emulator): Start /system/bin/sh, not /bin/sh. * lisp/net/tramp.el (tramp-encoding-shell): Use /system/bin/sh on Android. * lisp/net/eww.el (eww-form-submit, eww-form-file) (eww-form-checkbox, eww-form-select): Define these faces on Android as well. * lisp/net/browse-url.el (browse-url-default-browser) (browse-url--browser-defcustom-type): Specify on Android. (browse-url-android-share, browse-url-default-android-browser): New option and function. * lisp/mwheel.el (mouse-wheel-down-event, mouse-wheel-up-event) (mouse-wheel-left-event, mouse-wheel-right-event): Define suitably on Android. * lisp/mouse.el (minor-mode-menu-from-indicator): New argument EVENT. Use it for positioning the menu. (mouse-minor-mode-menu): Pass EVENT to that function. * lisp/minibuffer.el (clear-minibuffer-message): Don't clear the message if `touch-screen-preview-select' may be underway. (minibuffer-mode): Enable text conversion. (minibuffer-setup-on-screen-keyboard) (minibuffer-exit-on-screen-keyboard): New functions. * lisp/menu-bar.el (menu-bar-close-window): New option. (menu-bar-edit-menu): Bind execute-extended-command to a menu item. (kill-this-buffer, kill-this-buffer-enabled-p): Respect menu-bar-close-window. * lisp/mail/rmail.el (rmail-autodetect, rmail-insert-inbox-text): Don't hard-code the name of movemail; rather, use movemail-program-name. * lisp/mail/emacsbug.el (emacs-build-description): Insert the Android version and manufacturer. * lisp/ls-lisp.el (ls-lisp-use-insert-directory-program): Default to off on Android. * lisp/loadup.el: Set load-list to empty load list after startup; dump the first time Emacs starts, and load Android related miscellanea. * lisp/isearch.el (isearch-text-conversion-style): New variable. (isearch-mode, isearch-done): Display the OSK, then temporarily disable and restore the on screen keyboard. * lisp/international/mule-cmds.el (set-coding-system-map): Update menu definition for Android. * lisp/international/fontset.el (script-representative-chars) (setup-default-fontset): Improve detection of CJK fonts. * lisp/image/wallpaper.el: Fix compiler warning. * lisp/ielm.el (inferior-emacs-lisp-mode): Don't hard-code name of hexl, replacing that with hexl-program-name. * lisp/htmlfontify.el (hfy-etags-bin): Replace hard-coded Emacs with etags-program-name. * lisp/hexl.el (hexl-program): Replace hard-coded hexl. * lisp/help-macro.el (make-help-screen): Display the on screen keyboard and disable text conversion prior to reading options. * lisp/gnus/mail-source.el (mail-source-movemail-program): Replace hard-coded movemail with movemail-program-name. * lisp/gnus/gnus-score.el (gnus-read-char): New function. (gnus-summary-increase-score): Use a dialog box to display these options on Android. * lisp/frame.el (frame-geometry, frame-edges) (mouse-absolute-pixel-position, set-mouse-absolute-pixel-position) (frame-list-z-order, frame-restack, display-mouse-p) (display-popup-menus-p, display-graphic-p, display-symbol-keys-p) (display-screens, display-pixel-height, display-pixel-width) (display-mm-height, display-mm-width, display-backing-store) (display-save-under, display-planes, display-color-cells) (display-visual-class, display-monitor-attributes-list): Implement window system specific functions on Android. * lisp/files.el (basic-save-buffer): Allow files to exist without a parent directory. * lisp/faces.el (tool-bar): Use default definition on Android. * lisp/emacs-lisp/eldoc.el (eldoc-add-command-completions): Add touch-screen-handle-touch and analyze-text-conversion. * lisp/elec-pair.el (electric-pair-analyze-conversion): New function. * lisp/doc-view.el (doc-view-menu): Improve menu. (doc-view-tool-bar-map): Add a new tool bar for Doc View. (doc-view-new-search): New command. (doc-view-mode): Enable that new tool bar. * lisp/dired-aux.el (dired-do-chxxx, dired-do-chmod) (dired-do-print, dired-do-shell-command, dired-do-compress-to) (dired-do-create-files, dired-do-rename, dired-do-isearch) (dired-do-isearch-regexp, dired-do-search) (dired-do-query-replace-regexp, dired-do-find-regexp) (dired-vc-next-action): Disable ``click to select'' after running this command. * lisp/dired.el (dired-insert-set-properties): Attach click-to-select keymap to file names if necessary. (dired-mode-map): Bind `touchscreen-hold' to click to select mode. (dired-post-do-command): New function. (dired-do-delete): Call it. (dired-mark-for-click, dired-enable-click-to-select-mode): New functions. (dired-click-to-select-mode): New minor mode. * lisp/cus-edit.el (custom-button-mouse, custom-button-pressed) (custom-display): Define faces to their default values on Android. * lisp/comint.el (comint-mode): Enable text conversion. * lisp/cedet/semantic/db-ebrowse.el (semanticdb-create-ebrowse-database): Replace fixed ebrowse with ebrowse-program-name. * lisp/calc/calc.el (calc-mode): Display the on screen keyboard. (calc): Insist on displaying the on screen keyboard. * lisp/button.el (button-map): Bind touch screen events to push-button. (push-button): Deal with touch screen events. * lisp/bindings.el (cut, paste, cut, text-conversion): New bindings. * lisp/battery.el (battery-status-function): Use `battery-android'. (battery-android): New function. * lib/gnulib.mk.in: * lib/getline.c: * lib/getdelim.c: * lib/Makefile.in: Update from Gnulib. * lib-src/emacsclient.c (decode_options): Set `alt_display' to `android'. * lib-src/asset-directory-tool.c: New file. * lib-src/Makefile.in: Adapt for cross-compilation. * java/res/xml/preferences.xml: * java/res/values/style.xml: * java/res/values/strings.xml: * java/res/values/bool.xml: * java/res/values-v29/style.xml: * java/res/values-v24/bool.xml: * java/res/values-v19/bool.xml: * java/res/values-v14/style.xml: * java/res/values-v11/style.xml: * java/org/gnu/emacs/EmacsWindowAttachmentManager.java: * java/org/gnu/emacs/EmacsWindow.java: * java/org/gnu/emacs/EmacsView.java: * java/org/gnu/emacs/EmacsThread.java: * java/org/gnu/emacs/EmacsSurfaceView.java: * java/org/gnu/emacs/EmacsService.java: * java/org/gnu/emacs/EmacsSdk8Clipboard.java: * java/org/gnu/emacs/EmacsSdk7FontDriver.java: * java/org/gnu/emacs/EmacsSdk23FontDriver.java: * java/org/gnu/emacs/EmacsSdk11Clipboard.java: * java/org/gnu/emacs/EmacsSafThread.java: * java/org/gnu/emacs/EmacsPreferencesActivity.java: * java/org/gnu/emacs/EmacsPixmap.java: * java/org/gnu/emacs/EmacsOpenActivity.java: * java/org/gnu/emacs/EmacsNoninteractive.java: * java/org/gnu/emacs/EmacsNative.java: * java/org/gnu/emacs/EmacsMultitaskActivity.java: * java/org/gnu/emacs/EmacsLauncherPreferencesActivity.java: * java/org/gnu/emacs/EmacsInputConnection.java: * java/org/gnu/emacs/EmacsHolder.java: * java/org/gnu/emacs/EmacsHandleObject.java: * java/org/gnu/emacs/EmacsGC.java: * java/org/gnu/emacs/EmacsFontDriver.java: * java/org/gnu/emacs/EmacsFillRectangle.java: * java/org/gnu/emacs/EmacsFillPolygon.java: * java/org/gnu/emacs/EmacsDrawable.java: * java/org/gnu/emacs/EmacsDrawRectangle.java: * java/org/gnu/emacs/EmacsDrawPoint.java: * java/org/gnu/emacs/EmacsDrawLine.java: * java/org/gnu/emacs/EmacsDocumentsProvider.java: * java/org/gnu/emacs/EmacsDirectoryEntry.java: * java/org/gnu/emacs/EmacsDialogButtonLayout.java: * java/org/gnu/emacs/EmacsDialog.java: * java/org/gnu/emacs/EmacsCursor.java: * java/org/gnu/emacs/EmacsContextMenu.java: * java/org/gnu/emacs/EmacsClipboard.java: * java/org/gnu/emacs/EmacsApplication.java: * java/org/gnu/emacs/EmacsActivity.java: * java/debug.sh: * java/README: * java/Makefile.in: * java/INSTALL: * java/AndroidManifest.xml.in: * exec/trace.c: * exec/test.c: * exec/mipsfpu.h: * exec/mipsfpu.c: * exec/mipsel-user.h: * exec/loader-x86_64.s: * exec/loader-x86.s: * exec/loader-mipsel.s: * exec/loader-mips64el.s: * exec/loader-armeabi.s: * exec/loader-aarch64.s: * exec/install-sh: * exec/exec1.c: * exec/exec.h: * exec/exec.c: * exec/deps.mk: * exec/configure.ac: * exec/config.sub: * exec/config.h.in: * exec/config.guess: * exec/config-mips.m4.in: * exec/README: * exec/Makefile.in: * etc/images/last-page.xpm: New files. * etc/PROBLEMS: Expound upon problems with font instructing on Android. * etc/NEWS: Announce changes. * etc/MACHINES: Describe support for Android. * etc/DEBUG: Illustrate the steps to debug Emacs on Android. * doc/lispref/processes.texi (Subprocess Creation): * doc/lispref/os.texi (System Environment): * doc/lispref/keymaps.texi (Translation Keymaps): (Extended Menu Items): (Tool Bar): * doc/lispref/frames.texi (Frames): (Frame Layout): (Font and Color Parameters): (Pop-Up Menus): (Window System Selections): * doc/lispref/elisp.texi (Top): * doc/lispref/display.texi (Defining Faces): (Window Systems): * doc/lispref/commands.texi (Touchscreen Events): (Touchscreen Events): (Misc Events): (Key Sequence Input): * doc/emacs/windows.texi (Tab Line): * doc/emacs/input.texi: * doc/emacs/frames.texi (Tool Bars): (Tab Bars): * doc/emacs/emacs.texi (Top): * doc/emacs/dired.texi (Marks vs Flags): * doc/emacs/android.texi: * doc/emacs/Makefile.in (EMACSSOURCES): Update the documentation to properly describe changes effected. * cross/verbose.mk.android: * cross/ndk-build/ndk-resolve.mk: * cross/ndk-build/ndk-prebuilt-static-library.mk: * cross/ndk-build/ndk-prebuilt-shared-library.mk: * cross/ndk-build/ndk-clear-vars.mk: * cross/ndk-build/ndk-build.mk.in: * cross/ndk-build/ndk-build-static-library.mk: * cross/ndk-build/ndk-build-shared-library.mk: * cross/ndk-build/ndk-build-executable.mk: * cross/ndk-build/README: * cross/ndk-build/Makefile.in: * cross/langinfo.h: * cross/README: * cross/Makefile.in: New files. * configure.ac: Configure Emacs for cross-compilation on Android. * build-aux/ndk-module-extract.awk: * build-aux/ndk-build-helper.mk: * build-aux/ndk-build-helper-4.mk: * build-aux/ndk-build-helper-3.mk: * build-aux/ndk-build-helper-2.mk: * build-aux/ndk-build-helper-1.mk: * build-aux/makecounter.sh: New file. * autogen.sh: Autogen in exec as well. * admin/merge-gnulib (GNULIB_MODULES): Add getline, stpncpy and strnlen. Clean lib. * README: * Makefile.in: * INSTALL: Update for Android. * .dir-locals.el (c-mode): Add a few new types.
Diffstat (limited to 'java/README')
-rw-r--r--java/README1049
1 files changed, 1049 insertions, 0 deletions
diff --git a/java/README b/java/README
new file mode 100644
index 00000000000..a6adb805b9e
--- /dev/null
+++ b/java/README
@@ -0,0 +1,1049 @@
1This directory holds the Java sources of the port of GNU Emacs to
2Android-like systems, along with files needed to create an application
3package out of them. If you need to build this port, please read the
4file INSTALL in this directory.
5
6The ``org/gnu/emacs'' subdirectory contains the Java sources under the
7``org.gnu.emacs'' package identifier.
8
9``AndroidManifest.xml'' contains a manifest describing the Java
10sources to the system.
11
12The ``res'' directory contains resources, mainly the Emacs icon and
13several ``boolean resources'' which are used as a form of conditional
14evaluation for manifest entries.
15
16`emacs.keystore' is the signing key used to build Emacs. It is kept
17here, and we encourage all people redistributing Emacs to use this
18key. It holds no security value, and otherwise it will be impossible
19to install different builds of Emacs on top of each other.
20
21Please keep the Java code indented with tabs and formatted according
22to the rules for C code in the GNU coding standards. Always use
23C-style comments.
24
25======================================================================
26
27OVERVIEW OF JAVA
28
29Emacs developers do not know Java, and there is no reason they should
30have to. Thus, the code in this directory is confined to what is
31strictly necessary to support Emacs, and only uses a subset of Java
32written in a way that is easily understandable to C programmers.
33
34Java is required because the entire Android runtime is based around
35Java, and there is no way to write an Android program which runs
36without Java.
37
38This text exists to prime other Emacs developers, already familar with
39C, on the basic architecture of the Android port, and to teach them
40how to read and write the Java code found in this directory.
41
42Java is an object oriented language with automatic memory management
43compiled down to bytecode, which is then subject to interpretation by
44a Java virtual machine.
45
46What that means, is that:
47
48struct emacs_window
49{
50 int some_fields;
51 int of_emacs_window;
52};
53
54static void
55do_something_with_emacs_window (struct emacs_window *a, int n)
56{
57 a->some_fields = a->of_emacs_window + n;
58}
59
60would be written:
61
62public class EmacsWindow
63{
64 public int someFields;
65 public int ofEmacsWindow;
66
67 public void
68 doSomething (int n)
69 {
70 someFields = ofEmacsWindow + n;
71 }
72}
73
74and instead of doing:
75
76do_something_with_emacs_window (my_window, 1);
77
78you say:
79
80myWindow.doSomething (1);
81
82In addition to functions associated with an object of a given class
83(such as EmacsWindow), Java also has two other kinds of functions.
84
85The first are so-called ``static'' functions (the static means
86something entirely different from what it does in C.)
87
88A static function, while still having to be defined within a class,
89can be called without any object. Instead of the object, you write
90the name of the Java class within which it is defined. For example,
91the following C code:
92
93int
94multiply_a_with_b_and_then_add_c (int a, int b, int c)
95{
96 return a * b + c;
97}
98
99would be:
100
101public class EmacsSomething
102{
103 public static int
104 multiplyAWithBAndThenAddC (int a, int b, int c)
105 {
106 return a * b + c;
107 }
108};
109
110Then, instead of calling:
111
112int foo;
113
114foo = multiply_a_with_b_then_add_c (1, 2, 3);
115
116you say:
117
118int foo;
119
120foo = EmacsSomething.multiplyAWithBAndThenAddC (1, 2, 3);
121
122In Java, ``static'' does not mean that the function is only used
123within its compilation unit! Instead, the ``private'' qualifier is
124used to mean more or less the same thing:
125
126static void
127this_procedure_is_only_used_within_this_file (void)
128{
129 do_something ();
130}
131
132becomes
133
134public class EmacsSomething
135{
136 private static void
137 thisProcedureIsOnlyUsedWithinThisClass ()
138 {
139
140 }
141}
142
143the other kind are called ``constructors''. They are functions that
144must be called to allocate memory to hold a class:
145
146public class EmacsFoo
147{
148 int bar;
149
150 public
151 EmacsFoo (int tokenA, int tokenB)
152 {
153 bar = tokenA + tokenB;
154 }
155}
156
157now, the following statement:
158
159EmacsFoo foo;
160
161foo = new EmacsFoo (1, 2);
162
163becomes more or less equivalent to the following C code:
164
165struct emacs_foo
166{
167 int bar;
168};
169
170struct emacs_foo *
171make_emacs_foo (int token_a, int token_b)
172{
173 struct emacs_foo *foo;
174
175 foo = xmalloc (sizeof *foo);
176 foo->bar = token_a + token_b;
177
178 return foo;
179}
180
181/* ... */
182
183struct emacs_foo *foo;
184
185foo = make_emacs_foo (1, 2);
186
187A class may have any number of constructors, or no constructors at
188all, in which case the compiler inserts an empty constructor.
189
190
191
192Sometimes, you will see Java code that looks like this:
193
194 allFiles = filesDirectory.listFiles (new FileFilter () {
195 @Override
196 public boolean
197 accept (File file)
198 {
199 return (!file.isDirectory ()
200 && file.getName ().endsWith (".pdmp"));
201 }
202 });
203
204This is Java's version of GCC's nested function extension. The major
205difference is that the nested function may still be called even after
206it goes out of scope, and always retains a reference to the class and
207local variables around where it was called.
208
209Being an object-oriented language, Java also allows defining that a
210class ``extends'' another class. The following C code:
211
212struct a
213{
214 long thirty_two;
215};
216
217struct b
218{
219 struct a a;
220 long long sixty_four;
221};
222
223extern void do_something (struct a *);
224
225void
226my_function (struct b *b)
227{
228 do_something (&b->a);
229}
230
231is roughly equivalent to the following Java code, split into two
232files:
233
234 A.java
235
236public class A
237{
238 int thirtyTwo;
239
240 public void
241 doSomething ()
242 {
243 etcEtcEtc ();
244 }
245};
246
247 B.java
248
249public class B extends A
250{
251 long sixty_four;
252
253 public static void
254 myFunction (B b)
255 {
256 b.doSomething ();
257 }
258}
259
260the Java runtime has transformed the call to ``b.doSomething'' to
261``((A) b).doSomething''.
262
263However, Java also allows overriding this behavior, by specifying the
264@Override keyword:
265
266public class B extends A
267{
268 long sixty_four;
269
270 @Override
271 public void
272 doSomething ()
273 {
274 Something.doSomethingTwo ();
275 super.doSomething ();
276 }
277}
278
279now, any call to ``doSomething'' on a ``B'' created using ``new B ()''
280will end up calling ``Something.doSomethingTwo'', before calling back
281to ``A.doSomething''. This override also applies in reverse; that is
282to say, even if you write:
283
284 ((A) b).doSomething ();
285
286B's version of doSomething will still be called, if ``b'' was created
287using ``new B ()''.
288
289This mechanism is used extensively throughout the Java language and
290Android windowing APIs.
291
292Elsewhere, you will encounter Java code that defines arrays:
293
294public class EmacsFrobinicator
295{
296 public static void
297 emacsFrobinicate (int something)
298 {
299 int[] primesFromSomething;
300
301 primesFromSomething = new int[numberOfPrimes];
302 /* ... */
303 }
304}
305
306Java arrays are similar to C arrays in that they can not grow. But
307they are very much unlike C arrays in that they are always references
308(as opposed to decaying into pointers in only some situations), and
309contain information about their length.
310
311If another function named ``frobinicate1'' takes an array as an
312argument, then it need not take the length of the array.
313
314Instead, it may simply iterate over the array like so:
315
316int i, k;
317
318for (i = 0; i < array.length; ++i)
319 {
320 k = array[i];
321
322 Whatever.doSomethingWithK (k);
323 }
324
325The syntax used to define arrays is also slightly different. As
326arrays are always references, there is no way for you to tell the
327runtime to allocate an array of size N in a structure (class.)
328
329Instead, if you need an array of that size, you must declare a field
330with the type of the array, and allocate the array inside the class's
331constructor, like so:
332
333public class EmacsArrayContainer
334{
335 public int[] myArray;
336
337 public
338 EmacsArrayContainer ()
339 {
340 myArray = new array[10];
341 }
342}
343
344while in C, you could just have written:
345
346struct emacs_array_container
347{
348 int my_array[10];
349};
350
351or, possibly even better,
352
353typedef int emacs_array_container[10];
354
355Alas, Java has no equivalent of `typedef'.
356
357Like in C, Java string literals are delimited by double quotes.
358Unlike C, however, strings are not NULL-terminated arrays of
359characters, but a distinct type named ``String''. They store their
360own length, characters in Java's 16-bit ``char'' type, and are capable
361of holding NULL bytes.
362
363Instead of writing:
364
365wchar_t character;
366extern char *s;
367size_t s;
368
369 for (/* determine n, s in a loop. */)
370 s += mbstowc (&character, s, n);
371
372or:
373
374const char *byte;
375
376for (byte = my_string; *byte; ++byte)
377 /* do something with *byte. */;
378
379or perhaps even:
380
381size_t length, i;
382char foo;
383
384length = strlen (my_string);
385
386for (i = 0; i < length; ++i)
387 foo = my_string[i];
388
389you write:
390
391char foo;
392int i;
393
394for (i = 0; i < myString.length (); ++i)
395 foo = myString.charAt (0);
396
397Java also has stricter rules on what can be used as a truth value in a
398conditional. While in C, any non-zero value is true, Java requires
399that every truth value be of the boolean type ``boolean''.
400
401What this means is that instead of simply writing:
402
403 if (foo || bar)
404
405where foo can either be 1 or 0, and bar can either be NULL or a
406pointer to something, you must explicitly write:
407
408 if (foo != 0 || bar != null)
409
410in Java.
411
412JAVA NATIVE INTERFACE
413
414Java also provides an interface for C code to interface with Java.
415
416C functions exported from a shared library become static Java
417functions within a class, like so:
418
419public class EmacsNative
420{
421 /* Obtain the fingerprint of this build of Emacs. The fingerprint
422 can be used to determine the dump file name. */
423 public static native String getFingerprint ();
424
425 /* Set certain parameters before initializing Emacs.
426
427 assetManager must be the asset manager associated with the
428 context that is loading Emacs. It is saved and remains for the
429 remainder the lifetime of the Emacs process.
430
431 filesDir must be the package's data storage location for the
432 current Android user.
433
434 libDir must be the package's data storage location for native
435 libraries. It is used as PATH.
436
437 cacheDir must be the package's cache directory. It is used as
438 the `temporary-file-directory'.
439
440 pixelDensityX and pixelDensityY are the DPI values that will be
441 used by Emacs.
442
443 classPath must be the classpath of this app_process process, or
444 NULL.
445
446 emacsService must be the EmacsService singleton, or NULL. */
447 public static native void setEmacsParams (AssetManager assetManager,
448 String filesDir,
449 String libDir,
450 String cacheDir,
451 float pixelDensityX,
452 float pixelDensityY,
453 String classPath,
454 EmacsService emacsService);
455}
456
457Where the corresponding C functions are located in android.c, and
458loaded by the special invocation:
459
460 static
461 {
462 System.loadLibrary ("emacs");
463 };
464
465where ``static'' defines a section of code which will be run upon the
466object (containing class) being loaded. This is like:
467
468 __attribute__((constructor))
469
470on systems where shared object constructors are supported.
471
472See http://docs.oracle.com/en/java/javase/19/docs/specs/jni/intro.html
473for more details.
474
475
476
477OVERVIEW OF ANDROID
478
479When the Android system starts an application, it does not actually
480call the application's ``main'' function. It may not even start the
481application's process if one is already running.
482
483Instead, Android is organized around components. When the user opens
484the ``Emacs'' icon, the Android system looks up and starts the
485component associated with the ``Emacs'' icon. In this case, the
486component is called an activity, and is declared in
487the AndroidManifest.xml in this directory:
488
489 <activity android:name="org.gnu.emacs.EmacsActivity"
490 android:launchMode="singleTop"
491 android:windowSoftInputMode="adjustResize"
492 android:exported="true"
493 android:configChanges="orientation|screenSize|screenLayout|keyboardHidden">
494 <intent-filter>
495 <action android:name="android.intent.action.MAIN" />
496 <category android:name="android.intent.category.DEFAULT" />
497 <category android:name="android.intent.category.LAUNCHER" />
498 </intent-filter>
499 </activity>
500
501This tells Android to start the activity defined in ``EmacsActivity''
502(defined in org/gnu/emacs/EmacsActivity.java), a class extending the
503Android class ``Activity''.
504
505To do so, the Android system creates an instance of ``EmacsActivity''
506and the window system window associated with it, and eventually calls:
507
508 Activity activity;
509
510 activity.onCreate (...);
511
512But which ``onCreate'' is really called?
513It is actually the ``onCreate'' defined in EmacsActivity.java, as
514it overrides the ``onCreate'' defined in Android's own Activity class:
515
516 @Override
517 public void
518 onCreate (Bundle savedInstanceState)
519 {
520 FrameLayout.LayoutParams params;
521 Intent intent;
522
523Then, this is what happens step-by-step within the ``onCreate''
524function:
525
526 /* See if Emacs should be started with -Q. */
527 intent = getIntent ();
528 EmacsService.needDashQ
529 = intent.getBooleanExtra ("org.gnu.emacs.START_DASH_Q",
530 false);
531
532Here, Emacs obtains the intent (a request to start a component) which
533was used to start Emacs, and sets a special flag if it contains a
534request for Emacs to start with the ``-Q'' command-line argument.
535
536 /* Set the theme to one without a title bar. */
537
538 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH)
539 setTheme (android.R.style.Theme_DeviceDefault_NoActionBar);
540 else
541 setTheme (android.R.style.Theme_NoTitleBar);
542
543Next, Emacs sets an appropriate theme for the activity's associated
544window decorations.
545
546 params = new FrameLayout.LayoutParams (LayoutParams.MATCH_PARENT,
547 LayoutParams.MATCH_PARENT);
548
549 /* Make the frame layout. */
550 layout = new FrameLayout (this);
551 layout.setLayoutParams (params);
552
553 /* Set it as the content view. */
554 setContentView (layout);
555
556Then, Emacs creates a ``FrameLayout'', a widget that holds a single
557other widget, and makes it the activity's ``content view''.
558
559The activity itself is a ``FrameLayout'', so the ``layout parameters''
560here apply to the FrameLayout itself, and not its children.
561
562 /* Maybe start the Emacs service if necessary. */
563 EmacsService.startEmacsService (this);
564
565And after that, Emacs calls the static function ``startEmacsService'',
566defined in the class ``EmacsService''. This starts the Emacs service
567component if necessary.
568
569 /* Add this activity to the list of available activities. */
570 EmacsWindowAttachmentManager.MANAGER.registerWindowConsumer (this);
571
572 super.onCreate (savedInstanceState);
573
574Finally, Emacs registers that this activity is now ready to receive
575top-level frames (windows) created from Lisp.
576
577Activities come and go, but Emacs has to stay running in the mean
578time. Thus, Emacs also defines a ``service'', which is a long-running
579component that the Android system allows to run in the background.
580
581Let us go back and review the definition of ``startEmacsService'':
582
583 public static void
584 startEmacsService (Context context)
585 {
586 if (EmacsService.SERVICE == null)
587 {
588 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O)
589 /* Start the Emacs service now. */
590 context.startService (new Intent (context,
591 EmacsService.class));
592 else
593 /* Display the permanant notification and start Emacs as a
594 foreground service. */
595 context.startForegroundService (new Intent (context,
596 EmacsService.class));
597 }
598 }
599
600If ``EmacsService.SERVICE'' does not yet exist, what this does is to
601tell the ``context'' (the equivalent of an Xlib Display *) to start a
602service defined by the class ``EmacsService''. Eventually, this
603results in ``EmacsService.onCreate'' being called:
604
605 @Override
606 public void
607 onCreate ()
608 {
609 AssetManager manager;
610 Context app_context;
611 String filesDir, libDir, cacheDir, classPath;
612 double pixelDensityX;
613 double pixelDensityY;
614
615Here is what this function does, step-by-step:
616
617 SERVICE = this;
618
619First, it sets the special static variable ``SERVICE'' to ``this'',
620which is a pointer to the ``EmacsService' object that was created.
621
622 handler = new Handler (Looper.getMainLooper ());
623
624Next, it creates a ``Handler'' object for the ``main looper''.
625This is a helper structure which allows executing code on the Android
626user interface thread.
627
628 manager = getAssets ();
629 app_context = getApplicationContext ();
630 metrics = getResources ().getDisplayMetrics ();
631 pixelDensityX = metrics.xdpi;
632 pixelDensityY = metrics.ydpi;
633
634Finally, it obtains:
635
636 - the asset manager, which is used to retrieve assets packaged
637 into the Emacs application package.
638
639 - the application context, used to obtain application specific
640 information.
641
642 - the display metrics, and from them, the X and Y densities in dots
643 per inch.
644
645Then, inside a ``try'' block:
646
647 try
648 {
649 /* Configure Emacs with the asset manager and other necessary
650 parameters. */
651 filesDir = app_context.getFilesDir ().getCanonicalPath ();
652 libDir = getLibraryDirectory ();
653 cacheDir = app_context.getCacheDir ().getCanonicalPath ();
654
655It obtains the names of the Emacs home, shared library, and temporary
656file directories.
657
658 /* Now provide this application's apk file, so a recursive
659 invocation of app_process (through android-emacs) can
660 find EmacsNoninteractive. */
661 classPath = getApkFile ();
662
663The name of the Emacs application package.
664
665 Log.d (TAG, "Initializing Emacs, where filesDir = " + filesDir
666 + ", libDir = " + libDir + ", and classPath = " + classPath);
667
668Prints a debug message to the Android system log with this
669information.
670
671 EmacsNative.setEmacsParams (manager, filesDir, libDir,
672 cacheDir, (float) pixelDensityX,
673 (float) pixelDensityY,
674 classPath, this);
675
676And calls the native function ``setEmacsParams'' (defined in
677android.c) to configure Emacs with this information.
678
679 /* Start the thread that runs Emacs. */
680 thread = new EmacsThread (this, needDashQ);
681 thread.start ();
682
683Then, it allocates an ``EmacsThread'' object, and starts that thread.
684Inside that thread is where Emacs's C code runs.
685
686 }
687 catch (IOException exception)
688 {
689 EmacsNative.emacsAbort ();
690 return;
691
692And here is the purpose of the ``try'' block. Functions related to
693file names in Java will signal errors of various types upon failure.
694
695This ``catch'' block means that the Java virtual machine will abort
696execution of the contents of the ``try'' block as soon as an error of
697type ``IOException'' is encountered, and begin executing the contents
698of the ``catch'' block.
699
700Any failure of that type here is a crash, and
701``EmacsNative.emacsAbort'' is called to quickly abort the process to
702get a useful backtrace.
703 }
704 }
705
706Now, let us look at the definition of the class ``EmacsThread'', found
707in org/gnu/emacs/EmacsThread.java:
708
709public class EmacsThread extends Thread
710{
711 /* Whether or not Emacs should be started -Q. */
712 private boolean startDashQ;
713
714 public
715 EmacsThread (EmacsService service, boolean startDashQ)
716 {
717 super ("Emacs main thread");
718 this.startDashQ = startDashQ;
719 }
720
721 @Override
722 public void
723 run ()
724 {
725 String args[];
726
727 if (!startDashQ)
728 args = new String[] { "libandroid-emacs.so", };
729 else
730 args = new String[] { "libandroid-emacs.so", "-Q", };
731
732 /* Run the native code now. */
733 EmacsNative.initEmacs (args, EmacsApplication.dumpFileName);
734 }
735};
736
737The class itself defines a single field, ``startDashQ'', a constructor
738with an unused argument of the type ``EmacsService'' (which is useful
739while debugging) and a flag ``startDashQ'', and a single function
740``run'', overriding the same function in the class ``Thread''.
741
742When ``thread.start'' is called, the Java virtual machine creates a
743new thread, and then calls the function ``run'' within that thread.
744
745This function then computes a suitable argument vector, and calls
746``EmacsNative.initEmacs'' (defined in android.c), which then calls a
747modified version of the regular Emacs ``main'' function.
748
749At that point, Emacs initialization proceeds as usual:
750Vinitial_window_system is set, loadup.el calls `normal-top-level',
751which calls `command-line', and finally
752`window-system-initialization', which initializes the `android'
753terminal interface as usual.
754
755What happens here is the same as on other platforms. Now, here is
756what happens when the initial frame is created: Fx_create_frame calls
757`android_create_frame_window' to create a top level window:
758
759static void
760android_create_frame_window (struct frame *f)
761{
762 struct android_set_window_attributes attributes;
763 enum android_window_value_mask attribute_mask;
764
765 attributes.background_pixel = FRAME_BACKGROUND_PIXEL (f);
766 attribute_mask = ANDROID_CW_BACK_PIXEL;
767
768 block_input ();
769 FRAME_ANDROID_WINDOW (f)
770 = android_create_window (FRAME_DISPLAY_INFO (f)->root_window,
771 f->left_pos,
772 f->top_pos,
773 FRAME_PIXEL_WIDTH (f),
774 FRAME_PIXEL_HEIGHT (f),
775 attribute_mask, &attributes);
776 unblock_input ();
777}
778
779This calls the function `android_create_window' with some arguments
780whose meanings are identical to the arguments to `XCreateWindow'.
781
782Here is the definition of `android_create_window', in android.c:
783
784android_window
785android_create_window (android_window parent, int x, int y,
786 int width, int height,
787 enum android_window_value_mask value_mask,
788 struct android_set_window_attributes *attrs)
789{
790 static jclass class;
791 static jmethodID constructor;
792 jobject object, parent_object, old;
793 android_window window;
794 android_handle prev_max_handle;
795 bool override_redirect;
796
797What does it do? First, some context:
798
799At any time, there can be at most 65535 Java objects referred to by
800the rest of Emacs through the Java native interface. Each such object
801is assigned a ``handle'' (similar to an XID on X) and given a unique
802type. The function `android_resolve_handle' returns the JNI `jobject'
803associated with a given handle.
804
805 parent_object = android_resolve_handle (parent, ANDROID_HANDLE_WINDOW);
806
807Here, it is being used to look up the `jobject' associated with the
808`parent' handle.
809
810 prev_max_handle = max_handle;
811 window = android_alloc_id ();
812
813Next, `max_handle' is saved, and a new handle is allocated for
814`window'.
815
816 if (!window)
817 error ("Out of window handles!");
818
819An error is signalled if Emacs runs out of available handles.
820
821 if (!class)
822 {
823 class = (*android_java_env)->FindClass (android_java_env,
824 "org/gnu/emacs/EmacsWindow");
825 assert (class != NULL);
826
827Then, if this initialization has not yet been completed, Emacs
828proceeds to find the Java class named ``EmacsWindow''.
829
830 constructor
831 = (*android_java_env)->GetMethodID (android_java_env, class, "<init>",
832 "(SLorg/gnu/emacs/EmacsWindow;"
833 "IIIIZ)V");
834 assert (constructor != NULL);
835
836And it tries to look up the constructor, which should take seven
837arguments:
838
839 S - a short. (the handle ID)
840 Lorg/gnu/Emacs/EmacsWindow; - an instance of the EmacsWindow
841 class. (the parent)
842 IIII - four ints. (the window geometry.)
843 Z - a boolean. (whether or not the
844 window is override-redirect; see
845 XChangeWindowAttributes.)
846
847 old = class;
848 class = (*android_java_env)->NewGlobalRef (android_java_env, class);
849 (*android_java_env)->ExceptionClear (android_java_env);
850 ANDROID_DELETE_LOCAL_REF (old);
851
852Next, it saves a global reference to the class and deletes the local
853reference. Global references will never be deallocated by the Java
854virtual machine as long as they still exist.
855
856 if (!class)
857 memory_full (0);
858 }
859
860 /* N.B. that ANDROID_CW_OVERRIDE_REDIRECT can only be set at window
861 creation time. */
862 override_redirect = ((value_mask
863 & ANDROID_CW_OVERRIDE_REDIRECT)
864 && attrs->override_redirect);
865
866 object = (*android_java_env)->NewObject (android_java_env, class,
867 constructor, (jshort) window,
868 parent_object, (jint) x, (jint) y,
869 (jint) width, (jint) height,
870 (jboolean) override_redirect);
871
872Then, it creates an instance of the ``EmacsWindow'' class with the
873appropriate arguments and previously determined constructor.
874
875 if (!object)
876 {
877 (*android_java_env)->ExceptionClear (android_java_env);
878
879 max_handle = prev_max_handle;
880 memory_full (0);
881
882If creating the object fails, Emacs clears the ``pending exception''
883and signals that it is out of memory.
884 }
885
886 android_handles[window].type = ANDROID_HANDLE_WINDOW;
887 android_handles[window].handle
888 = (*android_java_env)->NewGlobalRef (android_java_env,
889 object);
890 (*android_java_env)->ExceptionClear (android_java_env);
891 ANDROID_DELETE_LOCAL_REF (object);
892
893Otherwise, it associates a new global reference to the object with the
894handle, and deletes the local reference returned from the JNI
895NewObject function.
896
897 if (!android_handles[window].handle)
898 memory_full (0);
899
900If allocating the global reference fails, Emacs signals that it is out
901of memory.
902
903 android_change_window_attributes (window, value_mask, attrs);
904 return window;
905
906Otherwise, it applies the specified window attributes and returns the
907handle of the new window.
908}
909
910
911
912DRAWABLES, CURSORS AND HANDLES
913
914Each widget created by Emacs corresponds to a single ``window'', which
915has its own backing store. This arrangement is quite similar to X.
916
917C code does not directly refer to the EmacsView widgets that implement
918the UI logic behind windows. Instead, its handles refer to
919EmacsWindow structures, which contain the state necessary to interact
920with the widgets in an orderly and synchronized manner.
921
922Like X, both pixmaps and windows are drawable resources, and the same
923graphics operations can be applied to both. Thus, a separate
924EmacsPixmap structure is used to wrap around Android Bitmap resources,
925and the Java-level graphics operation functions are capable of
926operating on them both.
927
928Finally, graphics contexts are maintained on both the C and Java
929levels; the C state recorded in `struct android_gc' is kept in sync
930with the Java state in the GContext handle's corresponding EmacsGC
931structure, and cursors are used through handles that refer to
932EmacsCursor structures that hold system PointerIcons.
933
934In all cases, the interfaces provided are identical to X.
935
936
937
938EVENT LOOP
939
940In a typical Android application, the event loop is managed by the
941operating system, and callbacks (implemented through overriding
942separate functions in widgets) are run by the event loop wherever
943necessary. The thread which runs the event loop is also the only
944thread capable of creating and manipulating widgets and activities,
945and is referred to as the ``UI thread''.
946
947These callbacks are used by Emacs to write representations of X-like
948events to a separate event queue, which are then read from Emacs's own
949event loop running in a separate thread. This is accomplished through
950replacing `select' by a function which waits for the event queue to be
951occupied, in addition to any file descriptors that `select' would
952normally wait for.
953
954Conversely, Emacs's event loop sometimes needs to send events to the
955UI thread. These events are implemented as tiny fragments of code,
956which are run as they are received by the main thread.
957
958A typical example is `displayToast', which is implemented in
959EmacsService.java:
960
961 public void
962 displayToast (final String string)
963 {
964 runOnUiThread (new Runnable () {
965 @Override
966 public void
967 run ()
968 {
969 Toast toast;
970
971 toast = Toast.makeText (getApplicationContext (),
972 string, Toast.LENGTH_SHORT);
973 toast.show ();
974 }
975 });
976 }
977
978Here, the variable `string' is used by a nested function. This nested
979function contains a copy of that variable, and is run on the main
980thread using the function `runOnUiThread', in order to display a short
981status message on the display.
982
983When Emacs needs to wait for the nested function to finish, it uses a
984mechanism implemented in `syncRunnable'. This mechanism first calls a
985deadlock avoidance mechanism, then runs a nested function on the UI
986thread, which is expected to signal itself as a condition variable
987upon completion. It is typically used to allocate resources that can
988only be allocated from the UI thread, or to obtain non-thread-safe
989information. The following function is an example; it returns a new
990EmacsView widget corresponding to the provided window:
991
992 public EmacsView
993 getEmacsView (final EmacsWindow window, final int visibility,
994 final boolean isFocusedByDefault)
995 {
996 Runnable runnable;
997 final EmacsHolder<EmacsView> view;
998
999 view = new EmacsHolder<EmacsView> ();
1000
1001 runnable = new Runnable () {
1002 public void
1003 run ()
1004 {
1005 synchronized (this)
1006 {
1007 view.thing = new EmacsView (window);
1008 view.thing.setVisibility (visibility);
1009
1010 /* The following function is only present on Android 26
1011 or later. */
1012 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
1013 view.thing.setFocusedByDefault (isFocusedByDefault);
1014
1015 notify ();
1016 }
1017 }
1018 };
1019
1020 syncRunnable (runnable);
1021 return view.thing;
1022 }
1023
1024As no value can be directly returned from the nested function, a
1025separate container object is used to hold the result after the
1026function finishes execution. Note the type name inside the angle
1027brackets: this type is substituted into the class definition as it is
1028used; a definition such as:
1029
1030public class Foo<T>
1031{
1032 T bar;
1033};
1034
1035can not be used alone:
1036
1037 Foo holder; /* Error! */
1038
1039but must have a type specified:
1040
1041 Foo<Object> holder;
1042
1043in which case the effective definition is:
1044
1045public class Foo
1046{
1047 Object bar;
1048};
1049