Bring up the Android operating system and its window system
* .dir-locals.el (c-mode): Add ANDROID_EXPORT noise macro.
* .gitignore: Add new files to ignore.
* Makefile.in: Adjust for Android.
* admin/merge-gnulib: Add new warning.
* configure.ac: Detect Android. Run cross-configuration for
Android when appropriate.
* etc/DEBUG: Document how to debug Emacs on Android.
* java/AndroidManifest.xml:
* java/Makefile.in:
* java/README:
* java/debug.sh:
* java/org/gnu/emacs/EmacsActivity.java (EmacsActivity):
* java/org/gnu/emacs/EmacsApplication.java (EmacsApplication):
* java/org/gnu/emacs/EmacsCopyArea.java (EmacsCopyArea):
* java/org/gnu/emacs/EmacsDrawLine.java (EmacsDrawLine):
* java/org/gnu/emacs/EmacsDrawPoint.java (EmacsDrawPoint):
* java/org/gnu/emacs/EmacsDrawRectangle.java
(EmacsDrawRectangle):
* java/org/gnu/emacs/EmacsDrawable.java (EmacsDrawable):
* java/org/gnu/emacs/EmacsFillPolygon.java (EmacsFillPolygon):
* java/org/gnu/emacs/EmacsFillRectangle.java
(EmacsFillRectangle):
* java/org/gnu/emacs/EmacsFontDriver.java (EmacsFontDriver):
* java/org/gnu/emacs/EmacsGC.java (EmacsGC):
* java/org/gnu/emacs/EmacsHandleObject.java (EmacsHandleObject):
* java/org/gnu/emacs/EmacsNative.java (EmacsNative):
* java/org/gnu/emacs/EmacsPaintQueue.java (EmacsPaintQueue):
* java/org/gnu/emacs/EmacsPaintReq.java (EmacsPaintReq):
* java/org/gnu/emacs/EmacsPixmap.java (EmacsPixmap):
* java/org/gnu/emacs/EmacsSdk7FontDriver.java
(EmacsSdk7FontDriver):
* java/org/gnu/emacs/EmacsService.java (class Holder<T>)
(EmacsService):
* java/org/gnu/emacs/EmacsSurfaceView.java (EmacsSurfaceView):
* java/org/gnu/emacs/EmacsThread.java (EmacsThread):
* java/org/gnu/emacs/EmacsView.java (EmacsView):
* java/org/gnu/emacs/EmacsWindow.java (EmacsWindow): New files
and classes.
* lib-src/Makefile.in (srcdir):
* lib/Makefile.in (VPATH):
(HAVE_NATIVE_COMP):
(libgnu_a_SOURCES):
(DEPFLAGS): Configure correctly for cross-compiling.
* lib/faccessat.c:
* lib/fpending.c (__fpending):
* lib/open.c:
* lib/unistd.c (_GL_UNISTD_INLINE): Temporary adjustments to
gnulib.
* lisp/frame.el (display-graphic-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): Adjust for new window system `android'.
* lisp/image/wallpaper.el (x-open-connection): Add declaration.
* lisp/loadup.el (featurep): Load up files for Android.
* lisp/net/eww.el (eww-form-submit, eww-form-file)
(eww-form-checkbox, eww-form-select): Adjust faces for android.
* lisp/term/android-win.el: New file.
* src/Makefile.in: Add new targets emacs.so and android-emacs,
then adjust for cross compilation.
* src/alloc.c (cleanup_vector): Clean up Android font entities
as well.
(garbage_collect): Mark androidterm.
* src/android-emacs.c (main):
* src/android.c (ANDROID_THROW, enum android_fd_table_entry_flags)
(struct android_emacs_service, struct android_emacs_pixmap)
(struct android_graphics_point, struct android_event_container)
(struct android_event_queue, android_run_select_thread)
(android_handle_sigusr1, android_init_events, android_pending)
(android_next_event, android_write_event, android_select)
(android_run_debug_thread, android_user_full_name)
(android_get_asset_name, android_fstat, android_fstatat)
(android_file_access_p, android_hack_asset_fd, android_open)
(android_close, JNICALL, android_init_emacs_service)
(android_init_emacs_pixmap, android_init_graphics_point)
(MAX_HANDLE, struct android_handle_entry, android_alloc_id)
(android_destroy_handle, android_resolve_handle)
(android_resolve_handle2, android_change_window_attributes)
(android_create_window, android_set_window_background)
(android_destroy_window, android_init_android_rect_class)
(android_init_emacs_gc_class, android_create_gc, android_free_gc)
(android_change_gc, android_set_clip_rectangles)
(android_reparent_window, android_lookup_method)
(android_clear_window, android_map_window, android_unmap_window)
(android_resize_window, android_move_window, android_swap_buffers)
(android_get_gc_values, android_set_foreground)
(android_fill_rectangle, android_create_pixmap_from_bitmap_data)
(android_set_clip_mask, android_set_fill_style, android_copy_area)
(android_free_pixmap, android_set_background, android_fill_polygon)
(android_draw_rectangle, android_draw_point, android_draw_line)
(android_create_pixmap, android_set_ts_origin, android_clear_area):
* src/android.h (ANDROID_EXPORT):
* src/androidfns.c (android_display_info_for_name)
(check_android_display_info, check_x_display_info, gamma_correct)
(android_defined_color, android_decode_color)
(android_implicitly_set_name, android_explicitly_set_name)
(android_set_tool_bar_lines, android_change_tool_bar_height)
(android_set_tab_bar_lines, android_change_tab_bar_height)
(android_set_scroll_bar_default_height)
(android_set_scroll_bar_default_width, android_icon_verify)
(android_icon, android_make_gc, android_free_gcs)
(unwind_create_frame, do_unwind_create_frame)
(android_default_font_parameter, android_create_frame_window)
(Fx_create_frame, Fxw_color_defined_p, Fxw_color_values)
(Fxw_display_color_p, Fx_display_grayscale_p)
(Fx_display_pixel_width, Fx_display_pixel_height)
(Fx_display_planes, Fx_display_color_cells, Fx_display_screens)
(Fx_display_mm_width, Fx_display_mm_height)
(Fx_display_backing_store, Fx_display_visual_class)
(Fx_display_monitor_attributes_list, Fx_frame_geometry)
(Fx_frame_list_z_order, Fx_frame_restack)
(Fx_mouse_absolute_pixel_position)
(Fx_set_mouse_absolute_pixel_position, Fandroid_get_connection)
(Fx_display_list, Fx_show_tip, Fx_hide_tip)
(android_set_background_color, android_set_border_color)
(android_set_cursor_color, android_set_cursor_type)
(android_set_foreground_color)
(android_set_child_frame_border_width)
(android_set_internal_border_width, android_set_menu_bar_lines)
(android_set_mouse_color, android_set_title, android_set_alpha)
(android_frame_parm_handlers, syms_of_androidfns):
* src/androidfont.c (struct android_emacs_font_driver)
(struct android_emacs_font_spec, struct android_emacs_font_metrics)
(struct android_emacs_font_object, struct android_integer)
(struct androidfont_info, struct androidfont_entity)
(android_init_font_driver, android_init_font_spec)
(android_init_font_metrics, android_init_integer)
(android_init_font_object, androidfont_get_cache)
(androidfont_from_lisp, androidfont_from_java, androidfont_list)
(androidfont_match, androidfont_draw, androidfont_open_font)
(androidfont_close_font, androidfont_has_char)
(androidfont_encode_char, androidfont_text_extents)
(androidfont_list_family, androidfont_driver)
(syms_of_androidfont_for_pdumper, syms_of_androidfont)
(init_androidfont, android_finalize_font_entity):
* src/androidgui.h (_ANDROID_GUI_H_, struct android_rectangle)
(struct android_point, enum android_gc_function)
(enum android_gc_value_mask, enum android_fill_style)
(enum android_window_value_mask)
(struct android_set_window_attributes, struct android_gc_values)
(struct android_gc, enum android_swap_action, enum android_shape)
(enum android_coord_mode, struct android_swap_info)
(NativeRectangle, struct android_any_event)
(struct android_key_event, struct android_configure_event)
(union android_event):
* src/androidterm.c (android_window_to_frame, android_clear_frame)
(android_ring_bell, android_toggle_invisible_pointer)
(android_update_begin, android_update_end, show_back_buffer)
(android_flush_dirty_back_buffer_on, handle_one_android_event)
(android_read_socket, android_frame_up_to_date)
(android_buffer_flipping_unblocked_hook)
(android_query_frame_background_color, android_parse_color)
(android_alloc_nearest_color, android_query_colors)
(android_mouse_position, android_get_focus_frame)
(android_focus_frame, android_frame_rehighlight)
(android_frame_raise_lower, android_make_frame_visible)
(android_make_frame_invisible)
(android_make_frame_visible_invisible, android_fullscreen_hook)
(android_iconify_frame, android_set_window_size_1)
(android_set_window_size, android_set_offset, android_set_alpha)
(android_new_font, android_bitmap_icon, android_free_pixmap_hook)
(android_free_frame_resources, android_delete_frame)
(android_delete_terminal, android_scroll_run)
(android_after_update_window_line, android_flip_and_flush)
(android_clear_rectangle, android_reset_clip_rectangles)
(android_clip_to_row, android_draw_fringe_bitmap)
(android_set_cursor_gc, android_set_mouse_face_gc)
(android_set_mode_line_face_gc, android_set_glyph_string_gc)
(android_set_glyph_string_clipping)
(android_set_glyph_string_clipping_exactly)
(android_compute_glyph_string_overhangs)
(android_clear_glyph_string_rect)
(android_draw_glyph_string_background, android_fill_triangle)
(android_make_point, android_inside_rect_p, android_clear_point)
(android_draw_relief_rect, android_draw_box_rect)
(HIGHLIGHT_COLOR_DARK_BOOST_LIMIT, android_setup_relief_color)
(android_setup_relief_colors, android_draw_glyph_string_box)
(android_draw_glyph_string_bg_rect, android_draw_image_relief)
(android_draw_image_foreground, android_draw_image_foreground_1)
(android_draw_image_glyph_string)
(android_draw_stretch_glyph_string, android_draw_underwave)
(android_draw_glyph_string_foreground)
(android_draw_composite_glyph_string_foreground)
(android_draw_glyphless_glyph_string_foreground)
(android_draw_glyph_string, android_define_frame_cursor)
(android_clear_frame_area, android_clear_under_internal_border)
(android_draw_hollow_cursor, android_draw_bar_cursor)
(android_draw_window_cursor, android_draw_vertical_window_border)
(android_draw_window_divider, android_redisplay_interface)
(frame_set_mouse_pixel_position, get_keysym_name)
(android_create_terminal, android_term_init, syms_of_androidterm)
(mark_androidterm):
* src/androidterm.h (_ANDROID_TERM_H_, struct android_display_info)
(struct android_output, FRAME_ANDROID_OUTPUT, XSCROLL_BAR): New
files.
* src/dired.c (file_attributes): Do not use openat on Android.
* src/dispextern.h (No_Cursor): Define appropriately on Android.
(struct glyph_string, struct face): Make gc field of type struct
android_gc on Android.
* src/dispnew.c (clear_current_matrices, clear_desired_matrices)
(adjust_frame_glyphs_for_window_redisplay, free_glyphs)
(update_frame, scrolling, char_ins_del_cost, update_frame_line)
(init_display_interactive): Disable text terminal support
completely on Android. Fix non-toolkit menus for non-X systems.
* src/editfns.c (Fuser_full_name): Call android_user_full_name.
* src/emacs.c (android_emacs_init): Make main this on Android.
Prohibit argv sorting from exceeding end of argv.
* src/epaths.in: Add path definitions for Android.
* src/fileio.c (file_access_p): Call android_file_access_p.
(file_name_directory): Avoid using openat on Android.
(Fcopy_file): Adjust to call sys_fstat instead.
(file_directory_p):
(Finsert_file_contents):
(write_region): Likewise.
* src/filelock.c:
* src/fns.c (Flocale_info): Pacify warning on Android.
* src/font.c (font_make_entity_android): New function.
* src/font.h:
* src/frame.c (Fframep):
(Fwindow_system): Handle new window system `android'. Update doc strings.
(Fmake_terminal_frame): Disable on Android.
(gui_display_get_resource): Disable get_string_resource_hook on Android.
(syms_of_frame): New defsym `android'.
* src/frame.h (GCALIGNED_STRUCT): Add new output data for
Android.
(ENUM_BF): Expand enumerator size.
(FRAME_ANDROID_P, FRAME_WINDOW_P, MOUSE_HL_INFO): Add
definitions for Android.
* src/image.c (GET_PIXEL):
(image_create_bitmap_from_file):
(image_create_x_image_and_pixmap_1):
(image_get_x_image):
(slurp_file):
(lookup_rgb_color):
(image_to_emacs_colors):
(image_from_emacs_colors):
(image_pixmap_draw_cross):
(image_disable_image):
(MaskForeground):
(gif_load): Add stubs for Android.
* src/lisp.h:
* src/lread.c (safe_to_load_version, maybe_swap_for_eln1, openp):
* src/pdumper.c (pdumper_load): Call sys_fstat instead of fstat.
* src/process.c (wait_reading_process_output): Use
android_select instead of pselect.
* src/scroll.c: Disable on Android.
* src/sysdep.c (widen_foreground_group, reset_sys_modes)
(init_signals, emacs_fstatat, sys_fstat): New function.
(emacs_open, emacs_open_noquit, emacs_close): Implement
differently on Android.
(close_output_streams): Disable what is not required on Android.
* src/term.c (OUTPUT1_IF, encode_terminal_code, string_cost)
(string_cost_one_line, per_line_cost, calculate_costs)
(struct fkey_table, tty_append_glyph, produce_glyphs)
(tty_capable_p, Fsuspend_tty, Fresume_tty, device, init_tty)
(maybe_fatal, syms_of_term): Disable text terminal support on
Android.
* src/termhooks.h (enum output_method): Add android output
method.
(GCALIGNED_STRUCT, TERMINAL_FONT_CACHE): Define for Android.
* src/terminal.c (Fterminal_live_p): Implement for Android.
* src/verbose.mk.in (AM_V_GLOBALS): Add JAVAC and DX.
* src/xdisp.c (redisplay_internal): Disable text terminals on Android.
(display_menu_bar):
(display_tty_menu_item):
(draw_row_with_mouse_face):
(expose_frame): Make the non toolkit menu bar work on Android.
* src/xfaces.c (GCGraphicsExposures):
(x_create_gc):
(x_free_gc):
(Fx_load_color_file): Define for Android.
* xcompile/Makefile.in (top_srcdir):
(top_builddir):
* xcompile/README:
* xcompile/langinfo.h (nl_langinfo): New files.
2022-12-31 10:04:18 +00:00
|
|
|
|
This directory holds the Java sources of the port of GNU Emacs to
|
2023-01-24 09:31:16 +00:00
|
|
|
|
Android-like systems, along with files needed to create an application
|
|
|
|
|
package out of them.
|
|
|
|
|
|
2023-02-02 02:31:10 +00:00
|
|
|
|
The ``org/gnu/emacs'' subdirectory contains the Java sources under the
|
|
|
|
|
``org.gnu.emacs'' package identifier.
|
|
|
|
|
|
2023-02-09 14:56:41 +00:00
|
|
|
|
``AndroidManifest.xml'' contains a manifest describing the Java
|
|
|
|
|
sources to the system.
|
|
|
|
|
|
|
|
|
|
The ``res'' directory contains resources, mainly the Emacs icon and
|
|
|
|
|
several ``boolean resources'' which are used as a form of conditional
|
|
|
|
|
evaluation for manifest entries.
|
2023-02-02 02:31:10 +00:00
|
|
|
|
|
2023-01-24 09:31:16 +00:00
|
|
|
|
`emacs.keystore' is the signing key used to build Emacs. It is kept
|
|
|
|
|
here, and we encourage all people redistributing Emacs to use this
|
|
|
|
|
key. It holds no security value, and otherwise it will be impossible
|
|
|
|
|
to install different builds of Emacs on top of each other.
|
Bring up the Android operating system and its window system
* .dir-locals.el (c-mode): Add ANDROID_EXPORT noise macro.
* .gitignore: Add new files to ignore.
* Makefile.in: Adjust for Android.
* admin/merge-gnulib: Add new warning.
* configure.ac: Detect Android. Run cross-configuration for
Android when appropriate.
* etc/DEBUG: Document how to debug Emacs on Android.
* java/AndroidManifest.xml:
* java/Makefile.in:
* java/README:
* java/debug.sh:
* java/org/gnu/emacs/EmacsActivity.java (EmacsActivity):
* java/org/gnu/emacs/EmacsApplication.java (EmacsApplication):
* java/org/gnu/emacs/EmacsCopyArea.java (EmacsCopyArea):
* java/org/gnu/emacs/EmacsDrawLine.java (EmacsDrawLine):
* java/org/gnu/emacs/EmacsDrawPoint.java (EmacsDrawPoint):
* java/org/gnu/emacs/EmacsDrawRectangle.java
(EmacsDrawRectangle):
* java/org/gnu/emacs/EmacsDrawable.java (EmacsDrawable):
* java/org/gnu/emacs/EmacsFillPolygon.java (EmacsFillPolygon):
* java/org/gnu/emacs/EmacsFillRectangle.java
(EmacsFillRectangle):
* java/org/gnu/emacs/EmacsFontDriver.java (EmacsFontDriver):
* java/org/gnu/emacs/EmacsGC.java (EmacsGC):
* java/org/gnu/emacs/EmacsHandleObject.java (EmacsHandleObject):
* java/org/gnu/emacs/EmacsNative.java (EmacsNative):
* java/org/gnu/emacs/EmacsPaintQueue.java (EmacsPaintQueue):
* java/org/gnu/emacs/EmacsPaintReq.java (EmacsPaintReq):
* java/org/gnu/emacs/EmacsPixmap.java (EmacsPixmap):
* java/org/gnu/emacs/EmacsSdk7FontDriver.java
(EmacsSdk7FontDriver):
* java/org/gnu/emacs/EmacsService.java (class Holder<T>)
(EmacsService):
* java/org/gnu/emacs/EmacsSurfaceView.java (EmacsSurfaceView):
* java/org/gnu/emacs/EmacsThread.java (EmacsThread):
* java/org/gnu/emacs/EmacsView.java (EmacsView):
* java/org/gnu/emacs/EmacsWindow.java (EmacsWindow): New files
and classes.
* lib-src/Makefile.in (srcdir):
* lib/Makefile.in (VPATH):
(HAVE_NATIVE_COMP):
(libgnu_a_SOURCES):
(DEPFLAGS): Configure correctly for cross-compiling.
* lib/faccessat.c:
* lib/fpending.c (__fpending):
* lib/open.c:
* lib/unistd.c (_GL_UNISTD_INLINE): Temporary adjustments to
gnulib.
* lisp/frame.el (display-graphic-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): Adjust for new window system `android'.
* lisp/image/wallpaper.el (x-open-connection): Add declaration.
* lisp/loadup.el (featurep): Load up files for Android.
* lisp/net/eww.el (eww-form-submit, eww-form-file)
(eww-form-checkbox, eww-form-select): Adjust faces for android.
* lisp/term/android-win.el: New file.
* src/Makefile.in: Add new targets emacs.so and android-emacs,
then adjust for cross compilation.
* src/alloc.c (cleanup_vector): Clean up Android font entities
as well.
(garbage_collect): Mark androidterm.
* src/android-emacs.c (main):
* src/android.c (ANDROID_THROW, enum android_fd_table_entry_flags)
(struct android_emacs_service, struct android_emacs_pixmap)
(struct android_graphics_point, struct android_event_container)
(struct android_event_queue, android_run_select_thread)
(android_handle_sigusr1, android_init_events, android_pending)
(android_next_event, android_write_event, android_select)
(android_run_debug_thread, android_user_full_name)
(android_get_asset_name, android_fstat, android_fstatat)
(android_file_access_p, android_hack_asset_fd, android_open)
(android_close, JNICALL, android_init_emacs_service)
(android_init_emacs_pixmap, android_init_graphics_point)
(MAX_HANDLE, struct android_handle_entry, android_alloc_id)
(android_destroy_handle, android_resolve_handle)
(android_resolve_handle2, android_change_window_attributes)
(android_create_window, android_set_window_background)
(android_destroy_window, android_init_android_rect_class)
(android_init_emacs_gc_class, android_create_gc, android_free_gc)
(android_change_gc, android_set_clip_rectangles)
(android_reparent_window, android_lookup_method)
(android_clear_window, android_map_window, android_unmap_window)
(android_resize_window, android_move_window, android_swap_buffers)
(android_get_gc_values, android_set_foreground)
(android_fill_rectangle, android_create_pixmap_from_bitmap_data)
(android_set_clip_mask, android_set_fill_style, android_copy_area)
(android_free_pixmap, android_set_background, android_fill_polygon)
(android_draw_rectangle, android_draw_point, android_draw_line)
(android_create_pixmap, android_set_ts_origin, android_clear_area):
* src/android.h (ANDROID_EXPORT):
* src/androidfns.c (android_display_info_for_name)
(check_android_display_info, check_x_display_info, gamma_correct)
(android_defined_color, android_decode_color)
(android_implicitly_set_name, android_explicitly_set_name)
(android_set_tool_bar_lines, android_change_tool_bar_height)
(android_set_tab_bar_lines, android_change_tab_bar_height)
(android_set_scroll_bar_default_height)
(android_set_scroll_bar_default_width, android_icon_verify)
(android_icon, android_make_gc, android_free_gcs)
(unwind_create_frame, do_unwind_create_frame)
(android_default_font_parameter, android_create_frame_window)
(Fx_create_frame, Fxw_color_defined_p, Fxw_color_values)
(Fxw_display_color_p, Fx_display_grayscale_p)
(Fx_display_pixel_width, Fx_display_pixel_height)
(Fx_display_planes, Fx_display_color_cells, Fx_display_screens)
(Fx_display_mm_width, Fx_display_mm_height)
(Fx_display_backing_store, Fx_display_visual_class)
(Fx_display_monitor_attributes_list, Fx_frame_geometry)
(Fx_frame_list_z_order, Fx_frame_restack)
(Fx_mouse_absolute_pixel_position)
(Fx_set_mouse_absolute_pixel_position, Fandroid_get_connection)
(Fx_display_list, Fx_show_tip, Fx_hide_tip)
(android_set_background_color, android_set_border_color)
(android_set_cursor_color, android_set_cursor_type)
(android_set_foreground_color)
(android_set_child_frame_border_width)
(android_set_internal_border_width, android_set_menu_bar_lines)
(android_set_mouse_color, android_set_title, android_set_alpha)
(android_frame_parm_handlers, syms_of_androidfns):
* src/androidfont.c (struct android_emacs_font_driver)
(struct android_emacs_font_spec, struct android_emacs_font_metrics)
(struct android_emacs_font_object, struct android_integer)
(struct androidfont_info, struct androidfont_entity)
(android_init_font_driver, android_init_font_spec)
(android_init_font_metrics, android_init_integer)
(android_init_font_object, androidfont_get_cache)
(androidfont_from_lisp, androidfont_from_java, androidfont_list)
(androidfont_match, androidfont_draw, androidfont_open_font)
(androidfont_close_font, androidfont_has_char)
(androidfont_encode_char, androidfont_text_extents)
(androidfont_list_family, androidfont_driver)
(syms_of_androidfont_for_pdumper, syms_of_androidfont)
(init_androidfont, android_finalize_font_entity):
* src/androidgui.h (_ANDROID_GUI_H_, struct android_rectangle)
(struct android_point, enum android_gc_function)
(enum android_gc_value_mask, enum android_fill_style)
(enum android_window_value_mask)
(struct android_set_window_attributes, struct android_gc_values)
(struct android_gc, enum android_swap_action, enum android_shape)
(enum android_coord_mode, struct android_swap_info)
(NativeRectangle, struct android_any_event)
(struct android_key_event, struct android_configure_event)
(union android_event):
* src/androidterm.c (android_window_to_frame, android_clear_frame)
(android_ring_bell, android_toggle_invisible_pointer)
(android_update_begin, android_update_end, show_back_buffer)
(android_flush_dirty_back_buffer_on, handle_one_android_event)
(android_read_socket, android_frame_up_to_date)
(android_buffer_flipping_unblocked_hook)
(android_query_frame_background_color, android_parse_color)
(android_alloc_nearest_color, android_query_colors)
(android_mouse_position, android_get_focus_frame)
(android_focus_frame, android_frame_rehighlight)
(android_frame_raise_lower, android_make_frame_visible)
(android_make_frame_invisible)
(android_make_frame_visible_invisible, android_fullscreen_hook)
(android_iconify_frame, android_set_window_size_1)
(android_set_window_size, android_set_offset, android_set_alpha)
(android_new_font, android_bitmap_icon, android_free_pixmap_hook)
(android_free_frame_resources, android_delete_frame)
(android_delete_terminal, android_scroll_run)
(android_after_update_window_line, android_flip_and_flush)
(android_clear_rectangle, android_reset_clip_rectangles)
(android_clip_to_row, android_draw_fringe_bitmap)
(android_set_cursor_gc, android_set_mouse_face_gc)
(android_set_mode_line_face_gc, android_set_glyph_string_gc)
(android_set_glyph_string_clipping)
(android_set_glyph_string_clipping_exactly)
(android_compute_glyph_string_overhangs)
(android_clear_glyph_string_rect)
(android_draw_glyph_string_background, android_fill_triangle)
(android_make_point, android_inside_rect_p, android_clear_point)
(android_draw_relief_rect, android_draw_box_rect)
(HIGHLIGHT_COLOR_DARK_BOOST_LIMIT, android_setup_relief_color)
(android_setup_relief_colors, android_draw_glyph_string_box)
(android_draw_glyph_string_bg_rect, android_draw_image_relief)
(android_draw_image_foreground, android_draw_image_foreground_1)
(android_draw_image_glyph_string)
(android_draw_stretch_glyph_string, android_draw_underwave)
(android_draw_glyph_string_foreground)
(android_draw_composite_glyph_string_foreground)
(android_draw_glyphless_glyph_string_foreground)
(android_draw_glyph_string, android_define_frame_cursor)
(android_clear_frame_area, android_clear_under_internal_border)
(android_draw_hollow_cursor, android_draw_bar_cursor)
(android_draw_window_cursor, android_draw_vertical_window_border)
(android_draw_window_divider, android_redisplay_interface)
(frame_set_mouse_pixel_position, get_keysym_name)
(android_create_terminal, android_term_init, syms_of_androidterm)
(mark_androidterm):
* src/androidterm.h (_ANDROID_TERM_H_, struct android_display_info)
(struct android_output, FRAME_ANDROID_OUTPUT, XSCROLL_BAR): New
files.
* src/dired.c (file_attributes): Do not use openat on Android.
* src/dispextern.h (No_Cursor): Define appropriately on Android.
(struct glyph_string, struct face): Make gc field of type struct
android_gc on Android.
* src/dispnew.c (clear_current_matrices, clear_desired_matrices)
(adjust_frame_glyphs_for_window_redisplay, free_glyphs)
(update_frame, scrolling, char_ins_del_cost, update_frame_line)
(init_display_interactive): Disable text terminal support
completely on Android. Fix non-toolkit menus for non-X systems.
* src/editfns.c (Fuser_full_name): Call android_user_full_name.
* src/emacs.c (android_emacs_init): Make main this on Android.
Prohibit argv sorting from exceeding end of argv.
* src/epaths.in: Add path definitions for Android.
* src/fileio.c (file_access_p): Call android_file_access_p.
(file_name_directory): Avoid using openat on Android.
(Fcopy_file): Adjust to call sys_fstat instead.
(file_directory_p):
(Finsert_file_contents):
(write_region): Likewise.
* src/filelock.c:
* src/fns.c (Flocale_info): Pacify warning on Android.
* src/font.c (font_make_entity_android): New function.
* src/font.h:
* src/frame.c (Fframep):
(Fwindow_system): Handle new window system `android'. Update doc strings.
(Fmake_terminal_frame): Disable on Android.
(gui_display_get_resource): Disable get_string_resource_hook on Android.
(syms_of_frame): New defsym `android'.
* src/frame.h (GCALIGNED_STRUCT): Add new output data for
Android.
(ENUM_BF): Expand enumerator size.
(FRAME_ANDROID_P, FRAME_WINDOW_P, MOUSE_HL_INFO): Add
definitions for Android.
* src/image.c (GET_PIXEL):
(image_create_bitmap_from_file):
(image_create_x_image_and_pixmap_1):
(image_get_x_image):
(slurp_file):
(lookup_rgb_color):
(image_to_emacs_colors):
(image_from_emacs_colors):
(image_pixmap_draw_cross):
(image_disable_image):
(MaskForeground):
(gif_load): Add stubs for Android.
* src/lisp.h:
* src/lread.c (safe_to_load_version, maybe_swap_for_eln1, openp):
* src/pdumper.c (pdumper_load): Call sys_fstat instead of fstat.
* src/process.c (wait_reading_process_output): Use
android_select instead of pselect.
* src/scroll.c: Disable on Android.
* src/sysdep.c (widen_foreground_group, reset_sys_modes)
(init_signals, emacs_fstatat, sys_fstat): New function.
(emacs_open, emacs_open_noquit, emacs_close): Implement
differently on Android.
(close_output_streams): Disable what is not required on Android.
* src/term.c (OUTPUT1_IF, encode_terminal_code, string_cost)
(string_cost_one_line, per_line_cost, calculate_costs)
(struct fkey_table, tty_append_glyph, produce_glyphs)
(tty_capable_p, Fsuspend_tty, Fresume_tty, device, init_tty)
(maybe_fatal, syms_of_term): Disable text terminal support on
Android.
* src/termhooks.h (enum output_method): Add android output
method.
(GCALIGNED_STRUCT, TERMINAL_FONT_CACHE): Define for Android.
* src/terminal.c (Fterminal_live_p): Implement for Android.
* src/verbose.mk.in (AM_V_GLOBALS): Add JAVAC and DX.
* src/xdisp.c (redisplay_internal): Disable text terminals on Android.
(display_menu_bar):
(display_tty_menu_item):
(draw_row_with_mouse_face):
(expose_frame): Make the non toolkit menu bar work on Android.
* src/xfaces.c (GCGraphicsExposures):
(x_create_gc):
(x_free_gc):
(Fx_load_color_file): Define for Android.
* xcompile/Makefile.in (top_srcdir):
(top_builddir):
* xcompile/README:
* xcompile/langinfo.h (nl_langinfo): New files.
2022-12-31 10:04:18 +00:00
|
|
|
|
|
|
|
|
|
Please keep the Java code indented with tabs and formatted according
|
|
|
|
|
to the rules for C code in the GNU coding standards. Always use
|
|
|
|
|
C-style comments.
|
2023-01-25 10:44:47 +00:00
|
|
|
|
|
|
|
|
|
======================================================================
|
|
|
|
|
|
|
|
|
|
OVERVIEW OF JAVA
|
|
|
|
|
|
|
|
|
|
Emacs developers do not know Java, and there is no reason they should
|
|
|
|
|
have to. Thus, the code in this directory is confined to what is
|
|
|
|
|
strictly necessary to support Emacs, and only uses a subset of Java
|
|
|
|
|
written in a way that is easily understandable to C programmers.
|
|
|
|
|
|
|
|
|
|
Java is required because the entire Android runtime is based around
|
|
|
|
|
Java, and there is no way to write an Android program which runs
|
|
|
|
|
without Java.
|
|
|
|
|
|
|
|
|
|
This text exists to prime other Emacs developers, already familar with
|
|
|
|
|
C, on the basic architecture of the Android port, and to teach them
|
|
|
|
|
how to read and write the Java code found in this directory.
|
|
|
|
|
|
|
|
|
|
Java is an object oriented language with automatic memory management
|
|
|
|
|
compiled down to bytecode, which is then subject to interpretation by
|
|
|
|
|
a Java virtual machine.
|
|
|
|
|
|
|
|
|
|
What that means, is that:
|
|
|
|
|
|
|
|
|
|
struct emacs_window
|
|
|
|
|
{
|
|
|
|
|
int some_fields;
|
|
|
|
|
int of_emacs_window;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
do_something_with_emacs_window (struct emacs_window *a, int n)
|
|
|
|
|
{
|
|
|
|
|
a->some_fields = a->of_emacs_window + n;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
would be written:
|
|
|
|
|
|
|
|
|
|
public class EmacsWindow
|
|
|
|
|
{
|
|
|
|
|
public int someFields;
|
|
|
|
|
public int ofEmacsWindow;
|
|
|
|
|
|
|
|
|
|
public void
|
|
|
|
|
doSomething (int n)
|
|
|
|
|
{
|
|
|
|
|
someFields = ofEmacsWindow + n;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
and instead of doing:
|
|
|
|
|
|
|
|
|
|
do_something_with_emacs_window (my_window, 1);
|
|
|
|
|
|
|
|
|
|
you say:
|
|
|
|
|
|
|
|
|
|
myWindow.doSomething (1);
|
|
|
|
|
|
|
|
|
|
In addition to functions associated with an object of a given class
|
|
|
|
|
(such as EmacsWindow), Java also has two other kinds of functions.
|
|
|
|
|
|
|
|
|
|
The first are so-called ``static'' functions (the static means
|
|
|
|
|
something entirely different from what it does in C.)
|
|
|
|
|
|
|
|
|
|
A static function, while still having to be defined within a class,
|
|
|
|
|
can be called without any object. Instead of the object, you write
|
|
|
|
|
the name of the Java class within which it is defined. For example,
|
|
|
|
|
the following C code:
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
multiply_a_with_b_and_then_add_c (int a, int b, int c)
|
|
|
|
|
{
|
|
|
|
|
return a * b + c;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
would be:
|
|
|
|
|
|
|
|
|
|
public class EmacsSomething
|
|
|
|
|
{
|
|
|
|
|
public static int
|
|
|
|
|
multiplyAWithBAndThenAddC (int a, int b, int c)
|
|
|
|
|
{
|
|
|
|
|
return a * b + c;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Then, instead of calling:
|
|
|
|
|
|
|
|
|
|
int foo;
|
|
|
|
|
|
|
|
|
|
foo = multiply_a_with_b_then_add_c (1, 2, 3);
|
|
|
|
|
|
|
|
|
|
you say:
|
|
|
|
|
|
|
|
|
|
int foo;
|
|
|
|
|
|
|
|
|
|
foo = EmacsSomething.multiplyAWithBAndThenAddC (1, 2, 3);
|
|
|
|
|
|
|
|
|
|
In Java, ``static'' does not mean that the function is only used
|
|
|
|
|
within its compilation unit! Instead, the ``private'' qualifier is
|
|
|
|
|
used to mean more or less the same thing:
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
this_procedure_is_only_used_within_this_file (void)
|
|
|
|
|
{
|
|
|
|
|
do_something ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
becomes
|
|
|
|
|
|
|
|
|
|
public class EmacsSomething
|
|
|
|
|
{
|
|
|
|
|
private static void
|
|
|
|
|
thisProcedureIsOnlyUsedWithinThisClass ()
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
the other kind are called ``constructors''. They are functions that
|
|
|
|
|
must be called to allocate memory to hold a class:
|
|
|
|
|
|
|
|
|
|
public class EmacsFoo
|
|
|
|
|
{
|
|
|
|
|
int bar;
|
|
|
|
|
|
|
|
|
|
public
|
|
|
|
|
EmacsFoo (int tokenA, int tokenB)
|
|
|
|
|
{
|
|
|
|
|
bar = tokenA + tokenB;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
now, the following statement:
|
|
|
|
|
|
|
|
|
|
EmacsFoo foo;
|
|
|
|
|
|
|
|
|
|
foo = new EmacsFoo (1, 2);
|
|
|
|
|
|
|
|
|
|
becomes more or less equivalent to the following C code:
|
|
|
|
|
|
|
|
|
|
struct emacs_foo
|
|
|
|
|
{
|
|
|
|
|
int bar;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct emacs_foo *
|
|
|
|
|
make_emacs_foo (int token_a, int token_b)
|
|
|
|
|
{
|
|
|
|
|
struct emacs_foo *foo;
|
|
|
|
|
|
|
|
|
|
foo = xmalloc (sizeof *foo);
|
|
|
|
|
foo->bar = token_a + token_b;
|
|
|
|
|
|
|
|
|
|
return foo;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ... */
|
|
|
|
|
|
|
|
|
|
struct emacs_foo *foo;
|
|
|
|
|
|
|
|
|
|
foo = make_emacs_foo (1, 2);
|
|
|
|
|
|
|
|
|
|
A class may have any number of constructors, or no constructors at
|
|
|
|
|
all, in which case the compiler inserts an empty constructor.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Sometimes, you will see Java code that looks like this:
|
|
|
|
|
|
|
|
|
|
allFiles = filesDirectory.listFiles (new FileFilter () {
|
|
|
|
|
@Override
|
|
|
|
|
public boolean
|
|
|
|
|
accept (File file)
|
|
|
|
|
{
|
|
|
|
|
return (!file.isDirectory ()
|
|
|
|
|
&& file.getName ().endsWith (".pdmp"));
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
This is Java's version of GCC's nested function extension. The major
|
|
|
|
|
difference is that the nested function may still be called even after
|
|
|
|
|
it goes out of scope, and always retains a reference to the class and
|
|
|
|
|
local variables around where it was called.
|
|
|
|
|
|
|
|
|
|
Being an object-oriented language, Java also allows defining that a
|
|
|
|
|
class ``extends'' another class. The following C code:
|
|
|
|
|
|
|
|
|
|
struct a
|
|
|
|
|
{
|
|
|
|
|
long thirty_two;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct b
|
|
|
|
|
{
|
|
|
|
|
struct a a;
|
|
|
|
|
long long sixty_four;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
extern void do_something (struct a *);
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
my_function (struct b *b)
|
|
|
|
|
{
|
|
|
|
|
do_something (&b->a);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
is roughly equivalent to the following Java code, split into two
|
|
|
|
|
files:
|
|
|
|
|
|
|
|
|
|
A.java
|
|
|
|
|
|
|
|
|
|
public class A
|
|
|
|
|
{
|
|
|
|
|
int thirtyTwo;
|
|
|
|
|
|
|
|
|
|
public void
|
|
|
|
|
doSomething ()
|
|
|
|
|
{
|
|
|
|
|
etcEtcEtc ();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
B.java
|
|
|
|
|
|
|
|
|
|
public class B extends A
|
|
|
|
|
{
|
|
|
|
|
long sixty_four;
|
|
|
|
|
|
|
|
|
|
public static void
|
|
|
|
|
myFunction (B b)
|
|
|
|
|
{
|
|
|
|
|
b.doSomething ();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
the Java runtime has transformed the call to ``b.doSomething'' to
|
|
|
|
|
``((A) b).doSomething''.
|
|
|
|
|
|
|
|
|
|
However, Java also allows overriding this behavior, by specifying the
|
|
|
|
|
@Override keyword:
|
|
|
|
|
|
|
|
|
|
public class B extends A
|
|
|
|
|
{
|
|
|
|
|
long sixty_four;
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void
|
|
|
|
|
doSomething ()
|
|
|
|
|
{
|
|
|
|
|
Something.doSomethingTwo ();
|
|
|
|
|
super.doSomething ();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
now, any call to ``doSomething'' on a ``B'' created using ``new B ()''
|
|
|
|
|
will end up calling ``Something.doSomethingTwo'', before calling back
|
|
|
|
|
to ``A.doSomething''. This override also applies in reverse; that is
|
|
|
|
|
to say, even if you write:
|
|
|
|
|
|
|
|
|
|
((A) b).doSomething ();
|
|
|
|
|
|
|
|
|
|
B's version of doSomething will still be called, if ``b'' was created
|
|
|
|
|
using ``new B ()''.
|
|
|
|
|
|
|
|
|
|
This mechanism is used extensively throughout the Java language and
|
|
|
|
|
Android windowing APIs.
|
|
|
|
|
|
|
|
|
|
Elsewhere, you will encounter Java code that defines arrays:
|
|
|
|
|
|
|
|
|
|
public class EmacsFrobinicator
|
|
|
|
|
{
|
|
|
|
|
public static void
|
|
|
|
|
emacsFrobinicate (int something)
|
|
|
|
|
{
|
|
|
|
|
int[] primesFromSomething;
|
|
|
|
|
|
|
|
|
|
primesFromSomething = new int[numberOfPrimes];
|
|
|
|
|
/* ... */
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-28 08:29:22 +00:00
|
|
|
|
Java arrays are similar to C arrays in that they can not grow. But
|
2023-01-25 10:44:47 +00:00
|
|
|
|
they are very much unlike C arrays in that they are always references
|
2023-01-28 08:29:22 +00:00
|
|
|
|
(as opposed to decaying into pointers in only some situations), and
|
2023-01-25 10:44:47 +00:00
|
|
|
|
contain information about their length.
|
|
|
|
|
|
|
|
|
|
If another function named ``frobinicate1'' takes an array as an
|
|
|
|
|
argument, then it need not take the length of the array.
|
|
|
|
|
|
2023-01-28 08:29:22 +00:00
|
|
|
|
Instead, it may simply iterate over the array like so:
|
2023-01-25 10:44:47 +00:00
|
|
|
|
|
|
|
|
|
int i, k;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < array.length; ++i)
|
|
|
|
|
{
|
|
|
|
|
k = array[i];
|
|
|
|
|
|
|
|
|
|
Whatever.doSomethingWithK (k);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
The syntax used to define arrays is also slightly different. As
|
|
|
|
|
arrays are always references, there is no way for you to tell the
|
|
|
|
|
runtime to allocate an array of size N in a structure (class.)
|
|
|
|
|
|
|
|
|
|
Instead, if you need an array of that size, you must declare a field
|
|
|
|
|
with the type of the array, and allocate the array inside the class's
|
|
|
|
|
constructor, like so:
|
|
|
|
|
|
|
|
|
|
public class EmacsArrayContainer
|
|
|
|
|
{
|
|
|
|
|
public int[] myArray;
|
|
|
|
|
|
|
|
|
|
public
|
|
|
|
|
EmacsArrayContainer ()
|
|
|
|
|
{
|
|
|
|
|
myArray = new array[10];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while in C, you could just have written:
|
|
|
|
|
|
|
|
|
|
struct emacs_array_container
|
|
|
|
|
{
|
|
|
|
|
int my_array[10];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
or, possibly even better,
|
|
|
|
|
|
2023-01-28 08:29:22 +00:00
|
|
|
|
typedef int emacs_array_container[10];
|
2023-01-25 10:44:47 +00:00
|
|
|
|
|
|
|
|
|
Alas, Java has no equivalent of `typedef'.
|
|
|
|
|
|
2023-01-28 08:29:22 +00:00
|
|
|
|
Like in C, Java string literals are delimited by double quotes.
|
|
|
|
|
Unlike C, however, strings are not NULL-terminated arrays of
|
|
|
|
|
characters, but a distinct type named ``String''. They store their
|
|
|
|
|
own length, characters in Java's 16-bit ``char'' type, and are capable
|
|
|
|
|
of holding NULL bytes.
|
|
|
|
|
|
|
|
|
|
Instead of writing:
|
|
|
|
|
|
|
|
|
|
wchar_t character;
|
|
|
|
|
extern char *s;
|
|
|
|
|
size_t s;
|
|
|
|
|
|
|
|
|
|
for (/* determine n, s in a loop. */)
|
|
|
|
|
s += mbstowc (&character, s, n);
|
|
|
|
|
|
|
|
|
|
or:
|
|
|
|
|
|
|
|
|
|
const char *byte;
|
|
|
|
|
|
|
|
|
|
for (byte = my_string; *byte; ++byte)
|
|
|
|
|
/* do something with *byte. */;
|
|
|
|
|
|
|
|
|
|
or perhaps even:
|
|
|
|
|
|
|
|
|
|
size_t length, i;
|
|
|
|
|
char foo;
|
|
|
|
|
|
|
|
|
|
length = strlen (my_string);
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < length; ++i)
|
|
|
|
|
foo = my_string[i];
|
|
|
|
|
|
|
|
|
|
you write:
|
|
|
|
|
|
|
|
|
|
char foo;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < myString.length (); ++i)
|
|
|
|
|
foo = myString.charAt (0);
|
|
|
|
|
|
|
|
|
|
Java also has stricter rules on what can be used as a truth value in a
|
|
|
|
|
conditional. While in C, any non-zero value is true, Java requires
|
|
|
|
|
that every truth value be of the boolean type ``boolean''.
|
|
|
|
|
|
|
|
|
|
What this means is that instead of simply writing:
|
|
|
|
|
|
|
|
|
|
if (foo || bar)
|
|
|
|
|
|
|
|
|
|
where foo can either be 1 or 0, and bar can either be NULL or a
|
|
|
|
|
pointer to something, you must explicitly write:
|
|
|
|
|
|
|
|
|
|
if (foo != 0 || bar != null)
|
|
|
|
|
|
|
|
|
|
in Java.
|
|
|
|
|
|
2023-01-25 10:44:47 +00:00
|
|
|
|
JAVA NATIVE INTERFACE
|
|
|
|
|
|
|
|
|
|
Java also provides an interface for C code to interface with Java.
|
|
|
|
|
|
|
|
|
|
C functions exported from a shared library become static Java
|
|
|
|
|
functions within a class, like so:
|
|
|
|
|
|
|
|
|
|
public class EmacsNative
|
|
|
|
|
{
|
|
|
|
|
/* Obtain the fingerprint of this build of Emacs. The fingerprint
|
|
|
|
|
can be used to determine the dump file name. */
|
|
|
|
|
public static native String getFingerprint ();
|
|
|
|
|
|
|
|
|
|
/* Set certain parameters before initializing Emacs.
|
|
|
|
|
|
|
|
|
|
assetManager must be the asset manager associated with the
|
|
|
|
|
context that is loading Emacs. It is saved and remains for the
|
|
|
|
|
remainder the lifetime of the Emacs process.
|
|
|
|
|
|
|
|
|
|
filesDir must be the package's data storage location for the
|
|
|
|
|
current Android user.
|
|
|
|
|
|
|
|
|
|
libDir must be the package's data storage location for native
|
|
|
|
|
libraries. It is used as PATH.
|
|
|
|
|
|
|
|
|
|
cacheDir must be the package's cache directory. It is used as
|
|
|
|
|
the `temporary-file-directory'.
|
|
|
|
|
|
|
|
|
|
pixelDensityX and pixelDensityY are the DPI values that will be
|
|
|
|
|
used by Emacs.
|
|
|
|
|
|
|
|
|
|
classPath must be the classpath of this app_process process, or
|
|
|
|
|
NULL.
|
|
|
|
|
|
|
|
|
|
emacsService must be the EmacsService singleton, or NULL. */
|
|
|
|
|
public static native void setEmacsParams (AssetManager assetManager,
|
|
|
|
|
String filesDir,
|
|
|
|
|
String libDir,
|
|
|
|
|
String cacheDir,
|
|
|
|
|
float pixelDensityX,
|
|
|
|
|
float pixelDensityY,
|
|
|
|
|
String classPath,
|
|
|
|
|
EmacsService emacsService);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Where the corresponding C functions are located in android.c, and
|
|
|
|
|
loaded by the special invocation:
|
|
|
|
|
|
|
|
|
|
static
|
|
|
|
|
{
|
|
|
|
|
System.loadLibrary ("emacs");
|
|
|
|
|
};
|
|
|
|
|
|
2023-02-09 14:56:41 +00:00
|
|
|
|
where ``static'' defines a section of code which will be run upon the
|
|
|
|
|
object (containing class) being loaded. This is like:
|
|
|
|
|
|
|
|
|
|
__attribute__((constructor))
|
|
|
|
|
|
|
|
|
|
on systems where shared object constructors are supported.
|
2023-01-25 10:44:47 +00:00
|
|
|
|
|
|
|
|
|
See http://docs.oracle.com/en/java/javase/19/docs/specs/jni/intro.html
|
|
|
|
|
for more details.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
OVERVIEW OF ANDROID
|
|
|
|
|
|
|
|
|
|
When the Android system starts an application, it does not actually
|
|
|
|
|
call the application's ``main'' function. It may not even start the
|
|
|
|
|
application's process if one is already running.
|
|
|
|
|
|
|
|
|
|
Instead, Android is organized around components. When the user opens
|
|
|
|
|
the ``Emacs'' icon, the Android system looks up and starts the
|
|
|
|
|
component associated with the ``Emacs'' icon. In this case, the
|
|
|
|
|
component is called an activity, and is declared in
|
|
|
|
|
the AndroidManifest.xml in this directory:
|
|
|
|
|
|
|
|
|
|
<activity android:name="org.gnu.emacs.EmacsActivity"
|
|
|
|
|
android:launchMode="singleTop"
|
|
|
|
|
android:windowSoftInputMode="adjustResize"
|
|
|
|
|
android:exported="true"
|
|
|
|
|
android:configChanges="orientation|screenSize|screenLayout|keyboardHidden">
|
|
|
|
|
<intent-filter>
|
|
|
|
|
<action android:name="android.intent.action.MAIN" />
|
|
|
|
|
<category android:name="android.intent.category.DEFAULT" />
|
|
|
|
|
<category android:name="android.intent.category.LAUNCHER" />
|
|
|
|
|
</intent-filter>
|
|
|
|
|
</activity>
|
|
|
|
|
|
|
|
|
|
This tells Android to start the activity defined in ``EmacsActivity''
|
|
|
|
|
(defined in org/gnu/emacs/EmacsActivity.java), a class extending the
|
|
|
|
|
Android class ``Activity''.
|
|
|
|
|
|
|
|
|
|
To do so, the Android system creates an instance of ``EmacsActivity''
|
|
|
|
|
and the window system window associated with it, and eventually calls:
|
|
|
|
|
|
|
|
|
|
Activity activity;
|
|
|
|
|
|
|
|
|
|
activity.onCreate (...);
|
|
|
|
|
|
|
|
|
|
But which ``onCreate'' is really called?
|
|
|
|
|
It is actually the ``onCreate'' defined in EmacsActivity.java, as
|
|
|
|
|
it overrides the ``onCreate'' defined in Android's own Activity class:
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void
|
|
|
|
|
onCreate (Bundle savedInstanceState)
|
|
|
|
|
{
|
|
|
|
|
FrameLayout.LayoutParams params;
|
|
|
|
|
Intent intent;
|
|
|
|
|
|
|
|
|
|
Then, this is what happens step-by-step within the ``onCreate''
|
|
|
|
|
function:
|
|
|
|
|
|
|
|
|
|
/* See if Emacs should be started with -Q. */
|
|
|
|
|
intent = getIntent ();
|
|
|
|
|
EmacsService.needDashQ
|
|
|
|
|
= intent.getBooleanExtra ("org.gnu.emacs.START_DASH_Q",
|
|
|
|
|
false);
|
|
|
|
|
|
|
|
|
|
Here, Emacs obtains the intent (a request to start a component) which
|
|
|
|
|
was used to start Emacs, and sets a special flag if it contains a
|
|
|
|
|
request for Emacs to start with the ``-Q'' command-line argument.
|
|
|
|
|
|
|
|
|
|
/* Set the theme to one without a title bar. */
|
|
|
|
|
|
|
|
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH)
|
|
|
|
|
setTheme (android.R.style.Theme_DeviceDefault_NoActionBar);
|
|
|
|
|
else
|
|
|
|
|
setTheme (android.R.style.Theme_NoTitleBar);
|
|
|
|
|
|
|
|
|
|
Next, Emacs sets an appropriate theme for the activity's associated
|
|
|
|
|
window decorations.
|
|
|
|
|
|
|
|
|
|
params = new FrameLayout.LayoutParams (LayoutParams.MATCH_PARENT,
|
|
|
|
|
LayoutParams.MATCH_PARENT);
|
|
|
|
|
|
|
|
|
|
/* Make the frame layout. */
|
|
|
|
|
layout = new FrameLayout (this);
|
|
|
|
|
layout.setLayoutParams (params);
|
|
|
|
|
|
|
|
|
|
/* Set it as the content view. */
|
|
|
|
|
setContentView (layout);
|
|
|
|
|
|
|
|
|
|
Then, Emacs creates a ``FrameLayout'', a widget that holds a single
|
|
|
|
|
other widget, and makes it the activity's ``content view''.
|
|
|
|
|
|
|
|
|
|
The activity itself is a ``FrameLayout'', so the ``layout parameters''
|
|
|
|
|
here apply to the FrameLayout itself, and not its children.
|
|
|
|
|
|
|
|
|
|
/* Maybe start the Emacs service if necessary. */
|
|
|
|
|
EmacsService.startEmacsService (this);
|
|
|
|
|
|
|
|
|
|
And after that, Emacs calls the static function ``startEmacsService'',
|
|
|
|
|
defined in the class ``EmacsService''. This starts the Emacs service
|
|
|
|
|
component if necessary.
|
|
|
|
|
|
|
|
|
|
/* Add this activity to the list of available activities. */
|
|
|
|
|
EmacsWindowAttachmentManager.MANAGER.registerWindowConsumer (this);
|
|
|
|
|
|
|
|
|
|
super.onCreate (savedInstanceState);
|
|
|
|
|
|
|
|
|
|
Finally, Emacs registers that this activity is now ready to receive
|
|
|
|
|
top-level frames (windows) created from Lisp.
|
|
|
|
|
|
|
|
|
|
Activities come and go, but Emacs has to stay running in the mean
|
|
|
|
|
time. Thus, Emacs also defines a ``service'', which is a long-running
|
|
|
|
|
component that the Android system allows to run in the background.
|
|
|
|
|
|
|
|
|
|
Let us go back and review the definition of ``startEmacsService'':
|
|
|
|
|
|
|
|
|
|
public static void
|
|
|
|
|
startEmacsService (Context context)
|
|
|
|
|
{
|
|
|
|
|
if (EmacsService.SERVICE == null)
|
|
|
|
|
{
|
|
|
|
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O)
|
|
|
|
|
/* Start the Emacs service now. */
|
|
|
|
|
context.startService (new Intent (context,
|
|
|
|
|
EmacsService.class));
|
|
|
|
|
else
|
|
|
|
|
/* Display the permanant notification and start Emacs as a
|
|
|
|
|
foreground service. */
|
|
|
|
|
context.startForegroundService (new Intent (context,
|
|
|
|
|
EmacsService.class));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
If ``EmacsService.SERVICE'' does not yet exist, what this does is to
|
|
|
|
|
tell the ``context'' (the equivalent of an Xlib Display *) to start a
|
|
|
|
|
service defined by the class ``EmacsService''. Eventually, this
|
|
|
|
|
results in ``EmacsService.onCreate'' being called:
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void
|
|
|
|
|
onCreate ()
|
|
|
|
|
{
|
|
|
|
|
AssetManager manager;
|
|
|
|
|
Context app_context;
|
|
|
|
|
String filesDir, libDir, cacheDir, classPath;
|
|
|
|
|
double pixelDensityX;
|
|
|
|
|
double pixelDensityY;
|
|
|
|
|
|
|
|
|
|
Here is what this function does, step-by-step:
|
|
|
|
|
|
|
|
|
|
SERVICE = this;
|
|
|
|
|
|
|
|
|
|
First, it sets the special static variable ``SERVICE'' to ``this'',
|
|
|
|
|
which is a pointer to the ``EmacsService' object that was created.
|
|
|
|
|
|
|
|
|
|
handler = new Handler (Looper.getMainLooper ());
|
|
|
|
|
|
|
|
|
|
Next, it creates a ``Handler'' object for the ``main looper''.
|
|
|
|
|
This is a helper structure which allows executing code on the Android
|
|
|
|
|
user interface thread.
|
|
|
|
|
|
|
|
|
|
manager = getAssets ();
|
|
|
|
|
app_context = getApplicationContext ();
|
|
|
|
|
metrics = getResources ().getDisplayMetrics ();
|
|
|
|
|
pixelDensityX = metrics.xdpi;
|
|
|
|
|
pixelDensityY = metrics.ydpi;
|
|
|
|
|
|
|
|
|
|
Finally, it obtains:
|
|
|
|
|
|
|
|
|
|
- the asset manager, which is used to retrieve assets packaged
|
|
|
|
|
into the Emacs application package.
|
|
|
|
|
|
|
|
|
|
- the application context, used to obtain application specific
|
|
|
|
|
information.
|
|
|
|
|
|
|
|
|
|
- the display metrics, and from them, the X and Y densities in dots
|
|
|
|
|
per inch.
|
|
|
|
|
|
|
|
|
|
Then, inside a ``try'' block:
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
/* Configure Emacs with the asset manager and other necessary
|
|
|
|
|
parameters. */
|
|
|
|
|
filesDir = app_context.getFilesDir ().getCanonicalPath ();
|
|
|
|
|
libDir = getLibraryDirectory ();
|
|
|
|
|
cacheDir = app_context.getCacheDir ().getCanonicalPath ();
|
|
|
|
|
|
|
|
|
|
It obtains the names of the Emacs home, shared library, and temporary
|
|
|
|
|
file directories.
|
|
|
|
|
|
|
|
|
|
/* Now provide this application's apk file, so a recursive
|
|
|
|
|
invocation of app_process (through android-emacs) can
|
|
|
|
|
find EmacsNoninteractive. */
|
|
|
|
|
classPath = getApkFile ();
|
|
|
|
|
|
|
|
|
|
The name of the Emacs application package.
|
|
|
|
|
|
|
|
|
|
Log.d (TAG, "Initializing Emacs, where filesDir = " + filesDir
|
|
|
|
|
+ ", libDir = " + libDir + ", and classPath = " + classPath);
|
|
|
|
|
|
|
|
|
|
Prints a debug message to the Android system log with this
|
|
|
|
|
information.
|
|
|
|
|
|
|
|
|
|
EmacsNative.setEmacsParams (manager, filesDir, libDir,
|
|
|
|
|
cacheDir, (float) pixelDensityX,
|
|
|
|
|
(float) pixelDensityY,
|
|
|
|
|
classPath, this);
|
|
|
|
|
|
|
|
|
|
And calls the native function ``setEmacsParams'' (defined in
|
|
|
|
|
android.c) to configure Emacs with this information.
|
|
|
|
|
|
|
|
|
|
/* Start the thread that runs Emacs. */
|
|
|
|
|
thread = new EmacsThread (this, needDashQ);
|
|
|
|
|
thread.start ();
|
|
|
|
|
|
|
|
|
|
Then, it allocates an ``EmacsThread'' object, and starts that thread.
|
|
|
|
|
Inside that thread is where Emacs's C code runs.
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
catch (IOException exception)
|
|
|
|
|
{
|
|
|
|
|
EmacsNative.emacsAbort ();
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
And here is the purpose of the ``try'' block. Functions related to
|
|
|
|
|
file names in Java will signal errors of various types upon failure.
|
|
|
|
|
|
|
|
|
|
This ``catch'' block means that the Java virtual machine will abort
|
|
|
|
|
execution of the contents of the ``try'' block as soon as an error of
|
|
|
|
|
type ``IOException'' is encountered, and begin executing the contents
|
|
|
|
|
of the ``catch'' block.
|
|
|
|
|
|
|
|
|
|
Any failure of that type here is a crash, and
|
|
|
|
|
``EmacsNative.emacsAbort'' is called to quickly abort the process to
|
|
|
|
|
get a useful backtrace.
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Now, let us look at the definition of the class ``EmacsThread'', found
|
|
|
|
|
in org/gnu/emacs/EmacsThread.java:
|
|
|
|
|
|
|
|
|
|
public class EmacsThread extends Thread
|
|
|
|
|
{
|
|
|
|
|
/* Whether or not Emacs should be started -Q. */
|
|
|
|
|
private boolean startDashQ;
|
|
|
|
|
|
|
|
|
|
public
|
|
|
|
|
EmacsThread (EmacsService service, boolean startDashQ)
|
|
|
|
|
{
|
|
|
|
|
super ("Emacs main thread");
|
|
|
|
|
this.startDashQ = startDashQ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void
|
|
|
|
|
run ()
|
|
|
|
|
{
|
|
|
|
|
String args[];
|
|
|
|
|
|
|
|
|
|
if (!startDashQ)
|
|
|
|
|
args = new String[] { "libandroid-emacs.so", };
|
|
|
|
|
else
|
|
|
|
|
args = new String[] { "libandroid-emacs.so", "-Q", };
|
|
|
|
|
|
|
|
|
|
/* Run the native code now. */
|
|
|
|
|
EmacsNative.initEmacs (args, EmacsApplication.dumpFileName);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
The class itself defines a single field, ``startDashQ'', a constructor
|
|
|
|
|
with an unused argument of the type ``EmacsService'' (which is useful
|
|
|
|
|
while debugging) and a flag ``startDashQ'', and a single function
|
|
|
|
|
``run'', overriding the same function in the class ``Thread''.
|
|
|
|
|
|
|
|
|
|
When ``thread.start'' is called, the Java virtual machine creates a
|
|
|
|
|
new thread, and then calls the function ``run'' within that thread.
|
|
|
|
|
|
|
|
|
|
This function then computes a suitable argument vector, and calls
|
|
|
|
|
``EmacsNative.initEmacs'' (defined in android.c), which then calls a
|
|
|
|
|
modified version of the regular Emacs ``main'' function.
|
|
|
|
|
|
|
|
|
|
At that point, Emacs initialization proceeds as usual:
|
|
|
|
|
Vinitial_window_system is set, loadup.el calls `normal-top-level',
|
|
|
|
|
which calls `command-line', and finally
|
|
|
|
|
`window-system-initialization', which initializes the `android'
|
|
|
|
|
terminal interface as usual.
|
|
|
|
|
|
|
|
|
|
What happens here is the same as on other platforms. Now, here is
|
|
|
|
|
what happens when the initial frame is created: Fx_create_frame calls
|
|
|
|
|
`android_create_frame_window' to create a top level window:
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
android_create_frame_window (struct frame *f)
|
|
|
|
|
{
|
|
|
|
|
struct android_set_window_attributes attributes;
|
|
|
|
|
enum android_window_value_mask attribute_mask;
|
|
|
|
|
|
|
|
|
|
attributes.background_pixel = FRAME_BACKGROUND_PIXEL (f);
|
|
|
|
|
attribute_mask = ANDROID_CW_BACK_PIXEL;
|
|
|
|
|
|
|
|
|
|
block_input ();
|
|
|
|
|
FRAME_ANDROID_WINDOW (f)
|
|
|
|
|
= android_create_window (FRAME_DISPLAY_INFO (f)->root_window,
|
|
|
|
|
f->left_pos,
|
|
|
|
|
f->top_pos,
|
|
|
|
|
FRAME_PIXEL_WIDTH (f),
|
|
|
|
|
FRAME_PIXEL_HEIGHT (f),
|
|
|
|
|
attribute_mask, &attributes);
|
|
|
|
|
unblock_input ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
This calls the function `android_create_window' with some arguments
|
|
|
|
|
whose meanings are identical to the arguments to `XCreateWindow'.
|
|
|
|
|
|
|
|
|
|
Here is the definition of `android_create_window', in android.c:
|
|
|
|
|
|
|
|
|
|
android_window
|
|
|
|
|
android_create_window (android_window parent, int x, int y,
|
|
|
|
|
int width, int height,
|
|
|
|
|
enum android_window_value_mask value_mask,
|
|
|
|
|
struct android_set_window_attributes *attrs)
|
|
|
|
|
{
|
|
|
|
|
static jclass class;
|
|
|
|
|
static jmethodID constructor;
|
|
|
|
|
jobject object, parent_object, old;
|
|
|
|
|
android_window window;
|
|
|
|
|
android_handle prev_max_handle;
|
|
|
|
|
bool override_redirect;
|
|
|
|
|
|
|
|
|
|
What does it do? First, some context:
|
|
|
|
|
|
|
|
|
|
At any time, there can be at most 65535 Java objects referred to by
|
|
|
|
|
the rest of Emacs through the Java native interface. Each such object
|
|
|
|
|
is assigned a ``handle'' (similar to an XID on X) and given a unique
|
|
|
|
|
type. The function `android_resolve_handle' returns the JNI `jobject'
|
|
|
|
|
associated with a given handle.
|
|
|
|
|
|
|
|
|
|
parent_object = android_resolve_handle (parent, ANDROID_HANDLE_WINDOW);
|
|
|
|
|
|
|
|
|
|
Here, it is being used to look up the `jobject' associated with the
|
|
|
|
|
`parent' handle.
|
|
|
|
|
|
|
|
|
|
prev_max_handle = max_handle;
|
|
|
|
|
window = android_alloc_id ();
|
|
|
|
|
|
|
|
|
|
Next, `max_handle' is saved, and a new handle is allocated for
|
|
|
|
|
`window'.
|
|
|
|
|
|
|
|
|
|
if (!window)
|
|
|
|
|
error ("Out of window handles!");
|
|
|
|
|
|
|
|
|
|
An error is signalled if Emacs runs out of available handles.
|
|
|
|
|
|
|
|
|
|
if (!class)
|
|
|
|
|
{
|
|
|
|
|
class = (*android_java_env)->FindClass (android_java_env,
|
|
|
|
|
"org/gnu/emacs/EmacsWindow");
|
|
|
|
|
assert (class != NULL);
|
|
|
|
|
|
|
|
|
|
Then, if this initialization has not yet been completed, Emacs
|
|
|
|
|
proceeds to find the Java class named ``EmacsWindow''.
|
|
|
|
|
|
|
|
|
|
constructor
|
|
|
|
|
= (*android_java_env)->GetMethodID (android_java_env, class, "<init>",
|
|
|
|
|
"(SLorg/gnu/emacs/EmacsWindow;"
|
|
|
|
|
"IIIIZ)V");
|
|
|
|
|
assert (constructor != NULL);
|
|
|
|
|
|
|
|
|
|
And it tries to look up the constructor, which should take seven
|
|
|
|
|
arguments:
|
|
|
|
|
|
|
|
|
|
S - a short. (the handle ID)
|
|
|
|
|
Lorg/gnu/Emacs/EmacsWindow; - an instance of the EmacsWindow
|
|
|
|
|
class. (the parent)
|
|
|
|
|
IIII - four ints. (the window geometry.)
|
|
|
|
|
Z - a boolean. (whether or not the
|
|
|
|
|
window is override-redirect; see
|
|
|
|
|
XChangeWindowAttributes.)
|
|
|
|
|
|
|
|
|
|
old = class;
|
|
|
|
|
class = (*android_java_env)->NewGlobalRef (android_java_env, class);
|
|
|
|
|
(*android_java_env)->ExceptionClear (android_java_env);
|
|
|
|
|
ANDROID_DELETE_LOCAL_REF (old);
|
|
|
|
|
|
|
|
|
|
Next, it saves a global reference to the class and deletes the local
|
|
|
|
|
reference. Global references will never be deallocated by the Java
|
|
|
|
|
virtual machine as long as they still exist.
|
|
|
|
|
|
|
|
|
|
if (!class)
|
|
|
|
|
memory_full (0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* N.B. that ANDROID_CW_OVERRIDE_REDIRECT can only be set at window
|
|
|
|
|
creation time. */
|
|
|
|
|
override_redirect = ((value_mask
|
|
|
|
|
& ANDROID_CW_OVERRIDE_REDIRECT)
|
|
|
|
|
&& attrs->override_redirect);
|
|
|
|
|
|
|
|
|
|
object = (*android_java_env)->NewObject (android_java_env, class,
|
|
|
|
|
constructor, (jshort) window,
|
|
|
|
|
parent_object, (jint) x, (jint) y,
|
|
|
|
|
(jint) width, (jint) height,
|
|
|
|
|
(jboolean) override_redirect);
|
|
|
|
|
|
|
|
|
|
Then, it creates an instance of the ``EmacsWindow'' class with the
|
|
|
|
|
appropriate arguments and previously determined constructor.
|
|
|
|
|
|
|
|
|
|
if (!object)
|
|
|
|
|
{
|
|
|
|
|
(*android_java_env)->ExceptionClear (android_java_env);
|
|
|
|
|
|
|
|
|
|
max_handle = prev_max_handle;
|
|
|
|
|
memory_full (0);
|
|
|
|
|
|
|
|
|
|
If creating the object fails, Emacs clears the ``pending exception''
|
|
|
|
|
and signals that it is out of memory.
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
android_handles[window].type = ANDROID_HANDLE_WINDOW;
|
|
|
|
|
android_handles[window].handle
|
|
|
|
|
= (*android_java_env)->NewGlobalRef (android_java_env,
|
|
|
|
|
object);
|
|
|
|
|
(*android_java_env)->ExceptionClear (android_java_env);
|
|
|
|
|
ANDROID_DELETE_LOCAL_REF (object);
|
|
|
|
|
|
|
|
|
|
Otherwise, it associates a new global reference to the object with the
|
|
|
|
|
handle, and deletes the local reference returned from the JNI
|
|
|
|
|
NewObject function.
|
|
|
|
|
|
|
|
|
|
if (!android_handles[window].handle)
|
|
|
|
|
memory_full (0);
|
|
|
|
|
|
|
|
|
|
If allocating the global reference fails, Emacs signals that it is out
|
|
|
|
|
of memory.
|
|
|
|
|
|
|
|
|
|
android_change_window_attributes (window, value_mask, attrs);
|
|
|
|
|
return window;
|
|
|
|
|
|
|
|
|
|
Otherwise, it applies the specified window attributes and returns the
|
|
|
|
|
handle of the new window.
|
|
|
|
|
}
|