mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-07 06:50:23 -08:00
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.
This commit is contained in:
parent
785095c416
commit
cfbc8a5dbc
83 changed files with 14297 additions and 217 deletions
|
|
@ -12,7 +12,7 @@
|
||||||
(c-mode . ((c-file-style . "GNU")
|
(c-mode . ((c-file-style . "GNU")
|
||||||
(c-noise-macro-names . ("INLINE" "NO_INLINE" "ATTRIBUTE_NO_SANITIZE_UNDEFINED"
|
(c-noise-macro-names . ("INLINE" "NO_INLINE" "ATTRIBUTE_NO_SANITIZE_UNDEFINED"
|
||||||
"UNINIT" "CALLBACK" "ALIGN_STACK" "ATTRIBUTE_MALLOC"
|
"UNINIT" "CALLBACK" "ALIGN_STACK" "ATTRIBUTE_MALLOC"
|
||||||
"ATTRIBUTE_DEALLOC_FREE"))
|
"ATTRIBUTE_DEALLOC_FREE" "ANDROID_EXPORT"))
|
||||||
(electric-quote-comment . nil)
|
(electric-quote-comment . nil)
|
||||||
(electric-quote-string . nil)
|
(electric-quote-string . nil)
|
||||||
(indent-tabs-mode . t)
|
(indent-tabs-mode . t)
|
||||||
|
|
|
||||||
17
.gitignore
vendored
17
.gitignore
vendored
|
|
@ -52,6 +52,15 @@ src/config.h
|
||||||
src/epaths.h
|
src/epaths.h
|
||||||
src/emacs-module.h
|
src/emacs-module.h
|
||||||
|
|
||||||
|
# Built by recursive call to `configure'.
|
||||||
|
*.android
|
||||||
|
|
||||||
|
# Built by `java'.
|
||||||
|
java/install_temp/*
|
||||||
|
java/*.apk*
|
||||||
|
java/*.dex
|
||||||
|
java/org/gnu/emacs/*.class
|
||||||
|
|
||||||
# C-level sources built by 'make'.
|
# C-level sources built by 'make'.
|
||||||
lib/alloca.h
|
lib/alloca.h
|
||||||
lib/assert.h
|
lib/assert.h
|
||||||
|
|
@ -81,6 +90,14 @@ src/globals.h
|
||||||
src/lisp.mk
|
src/lisp.mk
|
||||||
src/verbose.mk
|
src/verbose.mk
|
||||||
|
|
||||||
|
# Stuff built during cross compilation
|
||||||
|
xcompile/lib/*
|
||||||
|
xcompile/src/*
|
||||||
|
xcompile/lib-src/*
|
||||||
|
xcompile/sys/*
|
||||||
|
xcompile/config.status
|
||||||
|
xcompile/*.bak
|
||||||
|
|
||||||
# Lisp-level sources built by 'make'.
|
# Lisp-level sources built by 'make'.
|
||||||
*cus-load.el
|
*cus-load.el
|
||||||
*loaddefs.el
|
*loaddefs.el
|
||||||
|
|
|
||||||
68
Makefile.in
68
Makefile.in
|
|
@ -106,15 +106,15 @@ top_builddir = @top_builddir@
|
||||||
|
|
||||||
FIND_DELETE = @FIND_DELETE@
|
FIND_DELETE = @FIND_DELETE@
|
||||||
|
|
||||||
HAVE_NATIVE_COMP = @HAVE_NATIVE_COMP@
|
|
||||||
|
|
||||||
USE_STARTUP_NOTIFICATION = @USE_STARTUP_NOTIFICATION@
|
USE_STARTUP_NOTIFICATION = @USE_STARTUP_NOTIFICATION@
|
||||||
|
|
||||||
|
HAVE_NATIVE_COMP = @HAVE_NATIVE_COMP@
|
||||||
HAVE_BE_APP = @HAVE_BE_APP@
|
HAVE_BE_APP = @HAVE_BE_APP@
|
||||||
|
|
||||||
HAVE_PGTK = @HAVE_PGTK@
|
HAVE_PGTK = @HAVE_PGTK@
|
||||||
HAVE_GSETTINGS = @HAVE_GSETTINGS@
|
HAVE_GSETTINGS = @HAVE_GSETTINGS@
|
||||||
|
|
||||||
|
ANDROID = @ANDROID@
|
||||||
|
|
||||||
# ==================== Where To Install Things ====================
|
# ==================== Where To Install Things ====================
|
||||||
|
|
||||||
# Location to install Emacs.app under GNUstep / macOS.
|
# Location to install Emacs.app under GNUstep / macOS.
|
||||||
|
|
@ -339,6 +339,10 @@ EMACS_PDMP = `./src/emacs${EXEEXT} --fingerprint`.pdmp
|
||||||
# Subdirectories to make recursively.
|
# Subdirectories to make recursively.
|
||||||
SUBDIR = $(NTDIR) lib lib-src src lisp
|
SUBDIR = $(NTDIR) lib lib-src src lisp
|
||||||
|
|
||||||
|
ifeq ($(ANDROID),yes)
|
||||||
|
SUBDIR := $(SUBDIR) java
|
||||||
|
endif
|
||||||
|
|
||||||
# The subdir makefiles created by config.status.
|
# The subdir makefiles created by config.status.
|
||||||
SUBDIR_MAKEFILES_IN = @SUBDIR_MAKEFILES_IN@
|
SUBDIR_MAKEFILES_IN = @SUBDIR_MAKEFILES_IN@
|
||||||
SUBDIR_MAKEFILES = $(patsubst ${srcdir}/%,%,${SUBDIR_MAKEFILES_IN:.in=})
|
SUBDIR_MAKEFILES = $(patsubst ${srcdir}/%,%,${SUBDIR_MAKEFILES_IN:.in=})
|
||||||
|
|
@ -467,20 +471,20 @@ epaths-force:
|
||||||
esac; \
|
esac; \
|
||||||
done
|
done
|
||||||
@(gamedir='${gamedir}'; \
|
@(gamedir='${gamedir}'; \
|
||||||
sed < ${srcdir}/src/epaths.in > epaths.h.$$$$ \
|
sed < ${srcdir}/src/epaths.in > epaths.h.$$$$ \
|
||||||
-e 's;\(#.*PATH_LOADSEARCH\).*$$;\1 "${standardlisppath}";' \
|
-e 's;\(#define.*PATH_LOADSEARCH\).*$$;\1 "${standardlisppath}";' \
|
||||||
-e 's;\(#.*PATH_REL_LOADSEARCH\).*$$;\1 "${lispdirrel}";' \
|
-e 's;\(#define.*PATH_REL_LOADSEARCH\).*$$;\1 "${lispdirrel}";' \
|
||||||
-e 's;\(#.*PATH_SITELOADSEARCH\).*$$;\1 "${locallisppath}";' \
|
-e 's;\(#define.*PATH_SITELOADSEARCH\).*$$;\1 "${locallisppath}";' \
|
||||||
-e 's;\(#.*PATH_DUMPLOADSEARCH\).*$$;\1 "${buildlisppath}";' \
|
-e 's;\(#define.*PATH_DUMPLOADSEARCH\).*$$;\1 "${buildlisppath}";' \
|
||||||
-e '/^#define PATH_[^ ]*SEARCH /s/\([":]\):*/\1/g' \
|
-e '/^#define PATH_[^ ]*SEARCH /s/\([":]\):*/\1/g' \
|
||||||
-e '/^#define PATH_[^ ]*SEARCH /s/:"/"/' \
|
-e '/^#define PATH_[^ ]*SEARCH /s/:"/"/' \
|
||||||
-e 's;\(#.*PATH_EXEC\).*$$;\1 "${archlibdir}";' \
|
-e 's;\(#define.*PATH_EXEC\).*$$;\1 "${archlibdir}";' \
|
||||||
-e 's;\(#.*PATH_INFO\).*$$;\1 "${infodir}";' \
|
-e 's;\(#define.*PATH_INFO\).*$$;\1 "${infodir}";' \
|
||||||
-e 's;\(#.*PATH_DATA\).*$$;\1 "${etcdir}";' \
|
-e 's;\(#define.*PATH_DATA\).*$$;\1 "${etcdir}";' \
|
||||||
-e 's;\(#.*PATH_BITMAPS\).*$$;\1 "${bitmapdir}";' \
|
-e 's;\(#define.*PATH_BITMAPS\).*$$;\1 "${bitmapdir}";' \
|
||||||
-e 's;\(#.*PATH_X_DEFAULTS\).*$$;\1 "${x_default_search_path}";' \
|
-e 's;\(#define.*PATH_X_DEFAULTS\).*$$;\1 "${x_default_search_path}";' \
|
||||||
-e 's;\(#.*PATH_GAME\).*$$;\1 $(PATH_GAME);' \
|
-e 's;\(#define.*PATH_GAME\).*$$;\1 $(PATH_GAME);' \
|
||||||
-e 's;\(#.*PATH_DOC\).*$$;\1 "${etcdocdir}";') && \
|
-e 's;\(#define.*PATH_DOC\).*$$;\1 "${etcdocdir}";') && \
|
||||||
${srcdir}/build-aux/move-if-change epaths.h.$$$$ src/epaths.h
|
${srcdir}/build-aux/move-if-change epaths.h.$$$$ src/epaths.h
|
||||||
|
|
||||||
# The w32 build needs a slightly different editing, and it uses
|
# The w32 build needs a slightly different editing, and it uses
|
||||||
|
|
@ -532,6 +536,12 @@ lisp: src
|
||||||
lib lib-src lisp nt: Makefile
|
lib lib-src lisp nt: Makefile
|
||||||
$(MAKE) -C $@ all
|
$(MAKE) -C $@ all
|
||||||
|
|
||||||
|
java: lisp
|
||||||
|
$(MAKE) -C $@ all
|
||||||
|
|
||||||
|
xcompile: src
|
||||||
|
$(MAKE) -C $@ all
|
||||||
|
|
||||||
trampolines: src lisp
|
trampolines: src lisp
|
||||||
ifeq ($(HAVE_NATIVE_COMP),yes)
|
ifeq ($(HAVE_NATIVE_COMP),yes)
|
||||||
$(MAKE) -C lisp trampolines
|
$(MAKE) -C lisp trampolines
|
||||||
|
|
@ -561,20 +571,38 @@ blessmail: Makefile src
|
||||||
# then attempts to build that file. This forces 'Makefile', 'lib/Makefile',
|
# then attempts to build that file. This forces 'Makefile', 'lib/Makefile',
|
||||||
# etc. to be built without running into similar recursion problems.
|
# etc. to be built without running into similar recursion problems.
|
||||||
MAKEFILE_NAME = Makefile
|
MAKEFILE_NAME = Makefile
|
||||||
|
ifeq ($(ANDROID),)
|
||||||
$(MAKEFILE_NAME): config.status $(srcdir)/configure \
|
$(MAKEFILE_NAME): config.status $(srcdir)/configure \
|
||||||
$(srcdir)/lib/gnulib.mk.in \
|
$(srcdir)/lib/gnulib.mk.in \
|
||||||
$(srcdir)/Makefile.in $(SUBDIR_MAKEFILES_IN) $(CONFIG_STATUS_FILES_IN)
|
$(srcdir)/Makefile.in $(SUBDIR_MAKEFILES_IN) $(CONFIG_STATUS_FILES_IN)
|
||||||
MAKE='$(MAKE)' ./config.status
|
MAKE='$(MAKE)' ./config.status
|
||||||
|
else
|
||||||
|
# Note that calling config.status is insufficient on Android due to
|
||||||
|
# the recursive calls to configure.
|
||||||
|
|
||||||
|
$(MAKEFILE_NAME): $(srcdir)/configure \
|
||||||
|
$(srcdir)/lib/gnulib.mk.in \
|
||||||
|
$(srcdir)/Makefile.in $(SUBDIR_MAKEFILES_IN) $(CONFIG_STATUS_FILES_IN)
|
||||||
|
$(CFG) $(srcdir)/configure $(CONFIGURE_FLAGS);
|
||||||
|
endif
|
||||||
|
|
||||||
# Don't erase these files if make is interrupted while refreshing them.
|
# Don't erase these files if make is interrupted while refreshing them.
|
||||||
.PRECIOUS: Makefile config.status
|
.PRECIOUS: Makefile config.status
|
||||||
|
|
||||||
|
# Note that calling config.status --recheck is insufficient on Android
|
||||||
|
# due to the recursive calls to configure.
|
||||||
|
|
||||||
|
ifneq ($(ANDROID),)
|
||||||
config.status: ${srcdir}/configure
|
config.status: ${srcdir}/configure
|
||||||
if [ -x ./config.status ]; then \
|
$(CFG) $(srcdir)/configure $(CONFIGURE_FLAGS)
|
||||||
|
else
|
||||||
|
config.status: ${srcdir}/configure
|
||||||
|
if [ -x ./config.status ]; then \
|
||||||
$(CFG) ./config.status --recheck; \
|
$(CFG) ./config.status --recheck; \
|
||||||
else \
|
else \
|
||||||
$(CFG) $(srcdir)/configure $(CONFIGURE_FLAGS); \
|
$(CFG) $(srcdir)/configure $(CONFIGURE_FLAGS); \
|
||||||
fi
|
fi
|
||||||
|
endif
|
||||||
|
|
||||||
$(srcdir)/configure: $(srcdir)/configure.ac $(srcdir)/m4/*.m4
|
$(srcdir)/configure: $(srcdir)/configure.ac $(srcdir)/m4/*.m4
|
||||||
cd $(srcdir) && ./autogen.sh autoconf
|
cd $(srcdir) && ./autogen.sh autoconf
|
||||||
|
|
@ -999,7 +1027,7 @@ mostlyclean: $(mostlyclean_dirs:=_mostlyclean)
|
||||||
### with them.
|
### with them.
|
||||||
###
|
###
|
||||||
### Delete '.dvi' files here if they are not part of the distribution.
|
### Delete '.dvi' files here if they are not part of the distribution.
|
||||||
clean_dirs = $(mostlyclean_dirs) nextstep admin/charsets admin/unidata
|
clean_dirs = $(mostlyclean_dirs) java nextstep admin/charsets admin/unidata
|
||||||
|
|
||||||
$(foreach dir,$(clean_dirs),$(eval $(call submake_template,$(dir),clean)))
|
$(foreach dir,$(clean_dirs),$(eval $(call submake_template,$(dir),clean)))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -134,3 +134,5 @@ cp -- "$gnulib_srcdir"/lib/af_alg.h \
|
||||||
"$src"lib &&
|
"$src"lib &&
|
||||||
{ test -z "$src" || cd "$src"; } &&
|
{ test -z "$src" || cd "$src"; } &&
|
||||||
./autogen.sh
|
./autogen.sh
|
||||||
|
|
||||||
|
echo "Please update the block of vpath statements in lib/Makefile.in"
|
||||||
|
|
|
||||||
524
configure.ac
524
configure.ac
|
|
@ -26,6 +26,16 @@ dnl Note this is parsed by (at least) make-dist and lisp/cedet/ede/emacs.el.
|
||||||
AC_INIT([GNU Emacs], [30.0.50], [bug-gnu-emacs@gnu.org], [],
|
AC_INIT([GNU Emacs], [30.0.50], [bug-gnu-emacs@gnu.org], [],
|
||||||
[https://www.gnu.org/software/emacs/])
|
[https://www.gnu.org/software/emacs/])
|
||||||
|
|
||||||
|
if test "$XCONFIGURE" = "android"; then
|
||||||
|
# configure is being called recursively to configure Emacs for
|
||||||
|
# Android!
|
||||||
|
AC_MSG_NOTICE([called to recursively configure Emacs \
|
||||||
|
for Android.])
|
||||||
|
# Set CC to ANDROID_CC, and CXX to ANDROID_CXX.
|
||||||
|
CC=$ANDROID_CC
|
||||||
|
CXX=$ANDROID_CXX
|
||||||
|
fi
|
||||||
|
|
||||||
dnl Set emacs_config_options to the options of 'configure', quoted for the shell,
|
dnl Set emacs_config_options to the options of 'configure', quoted for the shell,
|
||||||
dnl and then quoted again for a C string. Separate options with spaces.
|
dnl and then quoted again for a C string. Separate options with spaces.
|
||||||
dnl Add some environment variables, if they were passed via the environment
|
dnl Add some environment variables, if they were passed via the environment
|
||||||
|
|
@ -126,7 +136,25 @@ MAKE=$ac_cv_path_MAKE
|
||||||
export MAKE
|
export MAKE
|
||||||
|
|
||||||
dnl Canonicalize the configuration name.
|
dnl Canonicalize the configuration name.
|
||||||
|
if test "$XCONFIGURE" = "android"; then
|
||||||
|
dnl Set host to whatever Android system Emacs is being configured
|
||||||
|
dnl for. Determine this by looking at the output of ANDROID_CC.
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([the cross-compiler's target])
|
||||||
|
cc_target=`${CC} -v 2>&1 | sed -n 's/Target: //p'`
|
||||||
|
case "$cc_target" in
|
||||||
|
*android*) host_alias=$cc_target
|
||||||
|
;;
|
||||||
|
*) AC_MSG_ERROR([The cross compiler does not compile for Android.
|
||||||
|
Please verify that you specified the correct compiler in the ANDROID_CC
|
||||||
|
and ANDROID_CXX variables when you ran configure.])
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
AC_MSG_RESULT([$host_alias])
|
||||||
|
fi
|
||||||
|
|
||||||
AC_CANONICAL_HOST
|
AC_CANONICAL_HOST
|
||||||
|
AC_CANONICAL_BUILD
|
||||||
|
|
||||||
case $host in
|
case $host in
|
||||||
*-mingw*)
|
*-mingw*)
|
||||||
|
|
@ -207,6 +235,13 @@ AC_ARG_WITH([all],
|
||||||
[with_features=$withval],
|
[with_features=$withval],
|
||||||
[with_features=yes])
|
[with_features=yes])
|
||||||
|
|
||||||
|
dnl ARCH_INDEPENDENT_CONFIG_FILES(FILE...)
|
||||||
|
dnl Like AC_CONFIG_FILES(FILE). However, do not generate this
|
||||||
|
dnl if configure is being called recursively in preparation
|
||||||
|
dnl for cross-compilation.
|
||||||
|
AC_DEFUN([ARCH_INDEPENDENT_CONFIG_FILES], [
|
||||||
|
AS_IF([test "$XCONFIGURE" != "android"], [AC_CONFIG_FILES([$1])])])
|
||||||
|
|
||||||
dnl OPTION_DEFAULT_OFF(NAME, HELP-STRING)
|
dnl OPTION_DEFAULT_OFF(NAME, HELP-STRING)
|
||||||
dnl Create a new --with option that defaults to being disabled.
|
dnl Create a new --with option that defaults to being disabled.
|
||||||
dnl NAME is the base name of the option. The shell variable with_NAME
|
dnl NAME is the base name of the option. The shell variable with_NAME
|
||||||
|
|
@ -498,6 +533,7 @@ OPTION_DEFAULT_ON([threads],[don't compile with elisp threading support])
|
||||||
OPTION_DEFAULT_OFF([cygwin32-native-compilation],[use native compilation on 32-bit Cygwin])
|
OPTION_DEFAULT_OFF([cygwin32-native-compilation],[use native compilation on 32-bit Cygwin])
|
||||||
OPTION_DEFAULT_ON([xinput2],[don't use version 2 of the X Input Extension for input])
|
OPTION_DEFAULT_ON([xinput2],[don't use version 2 of the X Input Extension for input])
|
||||||
OPTION_DEFAULT_OFF([small-ja-dic],[generate a smaller-size Japanese dictionary])
|
OPTION_DEFAULT_OFF([small-ja-dic],[generate a smaller-size Japanese dictionary])
|
||||||
|
OPTION_DEFAULT_OFF([android],[cross-compile Android application package])
|
||||||
|
|
||||||
AC_ARG_WITH([file-notification],[AS_HELP_STRING([--with-file-notification=LIB],
|
AC_ARG_WITH([file-notification],[AS_HELP_STRING([--with-file-notification=LIB],
|
||||||
[use a file notification library (LIB one of: yes, inotify, kqueue, gfile, w32, no)])],
|
[use a file notification library (LIB one of: yes, inotify, kqueue, gfile, w32, no)])],
|
||||||
|
|
@ -682,6 +718,237 @@ AC_ARG_ENABLE([build-details],
|
||||||
[test "$enableval" = no && BUILD_DETAILS=--no-build-details])
|
[test "$enableval" = no && BUILD_DETAILS=--no-build-details])
|
||||||
AC_SUBST([BUILD_DETAILS])
|
AC_SUBST([BUILD_DETAILS])
|
||||||
|
|
||||||
|
# Start Android configuration. This is done in three steps:
|
||||||
|
|
||||||
|
# First, the SDK tools needed to build the Android package on the host
|
||||||
|
# are found.
|
||||||
|
|
||||||
|
# Then, configure is called inside itself with the NDK C and C++
|
||||||
|
# compilers, and the Makefiles generated, along with config.h, are
|
||||||
|
# renamed to end with .android.
|
||||||
|
|
||||||
|
# Finally, configure continues to configure the Emacs binary that will
|
||||||
|
# run on the host.
|
||||||
|
|
||||||
|
ANDROID=
|
||||||
|
JAVAC=
|
||||||
|
AAPT=
|
||||||
|
JARSIGNER=
|
||||||
|
ZIPALIGN=
|
||||||
|
DX=
|
||||||
|
ANDROID_JAR=
|
||||||
|
ANDROID_ABI=
|
||||||
|
|
||||||
|
# This is a list of Makefiles that have alternative versions for
|
||||||
|
# Android.
|
||||||
|
android_makefiles="lib/Makefile lib/gnulib.mk lib-src/Makefile src/Makefile"
|
||||||
|
|
||||||
|
AC_ARG_VAR([JAVAC], [Java compiler path. Used for Android.])
|
||||||
|
AC_ARG_VAR([JARSIGNER], [Java package signer path. Used for Android.])
|
||||||
|
AC_ARG_VAR([SDK_BULD_TOOLS], [Path to the Android SDK build tools.])
|
||||||
|
|
||||||
|
if test "$with_android" = "yes"; then
|
||||||
|
AC_MSG_ERROR([Please specify the path to the Android.jar file, like so:
|
||||||
|
|
||||||
|
./configure --with-android=/path/to/android.jar
|
||||||
|
|
||||||
|
along with the path to the SDK build-tools (this is the directory with
|
||||||
|
tools such as aapt, dx, and aidl):
|
||||||
|
|
||||||
|
SDK_BUILD_TOOLS=/path/to/sdk-build-tools
|
||||||
|
|
||||||
|
The cross-compiler should then be specified:
|
||||||
|
|
||||||
|
ANDROID_CC=/path/to/armv7a-linux-androideabi19-clang
|
||||||
|
ANDROID_CXX=/path/to/armv7a-linux-androideabi19-clang++])
|
||||||
|
elif test "$with_android" = "no" || test "$with_android" = ""; then
|
||||||
|
ANDROID=no
|
||||||
|
else
|
||||||
|
AC_CHECK_PROGS([JAVAC], [javac])
|
||||||
|
if test "$JAVAC" = ""; then
|
||||||
|
AC_MSG_ERROR([The Java compiler required to build Emacs was not found.
|
||||||
|
Please make sure `javac' can be found on your path, or alternatively specify
|
||||||
|
the path to your Java compiler before configuring Emacs, like so:
|
||||||
|
|
||||||
|
JAVAC=/opt/jdk/bin/javac ./configure --with-android])
|
||||||
|
fi
|
||||||
|
AC_CHECK_PROGS([JARSIGNER], [jarsigner])
|
||||||
|
if test "$JARSIGNER" = ""; then
|
||||||
|
AC_MSG_ERROR([The Java package signing utility was not found.
|
||||||
|
Please make sure `jarsigner' can be found on your path, or alternatively
|
||||||
|
specify its location before configuring Emacs, like so:
|
||||||
|
|
||||||
|
JARSIGNER=/opt/jdk/bin/jarsigner ./configure --with-android])
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_CACHE_CHECK([whether or not the Java compiler works],
|
||||||
|
[emacs_cv_working_javac],
|
||||||
|
AS_IF([rm -f conftest.class
|
||||||
|
cat << EOF > conftest.java
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
class conftest extends Activity
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void
|
||||||
|
onCreate (Bundle savedInstanceState)
|
||||||
|
{
|
||||||
|
super.onCreate (savedInstanceState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EOF
|
||||||
|
("$JAVAC" -classpath "$with_android" -target 1.7 -source 1.7 conftest.java \
|
||||||
|
-d . >&AS_MESSAGE_LOG_FD 2>&1) && test -s conftest.class && rm -f conftest.class],
|
||||||
|
[emacs_cv_working_javac=yes],
|
||||||
|
[emacs_cv_working_javac=no]))
|
||||||
|
|
||||||
|
if test "$emacs_cv_working_javac" = "no"; then
|
||||||
|
AC_MSG_ERROR([The Java compiler does not work, or you did not specify
|
||||||
|
a valid path to android.jar. See config.log for more details.])
|
||||||
|
fi
|
||||||
|
|
||||||
|
ANDROID_JAR="$with_android"
|
||||||
|
|
||||||
|
AC_PATH_PROGS([AAPT], [aapt], [], "${SDK_BUILD_TOOLS}:$PATH")
|
||||||
|
if test "$AAPT" = ""; then
|
||||||
|
AC_MSG_ERROR([The Android asset packaging tool was not found.
|
||||||
|
Please verify that the path to the SDK build tools you specified is correct])
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_PATH_PROGS([DX], [dx d8], [], "${SDK_BUILD_TOOLS}:$PATH")
|
||||||
|
if test "DX" = ""; then
|
||||||
|
AC_MSG_ERROR([The Android dexer was not found.
|
||||||
|
Please verify that the path to the SDK build tools you specified is correct])
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_PATH_PROGS([ZIPALIGN], [zipalign], [], "${SDK_BUILD_TOOLS}:$PATH")
|
||||||
|
if test "ZIPALIGN" = ""; then
|
||||||
|
AC_MSG_ERROR([The Android ZIP archive alignment utility was not found.
|
||||||
|
Please verify that the path to the SDK build tools you specified is correct]);
|
||||||
|
fi
|
||||||
|
|
||||||
|
dnl Now configure Emacs to generate binaries for Android. After the
|
||||||
|
dnl configuration completes, move the generated Makefiles.
|
||||||
|
|
||||||
|
if test "$ANDROID_CC" = "" || test "$ANDROID_CXX" = ""; then
|
||||||
|
AC_MSG_ERROR([Please specify the path to the Android cross-compiler
|
||||||
|
for your machine. For example:
|
||||||
|
|
||||||
|
ANDROID_CC=/path/to/armv7a-linux-androideabi19-clang \\
|
||||||
|
ANDROID_CXX=/path/to/armv7a-linux-androideabi19-clang++ \\
|
||||||
|
./configure --with-android])
|
||||||
|
fi
|
||||||
|
|
||||||
|
dnl Obtain the cross compiler's target to find out where binaries go
|
||||||
|
dnl in the resulting package.
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([for the kind of Android system Emacs is being built for])
|
||||||
|
cc_target=`${ANDROID_CC} -v 2>&1 | sed -n 's/Target: //p'`
|
||||||
|
case "$cc_target" in
|
||||||
|
*i[3-6]86*) android_abi=x86
|
||||||
|
;;
|
||||||
|
*x86_64*) android_abi=x86_64
|
||||||
|
;;
|
||||||
|
*aarch64*) android_abi=arm64-v8a
|
||||||
|
;;
|
||||||
|
*arm*v7a*) android_abi=armeabi-v7a
|
||||||
|
;;
|
||||||
|
*mips*) android_abi=mips
|
||||||
|
;;
|
||||||
|
*arm*) android_abi=armeabi
|
||||||
|
;;
|
||||||
|
*) AC_MSG_ERROR([configure could not determine the type of Android \
|
||||||
|
binary Emacs is being configured for. Please port this configure script \
|
||||||
|
to your Android system, or verify that you specified the correct compiler \
|
||||||
|
in the ANDROID_CC and ANDROID_CXX variables when you ran configure.])
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
AC_MSG_RESULT([$android_abi])
|
||||||
|
|
||||||
|
ANDROID_ABI=$android_abi
|
||||||
|
|
||||||
|
# Save confdefs.h and config.log for now.
|
||||||
|
mv -f confdefs.h _confdefs.h
|
||||||
|
mv -f config.log _config.log
|
||||||
|
|
||||||
|
AS_IF([XCONFIGURE=android ANDROID_CC="$ANDROID_CC" \
|
||||||
|
ANDROID_CXX="$ANDROID_CXX" $0], [], [AC_MSG_ERROR([Failed to cross-\
|
||||||
|
configure Emacs for android.])])
|
||||||
|
|
||||||
|
# Now set ANDROID to yes.
|
||||||
|
ANDROID=yes
|
||||||
|
|
||||||
|
for makefile in $android_makefiles; do
|
||||||
|
AC_MSG_NOTICE([Generating $makefile.android])
|
||||||
|
mv -f "$makefile" "$makefile.android"
|
||||||
|
done
|
||||||
|
|
||||||
|
AC_MSG_NOTICE([Generating src/config.h.android])
|
||||||
|
mv -f src/config.h src/config.h.android
|
||||||
|
|
||||||
|
# Move confdefs.h back now that the recursive call to configure is
|
||||||
|
# complete.
|
||||||
|
mv -f _confdefs.h confdefs.h
|
||||||
|
|
||||||
|
# Move the Android config.log to config.log.android. */
|
||||||
|
mv -f config.log config.log.android
|
||||||
|
|
||||||
|
# And _config.log back.
|
||||||
|
mv -f _config.log config.log
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_SUBST([ANDROID])
|
||||||
|
AC_SUBST([JAVAC])
|
||||||
|
AC_SUBST([AAPT])
|
||||||
|
AC_SUBST([DX])
|
||||||
|
AC_SUBST([ZIPALIGN])
|
||||||
|
AC_SUBST([ANDROID_JAR])
|
||||||
|
AC_SUBST([ANDROID_ABI])
|
||||||
|
|
||||||
|
if test "$XCONFIGURE" = "android"; then
|
||||||
|
ANDROID=yes
|
||||||
|
|
||||||
|
# Enable cross compiling.
|
||||||
|
cross_compiling=yes
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_SUBST([XCONFIGURE])
|
||||||
|
|
||||||
|
if test "$ANDROID" = "yes"; then
|
||||||
|
# When --with-android is specified, all build options must be
|
||||||
|
# disabled, both within the recursive invocation of configure and
|
||||||
|
# outside.
|
||||||
|
with_xpm=no
|
||||||
|
with_jpeg=no
|
||||||
|
with_tiff=no
|
||||||
|
with_gif=no
|
||||||
|
with_png=no
|
||||||
|
with_rsvg=no
|
||||||
|
with_webp=no
|
||||||
|
with_sqlite3=no
|
||||||
|
with_lcms2=no
|
||||||
|
with_libsystemd=no
|
||||||
|
with_cairo=no
|
||||||
|
with_xml2=no
|
||||||
|
with_imagemagick=no
|
||||||
|
with_json=no
|
||||||
|
with_tree_sitter=no
|
||||||
|
with_xft=no
|
||||||
|
with_harfbuzz=no
|
||||||
|
with_libotf=no
|
||||||
|
with_gpm=no
|
||||||
|
with_dbus=no
|
||||||
|
with_gsettings=no
|
||||||
|
with_selinx=no
|
||||||
|
with_gnutls=no
|
||||||
|
with_zlib=no
|
||||||
|
with_modules=no
|
||||||
|
with_threads=no
|
||||||
|
fi
|
||||||
|
|
||||||
dnl This used to use changequote, but, apart from 'changequote is evil'
|
dnl This used to use changequote, but, apart from 'changequote is evil'
|
||||||
dnl per the autoconf manual, we can speed up autoconf somewhat by quoting
|
dnl per the autoconf manual, we can speed up autoconf somewhat by quoting
|
||||||
dnl the great gob of text. Thus it's not processed for possible expansion.
|
dnl the great gob of text. Thus it's not processed for possible expansion.
|
||||||
|
|
@ -705,6 +972,11 @@ dnl quotation begins
|
||||||
opsys='' unported=no
|
opsys='' unported=no
|
||||||
case "${canonical}" in
|
case "${canonical}" in
|
||||||
|
|
||||||
|
## Android
|
||||||
|
*linux-android* )
|
||||||
|
opsys=android
|
||||||
|
;;
|
||||||
|
|
||||||
## GNU/Linux and similar ports
|
## GNU/Linux and similar ports
|
||||||
*-*-linux* )
|
*-*-linux* )
|
||||||
opsys=gnu-linux
|
opsys=gnu-linux
|
||||||
|
|
@ -871,6 +1143,7 @@ AC_DEFUN([_AC_PROG_CC_C89], [$2])
|
||||||
|
|
||||||
dnl Sets GCC=yes if using gcc.
|
dnl Sets GCC=yes if using gcc.
|
||||||
AC_PROG_CC([gcc cc cl clang "$XCRUN gcc" "$XCRUN clang"])
|
AC_PROG_CC([gcc cc cl clang "$XCRUN gcc" "$XCRUN clang"])
|
||||||
|
|
||||||
if test -n "$XCRUN"; then
|
if test -n "$XCRUN"; then
|
||||||
AC_CHECK_PROGS([AR], [ar "$XCRUN ar"])
|
AC_CHECK_PROGS([AR], [ar "$XCRUN ar"])
|
||||||
test -n "$AR" && export AR
|
test -n "$AR" && export AR
|
||||||
|
|
@ -1123,6 +1396,12 @@ AS_IF([test $gl_gcc_warnings = no],
|
||||||
nw="$nw -Wsuggest-attribute=format"
|
nw="$nw -Wsuggest-attribute=format"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# If Emacs is being built for Android and many functions are
|
||||||
|
# currently stubbed out for operation on the build machine, disable
|
||||||
|
# -Wsuggest-attribute=noreturn.
|
||||||
|
|
||||||
|
nw="$nw -Wsuggest-attribute=noreturn"
|
||||||
|
|
||||||
gl_MANYWARN_ALL_GCC([ws])
|
gl_MANYWARN_ALL_GCC([ws])
|
||||||
gl_MANYWARN_COMPLEMENT([ws], [$ws], [$nw])
|
gl_MANYWARN_COMPLEMENT([ws], [$ws], [$nw])
|
||||||
for w in $ws; do
|
for w in $ws; do
|
||||||
|
|
@ -1143,6 +1422,8 @@ AS_IF([test $gl_gcc_warnings = no],
|
||||||
gl_WARN_ADD([-Wno-null-pointer-arithmetic])
|
gl_WARN_ADD([-Wno-null-pointer-arithmetic])
|
||||||
gl_WARN_ADD([-Wno-implicit-const-int-float-conversion])
|
gl_WARN_ADD([-Wno-implicit-const-int-float-conversion])
|
||||||
gl_WARN_ADD([-Wno-int-in-bool-context])
|
gl_WARN_ADD([-Wno-int-in-bool-context])
|
||||||
|
gl_WARN_ADD([-Wno-shift-overflow])
|
||||||
|
gl_WARN_ADD([-Wno-bitwise-instead-of-logical])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# This causes too much noise in the MinGW build
|
# This causes too much noise in the MinGW build
|
||||||
|
|
@ -1265,7 +1546,7 @@ else
|
||||||
AM_DEFAULT_VERBOSITY=0
|
AM_DEFAULT_VERBOSITY=0
|
||||||
fi
|
fi
|
||||||
AC_SUBST([AM_DEFAULT_VERBOSITY])
|
AC_SUBST([AM_DEFAULT_VERBOSITY])
|
||||||
AC_CONFIG_FILES([src/verbose.mk])
|
ARCH_INDEPENDENT_CONFIG_FILES([src/verbose.mk])
|
||||||
|
|
||||||
dnl Some other nice autoconf tests.
|
dnl Some other nice autoconf tests.
|
||||||
AC_PROG_INSTALL
|
AC_PROG_INSTALL
|
||||||
|
|
@ -1762,7 +2043,10 @@ AC_SUBST([SYSTEM_TYPE])
|
||||||
pre_PKG_CONFIG_CFLAGS=$CFLAGS
|
pre_PKG_CONFIG_CFLAGS=$CFLAGS
|
||||||
pre_PKG_CONFIG_LIBS=$LIBS
|
pre_PKG_CONFIG_LIBS=$LIBS
|
||||||
|
|
||||||
PKG_PROG_PKG_CONFIG([0.9.0])
|
dnl pkg-config does not work when cross-compiling for Android.
|
||||||
|
if test "${ANDROID}" != "yes"; then
|
||||||
|
PKG_PROG_PKG_CONFIG([0.9.0])
|
||||||
|
fi
|
||||||
|
|
||||||
dnl EMACS_CHECK_MODULES([GSTUFF], [gtk+-2.0 >= 1.3 glib = 1.3.4])
|
dnl EMACS_CHECK_MODULES([GSTUFF], [gtk+-2.0 >= 1.3 glib = 1.3.4])
|
||||||
dnl acts like PKG_CHECK_MODULES([GSTUFF], [gtk+-2.0 >= 1.3 glib = 1.3.4],
|
dnl acts like PKG_CHECK_MODULES([GSTUFF], [gtk+-2.0 >= 1.3 glib = 1.3.4],
|
||||||
|
|
@ -1945,14 +2229,49 @@ AC_SUBST([AUTO_DEPEND])
|
||||||
|
|
||||||
window_system=none
|
window_system=none
|
||||||
|
|
||||||
|
ANDROID_OBJ=
|
||||||
|
ANDROID_LIBS=
|
||||||
|
ANDROID_CFLAGS=
|
||||||
|
CM_OBJ="cm.o"
|
||||||
|
|
||||||
|
if test "${ANDROID}" = "yes"; then
|
||||||
|
window_system=android
|
||||||
|
no_x=yes
|
||||||
|
ANDROID_OBJ="androidterm.o androidfns.o androidfont.o android.o"
|
||||||
|
ANDROID_LIBS=
|
||||||
|
CM_OBJ=
|
||||||
|
|
||||||
|
AC_DEFINE([HAVE_ANDROID], [1], [Define to 1 if Emacs is being built
|
||||||
|
with Android support])
|
||||||
|
|
||||||
|
if test "${XCONFIGURE}" != "android"; then
|
||||||
|
AC_DEFINE([ANDROID_STUBIFY], [1], [Define to 1 if Emacs is being built
|
||||||
|
for Android, but all API calls need to be stubbed out])
|
||||||
|
else
|
||||||
|
# Emacs will be built as a shared library, and a wrapper around it
|
||||||
|
# will also be built for the benefit of applications. This
|
||||||
|
# requires Emacs be built as a position independent executable.
|
||||||
|
ANDROID_CFLAGS="-fPIC -fvisibility=hidden"
|
||||||
|
|
||||||
|
# Link with libraries required for Android support.
|
||||||
|
ANDROID_LIBS="-landroid -llog"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_SUBST(ANDROID)
|
||||||
|
AC_SUBST(ANDROID_OBJ)
|
||||||
|
AC_SUBST(ANDROID_LIBS)
|
||||||
|
AC_SUBST(ANDROID_CFLAGS)
|
||||||
|
|
||||||
if test "${with_pgtk}" = "yes"; then
|
if test "${with_pgtk}" = "yes"; then
|
||||||
window_system=pgtk
|
window_system=pgtk
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if test "${ANDROID}" != "yes"; then
|
||||||
AC_PATH_X
|
AC_PATH_X
|
||||||
if test "$no_x" != yes && test "${with_pgtk}" != "yes"; then
|
if test "$no_x" != yes && test "${with_pgtk}" != "yes"; then
|
||||||
window_system=x11
|
window_system=x11
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
LD_SWITCH_X_SITE_RPATH=
|
LD_SWITCH_X_SITE_RPATH=
|
||||||
|
|
@ -2276,7 +2595,6 @@ NTDIR=
|
||||||
LIBS_ECLIENT=
|
LIBS_ECLIENT=
|
||||||
LIB_WSOCK32=
|
LIB_WSOCK32=
|
||||||
NTLIB=
|
NTLIB=
|
||||||
CM_OBJ="cm.o"
|
|
||||||
XARGS_LIMIT=
|
XARGS_LIMIT=
|
||||||
if test "${HAVE_W32}" = "yes"; then
|
if test "${HAVE_W32}" = "yes"; then
|
||||||
AC_DEFINE([HAVE_NTGUI], [1], [Define to use native MS Windows GUI.])
|
AC_DEFINE([HAVE_NTGUI], [1], [Define to use native MS Windows GUI.])
|
||||||
|
|
@ -2439,7 +2757,11 @@ dnl use the toolkit if we have gtk, or X11R5 or newer.
|
||||||
haiku )
|
haiku )
|
||||||
term_header=haikuterm.h
|
term_header=haikuterm.h
|
||||||
;;
|
;;
|
||||||
|
android )
|
||||||
|
term_header=androidterm.h
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
AC_SUBST([HAVE_PGTK])
|
AC_SUBST([HAVE_PGTK])
|
||||||
|
|
||||||
if test "$window_system" = none && test "X$with_x" != "Xno"; then
|
if test "$window_system" = none && test "X$with_x" != "Xno"; then
|
||||||
|
|
@ -2773,7 +3095,6 @@ fail;
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
### Use -lrsvg-2 if available, unless '--with-rsvg=no' is specified.
|
### Use -lrsvg-2 if available, unless '--with-rsvg=no' is specified.
|
||||||
HAVE_RSVG=no
|
HAVE_RSVG=no
|
||||||
if test "${HAVE_X11}" = "yes" || test "${HAVE_NS}" = "yes" \
|
if test "${HAVE_X11}" = "yes" || test "${HAVE_NS}" = "yes" \
|
||||||
|
|
@ -4202,7 +4523,7 @@ AC_SUBST([HAVE_MODULES])
|
||||||
AC_SUBST([MODULES_SUFFIX])
|
AC_SUBST([MODULES_SUFFIX])
|
||||||
AC_SUBST([MODULES_SECONDARY_SUFFIX])
|
AC_SUBST([MODULES_SECONDARY_SUFFIX])
|
||||||
|
|
||||||
AC_CONFIG_FILES([src/emacs-module.h])
|
ARCH_INDEPENDENT_CONFIG_FILES([src/emacs-module.h])
|
||||||
AC_SUBST_FILE([module_env_snippet_25])
|
AC_SUBST_FILE([module_env_snippet_25])
|
||||||
AC_SUBST_FILE([module_env_snippet_26])
|
AC_SUBST_FILE([module_env_snippet_26])
|
||||||
AC_SUBST_FILE([module_env_snippet_27])
|
AC_SUBST_FILE([module_env_snippet_27])
|
||||||
|
|
@ -5003,6 +5324,40 @@ getpwent endpwent getgrent endgrent \
|
||||||
renameat2 \
|
renameat2 \
|
||||||
cfmakeraw cfsetspeed __executable_start log2 pthread_setname_np \
|
cfmakeraw cfsetspeed __executable_start log2 pthread_setname_np \
|
||||||
pthread_set_name_np])
|
pthread_set_name_np])
|
||||||
|
|
||||||
|
if test "$ac_cv_func_cfmakeraw" != "yes"; then
|
||||||
|
# On some systems (Android), cfmakeraw is inline, so AC_CHECK_FUNCS
|
||||||
|
# cannot find it. Check if some code including termios.h and using
|
||||||
|
# cfmakeraw builds.
|
||||||
|
AC_CACHE_CHECK([whether cfmakeraw is inline],
|
||||||
|
[emacs_cv_func_cfmakeraw_inline],
|
||||||
|
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
|
||||||
|
[[#include <termios.h>]],
|
||||||
|
[[&cfmakeraw;]])],
|
||||||
|
[emacs_cv_func_cfmakeraw_inline=yes],
|
||||||
|
[emacs_cv_func_cfmakeraw_inline=no])])
|
||||||
|
|
||||||
|
if test "$emacs_cv_func_cfmakeraw_inline" = "yes"; then
|
||||||
|
# Define HAVE_CFMAKERAW again.
|
||||||
|
AC_DEFINE([HAVE_CFMAKERAW], [1])
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "$ac_cv_func_cfsetspeed" != "yes"; then
|
||||||
|
AC_CACHE_CHECK([whether cfsetspeed is inline],
|
||||||
|
[emacs_cv_func_cfsetspeed_inline],
|
||||||
|
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
|
||||||
|
[[#include <termios.h>]],
|
||||||
|
[[&cfsetspeed;]])],
|
||||||
|
[emacs_cv_func_cfsetspeed_inline=yes],
|
||||||
|
[emacs_cv_func_cfsetspeed_inline=no])])
|
||||||
|
|
||||||
|
if test "$emacs_cv_func_cfsetspeed_inline" = "yes"; then
|
||||||
|
# Define HAVE_CFSETSPEED again.
|
||||||
|
AC_DEFINE([HAVE_CFSETSPEED], [1])
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
LIBS=$OLD_LIBS
|
LIBS=$OLD_LIBS
|
||||||
|
|
||||||
if test "$ac_cv_func_pthread_setname_np" = "yes"; then
|
if test "$ac_cv_func_pthread_setname_np" = "yes"; then
|
||||||
|
|
@ -5108,7 +5463,7 @@ AC_DEFUN([tputs_link_source], [
|
||||||
# than to expect to find it in ncurses.
|
# than to expect to find it in ncurses.
|
||||||
# Also we need tputs and friends to be able to build at all.
|
# Also we need tputs and friends to be able to build at all.
|
||||||
AC_CACHE_CHECK([for library containing tputs], [emacs_cv_tputs_lib],
|
AC_CACHE_CHECK([for library containing tputs], [emacs_cv_tputs_lib],
|
||||||
[if test "${opsys}" = "mingw32"; then
|
[if test "${opsys}" = "mingw32" || test "$opsys" = "android"; then
|
||||||
emacs_cv_tputs_lib='none required'
|
emacs_cv_tputs_lib='none required'
|
||||||
else
|
else
|
||||||
# curses precedes termcap because of AIX (Bug#9736#35) and OpenIndiana.
|
# curses precedes termcap because of AIX (Bug#9736#35) and OpenIndiana.
|
||||||
|
|
@ -5175,7 +5530,7 @@ fail;
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
|
|
||||||
mingw32)
|
mingw32 | android)
|
||||||
TERMINFO=no
|
TERMINFO=no
|
||||||
LIBS_TERMCAP=
|
LIBS_TERMCAP=
|
||||||
;;
|
;;
|
||||||
|
|
@ -5729,7 +6084,7 @@ case $opsys in
|
||||||
AC_DEFINE([FIRST_PTY_LETTER], ['p'])
|
AC_DEFINE([FIRST_PTY_LETTER], ['p'])
|
||||||
;;
|
;;
|
||||||
|
|
||||||
gnu-linux | gnu-kfreebsd | dragonfly | freebsd | openbsd | netbsd | darwin | nacl )
|
gnu-linux | gnu-kfreebsd | dragonfly | freebsd | openbsd | netbsd | darwin | nacl | android )
|
||||||
dnl if HAVE_GRANTPT
|
dnl if HAVE_GRANTPT
|
||||||
if test "x$ac_cv_func_grantpt" = xyes; then
|
if test "x$ac_cv_func_grantpt" = xyes; then
|
||||||
AC_DEFINE([UNIX98_PTYS], [1], [Define if the system has Unix98 PTYs.])
|
AC_DEFINE([UNIX98_PTYS], [1], [Define if the system has Unix98 PTYs.])
|
||||||
|
|
@ -6656,6 +7011,7 @@ AC_DEFINE_UNQUOTED([EMACS_CONFIG_FEATURES], ["${emacs_config_features}"],
|
||||||
[Summary of some of the main features enabled by configure.])
|
[Summary of some of the main features enabled by configure.])
|
||||||
|
|
||||||
AS_ECHO([" Does Emacs use -lXaw3d? ${HAVE_XAW3D}
|
AS_ECHO([" Does Emacs use -lXaw3d? ${HAVE_XAW3D}
|
||||||
|
Does Emacs use Android? ${ANDROID}
|
||||||
Does Emacs use -lXpm? ${HAVE_XPM}
|
Does Emacs use -lXpm? ${HAVE_XPM}
|
||||||
Does Emacs use -ljpeg? ${HAVE_JPEG}
|
Does Emacs use -ljpeg? ${HAVE_JPEG}
|
||||||
Does Emacs use -ltiff? ${HAVE_TIFF}
|
Does Emacs use -ltiff? ${HAVE_TIFF}
|
||||||
|
|
@ -6759,12 +7115,15 @@ fi
|
||||||
AC_CONFIG_FILES([Makefile lib/gnulib.mk])
|
AC_CONFIG_FILES([Makefile lib/gnulib.mk])
|
||||||
|
|
||||||
dnl config.status treats $srcdir specially, so I think this is ok...
|
dnl config.status treats $srcdir specially, so I think this is ok...
|
||||||
AC_CONFIG_FILES([$srcdir/doc/man/emacs.1])
|
ARCH_INDEPENDENT_CONFIG_FILES([$srcdir/doc/man/emacs.1])
|
||||||
|
|
||||||
m4_define([subdir_makefiles],
|
AC_CONFIG_FILES([lib/Makefile lib-src/Makefile oldXMenu/Makefile src/Makefile
|
||||||
[lib/Makefile lib-src/Makefile oldXMenu/Makefile doc/emacs/Makefile doc/misc/Makefile doc/lispintro/Makefile doc/lispref/Makefile src/Makefile lwlib/Makefile lisp/Makefile leim/Makefile nextstep/Makefile nt/Makefile])
|
lwlib/Makefile nextstep/Makefile nt/Makefile])
|
||||||
SUBDIR_MAKEFILES="subdir_makefiles"
|
ARCH_INDEPENDENT_CONFIG_FILES([doc/emacs/Makefile doc/misc/Makefile
|
||||||
AC_CONFIG_FILES(subdir_makefiles)
|
doc/lispintro/Makefile doc/lispref/Makefile
|
||||||
|
lisp/Makefile leim/Makefile])
|
||||||
|
|
||||||
|
SUBDIR_MAKEFILES="lib/Makefile lib-src/Makefile oldXMenu/Makefile src/Makefile lwlib/Makefile nextstep/Makefile nt/Makefile doc/emacs/Makefile doc/misc/Makefile doc/lispintro/Makefile doc/lispref/Makefile lisp/Makefile leim/Makefile"
|
||||||
|
|
||||||
dnl The test/ directory is missing if './make-dist --no-tests' was used.
|
dnl The test/ directory is missing if './make-dist --no-tests' was used.
|
||||||
opt_makefile=test/Makefile
|
opt_makefile=test/Makefile
|
||||||
|
|
@ -6772,24 +7131,31 @@ if test -f "$srcdir/$opt_makefile.in"; then
|
||||||
SUBDIR_MAKEFILES="$SUBDIR_MAKEFILES $opt_makefile"
|
SUBDIR_MAKEFILES="$SUBDIR_MAKEFILES $opt_makefile"
|
||||||
dnl Again, it's best not to use a variable. Though you can add
|
dnl Again, it's best not to use a variable. Though you can add
|
||||||
dnl ", [], [opt_makefile='$opt_makefile']" and it should work.
|
dnl ", [], [opt_makefile='$opt_makefile']" and it should work.
|
||||||
AC_CONFIG_FILES([test/Makefile])
|
ARCH_INDEPENDENT_CONFIG_FILES([test/Makefile])
|
||||||
AC_CONFIG_FILES([test/manual/noverlay/Makefile])
|
ARCH_INDEPENDENT_CONFIG_FILES([test/manual/noverlay/Makefile])
|
||||||
fi
|
fi
|
||||||
opt_makefile=test/infra/Makefile
|
opt_makefile=test/infra/Makefile
|
||||||
if test -f "$srcdir/$opt_makefile.in"; then
|
if test -f "$srcdir/$opt_makefile.in"; then
|
||||||
SUBDIR_MAKEFILES="$SUBDIR_MAKEFILES $opt_makefile"
|
SUBDIR_MAKEFILES="$SUBDIR_MAKEFILES $opt_makefile"
|
||||||
dnl Again, it's best not to use a variable. Though you can add
|
dnl Again, it's best not to use a variable. Though you can add
|
||||||
dnl ", [], [opt_makefile='$opt_makefile']" and it should work.
|
dnl ", [], [opt_makefile='$opt_makefile']" and it should work.
|
||||||
AC_CONFIG_FILES([test/infra/Makefile])
|
ARCH_INDEPENDENT_CONFIG_FILES([test/infra/Makefile])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if test "$ANDROID" = "yes"; then
|
||||||
|
SUBDIR_MAKEFILES="$SUBDIR_MAKEFILES java/Makefile"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "$XCOMPILE" = "yes"; then
|
||||||
|
SUBDIR_MAKEFILES="$SUBDIR_MAKEFILES xcompile/Makefile"
|
||||||
|
fi
|
||||||
|
|
||||||
dnl The admin/ directory used to be excluded from tarfiles.
|
dnl The admin/ directory used to be excluded from tarfiles.
|
||||||
if test -d $srcdir/admin; then
|
if test -d $srcdir/admin; then
|
||||||
SUBDIR_MAKEFILES="$SUBDIR_MAKEFILES admin/charsets/Makefile admin/unidata/Makefile admin/grammars/Makefile"
|
SUBDIR_MAKEFILES="$SUBDIR_MAKEFILES admin/charsets/Makefile admin/unidata/Makefile admin/grammars/Makefile"
|
||||||
AC_CONFIG_FILES([admin/charsets/Makefile])
|
ARCH_INDEPENDENT_CONFIG_FILES([admin/charsets/Makefile])
|
||||||
AC_CONFIG_FILES([admin/unidata/Makefile])
|
ARCH_INDEPENDENT_CONFIG_FILES([admin/unidata/Makefile])
|
||||||
AC_CONFIG_FILES([admin/grammars/Makefile])
|
ARCH_INDEPENDENT_CONFIG_FILES([admin/grammars/Makefile])
|
||||||
fi dnl -d admin
|
fi dnl -d admin
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -6800,65 +7166,75 @@ AC_SUBST([SUBDIR_MAKEFILES_IN])
|
||||||
SMALL_JA_DIC=$with_small_ja_dic
|
SMALL_JA_DIC=$with_small_ja_dic
|
||||||
AC_SUBST([SMALL_JA_DIC])
|
AC_SUBST([SMALL_JA_DIC])
|
||||||
|
|
||||||
dnl You might wonder (I did) why epaths.h is generated by running make,
|
dnl The following commands are run on the host system when building
|
||||||
dnl rather than just letting configure generate it from epaths.in.
|
dnl Emacs.
|
||||||
dnl One reason is that the various paths are not fully expanded (see above);
|
|
||||||
dnl e.g., gamedir='${localstatedir}/games/emacs'.
|
|
||||||
dnl Secondly, the GNU Coding standards require that one should be able
|
|
||||||
dnl to run 'make prefix=/some/where/else' and override the values set
|
|
||||||
dnl by configure. This also explains the 'move-if-change' test and
|
|
||||||
dnl the use of force in the 'epaths-force' rule in Makefile.in.
|
|
||||||
AC_CONFIG_COMMANDS([src/epaths.h], [
|
|
||||||
if test "${opsys}" = "mingw32"; then
|
|
||||||
${MAKE-make} MAKEFILE_NAME=do-not-make-Makefile epaths-force-w32
|
|
||||||
elif test "$HAVE_NS" = "yes" && test "$EN_NS_SELF_CONTAINED" = "yes"; then
|
|
||||||
${MAKE-make} MAKEFILE_NAME=do-not-make-Makefile epaths-force-ns-self-contained
|
|
||||||
else
|
|
||||||
${MAKE-make} MAKEFILE_NAME=do-not-make-Makefile epaths-force
|
|
||||||
fi || AC_MSG_ERROR(['src/epaths.h' could not be made.])
|
|
||||||
], [GCC="$GCC" CPPFLAGS="$CPPFLAGS" opsys="$opsys" HAVE_NS="$HAVE_NS"
|
|
||||||
EN_NS_SELF_CONTAINED="$EN_NS_SELF_CONTAINED"])
|
|
||||||
|
|
||||||
dnl NB we have to cheat and use the ac_... version because abs_top_srcdir
|
if test "$XCONFIGURE" != "android"; then
|
||||||
dnl is not yet set, sigh. Or we could use ../$srcdir/src/.gdbinit,
|
dnl You might wonder (I did) why epaths.h is generated by running
|
||||||
dnl or a symlink?
|
dnl make, rather than just letting configure generate it from
|
||||||
AC_CONFIG_COMMANDS([src/.gdbinit], [
|
dnl epaths.in. One reason is that the various paths are not fully
|
||||||
if test ! -f src/.gdbinit && test -f "$srcdir/src/.gdbinit"; then
|
dnl expanded (see above); e.g.,
|
||||||
AS_ECHO(["source $ac_abs_top_srcdir/src/.gdbinit"]) > src/.gdbinit
|
dnl gamedir='${localstatedir}/games/emacs'. Secondly, the GNU
|
||||||
fi
|
dnl Coding standards require that one should be able to run 'make
|
||||||
])
|
dnl prefix=/some/where/else' and override the values set by
|
||||||
|
dnl configure. This also explains the 'move-if-change' test and the
|
||||||
|
dnl use of force in the 'epaths-force' rule in Makefile.in.
|
||||||
|
AC_CONFIG_COMMANDS([src/epaths.h], [
|
||||||
|
if test "${opsys}" = "mingw32"; then
|
||||||
|
${MAKE-make} MAKEFILE_NAME=do-not-make-Makefile epaths-force-w32
|
||||||
|
elif test "$HAVE_NS" = "yes" && test "$EN_NS_SELF_CONTAINED" = "yes"; then
|
||||||
|
${MAKE-make} MAKEFILE_NAME=do-not-make-Makefile epaths-force-ns-self-contained
|
||||||
|
else
|
||||||
|
${MAKE-make} MAKEFILE_NAME=do-not-make-Makefile epaths-force
|
||||||
|
fi || AC_MSG_ERROR(['src/epaths.h' could not be made.])
|
||||||
|
], [GCC="$GCC" CPPFLAGS="$CPPFLAGS" opsys="$opsys" HAVE_NS="$HAVE_NS"
|
||||||
|
EN_NS_SELF_CONTAINED="$EN_NS_SELF_CONTAINED"])
|
||||||
|
|
||||||
dnl Perhaps this would be better named doc-emacs-emacsver.texi?
|
dnl NB we have to cheat and use the ac_... version because abs_top_srcdir
|
||||||
dnl See comments for etc-refcards-emacsver.tex.
|
dnl is not yet set, sigh. Or we could use ../$srcdir/src/.gdbinit,
|
||||||
dnl Since we get a doc/emacs directory generated anyway, for the Makefile,
|
dnl or a symlink?
|
||||||
dnl it is not quite the same. But we are generating in $srcdir.
|
AC_CONFIG_COMMANDS([src/.gdbinit], [
|
||||||
AC_CONFIG_COMMANDS([doc/emacs/emacsver.texi], [
|
if test ! -f src/.gdbinit && test -f "$srcdir/src/.gdbinit"; then
|
||||||
${MAKE-make} -s --no-print-directory -C doc/emacs doc-emacsver || \
|
AS_ECHO(["source $ac_abs_top_srcdir/src/.gdbinit"]) > src/.gdbinit
|
||||||
AC_MSG_ERROR(['doc/emacs/emacsver.texi' could not be made.])
|
fi
|
||||||
])
|
])
|
||||||
|
|
||||||
dnl If we give this the more natural name, etc/refcards/emacsver.texi,
|
dnl Perhaps this would be better named doc-emacs-emacsver.texi?
|
||||||
dnl then a directory etc/refcards is created in the build directory,
|
dnl See comments for etc-refcards-emacsver.tex.
|
||||||
dnl which is probably harmless, but confusing (in out-of-tree builds).
|
dnl Since we get a doc/emacs directory generated anyway, for the Makefile,
|
||||||
dnl (If we were to generate etc/refcards/Makefile, this might change.)
|
dnl it is not quite the same. But we are generating in $srcdir.
|
||||||
dnl It is really $srcdir/etc/refcards/emacsver.tex that we generate.
|
AC_CONFIG_COMMANDS([doc/emacs/emacsver.texi], [
|
||||||
AC_CONFIG_COMMANDS([etc-refcards-emacsver.tex], [
|
${MAKE-make} -s --no-print-directory -C doc/emacs doc-emacsver || \
|
||||||
${MAKE-make} -s MAKEFILE_NAME=do-not-make-Makefile etc-emacsver || \
|
AC_MSG_ERROR(['doc/emacs/emacsver.texi' could not be made.])
|
||||||
AC_MSG_ERROR(['etc/refcards/emacsver.tex' could not be made.])
|
])
|
||||||
])
|
|
||||||
|
dnl If we give this the more natural name, etc/refcards/emacsver.texi,
|
||||||
|
dnl then a directory etc/refcards is created in the build directory,
|
||||||
|
dnl which is probably harmless, but confusing (in out-of-tree builds).
|
||||||
|
dnl (If we were to generate etc/refcards/Makefile, this might change.)
|
||||||
|
dnl It is really $srcdir/etc/refcards/emacsver.tex that we generate.
|
||||||
|
AC_CONFIG_COMMANDS([etc-refcards-emacsver.tex], [
|
||||||
|
${MAKE-make} -s MAKEFILE_NAME=do-not-make-Makefile etc-emacsver || \
|
||||||
|
AC_MSG_ERROR(['etc/refcards/emacsver.tex' could not be made.])
|
||||||
|
])
|
||||||
|
|
||||||
if test $AUTO_DEPEND = yes; then
|
|
||||||
for dir in $AUTODEPEND_PARENTS; do
|
|
||||||
AS_MKDIR_P([$dir/deps])
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
if $gl_gnulib_enabled_dynarray || $gl_gnulib_enabled_scratch_buffer; then
|
|
||||||
AS_MKDIR_P([lib/malloc])
|
|
||||||
if test $AUTO_DEPEND = yes; then
|
if test $AUTO_DEPEND = yes; then
|
||||||
AS_MKDIR_P([lib/deps/malloc])
|
for dir in $AUTODEPEND_PARENTS; do
|
||||||
|
AS_MKDIR_P([$dir/deps])
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
if $gl_gnulib_enabled_dynarray || $gl_gnulib_enabled_scratch_buffer; then
|
||||||
|
AS_MKDIR_P([lib/malloc])
|
||||||
|
if test $AUTO_DEPEND = yes; then
|
||||||
|
AS_MKDIR_P([lib/deps/malloc])
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Make java/Makefile
|
||||||
|
ARCH_INDEPENDENT_CONFIG_FILES([java/Makefile])
|
||||||
|
ARCH_INDEPENDENT_CONFIG_FILES([xcompile/Makefile])
|
||||||
|
|
||||||
AC_OUTPUT
|
AC_OUTPUT
|
||||||
|
|
||||||
if test ! "$with_mailutils"; then
|
if test ! "$with_mailutils"; then
|
||||||
|
|
|
||||||
24
etc/DEBUG
24
etc/DEBUG
|
|
@ -1094,6 +1094,30 @@ Please refer to the LLDB reference on the web for more information
|
||||||
about LLDB. If you already know GDB, you will also find a mapping
|
about LLDB. If you already know GDB, you will also find a mapping
|
||||||
from GDB commands to corresponding LLDB commands there.
|
from GDB commands to corresponding LLDB commands there.
|
||||||
|
|
||||||
|
** Debugging Emacs on Android.
|
||||||
|
|
||||||
|
Attaching GDB to Emacs running inside the Android application setup
|
||||||
|
requires a special script found in the java/ directory, and a suitable
|
||||||
|
GDB server binary to be present on the Android device, which is
|
||||||
|
present on the free versions of Android. Connecting to the device
|
||||||
|
also requires the `adb' (Android Debug Bridge) utility, and telling
|
||||||
|
the Android system to resume the Emacs process after startup requires
|
||||||
|
the Java debugger (jdb).
|
||||||
|
|
||||||
|
If all three of those tools are present, simply run (from the Emacs
|
||||||
|
source directory):
|
||||||
|
|
||||||
|
../java/debug.sh -- [any extra arguments you wish to pass to gdb]
|
||||||
|
|
||||||
|
After which, upon waiting a while, the GDB prompt will show up.
|
||||||
|
|
||||||
|
If Emacs crashes and "JNI ERROR" shows up in the Android system log,
|
||||||
|
then placing a breakpoint on:
|
||||||
|
|
||||||
|
break art::JavaVMExt::JniAbort
|
||||||
|
|
||||||
|
will let you find the source of the crash.
|
||||||
|
|
||||||
|
|
||||||
This file is part of GNU Emacs.
|
This file is part of GNU Emacs.
|
||||||
|
|
||||||
|
|
|
||||||
54
java/AndroidManifest.xml
Normal file
54
java/AndroidManifest.xml
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="org.gnu.emacs" android:installLocation="auto">
|
||||||
|
|
||||||
|
<!-- Paste in every permission in existence so Emacs can do
|
||||||
|
anything. -->
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.READ_CONTACTS" />
|
||||||
|
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
|
||||||
|
<uses-permission android:name="android.permission.VIBRATE" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||||
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
<uses-permission android:name="android.permission.SET_WALLPAPER" />
|
||||||
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
|
<uses-permission android:name="android.permission.SEND_SMS" />
|
||||||
|
<uses-permission android:name="android.permission.RECEIVE_SMS" />
|
||||||
|
<uses-permission android:name="android.permission.RECEIVE_MMS"/>
|
||||||
|
<uses-permission android:name="android.permission.WRITE_SMS"/>
|
||||||
|
<uses-permission android:name="android.permission.READ_SMS"/>
|
||||||
|
<uses-permission android:name="android.permission.NFC" />
|
||||||
|
<uses-permission android:name="android.permission.TRANSMIT_IR" />
|
||||||
|
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
|
||||||
|
<uses-permission android:name="android.permission.WAKE_LOCK"/>
|
||||||
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
||||||
|
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
|
||||||
|
<uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES"/>
|
||||||
|
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
|
||||||
|
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||||
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
|
|
||||||
|
<uses-sdk android:minSdkVersion="7"
|
||||||
|
android:targetSdkVersion="28"/>
|
||||||
|
|
||||||
|
<application android:name="org.gnu.emacs.EmacsApplication"
|
||||||
|
android:label="GNU Emacs"
|
||||||
|
android:hardwareAccelerated="true"
|
||||||
|
android:supportsRtl="true"
|
||||||
|
android:theme="@android:style/Theme"
|
||||||
|
android:debuggable="true"
|
||||||
|
android:extractNativeLibs="true">
|
||||||
|
<activity android:name="org.gnu.emacs.EmacsActivity">
|
||||||
|
<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>
|
||||||
|
|
||||||
|
<service android:name="org.gnu.emacs.EmacsService"
|
||||||
|
android:directBootAware="false"
|
||||||
|
android:enabled="true"
|
||||||
|
android:exported="false"
|
||||||
|
android:label="GNU Emacs service"/>
|
||||||
|
</application>
|
||||||
|
</manifest>
|
||||||
150
java/Makefile.in
Normal file
150
java/Makefile.in
Normal file
|
|
@ -0,0 +1,150 @@
|
||||||
|
### @configure_input@
|
||||||
|
|
||||||
|
# Copyright (C) 2023 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This file is part of GNU Emacs.
|
||||||
|
|
||||||
|
# GNU Emacs is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
# GNU Emacs is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
top_builddir = @top_builddir@
|
||||||
|
|
||||||
|
-include ${top_builddir}/src/verbose.mk
|
||||||
|
|
||||||
|
SHELL = @SHELL@
|
||||||
|
JAVAC = @JAVAC@
|
||||||
|
AAPT = @AAPT@
|
||||||
|
DX = @DX@
|
||||||
|
ZIPALIGN = @ZIPALIGN@
|
||||||
|
JARSIGNER = @JARSIGNER@
|
||||||
|
ANDROID_JAR = @ANDROID_JAR@
|
||||||
|
ANDROID_ABI = @ANDROID_ABI@
|
||||||
|
|
||||||
|
WARN_JAVAFLAGS = -Xlint:deprecation
|
||||||
|
JAVAFLAGS = -classpath "$(ANDROID_JAR):." -target 1.7 -source 1.7 \
|
||||||
|
$(WARN_JAVAFLAGS)
|
||||||
|
|
||||||
|
SIGN_EMACS = -keystore emacs.keystore -storepass emacs1
|
||||||
|
|
||||||
|
JAVA_FILES = $(shell find . -type f -name *.java)
|
||||||
|
CLASS_FILES = $(foreach file,$(JAVA_FILES),$(basename $(file)).class)
|
||||||
|
|
||||||
|
# How this stuff works.
|
||||||
|
|
||||||
|
# emacs.apk depends on emacs.apk-in, which is simply a ZIP archive
|
||||||
|
# containing the following files:
|
||||||
|
# lib/$(ANDROID_ABI)/libemacs.so
|
||||||
|
# lib/$(ANDROID_ABI)/libandroid-emacs.so
|
||||||
|
# lib/$(ANDROID_ABI)/libctags.so
|
||||||
|
# lib/$(ANDROID_ABI)/libhexl.so
|
||||||
|
# lib/$(ANDROID_ABI)/libmovemail.so
|
||||||
|
# lib/$(ANDROID_ABI)/librcs2log.so
|
||||||
|
# lib/$(ANDROID_ABI)/libebrowse.so
|
||||||
|
# assets/info/
|
||||||
|
# assets/etc/
|
||||||
|
# assets/lisp/
|
||||||
|
|
||||||
|
.PHONY: emacs.apk-in all
|
||||||
|
all: emacs.apk
|
||||||
|
|
||||||
|
# Binaries to cross-compile.
|
||||||
|
CROSS_BINS = ../xcompile/src/android-emacs ../xcompile/lib-src/ctags \
|
||||||
|
../xcompile/lib-src/hexl ../xcompile/lib-src/movemail \
|
||||||
|
../xcompile/lib-src/ebrowse
|
||||||
|
|
||||||
|
# Libraries to cross-compile.
|
||||||
|
CROSS_LIBS = ../xcompile/src/libemacs.so
|
||||||
|
|
||||||
|
.PHONY: $(CROSS_BINS) $(CROSS_LIBS)
|
||||||
|
|
||||||
|
../xcompile/src/android-emacs ../xcompile/src/libemacs.so:
|
||||||
|
make -C ../xcompile src/$(notdir $@)
|
||||||
|
|
||||||
|
../xcompile/lib-src/hexl ../xcompile/lib-src/movemail \
|
||||||
|
../xcompile/lib-src/ctags ../xcompile/lib-src/ebrowse &:
|
||||||
|
make -C ../xcompile lib-src/$(notdir $@)
|
||||||
|
|
||||||
|
emacs.apk-in: $(CROSS_BINS) $(CROSS_LIBS) AndroidManifest.xml
|
||||||
|
# Make the working directory for this stuff
|
||||||
|
rm -rf install_temp
|
||||||
|
mkdir -p install_temp/lib/$(ANDROID_ABI)
|
||||||
|
mkdir -p install_temp/assets/etc
|
||||||
|
mkdir -p install_temp/assets/lisp
|
||||||
|
mkdir -p install_temp/assets/info
|
||||||
|
# Install architecture independents to assets/etc and assets/lisp
|
||||||
|
cp -r $(top_builddir)/lisp install_temp/assets
|
||||||
|
cp -r $(top_builddir)/etc install_temp/assets
|
||||||
|
# Remove undesirable files from those directories.
|
||||||
|
for subdir in `find install_temp -type d -print`; do \
|
||||||
|
chmod a+rx $${subdir} ; \
|
||||||
|
rm -rf $${subdir}/.gitignore ; \
|
||||||
|
rm -rf $${subdir}/.DS_Store ; \
|
||||||
|
rm -rf $${subdir}/#* ; \
|
||||||
|
rm -rf $${subdir}/.#* ; \
|
||||||
|
rm -rf $${subdir}/*~ ; \
|
||||||
|
rm -rf $${subdir}/*.orig ; \
|
||||||
|
rm -rf $${subdir}/ChangeLog* ; \
|
||||||
|
rm -rf $${subdir}/[mM]akefile*[.-]in ; \
|
||||||
|
rm -rf $${subdir}/Makefile; \
|
||||||
|
done
|
||||||
|
# Install architecture dependents to lib/$(ANDROID_ABI). This
|
||||||
|
# perculiar naming scheme is required to make Android preserve these
|
||||||
|
# binaries upon installation.
|
||||||
|
for file in $(CROSS_BINS); do \
|
||||||
|
if [ -x $$file ]; then \
|
||||||
|
filename=`basename $$file`; \
|
||||||
|
cp -f $$file install_temp/lib/$(ANDROID_ABI)/lib$${filename}.so; \
|
||||||
|
fi \
|
||||||
|
done
|
||||||
|
for file in $(CROSS_LIBS); do \
|
||||||
|
if [ -x $$file ]; then \
|
||||||
|
cp -f $$file install_temp/lib/$(ANDROID_ABI); \
|
||||||
|
fi \
|
||||||
|
done
|
||||||
|
# Package everything.
|
||||||
|
$(AAPT) package -I "$(ANDROID_JAR)" -F $@ -f -M AndroidManifest.xml
|
||||||
|
pushd install_temp; $(AAPT) add ../$@ `find lib -type f`; popd
|
||||||
|
pushd install_temp; $(AAPT) add ../$@ `find assets -type f`; popd
|
||||||
|
rm -rf install_temp
|
||||||
|
|
||||||
|
.SUFFIXES: .java .class
|
||||||
|
.java.class &:
|
||||||
|
$(AM_V_JAVAC) $(JAVAC) $(JAVAFLAGS) $<
|
||||||
|
|
||||||
|
# N.B. that find must be called all over again in case javac generated
|
||||||
|
# nested classes.
|
||||||
|
|
||||||
|
classes.dex: $(CLASS_FILES)
|
||||||
|
$(AM_V_DX) $(DX) --classpath $(ANDROID_JAR) \
|
||||||
|
$(subst $$,\$$,$(shell find . -type f -name *.class))
|
||||||
|
|
||||||
|
# When emacs.keystore expires, regenerate it with:
|
||||||
|
#
|
||||||
|
# keytool -genkey -v -keystore emacs.keystore -alias "Emacs keystore" \
|
||||||
|
# -keyalg RSA -sigalg SHA1withRSA -keysize 2048 -validity 100000
|
||||||
|
|
||||||
|
.PHONY: clean maintainer-clean
|
||||||
|
|
||||||
|
emacs.apk: classes.dex emacs.apk-in emacs.keystore
|
||||||
|
cp -f emacs.apk-in $@.unaligned
|
||||||
|
$(AAPT) add $@.unaligned classes.dex
|
||||||
|
$(JARSIGNER) $(SIGN_EMACS) $@.unaligned "Emacs keystore"
|
||||||
|
$(ZIPALIGN) -f 4 $@.unaligned $@
|
||||||
|
rm -f $@.unaligned
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f emacs.apk emacs.apk-in *.dex *.unaligned *.class
|
||||||
|
rm -rf install-temp
|
||||||
|
find . -name '*.class' -delete
|
||||||
|
|
||||||
|
maintainer-clean: clean
|
||||||
6
java/README
Normal file
6
java/README
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
This directory holds the Java sources of the port of GNU Emacs to
|
||||||
|
Android-like systems.
|
||||||
|
|
||||||
|
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.
|
||||||
242
java/debug.sh
Executable file
242
java/debug.sh
Executable file
|
|
@ -0,0 +1,242 @@
|
||||||
|
#!/bin/bash
|
||||||
|
### Run Emacs under GDB or JDB on Android.
|
||||||
|
|
||||||
|
## Copyright (C) 2023 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
## This file is part of GNU Emacs.
|
||||||
|
|
||||||
|
## GNU Emacs is free software: you can redistribute it and/or modify
|
||||||
|
## it under the terms of the GNU General Public License as published by
|
||||||
|
## the Free Software Foundation, either version 3 of the License, or
|
||||||
|
## (at your option) any later version.
|
||||||
|
|
||||||
|
## GNU Emacs is distributed in the hope that it will be useful,
|
||||||
|
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
## GNU General Public License for more details.
|
||||||
|
|
||||||
|
## You should have received a copy of the GNU General Public License
|
||||||
|
## along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
set -m
|
||||||
|
oldpwd=`pwd`
|
||||||
|
cd `dirname $0`
|
||||||
|
|
||||||
|
devices=`adb devices | grep device | awk -- '/device\y/ { print $1 }' -`
|
||||||
|
device=
|
||||||
|
progname=$0
|
||||||
|
package=org.gnu.emacs
|
||||||
|
activity=org.gnu.emacs.EmacsActivity
|
||||||
|
gdb_port=5039
|
||||||
|
jdb_port=64013
|
||||||
|
jdb=no
|
||||||
|
|
||||||
|
while [ $# -gt 0 ]; do
|
||||||
|
case "$1" in
|
||||||
|
## This option specifies the serial number of a device to use.
|
||||||
|
"--device" )
|
||||||
|
device="$2"
|
||||||
|
if [ -z device ]; then
|
||||||
|
echo "You must specify an argument to --device"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
"--help" )
|
||||||
|
echo "Usage: $progname [options] -- [gdb options]"
|
||||||
|
echo ""
|
||||||
|
echo " --device DEVICE run Emacs on the specified device"
|
||||||
|
echo " --port PORT run the GDB server on a specific port"
|
||||||
|
echo " --jdb-port PORT run the JDB server on a specific port"
|
||||||
|
echo " --jdb run JDB instead of GDB"
|
||||||
|
echo " --help print this message"
|
||||||
|
echo ""
|
||||||
|
echo "Available devices:"
|
||||||
|
for device in $devices; do
|
||||||
|
echo " " $device
|
||||||
|
done
|
||||||
|
echo ""
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
"--jdb" )
|
||||||
|
jdb=yes
|
||||||
|
;;
|
||||||
|
"--port" )
|
||||||
|
gdb_port=$1
|
||||||
|
;;
|
||||||
|
"--" )
|
||||||
|
shift
|
||||||
|
gdbargs=$@
|
||||||
|
break;
|
||||||
|
;;
|
||||||
|
* )
|
||||||
|
echo "$progname: Unrecognized argument $1"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z $devices ]; then
|
||||||
|
echo "No devices are available."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z $device ]; then
|
||||||
|
device=$devices
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ `wc -w <<< "$devices"` -gt 1 ] && [ -z device ]; then
|
||||||
|
echo "Multiple devices are available. Please pick one using"
|
||||||
|
echo "--device and try again."
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Looking for $package on device $device"
|
||||||
|
|
||||||
|
# Find the application data directory
|
||||||
|
app_data_dir=`adb -s $device shell run-as $package sh -c 'pwd 2> /dev/null'`
|
||||||
|
|
||||||
|
if [ -z $app_data_dir ]; then
|
||||||
|
echo "The data directory for the package $package was not found."
|
||||||
|
echo "Is it installed?"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Found application data directory at $app_data_dir..."
|
||||||
|
|
||||||
|
# Find which PIDs are associated with org.gnu.emacs
|
||||||
|
package_uid=`adb -s $device shell run-as $package id -u`
|
||||||
|
|
||||||
|
if [ -z $package_uid ]; then
|
||||||
|
echo "Failed to obtain UID of packages named $package"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# First, run ps -u $package_uid -o PID,CMD to fetch the list of
|
||||||
|
# process IDs.
|
||||||
|
package_pids=`adb -s $device shell run-as $package ps -u $package_uid -o PID,CMD`
|
||||||
|
|
||||||
|
# Next, remove lines matching "ps" itself.
|
||||||
|
package_pids=`awk -- '{
|
||||||
|
if (!match ($0, /(PID|ps)/))
|
||||||
|
print $1
|
||||||
|
}' <<< $package_pids`
|
||||||
|
|
||||||
|
# Finally, kill each existing process.
|
||||||
|
for pid in $package_pids; do
|
||||||
|
echo "Killing existing process $pid..."
|
||||||
|
adb -s $device shell run-as $package kill -9 $pid &> /dev/null
|
||||||
|
done
|
||||||
|
|
||||||
|
# Now run the main activity. This must be done as the adb user and
|
||||||
|
# not as the package user.
|
||||||
|
echo "Starting activity $activity and attaching debugger"
|
||||||
|
|
||||||
|
# Exit if the activity could not be started.
|
||||||
|
adb -s $device shell am start -D "$package/$activity"
|
||||||
|
if [ ! $? ]; then
|
||||||
|
exit 1;
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Now look for processes matching the package again.
|
||||||
|
package_pids=`adb -s $device shell run-as $package ps -u $package_uid -o PID,CMD`
|
||||||
|
|
||||||
|
# Next, remove lines matching "ps" itself.
|
||||||
|
package_pids=`awk -- '{
|
||||||
|
if (!match ($0, /(PID|ps)/))
|
||||||
|
print $1
|
||||||
|
}' <<< $package_pids`
|
||||||
|
|
||||||
|
pid=$package_pids
|
||||||
|
num_pids=`wc -w <<< "$package_pids"`
|
||||||
|
|
||||||
|
if [ $num_pids -gt 1 ]; then
|
||||||
|
echo "More than one process was started:"
|
||||||
|
echo ""
|
||||||
|
adb -s $device shell run-as $package ps -u $package_uid | awk -- '{
|
||||||
|
if (!match ($0, /ps/))
|
||||||
|
print $0
|
||||||
|
}'
|
||||||
|
echo ""
|
||||||
|
printf "Which one do you want to attach to? "
|
||||||
|
read pid
|
||||||
|
elif [ -z $package_pids ]; then
|
||||||
|
echo "No processes were found to attach to."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Start JDB to make the wait dialog disappear.
|
||||||
|
echo "Attaching JDB to unblock the application."
|
||||||
|
adb -s $device forward --remove-all
|
||||||
|
adb -s $device forward "tcp:$jdb_port" "jdwp:$pid"
|
||||||
|
|
||||||
|
if [ ! $? ]; then
|
||||||
|
echo "Failed to forward jdwp:$pid to $jdb_port!"
|
||||||
|
echo "Perhaps you need to specify a different port with --port?"
|
||||||
|
exit 1;
|
||||||
|
fi
|
||||||
|
|
||||||
|
jdb_command="jdb -connect \
|
||||||
|
com.sun.jdi.SocketAttach:hostname=localhost,port=$jdb_port"
|
||||||
|
|
||||||
|
if [ $jdb = "yes" ]; then
|
||||||
|
# Just start JDB and then exit
|
||||||
|
$jdb_command
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
exec 4<> /tmp/file-descriptor-stamp
|
||||||
|
|
||||||
|
# Now run JDB with IO redirected to file descriptor 4 in a subprocess.
|
||||||
|
$jdb_command <&4 >&4 &
|
||||||
|
|
||||||
|
character=
|
||||||
|
# Next, wait until the prompt is found.
|
||||||
|
while read -n1 -u 4 character; do
|
||||||
|
if [ "$character" = ">" ]; then
|
||||||
|
echo "JDB attached successfully"
|
||||||
|
break;
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Now start gdbserver on the device asynchronously.
|
||||||
|
|
||||||
|
echo "Attaching gdbserver to $pid on $device..."
|
||||||
|
exec 5<> /tmp/file-descriptor-stamp
|
||||||
|
adb -s $device shell run-as $package /system/bin/gdbserver --once \
|
||||||
|
"+debug.$package_uid.socket" --attach $pid >&5 &
|
||||||
|
|
||||||
|
# Wait until gdbserver successfully runs.
|
||||||
|
line=
|
||||||
|
while read -u 5 line; do
|
||||||
|
case "$line" in
|
||||||
|
*Attached* )
|
||||||
|
break;
|
||||||
|
;;
|
||||||
|
*error* | *Error* | failed )
|
||||||
|
echo $line
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
* )
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# Send EOF to JDB to make it go away. This will also cause Android to
|
||||||
|
# allow Emacs to continue executing.
|
||||||
|
echo "Making JDB go away..."
|
||||||
|
echo "exit" >&4
|
||||||
|
read -u 4 line
|
||||||
|
echo "JDB has gone away with $line"
|
||||||
|
|
||||||
|
# Forward the gdb server port here.
|
||||||
|
adb -s $device forward "tcp:$gdb_port" \
|
||||||
|
"localfilesystem:$app_data_dir/debug.$package_uid.socket"
|
||||||
|
if [ ! $? ]; then
|
||||||
|
echo "Failed to forward $app_data_dir/debug.$package_uid.socket"
|
||||||
|
echo "to $gdb_port! Perhaps you need to specify a different port"
|
||||||
|
echo "with --port?"
|
||||||
|
exit 1;
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Finally, start gdb with any extra arguments needed.
|
||||||
|
cd "$oldpwd"
|
||||||
|
gdb --eval-command "" --eval-command "target remote localhost:$gdb_port" $gdbargs
|
||||||
BIN
java/emacs.keystore
Normal file
BIN
java/emacs.keystore
Normal file
Binary file not shown.
146
java/org/gnu/emacs/EmacsActivity.java
Normal file
146
java/org/gnu/emacs/EmacsActivity.java
Normal file
|
|
@ -0,0 +1,146 @@
|
||||||
|
/* Communication module for Android terminals. -*- c-file-style: "GNU" -*-
|
||||||
|
|
||||||
|
Copyright (C) 2023 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GNU Emacs.
|
||||||
|
|
||||||
|
GNU Emacs is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
your option) any later version.
|
||||||
|
|
||||||
|
GNU Emacs is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
package org.gnu.emacs;
|
||||||
|
|
||||||
|
import java.lang.IllegalStateException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
import android.widget.FrameLayout.LayoutParams;
|
||||||
|
|
||||||
|
public class EmacsActivity extends Activity
|
||||||
|
{
|
||||||
|
public static final String TAG = "EmacsActivity";
|
||||||
|
|
||||||
|
/* List of all activities that do not have an associated
|
||||||
|
EmacsWindow. */
|
||||||
|
public static List<EmacsActivity> availableActivities;
|
||||||
|
|
||||||
|
/* The currently attached EmacsWindow, or null if none. */
|
||||||
|
private EmacsWindow window;
|
||||||
|
|
||||||
|
/* The frame layout associated with the activity. */
|
||||||
|
private FrameLayout layout;
|
||||||
|
|
||||||
|
static
|
||||||
|
{
|
||||||
|
/* Set up the list of available activities. */
|
||||||
|
availableActivities = new ArrayList<EmacsActivity> ();
|
||||||
|
};
|
||||||
|
|
||||||
|
public void
|
||||||
|
attachChild (EmacsWindow child)
|
||||||
|
{
|
||||||
|
if (window != null)
|
||||||
|
throw new IllegalStateException ("trying to attach window when one"
|
||||||
|
+ " already exists");
|
||||||
|
|
||||||
|
/* Record and attach the view. */
|
||||||
|
window = child;
|
||||||
|
layout.addView (window.view);
|
||||||
|
|
||||||
|
/* Remove the objects from the lists of what is available. */
|
||||||
|
EmacsService.availableChildren.remove (child);
|
||||||
|
availableActivities.remove (this);
|
||||||
|
|
||||||
|
/* Now set child->activity. */
|
||||||
|
child.setActivity (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make this activity available for future windows to attach
|
||||||
|
again. */
|
||||||
|
|
||||||
|
public void
|
||||||
|
makeAvailable ()
|
||||||
|
{
|
||||||
|
window = null;
|
||||||
|
|
||||||
|
for (EmacsWindow iterWindow
|
||||||
|
: EmacsService.availableChildren)
|
||||||
|
{
|
||||||
|
synchronized (iterWindow)
|
||||||
|
{
|
||||||
|
if (!iterWindow.isDestroyed ())
|
||||||
|
attachChild (iterWindow);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
availableActivities.add (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void
|
||||||
|
onCreate (Bundle savedInstanceState)
|
||||||
|
{
|
||||||
|
FrameLayout.LayoutParams params;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
/* Make the activity available before starting the
|
||||||
|
service. */
|
||||||
|
makeAvailable ();
|
||||||
|
|
||||||
|
if (EmacsService.SERVICE == null)
|
||||||
|
/* Start the Emacs service now. */
|
||||||
|
startService (new Intent (this, EmacsService.class));
|
||||||
|
|
||||||
|
super.onCreate (savedInstanceState);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void
|
||||||
|
onStop ()
|
||||||
|
{
|
||||||
|
/* The activity is no longer visible. If there is a window
|
||||||
|
attached, detach it. */
|
||||||
|
|
||||||
|
if (window != null)
|
||||||
|
{
|
||||||
|
layout.removeView (window.view);
|
||||||
|
|
||||||
|
/* Notice that the window is already available too. But do
|
||||||
|
not call noticeAvailableChild; that might assign it to some
|
||||||
|
other activity, which behaves badly. */
|
||||||
|
EmacsService.availableChildren.add (window);
|
||||||
|
window = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Finally, remove this activity from the list of available
|
||||||
|
activities. */
|
||||||
|
availableActivities.remove (this);
|
||||||
|
super.onStop ();
|
||||||
|
}
|
||||||
|
};
|
||||||
27
java/org/gnu/emacs/EmacsApplication.java
Normal file
27
java/org/gnu/emacs/EmacsApplication.java
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
/* Communication module for Android terminals. -*- c-file-style: "GNU" -*-
|
||||||
|
|
||||||
|
Copyright (C) 2023 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GNU Emacs.
|
||||||
|
|
||||||
|
GNU Emacs is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
your option) any later version.
|
||||||
|
|
||||||
|
GNU Emacs is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
package org.gnu.emacs;
|
||||||
|
|
||||||
|
import android.app.Application;
|
||||||
|
|
||||||
|
public class EmacsApplication extends Application
|
||||||
|
{
|
||||||
|
/* This class currently does nothing. */
|
||||||
|
};
|
||||||
131
java/org/gnu/emacs/EmacsCopyArea.java
Normal file
131
java/org/gnu/emacs/EmacsCopyArea.java
Normal file
|
|
@ -0,0 +1,131 @@
|
||||||
|
/* Communication module for Android terminals. -*- c-file-style: "GNU" -*-
|
||||||
|
|
||||||
|
Copyright (C) 2023 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GNU Emacs.
|
||||||
|
|
||||||
|
GNU Emacs is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
your option) any later version.
|
||||||
|
|
||||||
|
GNU Emacs is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
package org.gnu.emacs;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.PorterDuff.Mode;
|
||||||
|
import android.graphics.PorterDuffXfermode;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.graphics.Xfermode;
|
||||||
|
|
||||||
|
public class EmacsCopyArea implements EmacsPaintReq
|
||||||
|
{
|
||||||
|
private int src_x, src_y, dest_x, dest_y, width, height;
|
||||||
|
private EmacsDrawable destination, source;
|
||||||
|
private EmacsGC immutableGC;
|
||||||
|
private static Xfermode xorAlu, srcInAlu;
|
||||||
|
|
||||||
|
static
|
||||||
|
{
|
||||||
|
xorAlu = new PorterDuffXfermode (Mode.XOR);
|
||||||
|
srcInAlu = new PorterDuffXfermode (Mode.SRC_IN);
|
||||||
|
};
|
||||||
|
|
||||||
|
public
|
||||||
|
EmacsCopyArea (EmacsDrawable destination, EmacsDrawable source,
|
||||||
|
int src_x, int src_y, int width, int height,
|
||||||
|
int dest_x, int dest_y, EmacsGC immutableGC)
|
||||||
|
{
|
||||||
|
this.destination = destination;
|
||||||
|
this.source = source;
|
||||||
|
this.src_x = src_x;
|
||||||
|
this.src_y = src_y;
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
this.dest_x = dest_x;
|
||||||
|
this.dest_y = dest_y;
|
||||||
|
this.immutableGC = immutableGC;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Rect
|
||||||
|
getRect ()
|
||||||
|
{
|
||||||
|
return new Rect (dest_x, dest_y, dest_x + width,
|
||||||
|
dest_y + height);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EmacsDrawable
|
||||||
|
getDrawable ()
|
||||||
|
{
|
||||||
|
return destination;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EmacsGC
|
||||||
|
getGC ()
|
||||||
|
{
|
||||||
|
return immutableGC;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void
|
||||||
|
paintTo (Canvas canvas, Paint paint, EmacsGC immutableGC)
|
||||||
|
{
|
||||||
|
int alu;
|
||||||
|
Bitmap bitmap;
|
||||||
|
Paint maskPaint;
|
||||||
|
Canvas maskCanvas;
|
||||||
|
Bitmap maskBitmap;
|
||||||
|
Rect rect, srcRect;
|
||||||
|
|
||||||
|
/* TODO implement stippling. */
|
||||||
|
if (immutableGC.fill_style == EmacsGC.GC_FILL_OPAQUE_STIPPLED)
|
||||||
|
return;
|
||||||
|
|
||||||
|
alu = immutableGC.function;
|
||||||
|
rect = getRect ();
|
||||||
|
bitmap = source.getBitmap ();
|
||||||
|
|
||||||
|
if (alu == EmacsGC.GC_COPY)
|
||||||
|
paint.setXfermode (null);
|
||||||
|
else
|
||||||
|
paint.setXfermode (xorAlu);
|
||||||
|
|
||||||
|
if (immutableGC.clip_mask == null)
|
||||||
|
canvas.drawBitmap (bitmap, new Rect (src_x, src_y,
|
||||||
|
src_x + width,
|
||||||
|
src_y + height),
|
||||||
|
rect, paint);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
maskPaint = new Paint ();
|
||||||
|
srcRect = new Rect (0, 0, rect.width (),
|
||||||
|
rect.height ());
|
||||||
|
maskBitmap
|
||||||
|
= immutableGC.clip_mask.bitmap.copy (Bitmap.Config.ARGB_8888,
|
||||||
|
true);
|
||||||
|
|
||||||
|
if (maskBitmap == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
maskPaint.setXfermode (srcInAlu);
|
||||||
|
maskCanvas = new Canvas (maskBitmap);
|
||||||
|
maskCanvas.drawBitmap (bitmap, new Rect (src_x, src_y,
|
||||||
|
src_x + width,
|
||||||
|
src_y + height),
|
||||||
|
srcRect, maskPaint);
|
||||||
|
canvas.drawBitmap (maskBitmap, srcRect, rect, paint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
137
java/org/gnu/emacs/EmacsDrawLine.java
Normal file
137
java/org/gnu/emacs/EmacsDrawLine.java
Normal file
|
|
@ -0,0 +1,137 @@
|
||||||
|
/* Communication module for Android terminals. -*- c-file-style: "GNU" -*-
|
||||||
|
|
||||||
|
Copyright (C) 2023 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GNU Emacs.
|
||||||
|
|
||||||
|
GNU Emacs is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
your option) any later version.
|
||||||
|
|
||||||
|
GNU Emacs is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
package org.gnu.emacs;
|
||||||
|
|
||||||
|
import java.lang.Math;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.PorterDuff.Mode;
|
||||||
|
import android.graphics.PorterDuffXfermode;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.graphics.Xfermode;
|
||||||
|
|
||||||
|
public class EmacsDrawLine implements EmacsPaintReq
|
||||||
|
{
|
||||||
|
private int x, y, x2, y2;
|
||||||
|
private EmacsDrawable drawable;
|
||||||
|
private EmacsGC immutableGC;
|
||||||
|
private static Xfermode xorAlu, srcInAlu;
|
||||||
|
|
||||||
|
static
|
||||||
|
{
|
||||||
|
xorAlu = new PorterDuffXfermode (Mode.XOR);
|
||||||
|
srcInAlu = new PorterDuffXfermode (Mode.SRC_IN);
|
||||||
|
};
|
||||||
|
|
||||||
|
public
|
||||||
|
EmacsDrawLine (EmacsDrawable drawable, int x, int y,
|
||||||
|
int x2, int y2, EmacsGC immutableGC)
|
||||||
|
{
|
||||||
|
this.drawable = drawable;
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.x2 = x2;
|
||||||
|
this.y2 = y2;
|
||||||
|
this.immutableGC = immutableGC;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Rect
|
||||||
|
getRect ()
|
||||||
|
{
|
||||||
|
return new Rect (Math.min (x, x2 + 1),
|
||||||
|
Math.min (y, y2 + 1),
|
||||||
|
Math.max (x2 + 1, x),
|
||||||
|
Math.max (y2 + 1, y));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EmacsDrawable
|
||||||
|
getDrawable ()
|
||||||
|
{
|
||||||
|
return drawable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EmacsGC
|
||||||
|
getGC ()
|
||||||
|
{
|
||||||
|
return immutableGC;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void
|
||||||
|
paintTo (Canvas canvas, Paint paint, EmacsGC immutableGC)
|
||||||
|
{
|
||||||
|
int alu;
|
||||||
|
Paint maskPaint;
|
||||||
|
Canvas maskCanvas;
|
||||||
|
Bitmap maskBitmap;
|
||||||
|
Rect rect, srcRect;
|
||||||
|
int width, height;
|
||||||
|
|
||||||
|
/* TODO implement stippling. */
|
||||||
|
if (immutableGC.fill_style == EmacsGC.GC_FILL_OPAQUE_STIPPLED)
|
||||||
|
return;
|
||||||
|
|
||||||
|
alu = immutableGC.function;
|
||||||
|
rect = getRect ();
|
||||||
|
width = rect.width ();
|
||||||
|
height = rect.height ();
|
||||||
|
|
||||||
|
paint.setStyle (Paint.Style.STROKE);
|
||||||
|
|
||||||
|
if (alu == EmacsGC.GC_COPY)
|
||||||
|
paint.setXfermode (null);
|
||||||
|
else
|
||||||
|
paint.setXfermode (xorAlu);
|
||||||
|
|
||||||
|
if (immutableGC.clip_mask == null)
|
||||||
|
{
|
||||||
|
paint.setColor (immutableGC.foreground | 0xff000000);
|
||||||
|
canvas.drawLine ((float) x, (float) y,
|
||||||
|
(float) x2, (float) y2,
|
||||||
|
paint);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
maskPaint = new Paint ();
|
||||||
|
maskBitmap
|
||||||
|
= immutableGC.clip_mask.bitmap.copy (Bitmap.Config.ARGB_8888,
|
||||||
|
true);
|
||||||
|
|
||||||
|
if (maskBitmap == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
maskPaint.setXfermode (srcInAlu);
|
||||||
|
maskPaint.setColor (immutableGC.foreground | 0xff000000);
|
||||||
|
maskCanvas = new Canvas (maskBitmap);
|
||||||
|
srcRect = new Rect (0, 0, maskBitmap.getWidth (),
|
||||||
|
maskBitmap.getHeight ());
|
||||||
|
maskCanvas.drawLine (0.0f, 0.0f, (float) Math.abs (x - x2),
|
||||||
|
(float) Math.abs (y - y2), maskPaint);
|
||||||
|
canvas.drawBitmap (maskBitmap, srcRect, rect, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
paint.setXfermode (null);
|
||||||
|
}
|
||||||
|
}
|
||||||
30
java/org/gnu/emacs/EmacsDrawPoint.java
Normal file
30
java/org/gnu/emacs/EmacsDrawPoint.java
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
/* Communication module for Android terminals. -*- c-file-style: "GNU" -*-
|
||||||
|
|
||||||
|
Copyright (C) 2023 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GNU Emacs.
|
||||||
|
|
||||||
|
GNU Emacs is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
your option) any later version.
|
||||||
|
|
||||||
|
GNU Emacs is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
package org.gnu.emacs;
|
||||||
|
|
||||||
|
public class EmacsDrawPoint extends EmacsDrawRectangle
|
||||||
|
{
|
||||||
|
public
|
||||||
|
EmacsDrawPoint (EmacsDrawable drawable, int x, int y,
|
||||||
|
EmacsGC immutableGC)
|
||||||
|
{
|
||||||
|
super (drawable, x, y, 1, 1, immutableGC);
|
||||||
|
}
|
||||||
|
}
|
||||||
127
java/org/gnu/emacs/EmacsDrawRectangle.java
Normal file
127
java/org/gnu/emacs/EmacsDrawRectangle.java
Normal file
|
|
@ -0,0 +1,127 @@
|
||||||
|
/* Communication module for Android terminals. -*- c-file-style: "GNU" -*-
|
||||||
|
|
||||||
|
Copyright (C) 2023 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GNU Emacs.
|
||||||
|
|
||||||
|
GNU Emacs is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
your option) any later version.
|
||||||
|
|
||||||
|
GNU Emacs is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
package org.gnu.emacs;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.PorterDuff.Mode;
|
||||||
|
import android.graphics.PorterDuffXfermode;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.graphics.Xfermode;
|
||||||
|
|
||||||
|
public class EmacsDrawRectangle implements EmacsPaintReq
|
||||||
|
{
|
||||||
|
private int x, y, width, height;
|
||||||
|
private EmacsDrawable drawable;
|
||||||
|
private EmacsGC immutableGC;
|
||||||
|
private static Xfermode xorAlu, srcInAlu;
|
||||||
|
|
||||||
|
static
|
||||||
|
{
|
||||||
|
xorAlu = new PorterDuffXfermode (Mode.XOR);
|
||||||
|
srcInAlu = new PorterDuffXfermode (Mode.SRC_IN);
|
||||||
|
};
|
||||||
|
|
||||||
|
public
|
||||||
|
EmacsDrawRectangle (EmacsDrawable drawable, int x, int y,
|
||||||
|
int width, int height,
|
||||||
|
EmacsGC immutableGC)
|
||||||
|
{
|
||||||
|
this.drawable = drawable;
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
this.immutableGC = immutableGC;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Rect
|
||||||
|
getRect ()
|
||||||
|
{
|
||||||
|
return new Rect (x, y, x + width, y + height);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EmacsDrawable
|
||||||
|
getDrawable ()
|
||||||
|
{
|
||||||
|
return drawable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EmacsGC
|
||||||
|
getGC ()
|
||||||
|
{
|
||||||
|
return immutableGC;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void
|
||||||
|
paintTo (Canvas canvas, Paint paint, EmacsGC immutableGC)
|
||||||
|
{
|
||||||
|
int alu;
|
||||||
|
Paint maskPaint;
|
||||||
|
Canvas maskCanvas;
|
||||||
|
Bitmap maskBitmap;
|
||||||
|
Rect rect, srcRect;
|
||||||
|
|
||||||
|
/* TODO implement stippling. */
|
||||||
|
if (immutableGC.fill_style == EmacsGC.GC_FILL_OPAQUE_STIPPLED)
|
||||||
|
return;
|
||||||
|
|
||||||
|
alu = immutableGC.function;
|
||||||
|
rect = getRect ();
|
||||||
|
|
||||||
|
paint.setStyle (Paint.Style.STROKE);
|
||||||
|
|
||||||
|
if (alu == EmacsGC.GC_COPY)
|
||||||
|
paint.setXfermode (null);
|
||||||
|
else
|
||||||
|
paint.setXfermode (xorAlu);
|
||||||
|
|
||||||
|
if (immutableGC.clip_mask == null)
|
||||||
|
{
|
||||||
|
paint.setColor (immutableGC.foreground | 0xff000000);
|
||||||
|
canvas.drawRect (rect, paint);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
maskPaint = new Paint ();
|
||||||
|
maskBitmap
|
||||||
|
= immutableGC.clip_mask.bitmap.copy (Bitmap.Config.ARGB_8888,
|
||||||
|
true);
|
||||||
|
|
||||||
|
if (maskBitmap == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
maskPaint.setXfermode (srcInAlu);
|
||||||
|
maskPaint.setColor (immutableGC.foreground | 0xff000000);
|
||||||
|
maskCanvas = new Canvas (maskBitmap);
|
||||||
|
srcRect = new Rect (0, 0, maskBitmap.getWidth (),
|
||||||
|
maskBitmap.getHeight ());
|
||||||
|
maskCanvas.drawRect (srcRect, maskPaint);
|
||||||
|
canvas.drawBitmap (maskBitmap, srcRect, rect, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
paint.setXfermode (null);
|
||||||
|
}
|
||||||
|
}
|
||||||
33
java/org/gnu/emacs/EmacsDrawable.java
Normal file
33
java/org/gnu/emacs/EmacsDrawable.java
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
/* Communication module for Android terminals. -*- c-file-style: "GNU" -*-
|
||||||
|
|
||||||
|
Copyright (C) 2023 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GNU Emacs.
|
||||||
|
|
||||||
|
GNU Emacs is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
your option) any later version.
|
||||||
|
|
||||||
|
GNU Emacs is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
package org.gnu.emacs;
|
||||||
|
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
|
||||||
|
public interface EmacsDrawable
|
||||||
|
{
|
||||||
|
public Canvas lockCanvas ();
|
||||||
|
public void unlockCanvas ();
|
||||||
|
public void damageRect (Rect damageRect);
|
||||||
|
public Bitmap getBitmap ();
|
||||||
|
public boolean isDestroyed ();
|
||||||
|
};
|
||||||
150
java/org/gnu/emacs/EmacsFillPolygon.java
Normal file
150
java/org/gnu/emacs/EmacsFillPolygon.java
Normal file
|
|
@ -0,0 +1,150 @@
|
||||||
|
/* Communication module for Android terminals. -*- c-file-style: "GNU" -*-
|
||||||
|
|
||||||
|
Copyright (C) 2023 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GNU Emacs.
|
||||||
|
|
||||||
|
GNU Emacs is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
your option) any later version.
|
||||||
|
|
||||||
|
GNU Emacs is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
package org.gnu.emacs;
|
||||||
|
|
||||||
|
import java.lang.Math;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.Path;
|
||||||
|
import android.graphics.Point;
|
||||||
|
import android.graphics.PorterDuff.Mode;
|
||||||
|
import android.graphics.PorterDuffXfermode;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.graphics.RectF;
|
||||||
|
import android.graphics.Xfermode;
|
||||||
|
|
||||||
|
public class EmacsFillPolygon implements EmacsPaintReq
|
||||||
|
{
|
||||||
|
private EmacsDrawable drawable;
|
||||||
|
private EmacsGC immutableGC;
|
||||||
|
private Path path;
|
||||||
|
|
||||||
|
private static Xfermode xorAlu, srcInAlu;
|
||||||
|
|
||||||
|
static
|
||||||
|
{
|
||||||
|
xorAlu = new PorterDuffXfermode (Mode.XOR);
|
||||||
|
srcInAlu = new PorterDuffXfermode (Mode.SRC_IN);
|
||||||
|
};
|
||||||
|
|
||||||
|
public
|
||||||
|
EmacsFillPolygon (EmacsDrawable drawable, Point points[],
|
||||||
|
EmacsGC immutableGC)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
this.drawable = drawable;
|
||||||
|
this.immutableGC = immutableGC;
|
||||||
|
|
||||||
|
/* Build the path from the given array of points. */
|
||||||
|
path = new Path ();
|
||||||
|
|
||||||
|
if (points.length >= 1)
|
||||||
|
{
|
||||||
|
path.moveTo (points[0].x, points[0].y);
|
||||||
|
|
||||||
|
for (i = 1; i < points.length; ++i)
|
||||||
|
path.lineTo (points[i].x, points[i].y);
|
||||||
|
|
||||||
|
path.close ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Rect
|
||||||
|
getRect ()
|
||||||
|
{
|
||||||
|
RectF rect;
|
||||||
|
|
||||||
|
rect = new RectF (0, 0, 0, 0);
|
||||||
|
path.computeBounds (rect, true);
|
||||||
|
|
||||||
|
return new Rect ((int) Math.floor (rect.left),
|
||||||
|
(int) Math.floor (rect.top),
|
||||||
|
(int) Math.ceil (rect.right),
|
||||||
|
(int) Math.ceil (rect.bottom));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EmacsDrawable
|
||||||
|
getDrawable ()
|
||||||
|
{
|
||||||
|
return drawable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EmacsGC
|
||||||
|
getGC ()
|
||||||
|
{
|
||||||
|
return immutableGC;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void
|
||||||
|
paintTo (Canvas canvas, Paint paint, EmacsGC immutableGC)
|
||||||
|
{
|
||||||
|
int alu;
|
||||||
|
Paint maskPaint;
|
||||||
|
Canvas maskCanvas;
|
||||||
|
Bitmap maskBitmap;
|
||||||
|
Rect rect;
|
||||||
|
|
||||||
|
/* TODO implement stippling. */
|
||||||
|
if (immutableGC.fill_style == EmacsGC.GC_FILL_OPAQUE_STIPPLED)
|
||||||
|
return;
|
||||||
|
|
||||||
|
alu = immutableGC.function;
|
||||||
|
rect = getRect ();
|
||||||
|
|
||||||
|
if (alu == EmacsGC.GC_COPY)
|
||||||
|
paint.setXfermode (null);
|
||||||
|
else
|
||||||
|
paint.setXfermode (xorAlu);
|
||||||
|
|
||||||
|
paint.setStyle (Paint.Style.FILL);
|
||||||
|
|
||||||
|
if (immutableGC.clip_mask == null)
|
||||||
|
{
|
||||||
|
paint.setColor (immutableGC.foreground | 0xff000000);
|
||||||
|
canvas.drawPath (path, paint);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
maskPaint = new Paint ();
|
||||||
|
maskBitmap = immutableGC.clip_mask.bitmap;
|
||||||
|
maskBitmap = maskBitmap.copy (Bitmap.Config.ARGB_8888,
|
||||||
|
true);
|
||||||
|
|
||||||
|
if (maskBitmap == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
maskPaint.setXfermode (srcInAlu);
|
||||||
|
maskPaint.setColor (immutableGC.foreground | 0xff000000);
|
||||||
|
maskCanvas = new Canvas (maskBitmap);
|
||||||
|
path.offset (-rect.left, -rect.top, null);
|
||||||
|
maskCanvas.drawPath (path, maskPaint);
|
||||||
|
canvas.drawBitmap (maskBitmap, new Rect (0, 0, rect.width (),
|
||||||
|
rect.height ()),
|
||||||
|
rect, paint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
129
java/org/gnu/emacs/EmacsFillRectangle.java
Normal file
129
java/org/gnu/emacs/EmacsFillRectangle.java
Normal file
|
|
@ -0,0 +1,129 @@
|
||||||
|
/* Communication module for Android terminals. -*- c-file-style: "GNU" -*-
|
||||||
|
|
||||||
|
Copyright (C) 2023 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GNU Emacs.
|
||||||
|
|
||||||
|
GNU Emacs is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
your option) any later version.
|
||||||
|
|
||||||
|
GNU Emacs is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
package org.gnu.emacs;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.PorterDuff.Mode;
|
||||||
|
import android.graphics.PorterDuffXfermode;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.graphics.Xfermode;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
public class EmacsFillRectangle implements EmacsPaintReq
|
||||||
|
{
|
||||||
|
private int x, y, width, height;
|
||||||
|
private EmacsDrawable drawable;
|
||||||
|
private EmacsGC immutableGC;
|
||||||
|
private static Xfermode xorAlu, srcInAlu;
|
||||||
|
|
||||||
|
static
|
||||||
|
{
|
||||||
|
xorAlu = new PorterDuffXfermode (Mode.XOR);
|
||||||
|
srcInAlu = new PorterDuffXfermode (Mode.SRC_IN);
|
||||||
|
};
|
||||||
|
|
||||||
|
public
|
||||||
|
EmacsFillRectangle (EmacsDrawable drawable, int x, int y,
|
||||||
|
int width, int height,
|
||||||
|
EmacsGC immutableGC)
|
||||||
|
{
|
||||||
|
this.drawable = drawable;
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
this.immutableGC = immutableGC;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Rect
|
||||||
|
getRect ()
|
||||||
|
{
|
||||||
|
return new Rect (x, y, x + width, y + height);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EmacsDrawable
|
||||||
|
getDrawable ()
|
||||||
|
{
|
||||||
|
return drawable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EmacsGC
|
||||||
|
getGC ()
|
||||||
|
{
|
||||||
|
return immutableGC;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void
|
||||||
|
paintTo (Canvas canvas, Paint paint, EmacsGC immutableGC)
|
||||||
|
{
|
||||||
|
int alu;
|
||||||
|
Paint maskPaint;
|
||||||
|
Canvas maskCanvas;
|
||||||
|
Bitmap maskBitmap;
|
||||||
|
Rect rect, srcRect;
|
||||||
|
|
||||||
|
/* TODO implement stippling. */
|
||||||
|
if (immutableGC.fill_style == EmacsGC.GC_FILL_OPAQUE_STIPPLED)
|
||||||
|
return;
|
||||||
|
|
||||||
|
alu = immutableGC.function;
|
||||||
|
rect = getRect ();
|
||||||
|
|
||||||
|
paint.setStyle (Paint.Style.FILL);
|
||||||
|
|
||||||
|
if (alu == EmacsGC.GC_COPY)
|
||||||
|
paint.setXfermode (null);
|
||||||
|
else
|
||||||
|
paint.setXfermode (xorAlu);
|
||||||
|
|
||||||
|
if (immutableGC.clip_mask == null)
|
||||||
|
{
|
||||||
|
paint.setColor (immutableGC.foreground | 0xff000000);
|
||||||
|
canvas.drawRect (rect, paint);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
maskPaint = new Paint ();
|
||||||
|
maskBitmap
|
||||||
|
= immutableGC.clip_mask.bitmap.copy (Bitmap.Config.ARGB_8888,
|
||||||
|
true);
|
||||||
|
|
||||||
|
if (maskBitmap == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
maskPaint.setXfermode (srcInAlu);
|
||||||
|
maskPaint.setColor (immutableGC.foreground | 0xff000000);
|
||||||
|
maskCanvas = new Canvas (maskBitmap);
|
||||||
|
srcRect = new Rect (0, 0, maskBitmap.getWidth (),
|
||||||
|
maskBitmap.getHeight ());
|
||||||
|
maskCanvas.drawRect (srcRect, maskPaint);
|
||||||
|
canvas.drawBitmap (maskBitmap, srcRect, rect, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
paint.setXfermode (null);
|
||||||
|
}
|
||||||
|
}
|
||||||
150
java/org/gnu/emacs/EmacsFontDriver.java
Normal file
150
java/org/gnu/emacs/EmacsFontDriver.java
Normal file
|
|
@ -0,0 +1,150 @@
|
||||||
|
/* Font backend for Android terminals. -*- c-file-style: "GNU" -*-
|
||||||
|
|
||||||
|
Copyright (C) 2023 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GNU Emacs.
|
||||||
|
|
||||||
|
GNU Emacs is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
your option) any later version.
|
||||||
|
|
||||||
|
GNU Emacs is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
package org.gnu.emacs;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public abstract class EmacsFontDriver
|
||||||
|
{
|
||||||
|
/* Font weights. */
|
||||||
|
public static final int THIN = 0;
|
||||||
|
public static final int ULTRA_LIGHT = 40;
|
||||||
|
public static final int LIGHT = 50;
|
||||||
|
public static final int SEMI_LIGHT = 55;
|
||||||
|
public static final int REGULAR = 80;
|
||||||
|
public static final int MEDIUM = 100;
|
||||||
|
public static final int SEMI_BOLD = 180;
|
||||||
|
public static final int BOLD = 200;
|
||||||
|
public static final int EXTRA_BOLD = 205;
|
||||||
|
public static final int BLACK = 210;
|
||||||
|
public static final int ULTRA_HEAVY = 250;
|
||||||
|
|
||||||
|
/* Font slants. */
|
||||||
|
public static final int REVERSE_OBLIQUE = 0;
|
||||||
|
public static final int REVERSE_ITALIC = 10;
|
||||||
|
public static final int NORMAL = 100;
|
||||||
|
public static final int ITALIC = 200;
|
||||||
|
public static final int OBLIQUE = 210;
|
||||||
|
|
||||||
|
/* Font widths. */
|
||||||
|
public static final int ULTRA_CONDENSED = 50;
|
||||||
|
public static final int EXTRA_CONDENSED = 63;
|
||||||
|
public static final int CONDENSED = 75;
|
||||||
|
public static final int SEMI_CONDENSED = 87;
|
||||||
|
public static final int UNSPECIFIED = 100;
|
||||||
|
public static final int SEMI_EXPANDED = 113;
|
||||||
|
public static final int EXPANDED = 125;
|
||||||
|
public static final int EXTRA_EXPANDED = 150;
|
||||||
|
public static final int ULTRA_EXPANDED = 200;
|
||||||
|
|
||||||
|
/* Font spacings. */
|
||||||
|
public static final int PROPORTIONAL = 0;
|
||||||
|
public static final int DUAL = 90;
|
||||||
|
public static final int MONO = 100;
|
||||||
|
public static final int CHARCELL = 110;
|
||||||
|
|
||||||
|
public class FontSpec
|
||||||
|
{
|
||||||
|
/* The fields below mean the same as they do in enum
|
||||||
|
font_property_index in font.h. */
|
||||||
|
|
||||||
|
public String foundry;
|
||||||
|
public String family;
|
||||||
|
public String adstyle;
|
||||||
|
public String registry;
|
||||||
|
public Integer width;
|
||||||
|
public Integer weight;
|
||||||
|
public Integer slant;
|
||||||
|
public Integer size;
|
||||||
|
public Integer spacing;
|
||||||
|
public Integer avgwidth;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String
|
||||||
|
toString ()
|
||||||
|
{
|
||||||
|
return ("foundry: " + foundry
|
||||||
|
+ " family: " + family
|
||||||
|
+ " adstyle: " + adstyle
|
||||||
|
+ " registry: " + registry
|
||||||
|
+ " width: " + width
|
||||||
|
+ " weight: " + weight
|
||||||
|
+ " slant: " + slant
|
||||||
|
+ " spacing: " + spacing
|
||||||
|
+ " avgwidth: " + avgwidth);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public class FontMetrics
|
||||||
|
{
|
||||||
|
public short lbearing;
|
||||||
|
public short rbearing;
|
||||||
|
public short width;
|
||||||
|
public short ascent;
|
||||||
|
public short descent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class FontEntity extends FontSpec
|
||||||
|
{
|
||||||
|
/* No extra fields here. */
|
||||||
|
};
|
||||||
|
|
||||||
|
public abstract class FontObject extends FontSpec
|
||||||
|
{
|
||||||
|
public int minWidth;
|
||||||
|
public int maxWidth;
|
||||||
|
public int pixelSize;
|
||||||
|
public int height;
|
||||||
|
public int spaceWidth;
|
||||||
|
public int averageWidth;
|
||||||
|
public int ascent;
|
||||||
|
public int descent;
|
||||||
|
public int underlineThickness;
|
||||||
|
public int underlinePosition;
|
||||||
|
public int baselineOffset;
|
||||||
|
public int relativeCompose;
|
||||||
|
public int defaultAscent;
|
||||||
|
public int encodingCharset;
|
||||||
|
public int repertoryCharset;
|
||||||
|
|
||||||
|
public
|
||||||
|
FontObject ()
|
||||||
|
{
|
||||||
|
encodingCharset = -1;
|
||||||
|
repertoryCharset = -1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* These mean the same as they do in struct font_driver. */
|
||||||
|
public abstract FontEntity[] list (FontSpec fontSpec);
|
||||||
|
public abstract FontEntity match (FontSpec fontSpec);
|
||||||
|
public abstract String[] listFamilies ();
|
||||||
|
public abstract FontObject openFont (FontEntity fontEntity, int pixelSize);
|
||||||
|
public abstract int hasChar (FontSpec font, char charCode);
|
||||||
|
public abstract void textExtents (FontObject font, int code[],
|
||||||
|
FontMetrics fontMetrics[]);
|
||||||
|
public abstract int encodeChar (FontObject fontObject, char charCode);
|
||||||
|
|
||||||
|
public static EmacsFontDriver
|
||||||
|
createFontDriver ()
|
||||||
|
{
|
||||||
|
return new EmacsSdk7FontDriver ();
|
||||||
|
}
|
||||||
|
};
|
||||||
116
java/org/gnu/emacs/EmacsGC.java
Normal file
116
java/org/gnu/emacs/EmacsGC.java
Normal file
|
|
@ -0,0 +1,116 @@
|
||||||
|
/* Communication module for Android terminals. -*- c-file-style: "GNU" -*-
|
||||||
|
|
||||||
|
Copyright (C) 2023 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GNU Emacs.
|
||||||
|
|
||||||
|
GNU Emacs is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
your option) any later version.
|
||||||
|
|
||||||
|
GNU Emacs is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
package org.gnu.emacs;
|
||||||
|
|
||||||
|
import android.graphics.Rect;
|
||||||
|
|
||||||
|
/* X like graphics context structures. Keep the enums in synch with
|
||||||
|
androidgui.h! */
|
||||||
|
|
||||||
|
public class EmacsGC extends EmacsHandleObject
|
||||||
|
{
|
||||||
|
public static final int GC_COPY = 0;
|
||||||
|
public static final int GC_XOR = 1;
|
||||||
|
|
||||||
|
public static final int GC_FILL_SOLID = 0;
|
||||||
|
public static final int GC_FILL_OPAQUE_STIPPLED = 1;
|
||||||
|
|
||||||
|
public int function, fill_style;
|
||||||
|
public int foreground, background;
|
||||||
|
public int clip_x_origin, clip_y_origin;
|
||||||
|
public int ts_origin_x, ts_origin_y;
|
||||||
|
public Rect clip_rects[];
|
||||||
|
public EmacsPixmap clip_mask, stipple;
|
||||||
|
private boolean dirty;
|
||||||
|
private EmacsGC immutableGC;
|
||||||
|
|
||||||
|
/* The following fields are only set on immutable GCs. */
|
||||||
|
|
||||||
|
public
|
||||||
|
EmacsGC (short handle)
|
||||||
|
{
|
||||||
|
/* For historical reasons the C code has an extra layer of
|
||||||
|
indirection above this GC handle. struct android_gc is the GC
|
||||||
|
used by Emacs code, while android_gcontext is the type of the
|
||||||
|
handle. */
|
||||||
|
super (handle);
|
||||||
|
|
||||||
|
fill_style = GC_FILL_SOLID;
|
||||||
|
function = GC_COPY;
|
||||||
|
foreground = 0;
|
||||||
|
background = 0xffffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
public
|
||||||
|
EmacsGC (EmacsGC source)
|
||||||
|
{
|
||||||
|
super ((short) 0);
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
function = source.function;
|
||||||
|
fill_style = source.fill_style;
|
||||||
|
foreground = source.foreground;
|
||||||
|
background = source.background;
|
||||||
|
clip_x_origin = source.clip_x_origin;
|
||||||
|
clip_y_origin = source.clip_y_origin;
|
||||||
|
clip_rects = source.clip_rects;
|
||||||
|
clip_mask = source.clip_mask;
|
||||||
|
stipple = source.stipple;
|
||||||
|
ts_origin_x = source.ts_origin_x;
|
||||||
|
ts_origin_y = source.ts_origin_y;
|
||||||
|
|
||||||
|
/* Offset all the clip rects by ts_origin_x and ts_origin_y. */
|
||||||
|
|
||||||
|
if ((ts_origin_x != 0 || ts_origin_y != 0)
|
||||||
|
&& clip_rects != null)
|
||||||
|
{
|
||||||
|
clip_rects = new Rect[clip_rects.length];
|
||||||
|
|
||||||
|
for (i = 0; i < clip_rects.length; ++i)
|
||||||
|
{
|
||||||
|
clip_rects[i] = new Rect (source.clip_rects[i]);
|
||||||
|
clip_rects[i].offset (ts_origin_x,
|
||||||
|
ts_origin_y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mark this GC as dirty. This means immutableGC will return a new
|
||||||
|
copy of this GC the next time it is called. */
|
||||||
|
|
||||||
|
public void
|
||||||
|
markDirty ()
|
||||||
|
{
|
||||||
|
dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EmacsGC
|
||||||
|
immutableGC ()
|
||||||
|
{
|
||||||
|
if (immutableGC == null || dirty)
|
||||||
|
{
|
||||||
|
immutableGC = new EmacsGC (this);
|
||||||
|
dirty = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return immutableGC;
|
||||||
|
};
|
||||||
|
};
|
||||||
62
java/org/gnu/emacs/EmacsHandleObject.java
Normal file
62
java/org/gnu/emacs/EmacsHandleObject.java
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
/* Communication module for Android terminals. -*- c-file-style: "GNU" -*-
|
||||||
|
|
||||||
|
Copyright (C) 2023 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GNU Emacs.
|
||||||
|
|
||||||
|
GNU Emacs is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
your option) any later version.
|
||||||
|
|
||||||
|
GNU Emacs is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
package org.gnu.emacs;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.lang.Object;
|
||||||
|
import java.lang.IllegalStateException;
|
||||||
|
|
||||||
|
/* This defines something that is a so-called ``handle''. Handles
|
||||||
|
must be created by C code, and will remain existing until
|
||||||
|
destroyHandle is called. C code then refers to the handle by a
|
||||||
|
number which maps into the Java object representing the handle.
|
||||||
|
|
||||||
|
All handle operations must be done from the Emacs thread. */
|
||||||
|
|
||||||
|
public abstract class EmacsHandleObject
|
||||||
|
{
|
||||||
|
/* Whether or not this handle has been destroyed. */
|
||||||
|
volatile boolean destroyed;
|
||||||
|
|
||||||
|
/* The handle associated with this object. */
|
||||||
|
public short handle;
|
||||||
|
|
||||||
|
public
|
||||||
|
EmacsHandleObject (short handle)
|
||||||
|
{
|
||||||
|
this.handle = handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void
|
||||||
|
destroyHandle () throws IllegalStateException
|
||||||
|
{
|
||||||
|
synchronized (this)
|
||||||
|
{
|
||||||
|
destroyed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean
|
||||||
|
isDestroyed ()
|
||||||
|
{
|
||||||
|
return destroyed;
|
||||||
|
}
|
||||||
|
};
|
||||||
72
java/org/gnu/emacs/EmacsNative.java
Normal file
72
java/org/gnu/emacs/EmacsNative.java
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
/* Communication module for Android terminals. -*- c-file-style: "GNU" -*-
|
||||||
|
|
||||||
|
Copyright (C) 2023 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GNU Emacs.
|
||||||
|
|
||||||
|
GNU Emacs is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
your option) any later version.
|
||||||
|
|
||||||
|
GNU Emacs is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
package org.gnu.emacs;
|
||||||
|
|
||||||
|
import java.lang.System;
|
||||||
|
|
||||||
|
import android.content.res.AssetManager;
|
||||||
|
|
||||||
|
public class EmacsNative
|
||||||
|
{
|
||||||
|
/* Set certain parameters before initializing Emacs. This proves
|
||||||
|
that libemacs.so is being loaded from Java code.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
emacsService must be the emacsService singleton. */
|
||||||
|
public static native void setEmacsParams (AssetManager assetManager,
|
||||||
|
String filesDir,
|
||||||
|
String libDir,
|
||||||
|
EmacsService emacsService);
|
||||||
|
|
||||||
|
/* Initialize Emacs with the argument array ARGV. Each argument
|
||||||
|
must contain a NULL terminated string, or else the behavior is
|
||||||
|
undefined. */
|
||||||
|
public static native void initEmacs (String argv[]);
|
||||||
|
|
||||||
|
/* Abort and generate a native core dump. */
|
||||||
|
public static native void emacsAbort ();
|
||||||
|
|
||||||
|
/* Send an ANDROID_CONFIGURE_NOTIFY event. */
|
||||||
|
public static native void sendConfigureNotify (short window, long time,
|
||||||
|
int x, int y, int width,
|
||||||
|
int height);
|
||||||
|
|
||||||
|
/* Send an ANDROID_KEY_PRESS event. */
|
||||||
|
public static native void sendKeyPress (short window, long time, int state,
|
||||||
|
int keyCode);
|
||||||
|
|
||||||
|
/* Send an ANDROID_KEY_RELEASE event. */
|
||||||
|
public static native void sendKeyRelease (short window, long time, int state,
|
||||||
|
int keyRelease);
|
||||||
|
|
||||||
|
static
|
||||||
|
{
|
||||||
|
System.loadLibrary ("emacs");
|
||||||
|
};
|
||||||
|
};
|
||||||
138
java/org/gnu/emacs/EmacsPaintQueue.java
Normal file
138
java/org/gnu/emacs/EmacsPaintQueue.java
Normal file
|
|
@ -0,0 +1,138 @@
|
||||||
|
/* Communication module for Android terminals. -*- c-file-style: "GNU" -*-
|
||||||
|
|
||||||
|
Copyright (C) 2023 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GNU Emacs.
|
||||||
|
|
||||||
|
GNU Emacs is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
your option) any later version.
|
||||||
|
|
||||||
|
GNU Emacs is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
package org.gnu.emacs;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
|
||||||
|
public class EmacsPaintQueue
|
||||||
|
{
|
||||||
|
/* Queue of paint operations. This is modified from the Emacs
|
||||||
|
thread, and entire paint queues are periodically flushed to the
|
||||||
|
application thread where it is executed. */
|
||||||
|
private List<EmacsPaintReq> paintOperations;
|
||||||
|
|
||||||
|
/* Number of operations in this queue. */
|
||||||
|
public int numRequests;
|
||||||
|
|
||||||
|
public
|
||||||
|
EmacsPaintQueue ()
|
||||||
|
{
|
||||||
|
paintOperations = new LinkedList<EmacsPaintReq> ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void
|
||||||
|
run ()
|
||||||
|
{
|
||||||
|
EmacsDrawable drawable, last;
|
||||||
|
Canvas canvas;
|
||||||
|
EmacsGC gc, lastGC;
|
||||||
|
int i;
|
||||||
|
Paint paint;
|
||||||
|
Rect rect, offsetRect, copyRect;
|
||||||
|
|
||||||
|
canvas = null;
|
||||||
|
last = null;
|
||||||
|
gc = null;
|
||||||
|
paint = new Paint ();
|
||||||
|
|
||||||
|
for (EmacsPaintReq req : paintOperations)
|
||||||
|
{
|
||||||
|
drawable = req.getDrawable ();
|
||||||
|
|
||||||
|
synchronized (req)
|
||||||
|
{
|
||||||
|
/* Ignore graphics requests for drawables that have been
|
||||||
|
destroyed. */
|
||||||
|
if (drawable.isDestroyed ())
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
canvas = drawable.lockCanvas ();
|
||||||
|
|
||||||
|
if (canvas == null)
|
||||||
|
/* No canvas is currently available. */
|
||||||
|
continue;
|
||||||
|
|
||||||
|
lastGC = gc;
|
||||||
|
gc = req.getGC ();
|
||||||
|
rect = req.getRect ();
|
||||||
|
|
||||||
|
if (gc.clip_rects == null)
|
||||||
|
{
|
||||||
|
/* No clipping is applied. Just draw and continue. */
|
||||||
|
canvas.save ();
|
||||||
|
req.paintTo (canvas, paint, gc);
|
||||||
|
canvas.restore ();
|
||||||
|
drawable.damageRect (rect);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gc.clip_rects != null && gc.clip_rects.length > 0)
|
||||||
|
{
|
||||||
|
canvas.save ();
|
||||||
|
|
||||||
|
if (gc.clip_rects.length == 1)
|
||||||
|
{
|
||||||
|
/* There is only a single clip rect, which is simple
|
||||||
|
enough. */
|
||||||
|
canvas.clipRect (gc.clip_rects[0]);
|
||||||
|
req.paintTo (canvas, paint, gc);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* There are multiple clip rects. Android doesn't let
|
||||||
|
programs use RegionOp.UNION on the clip rectangle,
|
||||||
|
so Emacs must iterate over each intersection and
|
||||||
|
paint it manually. This seems inefficient but
|
||||||
|
thankfully Emacs never seems to use more than one
|
||||||
|
clip rect. */
|
||||||
|
|
||||||
|
for (i = 0; i < gc.clip_rects.length; ++i)
|
||||||
|
{
|
||||||
|
copyRect = new Rect (gc.clip_rects[i]);
|
||||||
|
|
||||||
|
if (copyRect.intersect (rect))
|
||||||
|
{
|
||||||
|
canvas.save ();
|
||||||
|
canvas.clipRect (copyRect);
|
||||||
|
req.paintTo (canvas, paint, gc);
|
||||||
|
canvas.restore ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
drawable.damageRect (rect);
|
||||||
|
canvas.restore ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void
|
||||||
|
appendPaintOperation (EmacsPaintReq req)
|
||||||
|
{
|
||||||
|
paintOperations.add (req);
|
||||||
|
numRequests++;
|
||||||
|
}
|
||||||
|
};
|
||||||
33
java/org/gnu/emacs/EmacsPaintReq.java
Normal file
33
java/org/gnu/emacs/EmacsPaintReq.java
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
/* Communication module for Android terminals. -*- c-file-style: "GNU" -*-
|
||||||
|
|
||||||
|
Copyright (C) 2023 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GNU Emacs.
|
||||||
|
|
||||||
|
GNU Emacs is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
your option) any later version.
|
||||||
|
|
||||||
|
GNU Emacs is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
package org.gnu.emacs;
|
||||||
|
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
|
||||||
|
public interface EmacsPaintReq
|
||||||
|
{
|
||||||
|
public EmacsDrawable getDrawable ();
|
||||||
|
public EmacsGC getGC ();
|
||||||
|
public void paintTo (Canvas canvas, Paint paint,
|
||||||
|
EmacsGC immutableGC);
|
||||||
|
public Rect getRect ();
|
||||||
|
};
|
||||||
102
java/org/gnu/emacs/EmacsPixmap.java
Normal file
102
java/org/gnu/emacs/EmacsPixmap.java
Normal file
|
|
@ -0,0 +1,102 @@
|
||||||
|
/* Communication module for Android terminals. -*- c-file-style: "GNU" -*-
|
||||||
|
|
||||||
|
Copyright (C) 2023 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GNU Emacs.
|
||||||
|
|
||||||
|
GNU Emacs is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
your option) any later version.
|
||||||
|
|
||||||
|
GNU Emacs is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
package org.gnu.emacs;
|
||||||
|
|
||||||
|
import java.lang.IllegalArgumentException;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
|
||||||
|
/* Drawable backed by bitmap. */
|
||||||
|
|
||||||
|
public class EmacsPixmap extends EmacsHandleObject
|
||||||
|
implements EmacsDrawable
|
||||||
|
{
|
||||||
|
/* The depth of the bitmap. This is not actually used, just defined
|
||||||
|
in order to be consistent with X. */
|
||||||
|
public int depth, width, height;
|
||||||
|
|
||||||
|
/* The bitmap itself. */
|
||||||
|
public Bitmap bitmap;
|
||||||
|
|
||||||
|
/* The canvas used to draw to BITMAP. */
|
||||||
|
public Canvas canvas;
|
||||||
|
|
||||||
|
public
|
||||||
|
EmacsPixmap (short handle, int colors[], int width,
|
||||||
|
int height, int depth)
|
||||||
|
{
|
||||||
|
super (handle);
|
||||||
|
|
||||||
|
if (depth != 1 && depth != 24)
|
||||||
|
throw new IllegalArgumentException ("Invalid depth specified"
|
||||||
|
+ " for pixmap: " + depth);
|
||||||
|
|
||||||
|
switch (depth)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
bitmap = Bitmap.createBitmap (colors, width, height,
|
||||||
|
Bitmap.Config.ALPHA_8);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 24:
|
||||||
|
bitmap = Bitmap.createBitmap (colors, width, height,
|
||||||
|
Bitmap.Config.ARGB_8888);
|
||||||
|
bitmap.setHasAlpha (false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
this.depth = depth;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Canvas
|
||||||
|
lockCanvas ()
|
||||||
|
{
|
||||||
|
if (canvas == null)
|
||||||
|
canvas = new Canvas (bitmap);
|
||||||
|
|
||||||
|
return canvas;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void
|
||||||
|
unlockCanvas ()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void
|
||||||
|
damageRect (Rect damageRect)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Bitmap
|
||||||
|
getBitmap ()
|
||||||
|
{
|
||||||
|
return bitmap;
|
||||||
|
}
|
||||||
|
};
|
||||||
460
java/org/gnu/emacs/EmacsSdk7FontDriver.java
Normal file
460
java/org/gnu/emacs/EmacsSdk7FontDriver.java
Normal file
|
|
@ -0,0 +1,460 @@
|
||||||
|
/* Font backend for Android terminals. -*- c-file-style: "GNU" -*-
|
||||||
|
|
||||||
|
Copyright (C) 2023 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GNU Emacs.
|
||||||
|
|
||||||
|
GNU Emacs is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
your option) any later version.
|
||||||
|
|
||||||
|
GNU Emacs is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
package org.gnu.emacs;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.graphics.Typeface;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
public class EmacsSdk7FontDriver extends EmacsFontDriver
|
||||||
|
{
|
||||||
|
private static final String TOFU_STRING = "\uDB3F\uDFFD";
|
||||||
|
private static final String EM_STRING = "m";
|
||||||
|
private static final String TAG = "EmacsSdk7FontDriver";
|
||||||
|
|
||||||
|
private class Sdk7Typeface
|
||||||
|
{
|
||||||
|
/* The typeface and paint. */
|
||||||
|
public Typeface typeface;
|
||||||
|
public Paint typefacePaint;
|
||||||
|
public String familyName;
|
||||||
|
public int slant, width, weight, spacing;
|
||||||
|
|
||||||
|
public
|
||||||
|
Sdk7Typeface (String fileName, Typeface typeface)
|
||||||
|
{
|
||||||
|
String style, testString;
|
||||||
|
int index, measured, i;
|
||||||
|
float[] widths;
|
||||||
|
|
||||||
|
slant = NORMAL;
|
||||||
|
weight = REGULAR;
|
||||||
|
width = UNSPECIFIED;
|
||||||
|
spacing = PROPORTIONAL;
|
||||||
|
|
||||||
|
typefacePaint = new Paint ();
|
||||||
|
typefacePaint.setTypeface (typeface);
|
||||||
|
|
||||||
|
/* For the calls to measureText below. */
|
||||||
|
typefacePaint.setTextSize (10.0f);
|
||||||
|
|
||||||
|
/* Parse the file name into some useful data. First, strip off
|
||||||
|
the extension. */
|
||||||
|
fileName = fileName.split ("\\.", 2)[0];
|
||||||
|
|
||||||
|
/* Next, split the file name by dashes. Everything before the
|
||||||
|
last dash is part of the family name. */
|
||||||
|
index = fileName.lastIndexOf ("-");
|
||||||
|
|
||||||
|
if (index > 0)
|
||||||
|
{
|
||||||
|
style = fileName.substring (index + 1, fileName.length ());
|
||||||
|
familyName = fileName.substring (0, index);
|
||||||
|
|
||||||
|
/* Look for something describing the weight. */
|
||||||
|
if (style.contains ("Thin"))
|
||||||
|
weight = THIN;
|
||||||
|
else if (style.contains ("UltraLight"))
|
||||||
|
weight = ULTRA_LIGHT;
|
||||||
|
else if (style.contains ("SemiLight"))
|
||||||
|
weight = SEMI_LIGHT;
|
||||||
|
else if (style.contains ("Light"))
|
||||||
|
weight = LIGHT;
|
||||||
|
else if (style.contains ("Medium"))
|
||||||
|
weight = MEDIUM;
|
||||||
|
else if (style.contains ("SemiBold"))
|
||||||
|
weight = SEMI_BOLD;
|
||||||
|
else if (style.contains ("ExtraBold"))
|
||||||
|
weight = EXTRA_BOLD;
|
||||||
|
else if (style.contains ("Bold"))
|
||||||
|
weight = BOLD;
|
||||||
|
else if (style.contains ("Black"))
|
||||||
|
weight = BLACK;
|
||||||
|
else if (style.contains ("UltraHeavy"))
|
||||||
|
weight = ULTRA_HEAVY;
|
||||||
|
|
||||||
|
/* And the slant. */
|
||||||
|
if (style.contains ("ReverseOblique"))
|
||||||
|
slant = OBLIQUE;
|
||||||
|
else if (style.contains ("ReverseItalic"))
|
||||||
|
slant = REVERSE_ITALIC;
|
||||||
|
else if (style.contains ("Italic"))
|
||||||
|
slant = ITALIC;
|
||||||
|
else if (style.contains ("Oblique"))
|
||||||
|
slant = OBLIQUE;
|
||||||
|
|
||||||
|
/* Finally, the width. */
|
||||||
|
if (style.contains ("UltraCondensed"))
|
||||||
|
width = ULTRA_CONDENSED;
|
||||||
|
else if (style.contains ("ExtraCondensed"))
|
||||||
|
width = EXTRA_CONDENSED;
|
||||||
|
else if (style.contains ("SemiCondensed"))
|
||||||
|
width = SEMI_CONDENSED;
|
||||||
|
else if (style.contains ("Condensed"))
|
||||||
|
width = CONDENSED;
|
||||||
|
else if (style.contains ("SemiExpanded"))
|
||||||
|
width = SEMI_EXPANDED;
|
||||||
|
else if (style.contains ("ExtraExpanded"))
|
||||||
|
width = EXTRA_EXPANDED;
|
||||||
|
else if (style.contains ("UltraExpanded"))
|
||||||
|
width = ULTRA_EXPANDED;
|
||||||
|
else if (style.contains ("Expanded"))
|
||||||
|
width = EXPANDED;
|
||||||
|
|
||||||
|
/* Guess the spacing information. */
|
||||||
|
testString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
|
widths = new float[testString.length ()];
|
||||||
|
|
||||||
|
measured = typefacePaint.getTextWidths (testString,
|
||||||
|
0, testString.length (),
|
||||||
|
widths);
|
||||||
|
spacing = MONO;
|
||||||
|
for (i = 0; i < measured; ++i)
|
||||||
|
{
|
||||||
|
if (i != 0 && widths[i - 1] != widths[i])
|
||||||
|
/* This isn't a monospace font. */
|
||||||
|
spacing = PROPORTIONAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
familyName = fileName;
|
||||||
|
|
||||||
|
Log.d (TAG, "Initialized new typeface " + familyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String
|
||||||
|
toString ()
|
||||||
|
{
|
||||||
|
return ("Sdk7Typeface ("
|
||||||
|
+ String.valueOf (familyName) + ", "
|
||||||
|
+ String.valueOf (slant) + ", "
|
||||||
|
+ String.valueOf (width) + ", "
|
||||||
|
+ String.valueOf (weight) + ", "
|
||||||
|
+ String.valueOf (spacing) + ")");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private class Sdk7FontEntity extends FontEntity
|
||||||
|
{
|
||||||
|
/* The typeface. */
|
||||||
|
public Sdk7Typeface typeface;
|
||||||
|
|
||||||
|
public
|
||||||
|
Sdk7FontEntity (Sdk7Typeface typeface)
|
||||||
|
{
|
||||||
|
float width;
|
||||||
|
|
||||||
|
foundry = "Google";
|
||||||
|
family = typeface.familyName;
|
||||||
|
adstyle = null;
|
||||||
|
weight = typeface.weight;
|
||||||
|
slant = typeface.slant;
|
||||||
|
spacing = typeface.spacing;
|
||||||
|
width = typeface.width;
|
||||||
|
|
||||||
|
this.typeface = typeface;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private class Sdk7FontObject extends FontObject
|
||||||
|
{
|
||||||
|
/* The typeface. */
|
||||||
|
public Sdk7Typeface typeface;
|
||||||
|
|
||||||
|
/* The text size. */
|
||||||
|
public int pixelSize;
|
||||||
|
|
||||||
|
public
|
||||||
|
Sdk7FontObject (Sdk7Typeface typeface, int pixelSize)
|
||||||
|
{
|
||||||
|
float totalWidth;
|
||||||
|
String testWidth, testString;
|
||||||
|
|
||||||
|
this.typeface = typeface;
|
||||||
|
this.pixelSize = pixelSize;
|
||||||
|
|
||||||
|
family = typeface.familyName;
|
||||||
|
adstyle = null;
|
||||||
|
weight = typeface.weight;
|
||||||
|
slant = typeface.slant;
|
||||||
|
spacing = typeface.spacing;
|
||||||
|
width = typeface.width;
|
||||||
|
|
||||||
|
/* Compute the ascent and descent. */
|
||||||
|
typeface.typefacePaint.setTextSize (pixelSize);
|
||||||
|
ascent
|
||||||
|
= Math.round (-typeface.typefacePaint.ascent ());
|
||||||
|
descent
|
||||||
|
= Math.round (typeface.typefacePaint.descent ());
|
||||||
|
|
||||||
|
/* Compute the average width. */
|
||||||
|
testString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
|
totalWidth = typeface.typefacePaint.measureText (testString);
|
||||||
|
|
||||||
|
if (totalWidth > 0)
|
||||||
|
avgwidth = Math.round (totalWidth
|
||||||
|
/ testString.length ());
|
||||||
|
|
||||||
|
/* Android doesn't expose the font average width and height
|
||||||
|
information, so this will have to do. */
|
||||||
|
minWidth = maxWidth = avgwidth;
|
||||||
|
|
||||||
|
/* This is different from avgwidth in the font spec! */
|
||||||
|
averageWidth = avgwidth;
|
||||||
|
|
||||||
|
/* Set the space width. */
|
||||||
|
totalWidth = typeface.typefacePaint.measureText (" ");
|
||||||
|
spaceWidth = Math.round (totalWidth);
|
||||||
|
|
||||||
|
/* Set the height and default ascent. */
|
||||||
|
height = ascent + descent;
|
||||||
|
defaultAscent = ascent;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private String[] fontFamilyList;
|
||||||
|
private Sdk7Typeface[] typefaceList;
|
||||||
|
private Sdk7Typeface fallbackTypeface;
|
||||||
|
|
||||||
|
public
|
||||||
|
EmacsSdk7FontDriver ()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
File systemFontsDirectory, fontFile;
|
||||||
|
Typeface typeface;
|
||||||
|
|
||||||
|
systemFontsDirectory = new File ("/system/fonts");
|
||||||
|
|
||||||
|
fontFamilyList = systemFontsDirectory.list ();
|
||||||
|
typefaceList = new Sdk7Typeface[fontFamilyList.length];
|
||||||
|
|
||||||
|
/* It would be nice to avoid opening each and every font upon
|
||||||
|
startup. But that doesn't seem to be possible on
|
||||||
|
Android. */
|
||||||
|
|
||||||
|
for (i = 0; i < fontFamilyList.length; ++i)
|
||||||
|
{
|
||||||
|
fontFile = new File (systemFontsDirectory,
|
||||||
|
fontFamilyList[i]);
|
||||||
|
typeface = Typeface.createFromFile (fontFile);
|
||||||
|
typefaceList[i] = new Sdk7Typeface (fontFile.getName (),
|
||||||
|
typeface);
|
||||||
|
}
|
||||||
|
|
||||||
|
fallbackTypeface = new Sdk7Typeface ("monospace",
|
||||||
|
Typeface.MONOSPACE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean
|
||||||
|
checkMatch (Sdk7Typeface typeface, FontSpec fontSpec)
|
||||||
|
{
|
||||||
|
if (fontSpec.family != null
|
||||||
|
&& !fontSpec.family.equals (typeface.familyName))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
|
||||||
|
if (fontSpec.adstyle != null
|
||||||
|
&& !fontSpec.adstyle.isEmpty ())
|
||||||
|
/* return false; */;
|
||||||
|
|
||||||
|
if (fontSpec.slant != null
|
||||||
|
&& !fontSpec.weight.equals (typeface.weight))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (fontSpec.spacing != null
|
||||||
|
&& !fontSpec.spacing.equals (typeface.spacing))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (fontSpec.weight != null
|
||||||
|
&& !fontSpec.weight.equals (typeface.weight))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (fontSpec.width != null
|
||||||
|
&& !fontSpec.width.equals (typeface.width))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FontEntity[]
|
||||||
|
list (FontSpec fontSpec)
|
||||||
|
{
|
||||||
|
LinkedList<FontEntity> list;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
list = new LinkedList<FontEntity> ();
|
||||||
|
|
||||||
|
Log.d (TAG, ("Looking for fonts matching font spec: "
|
||||||
|
+ fontSpec.toString ()));
|
||||||
|
|
||||||
|
for (i = 0; i < typefaceList.length; ++i)
|
||||||
|
{
|
||||||
|
if (checkMatch (typefaceList[i], fontSpec))
|
||||||
|
list.add (new Sdk7FontEntity (typefaceList[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.d (TAG, "Found font entities: " + list.toString ());
|
||||||
|
|
||||||
|
return (FontEntity[]) list.toArray (new FontEntity[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FontEntity
|
||||||
|
match (FontSpec fontSpec)
|
||||||
|
{
|
||||||
|
FontEntity[] entities;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
entities = this.list (fontSpec);
|
||||||
|
|
||||||
|
if (entities.length == 0)
|
||||||
|
return new Sdk7FontEntity (fallbackTypeface);
|
||||||
|
|
||||||
|
return entities[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[]
|
||||||
|
listFamilies ()
|
||||||
|
{
|
||||||
|
return fontFamilyList;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FontObject
|
||||||
|
openFont (FontEntity fontEntity, int pixelSize)
|
||||||
|
{
|
||||||
|
return new Sdk7FontObject (((Sdk7FontEntity) fontEntity).typeface,
|
||||||
|
pixelSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int
|
||||||
|
hasChar (FontSpec font, char charCode)
|
||||||
|
{
|
||||||
|
float missingGlyphWidth, emGlyphWidth, width;
|
||||||
|
Rect rect1, rect2;
|
||||||
|
Paint paint;
|
||||||
|
Sdk7FontObject fontObject;
|
||||||
|
|
||||||
|
if (font instanceof Sdk7FontObject)
|
||||||
|
{
|
||||||
|
fontObject = (Sdk7FontObject) font;
|
||||||
|
paint = fontObject.typeface.typefacePaint;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
paint = ((Sdk7FontEntity) font).typeface.typefacePaint;
|
||||||
|
|
||||||
|
paint.setTextSize (10);
|
||||||
|
|
||||||
|
if (Character.isWhitespace (charCode))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
missingGlyphWidth = paint.measureText (TOFU_STRING);
|
||||||
|
emGlyphWidth = paint.measureText (EM_STRING);
|
||||||
|
width = paint.measureText ("" + charCode);
|
||||||
|
|
||||||
|
if (width == 0f)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (width != missingGlyphWidth)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
rect1 = new Rect ();
|
||||||
|
rect2 = new Rect ();
|
||||||
|
|
||||||
|
paint.getTextBounds (TOFU_STRING, 0, TOFU_STRING.length (),
|
||||||
|
rect1);
|
||||||
|
paint.getTextBounds ("" + charCode, 0, 1, rect2);
|
||||||
|
return rect1.equals (rect2) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void
|
||||||
|
textExtents1 (Sdk7FontObject font, int code, FontMetrics metrics,
|
||||||
|
Paint paint, Rect bounds)
|
||||||
|
{
|
||||||
|
char[] text;
|
||||||
|
float[] width;
|
||||||
|
|
||||||
|
text = new char[1];
|
||||||
|
text[0] = (char) code;
|
||||||
|
|
||||||
|
paint.getTextBounds (text, 0, 1, bounds);
|
||||||
|
width = new float[1];
|
||||||
|
paint.getTextWidths (text, 0, 1, width);
|
||||||
|
|
||||||
|
/* bounds is the bounding box of the glyph corresponding to CODE.
|
||||||
|
Translate these into XCharStruct values.
|
||||||
|
|
||||||
|
The origin is at 0, 0, and lbearing is the distance counting
|
||||||
|
rightwards from the origin to the left most pixel in the glyph
|
||||||
|
raster. rbearing is the distance between the origin and the
|
||||||
|
rightmost pixel in the glyph raster. ascent is the distance
|
||||||
|
counting upwards between the the topmost pixel in the glyph
|
||||||
|
raster. descent is the distance (once again counting
|
||||||
|
downwards) between the origin and the bottommost pixel in the
|
||||||
|
glyph raster.
|
||||||
|
|
||||||
|
width is the distance between the origin and the origin of any
|
||||||
|
character to the right. */
|
||||||
|
|
||||||
|
metrics.lbearing = (short) bounds.left;
|
||||||
|
metrics.rbearing = (short) bounds.right;
|
||||||
|
metrics.ascent = (short) -bounds.top;
|
||||||
|
metrics.descent = (short) bounds.bottom;
|
||||||
|
metrics.width = (short) Math.round (width[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void
|
||||||
|
textExtents (FontObject font, int code[], FontMetrics fontMetrics[])
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
Paint paintCache;
|
||||||
|
Rect boundsCache;
|
||||||
|
Sdk7FontObject fontObject;
|
||||||
|
|
||||||
|
fontObject = (Sdk7FontObject) font;
|
||||||
|
paintCache = fontObject.typeface.typefacePaint;
|
||||||
|
paintCache.setTextSize (fontObject.pixelSize);
|
||||||
|
boundsCache = new Rect ();
|
||||||
|
|
||||||
|
for (i = 0; i < code.length; ++i)
|
||||||
|
textExtents1 ((Sdk7FontObject) font, code[i], fontMetrics[i],
|
||||||
|
paintCache, boundsCache);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int
|
||||||
|
encodeChar (FontObject fontObject, char charCode)
|
||||||
|
{
|
||||||
|
return charCode;
|
||||||
|
}
|
||||||
|
};
|
||||||
384
java/org/gnu/emacs/EmacsService.java
Normal file
384
java/org/gnu/emacs/EmacsService.java
Normal file
|
|
@ -0,0 +1,384 @@
|
||||||
|
/* Communication module for Android terminals. -*- c-file-style: "GNU" -*-
|
||||||
|
|
||||||
|
Copyright (C) 2023 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GNU Emacs.
|
||||||
|
|
||||||
|
GNU Emacs is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
your option) any later version.
|
||||||
|
|
||||||
|
GNU Emacs is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
package org.gnu.emacs;
|
||||||
|
|
||||||
|
import java.lang.Runnable;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.Point;
|
||||||
|
|
||||||
|
import android.annotation.TargetApi;
|
||||||
|
import android.app.Service;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.res.AssetManager;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Looper;
|
||||||
|
import android.os.IBinder;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
class Holder<T>
|
||||||
|
{
|
||||||
|
T thing;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* EmacsService is the service that starts the thread running Emacs
|
||||||
|
and handles requests by that Emacs instance. */
|
||||||
|
|
||||||
|
public class EmacsService extends Service
|
||||||
|
{
|
||||||
|
public static final String TAG = "EmacsService";
|
||||||
|
public static final int MAX_PENDING_REQUESTS = 256;
|
||||||
|
public static volatile EmacsService SERVICE;
|
||||||
|
|
||||||
|
private EmacsThread thread;
|
||||||
|
private Handler handler;
|
||||||
|
private EmacsPaintQueue paintQueue;
|
||||||
|
|
||||||
|
/* List of all EmacsWindows that are available to attach to an
|
||||||
|
activity. */
|
||||||
|
public static List<EmacsWindow> availableChildren;
|
||||||
|
|
||||||
|
static
|
||||||
|
{
|
||||||
|
availableChildren = new ArrayList<EmacsWindow> ();
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int
|
||||||
|
onStartCommand (Intent intent, int flags, int startId)
|
||||||
|
{
|
||||||
|
return START_NOT_STICKY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IBinder
|
||||||
|
onBind (Intent intent)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@TargetApi (Build.VERSION_CODES.GINGERBREAD)
|
||||||
|
String
|
||||||
|
getLibraryDirectory ()
|
||||||
|
{
|
||||||
|
int apiLevel;
|
||||||
|
Context context;
|
||||||
|
|
||||||
|
context = getApplicationContext ();
|
||||||
|
apiLevel = android.os.Build.VERSION.SDK_INT;
|
||||||
|
|
||||||
|
if (apiLevel >= Build.VERSION_CODES.GINGERBREAD)
|
||||||
|
return context.getApplicationInfo().nativeLibraryDir;
|
||||||
|
else if (apiLevel >= Build.VERSION_CODES.DONUT)
|
||||||
|
return context.getApplicationInfo().dataDir + "/lib";
|
||||||
|
|
||||||
|
return "/data/data/" + context.getPackageName() + "/lib";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void
|
||||||
|
onCreate ()
|
||||||
|
{
|
||||||
|
AssetManager manager;
|
||||||
|
Context app_context;
|
||||||
|
String filesDir, libDir;
|
||||||
|
|
||||||
|
SERVICE = this;
|
||||||
|
handler = new Handler (Looper.getMainLooper ());
|
||||||
|
manager = getAssets ();
|
||||||
|
app_context = getApplicationContext ();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
/* Configure Emacs with the asset manager and other necessary
|
||||||
|
parameters. */
|
||||||
|
filesDir = app_context.getFilesDir ().getCanonicalPath ();
|
||||||
|
libDir = getLibraryDirectory ();
|
||||||
|
|
||||||
|
Log.d (TAG, "Initializing Emacs, where filesDir = " + filesDir
|
||||||
|
+ " and libDir = " + libDir);
|
||||||
|
|
||||||
|
EmacsNative.setEmacsParams (manager, filesDir, libDir,
|
||||||
|
this);
|
||||||
|
|
||||||
|
/* Start the thread that runs Emacs. */
|
||||||
|
thread = new EmacsThread (this);
|
||||||
|
thread.start ();
|
||||||
|
}
|
||||||
|
catch (IOException exception)
|
||||||
|
{
|
||||||
|
EmacsNative.emacsAbort ();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Functions from here on must only be called from the Emacs
|
||||||
|
thread. */
|
||||||
|
|
||||||
|
void
|
||||||
|
runOnUiThread (Runnable runnable)
|
||||||
|
{
|
||||||
|
handler.post (runnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
EmacsView
|
||||||
|
getEmacsView (final EmacsWindow window)
|
||||||
|
{
|
||||||
|
Runnable runnable;
|
||||||
|
final Holder<EmacsView> view;
|
||||||
|
|
||||||
|
view = new Holder<EmacsView> ();
|
||||||
|
|
||||||
|
runnable = new Runnable () {
|
||||||
|
public void
|
||||||
|
run ()
|
||||||
|
{
|
||||||
|
synchronized (this)
|
||||||
|
{
|
||||||
|
view.thing = new EmacsView (window);
|
||||||
|
notify ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
synchronized (runnable)
|
||||||
|
{
|
||||||
|
runOnUiThread (runnable);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
runnable.wait ();
|
||||||
|
}
|
||||||
|
catch (InterruptedException e)
|
||||||
|
{
|
||||||
|
EmacsNative.emacsAbort ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return view.thing;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Notice that a child of the root window named WINDOW is now
|
||||||
|
available for attachment to a specific activity. */
|
||||||
|
|
||||||
|
public void
|
||||||
|
noticeAvailableChild (final EmacsWindow window)
|
||||||
|
{
|
||||||
|
Log.d (TAG, "A new child is available: " + window);
|
||||||
|
|
||||||
|
handler.post (new Runnable () {
|
||||||
|
public void
|
||||||
|
run ()
|
||||||
|
{
|
||||||
|
for (EmacsActivity activity
|
||||||
|
: EmacsActivity.availableActivities)
|
||||||
|
{
|
||||||
|
/* TODO: check if the activity matches. */
|
||||||
|
activity.attachChild (window);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Nope, wait for an activity to become available. */
|
||||||
|
availableChildren.add (window);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Notice that a child of the root window named WINDOW has been
|
||||||
|
destroyed. */
|
||||||
|
|
||||||
|
public void
|
||||||
|
noticeChildDestroyed (final EmacsWindow child)
|
||||||
|
{
|
||||||
|
handler.post (new Runnable () {
|
||||||
|
@Override
|
||||||
|
public void
|
||||||
|
run ()
|
||||||
|
{
|
||||||
|
availableChildren.remove (child);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/* X drawing operations. These are quite primitive operations. The
|
||||||
|
drawing queue is kept on the Emacs thread, but is periodically
|
||||||
|
flushed to the application thread, upon buffers swaps and once it
|
||||||
|
gets too big. */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void
|
||||||
|
ensurePaintQueue ()
|
||||||
|
{
|
||||||
|
if (paintQueue == null)
|
||||||
|
paintQueue = new EmacsPaintQueue ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void
|
||||||
|
flushPaintQueue ()
|
||||||
|
{
|
||||||
|
final EmacsPaintQueue queue;
|
||||||
|
|
||||||
|
if (paintQueue == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (paintQueue.numRequests < 1)
|
||||||
|
/* No requests to flush. */
|
||||||
|
return;
|
||||||
|
|
||||||
|
queue = paintQueue;
|
||||||
|
|
||||||
|
handler.post (new Runnable () {
|
||||||
|
@Override
|
||||||
|
public void
|
||||||
|
run ()
|
||||||
|
{
|
||||||
|
queue.run ();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/* Clear the paint queue. */
|
||||||
|
paintQueue = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void
|
||||||
|
checkFlush ()
|
||||||
|
{
|
||||||
|
if (paintQueue != null
|
||||||
|
&& paintQueue.numRequests > MAX_PENDING_REQUESTS)
|
||||||
|
flushPaintQueue ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void
|
||||||
|
fillRectangle (EmacsDrawable drawable, EmacsGC gc,
|
||||||
|
int x, int y, int width, int height)
|
||||||
|
{
|
||||||
|
EmacsPaintReq req;
|
||||||
|
|
||||||
|
ensurePaintQueue ();
|
||||||
|
|
||||||
|
req = new EmacsFillRectangle (drawable, x, y,
|
||||||
|
width, height,
|
||||||
|
gc.immutableGC ());
|
||||||
|
paintQueue.appendPaintOperation (req);
|
||||||
|
checkFlush ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void
|
||||||
|
fillPolygon (EmacsDrawable drawable, EmacsGC gc,
|
||||||
|
Point points[])
|
||||||
|
{
|
||||||
|
EmacsPaintReq req;
|
||||||
|
|
||||||
|
ensurePaintQueue ();
|
||||||
|
|
||||||
|
req = new EmacsFillPolygon (drawable, points,
|
||||||
|
gc.immutableGC ());
|
||||||
|
paintQueue.appendPaintOperation (req);
|
||||||
|
checkFlush ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void
|
||||||
|
drawRectangle (EmacsDrawable drawable, EmacsGC gc,
|
||||||
|
int x, int y, int width, int height)
|
||||||
|
{
|
||||||
|
EmacsPaintReq req;
|
||||||
|
|
||||||
|
ensurePaintQueue ();
|
||||||
|
|
||||||
|
if (gc.clip_rects != null && gc.clip_rects.length >= 1)
|
||||||
|
android.util.Log.d ("drawRectangle",
|
||||||
|
gc.clip_rects[0].toString ()
|
||||||
|
+ " " + gc.toString ());
|
||||||
|
|
||||||
|
req = new EmacsDrawRectangle (drawable, x, y,
|
||||||
|
width, height,
|
||||||
|
gc.immutableGC ());
|
||||||
|
paintQueue.appendPaintOperation (req);
|
||||||
|
checkFlush ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void
|
||||||
|
drawLine (EmacsDrawable drawable, EmacsGC gc,
|
||||||
|
int x, int y, int x2, int y2)
|
||||||
|
{
|
||||||
|
EmacsPaintReq req;
|
||||||
|
|
||||||
|
ensurePaintQueue ();
|
||||||
|
|
||||||
|
req = new EmacsDrawLine (drawable, x, y,
|
||||||
|
x2, y2,
|
||||||
|
gc.immutableGC ());
|
||||||
|
paintQueue.appendPaintOperation (req);
|
||||||
|
checkFlush ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void
|
||||||
|
drawPoint (EmacsDrawable drawable, EmacsGC gc,
|
||||||
|
int x, int y)
|
||||||
|
{
|
||||||
|
EmacsPaintReq req;
|
||||||
|
|
||||||
|
ensurePaintQueue ();
|
||||||
|
|
||||||
|
req = new EmacsDrawPoint (drawable, x, y,
|
||||||
|
gc.immutableGC ());
|
||||||
|
paintQueue.appendPaintOperation (req);
|
||||||
|
checkFlush ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void
|
||||||
|
copyArea (EmacsDrawable srcDrawable, EmacsDrawable dstDrawable,
|
||||||
|
EmacsGC gc,
|
||||||
|
int srcX, int srcY, int width, int height, int destX,
|
||||||
|
int destY)
|
||||||
|
{
|
||||||
|
EmacsPaintReq req;
|
||||||
|
|
||||||
|
ensurePaintQueue ();
|
||||||
|
|
||||||
|
req = new EmacsCopyArea (srcDrawable, dstDrawable,
|
||||||
|
srcX, srcY, width, height, destX,
|
||||||
|
destY, gc.immutableGC ());
|
||||||
|
paintQueue.appendPaintOperation (req);
|
||||||
|
checkFlush ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void
|
||||||
|
clearWindow (EmacsWindow window)
|
||||||
|
{
|
||||||
|
window.clearWindow ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void
|
||||||
|
clearArea (EmacsWindow window, int x, int y, int width,
|
||||||
|
int height)
|
||||||
|
{
|
||||||
|
window.clearArea (x, y, width, height);
|
||||||
|
}
|
||||||
|
};
|
||||||
83
java/org/gnu/emacs/EmacsSurfaceView.java
Normal file
83
java/org/gnu/emacs/EmacsSurfaceView.java
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
/* Communication module for Android terminals. -*- c-file-style: "GNU" -*-
|
||||||
|
|
||||||
|
Copyright (C) 2023 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GNU Emacs.
|
||||||
|
|
||||||
|
GNU Emacs is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
your option) any later version.
|
||||||
|
|
||||||
|
GNU Emacs is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
package org.gnu.emacs;
|
||||||
|
|
||||||
|
import android.view.SurfaceView;
|
||||||
|
import android.view.SurfaceHolder;
|
||||||
|
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
|
||||||
|
public class EmacsSurfaceView extends SurfaceView
|
||||||
|
{
|
||||||
|
private boolean created;
|
||||||
|
|
||||||
|
public
|
||||||
|
EmacsSurfaceView (final EmacsView view)
|
||||||
|
{
|
||||||
|
super (view.getContext ());
|
||||||
|
|
||||||
|
getHolder ().addCallback (new SurfaceHolder.Callback () {
|
||||||
|
@Override
|
||||||
|
public void
|
||||||
|
surfaceChanged (SurfaceHolder holder, int format,
|
||||||
|
int width, int height)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void
|
||||||
|
surfaceCreated (SurfaceHolder holder)
|
||||||
|
{
|
||||||
|
created = true;
|
||||||
|
|
||||||
|
/* Force a buffer swap now to get the contents of the Emacs
|
||||||
|
view on screen. */
|
||||||
|
view.swapBuffers ();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void
|
||||||
|
surfaceDestroyed (SurfaceHolder holder)
|
||||||
|
{
|
||||||
|
created = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean
|
||||||
|
isCreated ()
|
||||||
|
{
|
||||||
|
return created;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Canvas
|
||||||
|
lockCanvas (Rect damage)
|
||||||
|
{
|
||||||
|
return getHolder ().lockCanvas (damage);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void
|
||||||
|
unlockCanvasAndPost (Canvas canvas)
|
||||||
|
{
|
||||||
|
getHolder ().unlockCanvasAndPost (canvas);
|
||||||
|
}
|
||||||
|
};
|
||||||
44
java/org/gnu/emacs/EmacsThread.java
Normal file
44
java/org/gnu/emacs/EmacsThread.java
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
/* Communication module for Android terminals. -*- c-file-style: "GNU" -*-
|
||||||
|
|
||||||
|
Copyright (C) 2023 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GNU Emacs.
|
||||||
|
|
||||||
|
GNU Emacs is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
your option) any later version.
|
||||||
|
|
||||||
|
GNU Emacs is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
package org.gnu.emacs;
|
||||||
|
|
||||||
|
import java.lang.Thread;
|
||||||
|
|
||||||
|
public class EmacsThread extends Thread
|
||||||
|
{
|
||||||
|
EmacsService context;
|
||||||
|
|
||||||
|
public
|
||||||
|
EmacsThread (EmacsService service)
|
||||||
|
{
|
||||||
|
context = service;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void
|
||||||
|
run ()
|
||||||
|
{
|
||||||
|
String args[];
|
||||||
|
|
||||||
|
args = new String[] { "android-emacs", };
|
||||||
|
|
||||||
|
/* Run the native code now. */
|
||||||
|
EmacsNative.initEmacs (args);
|
||||||
|
}
|
||||||
|
};
|
||||||
211
java/org/gnu/emacs/EmacsView.java
Normal file
211
java/org/gnu/emacs/EmacsView.java
Normal file
|
|
@ -0,0 +1,211 @@
|
||||||
|
/* Communication module for Android terminals. -*- c-file-style: "GNU" -*-
|
||||||
|
|
||||||
|
Copyright (C) 2023 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GNU Emacs.
|
||||||
|
|
||||||
|
GNU Emacs is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
your option) any later version.
|
||||||
|
|
||||||
|
GNU Emacs is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
package org.gnu.emacs;
|
||||||
|
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.KeyEvent;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.graphics.Region;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import android.os.Build;
|
||||||
|
|
||||||
|
/* This is an Android view which has a back and front buffer. When
|
||||||
|
swapBuffers is called, the back buffer is swapped to the front
|
||||||
|
buffer, and any damage is invalidated. frontBitmap and backBitmap
|
||||||
|
are modified and used both from the UI and the Emacs thread. As a
|
||||||
|
result, there is a lock held during all drawing operations.
|
||||||
|
|
||||||
|
It is also a ViewGroup, as it also lays out children. */
|
||||||
|
|
||||||
|
public class EmacsView extends ViewGroup
|
||||||
|
{
|
||||||
|
public static final String TAG = "EmacsView";
|
||||||
|
|
||||||
|
/* The associated EmacsWindow. */
|
||||||
|
public EmacsWindow window;
|
||||||
|
|
||||||
|
/* The buffer bitmap. */
|
||||||
|
public Bitmap bitmap;
|
||||||
|
|
||||||
|
/* The associated canvases. */
|
||||||
|
public Canvas canvas;
|
||||||
|
|
||||||
|
/* The damage region. */
|
||||||
|
public Region damageRegion;
|
||||||
|
|
||||||
|
/* The paint. */
|
||||||
|
public Paint paint;
|
||||||
|
|
||||||
|
/* The associated surface view. */
|
||||||
|
private EmacsSurfaceView surfaceView;
|
||||||
|
|
||||||
|
public
|
||||||
|
EmacsView (EmacsWindow window)
|
||||||
|
{
|
||||||
|
super (EmacsService.SERVICE);
|
||||||
|
|
||||||
|
this.window = window;
|
||||||
|
this.damageRegion = new Region ();
|
||||||
|
this.paint = new Paint ();
|
||||||
|
|
||||||
|
/* Create the surface view. */
|
||||||
|
this.surfaceView = new EmacsSurfaceView (this);
|
||||||
|
|
||||||
|
setFocusable (FOCUSABLE);
|
||||||
|
addView (this.surfaceView);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void
|
||||||
|
onMeasure (int widthMeasureSpec, int heightMeasureSpec)
|
||||||
|
{
|
||||||
|
Rect measurements;
|
||||||
|
int width, height;
|
||||||
|
|
||||||
|
/* Return the width and height of the window regardless of what
|
||||||
|
the parent says. */
|
||||||
|
measurements = window.getGeometry ();
|
||||||
|
|
||||||
|
width = measurements.width ();
|
||||||
|
height = measurements.height ();
|
||||||
|
|
||||||
|
/* Now apply any extra requirements in widthMeasureSpec and
|
||||||
|
heightMeasureSpec. */
|
||||||
|
|
||||||
|
if (MeasureSpec.getMode (widthMeasureSpec) == MeasureSpec.EXACTLY)
|
||||||
|
width = MeasureSpec.getSize (widthMeasureSpec);
|
||||||
|
else if (MeasureSpec.getMode (widthMeasureSpec) == MeasureSpec.AT_MOST
|
||||||
|
&& width > MeasureSpec.getSize (widthMeasureSpec))
|
||||||
|
width = MeasureSpec.getSize (widthMeasureSpec);
|
||||||
|
|
||||||
|
if (MeasureSpec.getMode (heightMeasureSpec) == MeasureSpec.EXACTLY)
|
||||||
|
height = MeasureSpec.getSize (heightMeasureSpec);
|
||||||
|
else if (MeasureSpec.getMode (heightMeasureSpec) == MeasureSpec.AT_MOST
|
||||||
|
&& height > MeasureSpec.getSize (heightMeasureSpec))
|
||||||
|
height = MeasureSpec.getSize (heightMeasureSpec);
|
||||||
|
|
||||||
|
super.setMeasuredDimension (width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void
|
||||||
|
onLayout (boolean changed, int left, int top, int right,
|
||||||
|
int bottom)
|
||||||
|
{
|
||||||
|
int count, i;
|
||||||
|
View child;
|
||||||
|
Rect windowRect;
|
||||||
|
|
||||||
|
if (changed)
|
||||||
|
{
|
||||||
|
window.viewLayout (left, top, right, bottom);
|
||||||
|
|
||||||
|
/* Recreate the front and back buffer bitmaps. */
|
||||||
|
bitmap
|
||||||
|
= Bitmap.createBitmap (right - left, bottom - top,
|
||||||
|
Bitmap.Config.ARGB_8888);
|
||||||
|
|
||||||
|
/* And canvases. */
|
||||||
|
canvas = new Canvas (bitmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
count = getChildCount ();
|
||||||
|
|
||||||
|
for (i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
child = getChildAt (i);
|
||||||
|
|
||||||
|
if (child == surfaceView)
|
||||||
|
/* The child is the surface view, so give it the entire
|
||||||
|
view. */
|
||||||
|
child.layout (left, top, right, bottom);
|
||||||
|
else if (child.getVisibility () != GONE)
|
||||||
|
{
|
||||||
|
if (!(child instanceof EmacsView))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* What to do: lay out the view precisely according to its
|
||||||
|
window rect. */
|
||||||
|
windowRect = ((EmacsView) child).window.getGeometry ();
|
||||||
|
child.layout (windowRect.left, windowRect.top,
|
||||||
|
windowRect.right, windowRect.bottom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void
|
||||||
|
damageRect (Rect damageRect)
|
||||||
|
{
|
||||||
|
damageRegion.union (damageRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void
|
||||||
|
swapBuffers ()
|
||||||
|
{
|
||||||
|
Bitmap back;
|
||||||
|
Canvas canvas;
|
||||||
|
Rect damageRect;
|
||||||
|
|
||||||
|
if (damageRegion.isEmpty ())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!surfaceView.isCreated ())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (bitmap == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Lock the canvas with the specified damage. */
|
||||||
|
damageRect = damageRegion.getBounds ();
|
||||||
|
canvas = surfaceView.lockCanvas (damageRect);
|
||||||
|
|
||||||
|
/* Return if locking the canvas failed. */
|
||||||
|
if (canvas == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Copy from the back buffer to the canvas. */
|
||||||
|
canvas.drawBitmap (bitmap, damageRect, damageRect, paint);
|
||||||
|
|
||||||
|
/* Unlock the canvas and clear the damage. */
|
||||||
|
surfaceView.unlockCanvasAndPost (canvas);
|
||||||
|
damageRegion.setEmpty ();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean
|
||||||
|
onKeyDown (int keyCode, KeyEvent event)
|
||||||
|
{
|
||||||
|
window.onKeyDown (keyCode, event);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean
|
||||||
|
onKeyUp (int keyCode, KeyEvent event)
|
||||||
|
{
|
||||||
|
window.onKeyUp (keyCode, event);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
336
java/org/gnu/emacs/EmacsWindow.java
Normal file
336
java/org/gnu/emacs/EmacsWindow.java
Normal file
|
|
@ -0,0 +1,336 @@
|
||||||
|
/* Communication module for Android terminals. -*- c-file-style: "GNU" -*-
|
||||||
|
|
||||||
|
Copyright (C) 2023 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GNU Emacs.
|
||||||
|
|
||||||
|
GNU Emacs is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
your option) any later version.
|
||||||
|
|
||||||
|
GNU Emacs is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
package org.gnu.emacs;
|
||||||
|
|
||||||
|
import java.lang.IllegalStateException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.Point;
|
||||||
|
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.view.KeyEvent;
|
||||||
|
|
||||||
|
/* This defines a window, which is a handle. Windows represent a
|
||||||
|
rectangular subset of the screen with their own contents.
|
||||||
|
|
||||||
|
Windows either have a parent window, in which case their views are
|
||||||
|
attached to the parent's view, or are "floating", in which case
|
||||||
|
their views are attached to the parent activity (if any), else
|
||||||
|
nothing.
|
||||||
|
|
||||||
|
Views are also drawables, meaning they can accept drawing
|
||||||
|
requests. */
|
||||||
|
|
||||||
|
public class EmacsWindow extends EmacsHandleObject
|
||||||
|
implements EmacsDrawable
|
||||||
|
{
|
||||||
|
/* The view associated with the window. */
|
||||||
|
public EmacsView view;
|
||||||
|
|
||||||
|
/* The geometry of the window. */
|
||||||
|
private Rect rect;
|
||||||
|
|
||||||
|
/* The parent window, or null if it is the root window. */
|
||||||
|
private EmacsWindow parent;
|
||||||
|
|
||||||
|
/* List of all children in stacking order. This must be kept
|
||||||
|
consistent! */
|
||||||
|
private ArrayList<EmacsWindow> children;
|
||||||
|
|
||||||
|
/* The EmacsActivity currently attached, if it exists. */
|
||||||
|
private EmacsActivity attached;
|
||||||
|
|
||||||
|
/* The window background scratch GC. foreground is always the
|
||||||
|
window background. */
|
||||||
|
private EmacsGC scratchGC;
|
||||||
|
|
||||||
|
public
|
||||||
|
EmacsWindow (short handle, final EmacsWindow parent, int x, int y,
|
||||||
|
int width, int height)
|
||||||
|
{
|
||||||
|
super (handle);
|
||||||
|
|
||||||
|
rect = new Rect (x, y, x + width, y + height);
|
||||||
|
|
||||||
|
/* Create the view from the context's UI thread. */
|
||||||
|
view = EmacsService.SERVICE.getEmacsView (this);
|
||||||
|
this.parent = parent;
|
||||||
|
children = new ArrayList<EmacsWindow> ();
|
||||||
|
|
||||||
|
/* The window is unmapped by default. */
|
||||||
|
view.setVisibility (View.GONE);
|
||||||
|
|
||||||
|
/* If parent is the root window, notice that there are new
|
||||||
|
children available for interested activites to pick up. */
|
||||||
|
if (parent == null)
|
||||||
|
EmacsService.SERVICE.noticeAvailableChild (this);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Otherwise, directly add this window as a child of that
|
||||||
|
window's view. */
|
||||||
|
synchronized (parent)
|
||||||
|
{
|
||||||
|
parent.children.add (this);
|
||||||
|
parent.view.post (new Runnable () {
|
||||||
|
@Override
|
||||||
|
public void
|
||||||
|
run ()
|
||||||
|
{
|
||||||
|
parent.view.addView (view);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scratchGC = new EmacsGC ((short) 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void
|
||||||
|
changeWindowBackground (int pixel)
|
||||||
|
{
|
||||||
|
/* scratchGC is used as the argument to a FillRectangles req. */
|
||||||
|
scratchGC.foreground = pixel;
|
||||||
|
scratchGC.markDirty ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Rect
|
||||||
|
getGeometry ()
|
||||||
|
{
|
||||||
|
synchronized (this)
|
||||||
|
{
|
||||||
|
/* Huh, this is it. */
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void
|
||||||
|
destroyHandle () throws IllegalStateException
|
||||||
|
{
|
||||||
|
synchronized (this)
|
||||||
|
{
|
||||||
|
if (!children.isEmpty ())
|
||||||
|
throw new IllegalStateException ("Trying to destroy window with "
|
||||||
|
+ "children!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Notice that the child has been destroyed. */
|
||||||
|
EmacsService.SERVICE.noticeChildDestroyed (this);
|
||||||
|
|
||||||
|
/* Remove the view from its parent and make it invisible. */
|
||||||
|
view.post (new Runnable () {
|
||||||
|
public void
|
||||||
|
run ()
|
||||||
|
{
|
||||||
|
view.setVisibility (View.GONE);
|
||||||
|
|
||||||
|
if (view.getParent () != null)
|
||||||
|
((ViewGroup) view.getParent ()).removeView (view);
|
||||||
|
|
||||||
|
if (attached != null)
|
||||||
|
attached.makeAvailable ();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
super.destroyHandle ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void
|
||||||
|
setActivity (EmacsActivity activity)
|
||||||
|
{
|
||||||
|
synchronized (this)
|
||||||
|
{
|
||||||
|
activity = activity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void
|
||||||
|
viewLayout (int left, int top, int right, int bottom)
|
||||||
|
{
|
||||||
|
synchronized (this)
|
||||||
|
{
|
||||||
|
rect.left = left;
|
||||||
|
rect.top = top;
|
||||||
|
rect.right = right;
|
||||||
|
rect.bottom = bottom;
|
||||||
|
|
||||||
|
EmacsNative.sendConfigureNotify (this.handle,
|
||||||
|
System.currentTimeMillis (),
|
||||||
|
left, top, rect.width (),
|
||||||
|
rect.height ());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void
|
||||||
|
requestViewLayout ()
|
||||||
|
{
|
||||||
|
view.post (new Runnable () {
|
||||||
|
@Override
|
||||||
|
public void
|
||||||
|
run ()
|
||||||
|
{
|
||||||
|
view.requestLayout ();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void
|
||||||
|
resizeWindow (int width, int height)
|
||||||
|
{
|
||||||
|
synchronized (this)
|
||||||
|
{
|
||||||
|
rect.right = rect.left + width;
|
||||||
|
rect.bottom = rect.top + height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void
|
||||||
|
moveWindow (int x, int y)
|
||||||
|
{
|
||||||
|
int width, height;
|
||||||
|
|
||||||
|
synchronized (this)
|
||||||
|
{
|
||||||
|
width = rect.width ();
|
||||||
|
height = rect.height ();
|
||||||
|
|
||||||
|
rect.left = x;
|
||||||
|
rect.top = y;
|
||||||
|
rect.right = x + width;
|
||||||
|
rect.bottom = y + height;
|
||||||
|
|
||||||
|
requestViewLayout ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void
|
||||||
|
mapWindow ()
|
||||||
|
{
|
||||||
|
view.post (new Runnable () {
|
||||||
|
@Override
|
||||||
|
public void
|
||||||
|
run ()
|
||||||
|
{
|
||||||
|
view.setVisibility (View.VISIBLE);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void
|
||||||
|
unmapWindow ()
|
||||||
|
{
|
||||||
|
view.post (new Runnable () {
|
||||||
|
@Override
|
||||||
|
public void
|
||||||
|
run ()
|
||||||
|
{
|
||||||
|
view.setVisibility (View.GONE);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Canvas
|
||||||
|
lockCanvas ()
|
||||||
|
{
|
||||||
|
if (view.canvas != null)
|
||||||
|
return view.canvas;
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void
|
||||||
|
unlockCanvas ()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void
|
||||||
|
damageRect (Rect damageRect)
|
||||||
|
{
|
||||||
|
view.damageRect (damageRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void
|
||||||
|
swapBuffers ()
|
||||||
|
{
|
||||||
|
/* Before calling swapBuffers, make sure to flush the paint
|
||||||
|
queue. */
|
||||||
|
EmacsService.SERVICE.flushPaintQueue ();
|
||||||
|
view.post (new Runnable () {
|
||||||
|
@Override
|
||||||
|
public void
|
||||||
|
run ()
|
||||||
|
{
|
||||||
|
view.swapBuffers ();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void
|
||||||
|
clearWindow ()
|
||||||
|
{
|
||||||
|
synchronized (this)
|
||||||
|
{
|
||||||
|
EmacsService.SERVICE.fillRectangle (this, scratchGC,
|
||||||
|
0, 0, rect.width (),
|
||||||
|
rect.height ());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void
|
||||||
|
clearArea (int x, int y, int width, int height)
|
||||||
|
{
|
||||||
|
EmacsService.SERVICE.fillRectangle (this, scratchGC,
|
||||||
|
x, y, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Bitmap
|
||||||
|
getBitmap ()
|
||||||
|
{
|
||||||
|
return view.bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void
|
||||||
|
onKeyDown (int keyCode, KeyEvent event)
|
||||||
|
{
|
||||||
|
EmacsNative.sendKeyPress (this.handle,
|
||||||
|
event.getEventTime (),
|
||||||
|
event.getModifiers (),
|
||||||
|
keyCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void
|
||||||
|
onKeyUp (int keyCode, KeyEvent event)
|
||||||
|
{
|
||||||
|
EmacsNative.sendKeyRelease (this.handle,
|
||||||
|
event.getEventTime (),
|
||||||
|
event.getModifiers (),
|
||||||
|
keyCode);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -96,6 +96,14 @@ localstatedir=@localstatedir@
|
||||||
srcdir=@srcdir@
|
srcdir=@srcdir@
|
||||||
VPATH=@srcdir@
|
VPATH=@srcdir@
|
||||||
|
|
||||||
|
# Cross-compilation setup
|
||||||
|
|
||||||
|
XCONFIGURE=@XCONFIGURE@
|
||||||
|
|
||||||
|
ifneq ($(XCONFIGURE),)
|
||||||
|
vpath $(srcdir)
|
||||||
|
endif
|
||||||
|
|
||||||
# The top-level source directory, also set by configure.
|
# The top-level source directory, also set by configure.
|
||||||
top_srcdir=@top_srcdir@
|
top_srcdir=@top_srcdir@
|
||||||
# MinGW CPPFLAGS may use this.
|
# MinGW CPPFLAGS may use this.
|
||||||
|
|
|
||||||
137
lib/Makefile.in
137
lib/Makefile.in
|
|
@ -20,6 +20,130 @@
|
||||||
srcdir = @srcdir@
|
srcdir = @srcdir@
|
||||||
VPATH = @srcdir@
|
VPATH = @srcdir@
|
||||||
|
|
||||||
|
# This is not empty if this is a Makefile that will be copied to
|
||||||
|
# xcompile/lib.
|
||||||
|
XCONFIGURE = @XCONFIGURE@
|
||||||
|
|
||||||
|
# This is required to make sure symbol visibility is correct and
|
||||||
|
# functions like readlinkat do not end up replacing their OS
|
||||||
|
# counterparts.
|
||||||
|
ANDROID_CFLAGS = @ANDROID_CFLAGS@
|
||||||
|
|
||||||
|
ifneq ($(XCONFIGURE),)
|
||||||
|
|
||||||
|
# Set vpath. Only look for C files and some headers in srcdir:
|
||||||
|
# Headers that are generated by gnulib must be spared, or otherwise
|
||||||
|
# the versions previously built on the host will be used, if builddir
|
||||||
|
# is the same as srcdir. Following this is a list of files in lib/
|
||||||
|
# that are not generated during the gnulib build process. Please keep
|
||||||
|
# it up to date!
|
||||||
|
|
||||||
|
vpath _Noreturn.h $(srcdir)
|
||||||
|
vpath acl-internal.h $(srcdir)
|
||||||
|
vpath acl.h $(srcdir)
|
||||||
|
vpath af_alg.h $(srcdir)
|
||||||
|
vpath alloca.in.h $(srcdir)
|
||||||
|
vpath allocator.h $(srcdir)
|
||||||
|
vpath arg-nonnull.h $(srcdir)
|
||||||
|
vpath assert.in.h $(srcdir)
|
||||||
|
vpath attribute.h $(srcdir)
|
||||||
|
vpath binary-io.h $(srcdir)
|
||||||
|
vpath byteswap.in.h $(srcdir)
|
||||||
|
vpath c++defs.h $(srcdir)
|
||||||
|
vpath c-ctype.h $(srcdir)
|
||||||
|
vpath c-strcase.h $(srcdir)
|
||||||
|
vpath careadlinkat.h $(srcdir)
|
||||||
|
vpath cdefs.h $(srcdir)
|
||||||
|
vpath cloexec.h $(srcdir)
|
||||||
|
vpath close-stream.h $(srcdir)
|
||||||
|
vpath count-leading-zeros.h $(srcdir)
|
||||||
|
vpath count-one-bits.h $(srcdir)
|
||||||
|
vpath count-trailing-zeros.h $(srcdir)
|
||||||
|
vpath diffseq.h $(srcdir)
|
||||||
|
vpath dirent.h $(srcdir)
|
||||||
|
vpath dirent.in.h $(srcdir)
|
||||||
|
vpath dynarray.h $(srcdir)
|
||||||
|
vpath eloop-threshold.h $(srcdir)
|
||||||
|
vpath errno.in.h $(srcdir)
|
||||||
|
vpath execinfo.in.h $(srcdir)
|
||||||
|
vpath fcntl.in.h $(srcdir)
|
||||||
|
vpath filemode.h $(srcdir)
|
||||||
|
vpath filename.h $(srcdir)
|
||||||
|
vpath filevercmp.h $(srcdir)
|
||||||
|
vpath fingerprint.h $(srcdir)
|
||||||
|
vpath flexmember.h $(srcdir)
|
||||||
|
vpath fpending.h $(srcdir)
|
||||||
|
vpath fsusage.h $(srcdir)
|
||||||
|
vpath ftoastr.h $(srcdir)
|
||||||
|
vpath getopt-cdefs.in.h $(srcdir)
|
||||||
|
vpath getopt-core.h $(srcdir)
|
||||||
|
vpath getopt-ext.h $(srcdir)
|
||||||
|
vpath getopt-pfx-core.h $(srcdir)
|
||||||
|
vpath getopt-pfx-ext.h $(srcdir)
|
||||||
|
vpath getopt.in.h $(srcdir)
|
||||||
|
vpath getopt_int.h $(srcdir)
|
||||||
|
vpath gettext.h $(srcdir)
|
||||||
|
vpath idx.h $(srcdir)
|
||||||
|
vpath ieee754.in.h $(srcdir)
|
||||||
|
vpath ignore-value.h $(srcdir)
|
||||||
|
vpath intprops-internal.h $(srcdir)
|
||||||
|
vpath intprops.h $(srcdir)
|
||||||
|
vpath inttypes.in.h $(srcdir)
|
||||||
|
vpath libc-config.h $(srcdir)
|
||||||
|
vpath limits.in.h $(srcdir)
|
||||||
|
vpath malloc/dynarray.h $(srcdir)
|
||||||
|
vpath malloc/scratch_buffer.h $(srcdir)
|
||||||
|
vpath md5.h $(srcdir)
|
||||||
|
vpath min-max.h $(srcdir)
|
||||||
|
vpath mini-gmp.h $(srcdir)
|
||||||
|
vpath minmax.h $(srcdir)
|
||||||
|
vpath mktime-internal.h $(srcdir)
|
||||||
|
vpath nproc.h $(srcdir)
|
||||||
|
vpath openat-priv.h $(srcdir)
|
||||||
|
vpath openat.h $(srcdir)
|
||||||
|
vpath pathmax.h $(srcdir)
|
||||||
|
vpath regex.h $(srcdir)
|
||||||
|
vpath regex_internal.h $(srcdir)
|
||||||
|
vpath root-uid.h $(srcdir)
|
||||||
|
vpath save-cwd.h $(srcdir)
|
||||||
|
vpath scratch_buffer.h $(srcdir)
|
||||||
|
vpath sha1.h $(srcdir)
|
||||||
|
vpath sha256.h $(srcdir)
|
||||||
|
vpath sha512.h $(srcdir)
|
||||||
|
vpath sig2str.h $(srcdir)
|
||||||
|
vpath signal.in.h $(srcdir)
|
||||||
|
vpath stat-time.h $(srcdir)
|
||||||
|
vpath stdalign.in.h $(srcdir)
|
||||||
|
vpath stdckdint.in.h $(srcdir)
|
||||||
|
vpath stddef.in.h $(srcdir)
|
||||||
|
vpath stdint.in.h $(srcdir)
|
||||||
|
vpath stdio-impl.h $(srcdir)
|
||||||
|
vpath stdio.h $(srcdir)
|
||||||
|
vpath stdio.in.h $(srcdir)
|
||||||
|
vpath stdlib.in.h $(srcdir)
|
||||||
|
vpath str-two-way.h $(srcdir)
|
||||||
|
vpath strftime.h $(srcdir)
|
||||||
|
vpath string.in.h $(srcdir)
|
||||||
|
vpath sys_random.in.h $(srcdir)
|
||||||
|
vpath sys_select.in.h $(srcdir)
|
||||||
|
vpath sys_stat.in.h $(srcdir)
|
||||||
|
vpath sys_time.in.h $(srcdir)
|
||||||
|
vpath sys_types.in.h $(srcdir)
|
||||||
|
vpath tempname.h $(srcdir)
|
||||||
|
vpath time-internal.h $(srcdir)
|
||||||
|
vpath time.in.h $(srcdir)
|
||||||
|
vpath timespec.h $(srcdir)
|
||||||
|
vpath u64.h $(srcdir)
|
||||||
|
vpath unistd.in.h $(srcdir)
|
||||||
|
vpath unlocked-io.h $(srcdir)
|
||||||
|
vpath utimens.h $(srcdir)
|
||||||
|
vpath verify.h $(srcdir)
|
||||||
|
vpath vla.h $(srcdir)
|
||||||
|
vpath warn-on-use.h $(srcdir)
|
||||||
|
vpath xalloc-oversized.h $(srcdir)
|
||||||
|
vpath %.c $(srcdir)
|
||||||
|
endif
|
||||||
|
|
||||||
# Variables substituted by 'configure', and not autogenerated in gnulib.mk,
|
# Variables substituted by 'configure', and not autogenerated in gnulib.mk,
|
||||||
# or needed before gnulib.mk is included.
|
# or needed before gnulib.mk is included.
|
||||||
abs_top_srcdir = @abs_top_srcdir@
|
abs_top_srcdir = @abs_top_srcdir@
|
||||||
|
|
@ -33,11 +157,11 @@ all:
|
||||||
|
|
||||||
HAVE_NATIVE_COMP = @HAVE_NATIVE_COMP@
|
HAVE_NATIVE_COMP = @HAVE_NATIVE_COMP@
|
||||||
|
|
||||||
ALL_CFLAGS= \
|
ALL_CFLAGS = \
|
||||||
$(C_SWITCH_SYSTEM) $(C_SWITCH_MACHINE) $(DEPFLAGS) \
|
$(C_SWITCH_SYSTEM) $(C_SWITCH_MACHINE) $(DEPFLAGS) \
|
||||||
$(GNULIB_WARN_CFLAGS) $(WERROR_CFLAGS) $(PROFILING_CFLAGS) $(CFLAGS) \
|
$(GNULIB_WARN_CFLAGS) $(WERROR_CFLAGS) $(PROFILING_CFLAGS) $(CFLAGS) \
|
||||||
-I. -I../src -I$(srcdir) -I$(srcdir)/../src \
|
-I. -I../src -I$(srcdir) -I$(srcdir)/../src \
|
||||||
$(if $(patsubst e-%,,$(notdir $<)),,-Demacs)
|
$(if $(patsubst e-%,,$(notdir $<)),,-Demacs) $(ANDROID_CFLAGS)
|
||||||
|
|
||||||
ifeq ($(HAVE_NATIVE_COMP),yes)
|
ifeq ($(HAVE_NATIVE_COMP),yes)
|
||||||
ALL_CFLAGS += -DGL_COMPILE_CRYPTO_STREAM
|
ALL_CFLAGS += -DGL_COMPILE_CRYPTO_STREAM
|
||||||
|
|
@ -52,6 +176,12 @@ ifneq ($(SYSTEM_TYPE),windows-nt)
|
||||||
libgnu_a_SOURCES += openat-die.c save-cwd.c
|
libgnu_a_SOURCES += openat-die.c save-cwd.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(XCONFIGURE),android)
|
||||||
|
# The next line is necessary to override -I$(srcdir), which will end
|
||||||
|
# up pulling in lots of headers from the host.
|
||||||
|
ALL_CFLAGS += -I$(top_srcdir)/xcompile -I.
|
||||||
|
endif
|
||||||
|
|
||||||
DEPDIR = deps
|
DEPDIR = deps
|
||||||
ifeq ($(AUTO_DEPEND),yes)
|
ifeq ($(AUTO_DEPEND),yes)
|
||||||
DEPFLAGS = -MMD -MF $(DEPDIR)/$*.d -MP
|
DEPFLAGS = -MMD -MF $(DEPDIR)/$*.d -MP
|
||||||
|
|
@ -60,11 +190,14 @@ else
|
||||||
DEPFLAGS =
|
DEPFLAGS =
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# This piece of code interferes with cross compilation
|
||||||
|
ifeq ($(XCONFIGURE),)
|
||||||
.PRECIOUS: ../config.status Makefile
|
.PRECIOUS: ../config.status Makefile
|
||||||
../config.status: $(top_srcdir)/configure.ac $(top_srcdir)/m4/*.m4
|
../config.status: $(top_srcdir)/configure.ac $(top_srcdir)/m4/*.m4
|
||||||
$(MAKE) -C .. $(notdir $@)
|
$(MAKE) -C .. $(notdir $@)
|
||||||
Makefile: ../config.status $(srcdir)/Makefile.in
|
Makefile: ../config.status $(srcdir)/Makefile.in
|
||||||
$(MAKE) -C .. lib/$@
|
$(MAKE) -C .. lib/$@
|
||||||
|
endif
|
||||||
|
|
||||||
# Object modules that need not be built for Emacs.
|
# Object modules that need not be built for Emacs.
|
||||||
# Emacs does not need e-regex.o (it has its own regex-emacs.c),
|
# Emacs does not need e-regex.o (it has its own regex-emacs.c),
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,11 @@ orig_faccessat (int fd, char const *name, int mode, int flag)
|
||||||
/* Write "unistd.h" here, not <unistd.h>, otherwise OSF/1 5.1 DTK cc
|
/* Write "unistd.h" here, not <unistd.h>, otherwise OSF/1 5.1 DTK cc
|
||||||
eliminates this include because of the preliminary #include <unistd.h>
|
eliminates this include because of the preliminary #include <unistd.h>
|
||||||
above. */
|
above. */
|
||||||
|
#ifdef __ANROID__
|
||||||
|
#include <unistd.h>
|
||||||
|
#else
|
||||||
#include "unistd.h"
|
#include "unistd.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef HAVE_ACCESS
|
#ifndef HAVE_ACCESS
|
||||||
/* Mingw lacks access, but it also lacks real vs. effective ids, so
|
/* Mingw lacks access, but it also lacks real vs. effective ids, so
|
||||||
|
|
|
||||||
|
|
@ -33,13 +33,15 @@
|
||||||
size_t
|
size_t
|
||||||
__fpending (FILE *fp)
|
__fpending (FILE *fp)
|
||||||
{
|
{
|
||||||
|
#if defined __ANDROID__
|
||||||
|
return 0;
|
||||||
/* Most systems provide FILE as a struct and the necessary bitmask in
|
/* Most systems provide FILE as a struct and the necessary bitmask in
|
||||||
<stdio.h>, because they need it for implementing getc() and putc() as
|
<stdio.h>, because they need it for implementing getc() and putc() as
|
||||||
fast macros. */
|
fast macros. */
|
||||||
#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1
|
#elif defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1
|
||||||
/* GNU libc, BeOS, Haiku, Linux libc5 */
|
/* GNU libc, BeOS, Haiku, Linux libc5 */
|
||||||
return fp->_IO_write_ptr - fp->_IO_write_base;
|
return fp->_IO_write_ptr - fp->_IO_write_base;
|
||||||
#elif defined __sferror || defined __DragonFly__ || defined __ANDROID__
|
#elif defined __sferror || defined __DragonFly__
|
||||||
/* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin < 1.7.34, Minix 3, Android */
|
/* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin < 1.7.34, Minix 3, Android */
|
||||||
return fp->_p - fp->_bf._base;
|
return fp->_p - fp->_bf._base;
|
||||||
#elif defined __EMX__ /* emx+gcc */
|
#elif defined __EMX__ /* emx+gcc */
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,11 @@ orig_open (const char *filename, int flags, mode_t mode)
|
||||||
/* Specification. */
|
/* Specification. */
|
||||||
/* Write "fcntl.h" here, not <fcntl.h>, otherwise OSF/1 5.1 DTK cc eliminates
|
/* Write "fcntl.h" here, not <fcntl.h>, otherwise OSF/1 5.1 DTK cc eliminates
|
||||||
this include because of the preliminary #include <fcntl.h> above. */
|
this include because of the preliminary #include <fcntl.h> above. */
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
#include <fnctl.h>
|
||||||
|
#else
|
||||||
#include "fcntl.h"
|
#include "fcntl.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "cloexec.h"
|
#include "cloexec.h"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,5 +18,5 @@
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#define _GL_UNISTD_INLINE _GL_EXTERN_INLINE
|
#define _GL_UNISTD_INLINE _GL_EXTERN_INLINE
|
||||||
#include "unistd.h"
|
#include <unistd.h>
|
||||||
typedef int dummy;
|
typedef int dummy;
|
||||||
|
|
|
||||||
|
|
@ -2137,7 +2137,8 @@ frames and several different fonts at once. This is true for displays
|
||||||
that use a window system such as X, and false for text-only terminals.
|
that use a window system such as X, and false for text-only terminals.
|
||||||
DISPLAY can be a display name, a frame, or nil (meaning the selected
|
DISPLAY can be a display name, a frame, or nil (meaning the selected
|
||||||
frame's display)."
|
frame's display)."
|
||||||
(not (null (memq (framep-on-display display) '(x w32 ns pgtk haiku)))))
|
(not (null (memq (framep-on-display display) '(x w32 ns pgtk haiku
|
||||||
|
android)))))
|
||||||
|
|
||||||
(defun display-images-p (&optional display)
|
(defun display-images-p (&optional display)
|
||||||
"Return non-nil if DISPLAY can display images.
|
"Return non-nil if DISPLAY can display images.
|
||||||
|
|
@ -2202,7 +2203,7 @@ DISPLAY should be either a frame or a display name (a string).
|
||||||
If DISPLAY is omitted or nil, it defaults to the selected frame's display."
|
If DISPLAY is omitted or nil, it defaults to the selected frame's display."
|
||||||
(let ((frame-type (framep-on-display display)))
|
(let ((frame-type (framep-on-display display)))
|
||||||
(cond
|
(cond
|
||||||
((memq frame-type '(x w32 ns haiku pgtk))
|
((memq frame-type '(x w32 ns haiku pgtk android))
|
||||||
(x-display-screens display))
|
(x-display-screens display))
|
||||||
(t
|
(t
|
||||||
1))))
|
1))))
|
||||||
|
|
@ -2222,7 +2223,7 @@ with DISPLAY. To get information for each physical monitor, use
|
||||||
`display-monitor-attributes-list'."
|
`display-monitor-attributes-list'."
|
||||||
(let ((frame-type (framep-on-display display)))
|
(let ((frame-type (framep-on-display display)))
|
||||||
(cond
|
(cond
|
||||||
((memq frame-type '(x w32 ns haiku pgtk))
|
((memq frame-type '(x w32 ns haiku pgtk android))
|
||||||
(x-display-pixel-height display))
|
(x-display-pixel-height display))
|
||||||
(t
|
(t
|
||||||
(frame-height (if (framep display) display (selected-frame)))))))
|
(frame-height (if (framep display) display (selected-frame)))))))
|
||||||
|
|
@ -2242,7 +2243,7 @@ with DISPLAY. To get information for each physical monitor, use
|
||||||
`display-monitor-attributes-list'."
|
`display-monitor-attributes-list'."
|
||||||
(let ((frame-type (framep-on-display display)))
|
(let ((frame-type (framep-on-display display)))
|
||||||
(cond
|
(cond
|
||||||
((memq frame-type '(x w32 ns haiku pgtk))
|
((memq frame-type '(x w32 ns haiku pgtk android))
|
||||||
(x-display-pixel-width display))
|
(x-display-pixel-width display))
|
||||||
(t
|
(t
|
||||||
(frame-width (if (framep display) display (selected-frame)))))))
|
(frame-width (if (framep display) display (selected-frame)))))))
|
||||||
|
|
@ -2280,7 +2281,7 @@ For graphical terminals, note that on \"multi-monitor\" setups this
|
||||||
refers to the height in millimeters for all physical monitors
|
refers to the height in millimeters for all physical monitors
|
||||||
associated with DISPLAY. To get information for each physical
|
associated with DISPLAY. To get information for each physical
|
||||||
monitor, use `display-monitor-attributes-list'."
|
monitor, use `display-monitor-attributes-list'."
|
||||||
(and (memq (framep-on-display display) '(x w32 ns haiku pgtk))
|
(and (memq (framep-on-display display) '(x w32 ns haiku pgtk android))
|
||||||
(or (cddr (assoc (or display (frame-parameter nil 'display))
|
(or (cddr (assoc (or display (frame-parameter nil 'display))
|
||||||
display-mm-dimensions-alist))
|
display-mm-dimensions-alist))
|
||||||
(cddr (assoc t display-mm-dimensions-alist))
|
(cddr (assoc t display-mm-dimensions-alist))
|
||||||
|
|
@ -2301,7 +2302,7 @@ For graphical terminals, note that on \"multi-monitor\" setups this
|
||||||
refers to the width in millimeters for all physical monitors
|
refers to the width in millimeters for all physical monitors
|
||||||
associated with DISPLAY. To get information for each physical
|
associated with DISPLAY. To get information for each physical
|
||||||
monitor, use `display-monitor-attributes-list'."
|
monitor, use `display-monitor-attributes-list'."
|
||||||
(and (memq (framep-on-display display) '(x w32 ns haiku pgtk))
|
(and (memq (framep-on-display display) '(x w32 ns haiku pgtk android))
|
||||||
(or (cadr (assoc (or display (frame-parameter nil 'display))
|
(or (cadr (assoc (or display (frame-parameter nil 'display))
|
||||||
display-mm-dimensions-alist))
|
display-mm-dimensions-alist))
|
||||||
(cadr (assoc t display-mm-dimensions-alist))
|
(cadr (assoc t display-mm-dimensions-alist))
|
||||||
|
|
@ -2319,7 +2320,7 @@ DISPLAY can be a display name or a frame.
|
||||||
If DISPLAY is omitted or nil, it defaults to the selected frame's display."
|
If DISPLAY is omitted or nil, it defaults to the selected frame's display."
|
||||||
(let ((frame-type (framep-on-display display)))
|
(let ((frame-type (framep-on-display display)))
|
||||||
(cond
|
(cond
|
||||||
((memq frame-type '(x w32 ns haiku pgtk))
|
((memq frame-type '(x w32 ns haiku pgtk android))
|
||||||
(x-display-backing-store display))
|
(x-display-backing-store display))
|
||||||
(t
|
(t
|
||||||
'not-useful))))
|
'not-useful))))
|
||||||
|
|
@ -2332,7 +2333,7 @@ DISPLAY can be a display name or a frame.
|
||||||
If DISPLAY is omitted or nil, it defaults to the selected frame's display."
|
If DISPLAY is omitted or nil, it defaults to the selected frame's display."
|
||||||
(let ((frame-type (framep-on-display display)))
|
(let ((frame-type (framep-on-display display)))
|
||||||
(cond
|
(cond
|
||||||
((memq frame-type '(x w32 ns haiku pgtk))
|
((memq frame-type '(x w32 ns haiku pgtk android))
|
||||||
(x-display-save-under display))
|
(x-display-save-under display))
|
||||||
(t
|
(t
|
||||||
'not-useful))))
|
'not-useful))))
|
||||||
|
|
@ -2345,7 +2346,7 @@ DISPLAY can be a display name or a frame.
|
||||||
If DISPLAY is omitted or nil, it defaults to the selected frame's display."
|
If DISPLAY is omitted or nil, it defaults to the selected frame's display."
|
||||||
(let ((frame-type (framep-on-display display)))
|
(let ((frame-type (framep-on-display display)))
|
||||||
(cond
|
(cond
|
||||||
((memq frame-type '(x w32 ns haiku pgtk))
|
((memq frame-type '(x w32 ns haiku pgtk android))
|
||||||
(x-display-planes display))
|
(x-display-planes display))
|
||||||
((eq frame-type 'pc)
|
((eq frame-type 'pc)
|
||||||
4)
|
4)
|
||||||
|
|
@ -2360,7 +2361,7 @@ DISPLAY can be a display name or a frame.
|
||||||
If DISPLAY is omitted or nil, it defaults to the selected frame's display."
|
If DISPLAY is omitted or nil, it defaults to the selected frame's display."
|
||||||
(let ((frame-type (framep-on-display display)))
|
(let ((frame-type (framep-on-display display)))
|
||||||
(cond
|
(cond
|
||||||
((memq frame-type '(x w32 ns haiku pgtk))
|
((memq frame-type '(x w32 ns haiku pgtk android))
|
||||||
(x-display-color-cells display))
|
(x-display-color-cells display))
|
||||||
((eq frame-type 'pc)
|
((eq frame-type 'pc)
|
||||||
16)
|
16)
|
||||||
|
|
@ -2377,7 +2378,7 @@ DISPLAY can be a display name or a frame.
|
||||||
If DISPLAY is omitted or nil, it defaults to the selected frame's display."
|
If DISPLAY is omitted or nil, it defaults to the selected frame's display."
|
||||||
(let ((frame-type (framep-on-display display)))
|
(let ((frame-type (framep-on-display display)))
|
||||||
(cond
|
(cond
|
||||||
((memq frame-type '(x w32 ns haiku pgtk))
|
((memq frame-type '(x w32 ns haiku pgtk android))
|
||||||
(x-display-visual-class display))
|
(x-display-visual-class display))
|
||||||
((and (memq frame-type '(pc t))
|
((and (memq frame-type '(pc t))
|
||||||
(tty-display-color-p display))
|
(tty-display-color-p display))
|
||||||
|
|
|
||||||
|
|
@ -432,6 +432,8 @@ See also `wallpaper-default-width'.")
|
||||||
|
|
||||||
;;; wallpaper-set
|
;;; wallpaper-set
|
||||||
|
|
||||||
|
(declare-function x-open-connection "xfns.c")
|
||||||
|
|
||||||
(defun wallpaper--x-monitor-name ()
|
(defun wallpaper--x-monitor-name ()
|
||||||
"Get the monitor name for `wallpaper-set'.
|
"Get the monitor name for `wallpaper-set'.
|
||||||
On a graphical display, try using the same monitor as the current
|
On a graphical display, try using the same monitor as the current
|
||||||
|
|
|
||||||
|
|
@ -306,6 +306,11 @@
|
||||||
(load "term/common-win")
|
(load "term/common-win")
|
||||||
(load "term/haiku-win")))
|
(load "term/haiku-win")))
|
||||||
|
|
||||||
|
(if (featurep 'android)
|
||||||
|
(progn
|
||||||
|
(load "term/common-win")
|
||||||
|
(load "term/android-win")))
|
||||||
|
|
||||||
(if (or (eq system-type 'windows-nt)
|
(if (or (eq system-type 'windows-nt)
|
||||||
(featurep 'w32))
|
(featurep 'w32))
|
||||||
(progn
|
(progn
|
||||||
|
|
|
||||||
|
|
@ -240,7 +240,7 @@ parameter, and should return the (possibly) transformed URL."
|
||||||
:version "29.1")
|
:version "29.1")
|
||||||
|
|
||||||
(defface eww-form-submit
|
(defface eww-form-submit
|
||||||
'((((type x w32 ns haiku pgtk) (class color)) ; Like default mode line
|
'((((type x w32 ns haiku pgtk android) (class color)) ; Like default mode line
|
||||||
:box (:line-width 2 :style released-button)
|
:box (:line-width 2 :style released-button)
|
||||||
:background "#808080" :foreground "black"))
|
:background "#808080" :foreground "black"))
|
||||||
"Face for eww buffer buttons."
|
"Face for eww buffer buttons."
|
||||||
|
|
@ -248,7 +248,7 @@ parameter, and should return the (possibly) transformed URL."
|
||||||
:group 'eww)
|
:group 'eww)
|
||||||
|
|
||||||
(defface eww-form-file
|
(defface eww-form-file
|
||||||
'((((type x w32 ns haiku pgtk) (class color)) ; Like default mode line
|
'((((type x w32 ns haiku pgtk android) (class color)) ; Like default mode line
|
||||||
:box (:line-width 2 :style released-button)
|
:box (:line-width 2 :style released-button)
|
||||||
:background "#808080" :foreground "black"))
|
:background "#808080" :foreground "black"))
|
||||||
"Face for eww buffer buttons."
|
"Face for eww buffer buttons."
|
||||||
|
|
@ -256,7 +256,7 @@ parameter, and should return the (possibly) transformed URL."
|
||||||
:group 'eww)
|
:group 'eww)
|
||||||
|
|
||||||
(defface eww-form-checkbox
|
(defface eww-form-checkbox
|
||||||
'((((type x w32 ns haiku pgtk) (class color)) ; Like default mode line
|
'((((type x w32 ns haiku pgtk android) (class color)) ; Like default mode line
|
||||||
:box (:line-width 2 :style released-button)
|
:box (:line-width 2 :style released-button)
|
||||||
:background "lightgrey" :foreground "black"))
|
:background "lightgrey" :foreground "black"))
|
||||||
"Face for eww buffer buttons."
|
"Face for eww buffer buttons."
|
||||||
|
|
@ -264,7 +264,7 @@ parameter, and should return the (possibly) transformed URL."
|
||||||
:group 'eww)
|
:group 'eww)
|
||||||
|
|
||||||
(defface eww-form-select
|
(defface eww-form-select
|
||||||
'((((type x w32 ns haiku pgtk) (class color)) ; Like default mode line
|
'((((type x w32 ns haiku pgtk android) (class color)) ; Like default mode line
|
||||||
:box (:line-width 2 :style released-button)
|
:box (:line-width 2 :style released-button)
|
||||||
:background "lightgrey" :foreground "black"))
|
:background "lightgrey" :foreground "black"))
|
||||||
"Face for eww buffer buttons."
|
"Face for eww buffer buttons."
|
||||||
|
|
|
||||||
62
lisp/term/android-win.el
Normal file
62
lisp/term/android-win.el
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
;;; x-win.el --- parse relevant switches and set up for Android -*- lexical-binding:t -*-
|
||||||
|
|
||||||
|
;; Copyright (C) 2023 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
;; Author: FSF
|
||||||
|
;; Keywords: terminals, i18n, android
|
||||||
|
|
||||||
|
;; This file is part of GNU Emacs.
|
||||||
|
|
||||||
|
;; GNU Emacs is free software: you can redistribute it and/or modify
|
||||||
|
;; it under the terms of the GNU General Public License as published by
|
||||||
|
;; the Free Software Foundation, either version 3 of the License, or
|
||||||
|
;; (at your option) any later version.
|
||||||
|
|
||||||
|
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||||
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
;; GNU General Public License for more details.
|
||||||
|
|
||||||
|
;; You should have received a copy of the GNU General Public License
|
||||||
|
;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
|
||||||
|
;; This file contains the support for initializing the Lisp side of
|
||||||
|
;; Android windowing.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
|
||||||
|
(unless (featurep 'android)
|
||||||
|
(error "%s: Loading android-win without having Android"
|
||||||
|
invocation-name))
|
||||||
|
|
||||||
|
;; Documentation-purposes only: actually loaded in loadup.el.
|
||||||
|
(require 'frame)
|
||||||
|
(require 'mouse)
|
||||||
|
(require 'fontset)
|
||||||
|
(require 'dnd)
|
||||||
|
|
||||||
|
(add-to-list 'display-format-alist '(".*" . android))
|
||||||
|
|
||||||
|
;; Window system initialization. This is extremely simple because all
|
||||||
|
;; initialization is done in android_term_init.
|
||||||
|
|
||||||
|
(cl-defmethod window-system-initialization (&context (window-system android)
|
||||||
|
&optional _ignored)
|
||||||
|
"Set up the window system. WINDOW-SYSTEM must be ANDROID.
|
||||||
|
DISPLAY is ignored on Android."
|
||||||
|
;; Just make sure the window system was initialized at startup.
|
||||||
|
(android-get-connection))
|
||||||
|
|
||||||
|
(cl-defmethod frame-creation-function (params &context (window-system android))
|
||||||
|
(x-create-frame-with-faces params))
|
||||||
|
|
||||||
|
(cl-defmethod handle-args-function (_ignored &context (window-system android))
|
||||||
|
;; Nothing to do here: Android has no command line to provide
|
||||||
|
;; arguments on.
|
||||||
|
(ignore))
|
||||||
|
|
||||||
|
(provide 'android-win)
|
||||||
|
;; android-win.el ends here.
|
||||||
|
|
@ -33,6 +33,16 @@ top_builddir = @top_builddir@
|
||||||
# MinGW CPPFLAGS may use this.
|
# MinGW CPPFLAGS may use this.
|
||||||
abs_top_srcdir=@abs_top_srcdir@
|
abs_top_srcdir=@abs_top_srcdir@
|
||||||
VPATH = $(srcdir)
|
VPATH = $(srcdir)
|
||||||
|
|
||||||
|
# This is not empty if this is a Makefile that will be copied to
|
||||||
|
# xcompile/src.
|
||||||
|
XCONFIGURE = @XCONFIGURE@
|
||||||
|
|
||||||
|
ifneq ($(XCONFIGURE),)
|
||||||
|
vpath %.c := $(srcdir)
|
||||||
|
vpath %.h := $(srcdir)
|
||||||
|
endif
|
||||||
|
|
||||||
CC = @CC@
|
CC = @CC@
|
||||||
CXX = @CXX@
|
CXX = @CXX@
|
||||||
CFLAGS = @CFLAGS@
|
CFLAGS = @CFLAGS@
|
||||||
|
|
@ -48,6 +58,7 @@ LIBOBJS = @LIBOBJS@
|
||||||
|
|
||||||
lispsource = $(top_srcdir)/lisp
|
lispsource = $(top_srcdir)/lisp
|
||||||
lib = ../lib
|
lib = ../lib
|
||||||
|
hostlib = $(top_builddir)/lib
|
||||||
libsrc = ../lib-src
|
libsrc = ../lib-src
|
||||||
etc = ../etc
|
etc = ../etc
|
||||||
oldXMenudir = ../oldXMenu
|
oldXMenudir = ../oldXMenu
|
||||||
|
|
@ -326,7 +337,7 @@ W32_RES_LINK=@W32_RES_LINK@
|
||||||
## if HAVE_HARFBUZZ, hbfont.o is added regardless of the rest
|
## if HAVE_HARFBUZZ, hbfont.o is added regardless of the rest
|
||||||
FONT_OBJ=@FONT_OBJ@
|
FONT_OBJ=@FONT_OBJ@
|
||||||
|
|
||||||
## Empty for MinGW, cm.o for the rest.
|
## Empty for MinGW and Android, cm.o for the rest.
|
||||||
CM_OBJ=@CM_OBJ@
|
CM_OBJ=@CM_OBJ@
|
||||||
|
|
||||||
LIBGPM = @LIBGPM@
|
LIBGPM = @LIBGPM@
|
||||||
|
|
@ -370,6 +381,10 @@ HAIKU_CXX_OBJ = @HAIKU_CXX_OBJ@
|
||||||
HAIKU_LIBS = @HAIKU_LIBS@
|
HAIKU_LIBS = @HAIKU_LIBS@
|
||||||
HAIKU_CFLAGS = @HAIKU_CFLAGS@
|
HAIKU_CFLAGS = @HAIKU_CFLAGS@
|
||||||
|
|
||||||
|
ANDROID_OBJ = @ANDROID_OBJ@
|
||||||
|
ANDROID_LIBS = @ANDROID_LIBS@
|
||||||
|
ANDROID_CFLAGS = @ANDROID_CFLAGS@
|
||||||
|
|
||||||
DUMPING=@DUMPING@
|
DUMPING=@DUMPING@
|
||||||
CHECK_STRUCTS = @CHECK_STRUCTS@
|
CHECK_STRUCTS = @CHECK_STRUCTS@
|
||||||
HAVE_PDUMPER = @HAVE_PDUMPER@
|
HAVE_PDUMPER = @HAVE_PDUMPER@
|
||||||
|
|
@ -411,7 +426,8 @@ EMACS_CFLAGS=-Demacs $(MYCPPFLAGS) -I. -I$(srcdir) \
|
||||||
$(HARFBUZZ_CFLAGS) $(LIBOTF_CFLAGS) $(M17N_FLT_CFLAGS) $(DEPFLAGS) \
|
$(HARFBUZZ_CFLAGS) $(LIBOTF_CFLAGS) $(M17N_FLT_CFLAGS) $(DEPFLAGS) \
|
||||||
$(LIBSYSTEMD_CFLAGS) $(JSON_CFLAGS) $(XSYNC_CFLAGS) $(TREE_SITTER_CFLAGS) \
|
$(LIBSYSTEMD_CFLAGS) $(JSON_CFLAGS) $(XSYNC_CFLAGS) $(TREE_SITTER_CFLAGS) \
|
||||||
$(LIBGNUTLS_CFLAGS) $(NOTIFY_CFLAGS) $(CAIRO_CFLAGS) \
|
$(LIBGNUTLS_CFLAGS) $(NOTIFY_CFLAGS) $(CAIRO_CFLAGS) \
|
||||||
$(WERROR_CFLAGS) $(HAIKU_CFLAGS) $(XCOMPOSITE_CFLAGS) $(XSHAPE_CFLAGS)
|
$(WERROR_CFLAGS) $(HAIKU_CFLAGS) $(XCOMPOSITE_CFLAGS) $(XSHAPE_CFLAGS) \
|
||||||
|
$(ANDROID_CFLAGS)
|
||||||
ALL_CFLAGS = $(EMACS_CFLAGS) $(WARN_CFLAGS) $(CFLAGS)
|
ALL_CFLAGS = $(EMACS_CFLAGS) $(WARN_CFLAGS) $(CFLAGS)
|
||||||
ALL_OBJC_CFLAGS = $(EMACS_CFLAGS) \
|
ALL_OBJC_CFLAGS = $(EMACS_CFLAGS) \
|
||||||
$(filter-out $(NON_OBJC_CFLAGS),$(WARN_CFLAGS)) $(CFLAGS) \
|
$(filter-out $(NON_OBJC_CFLAGS),$(WARN_CFLAGS)) $(CFLAGS) \
|
||||||
|
|
@ -449,7 +465,7 @@ base_obj = dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o \
|
||||||
$(if $(HYBRID_MALLOC),sheap.o) \
|
$(if $(HYBRID_MALLOC),sheap.o) \
|
||||||
$(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ) \
|
$(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ) \
|
||||||
$(W32_OBJ) $(WINDOW_SYSTEM_OBJ) $(XGSELOBJ) $(JSON_OBJ) \
|
$(W32_OBJ) $(WINDOW_SYSTEM_OBJ) $(XGSELOBJ) $(JSON_OBJ) \
|
||||||
$(HAIKU_OBJ) $(PGTK_OBJ)
|
$(HAIKU_OBJ) $(PGTK_OBJ) $(ANDROID_OBJ)
|
||||||
doc_obj = $(base_obj) $(NS_OBJC_OBJ)
|
doc_obj = $(base_obj) $(NS_OBJC_OBJ)
|
||||||
obj = $(doc_obj) $(HAIKU_CXX_OBJ)
|
obj = $(doc_obj) $(HAIKU_CXX_OBJ)
|
||||||
|
|
||||||
|
|
@ -466,7 +482,8 @@ SOME_MACHINE_OBJECTS = dosfns.o msdos.o \
|
||||||
w32menu.o w32proc.o w32reg.o w32select.o w32term.o w32xfns.o \
|
w32menu.o w32proc.o w32reg.o w32select.o w32term.o w32xfns.o \
|
||||||
w16select.o widget.o xfont.o ftfont.o xftfont.o gtkutil.o \
|
w16select.o widget.o xfont.o ftfont.o xftfont.o gtkutil.o \
|
||||||
xsettings.o xgselect.o termcap.o hbfont.o \
|
xsettings.o xgselect.o termcap.o hbfont.o \
|
||||||
haikuterm.o haikufns.o haikumenu.o haikufont.o
|
haikuterm.o haikufns.o haikumenu.o haikufont.o androidterm.o androidfns.o \
|
||||||
|
androidfont.o
|
||||||
|
|
||||||
## gmalloc.o if !SYSTEM_MALLOC && !DOUG_LEA_MALLOC, else empty.
|
## gmalloc.o if !SYSTEM_MALLOC && !DOUG_LEA_MALLOC, else empty.
|
||||||
GMALLOC_OBJ=@GMALLOC_OBJ@
|
GMALLOC_OBJ=@GMALLOC_OBJ@
|
||||||
|
|
@ -569,7 +586,8 @@ LIBES = $(LIBS) $(W32_LIBS) $(LIBS_GNUSTEP) $(PGTK_LIBS) $(LIBX_BASE) $(LIBIMAGE
|
||||||
$(LIBGNUTLS_LIBS) $(LIB_PTHREAD) $(GETADDRINFO_A_LIBS) $(LCMS2_LIBS) \
|
$(LIBGNUTLS_LIBS) $(LIB_PTHREAD) $(GETADDRINFO_A_LIBS) $(LCMS2_LIBS) \
|
||||||
$(NOTIFY_LIBS) $(LIB_MATH) $(LIBZ) $(LIBMODULES) $(LIBSYSTEMD_LIBS) \
|
$(NOTIFY_LIBS) $(LIB_MATH) $(LIBZ) $(LIBMODULES) $(LIBSYSTEMD_LIBS) \
|
||||||
$(JSON_LIBS) $(LIBGMP) $(LIBGCCJIT_LIBS) $(XINPUT_LIBS) $(HAIKU_LIBS) \
|
$(JSON_LIBS) $(LIBGMP) $(LIBGCCJIT_LIBS) $(XINPUT_LIBS) $(HAIKU_LIBS) \
|
||||||
$(TREE_SITTER_LIBS) $(SQLITE3_LIBS) $(XCOMPOSITE_LIBS) $(XSHAPE_LIBS)
|
$(TREE_SITTER_LIBS) $(SQLITE3_LIBS) $(XCOMPOSITE_LIBS) $(XSHAPE_LIBS) \
|
||||||
|
$(ANDROID_LIBS)
|
||||||
|
|
||||||
## FORCE it so that admin/unidata can decide whether this file is
|
## FORCE it so that admin/unidata can decide whether this file is
|
||||||
## up-to-date. Although since charprop depends on bootstrap-emacs,
|
## up-to-date. Although since charprop depends on bootstrap-emacs,
|
||||||
|
|
@ -658,7 +676,7 @@ $(etc)/DOC: $(libsrc)/make-docfile$(EXEEXT) $(doc_obj)
|
||||||
$(SOME_MACHINE_OBJECTS) $(doc_obj) > $(etc)/DOC
|
$(SOME_MACHINE_OBJECTS) $(doc_obj) > $(etc)/DOC
|
||||||
|
|
||||||
$(libsrc)/make-docfile$(EXEEXT) $(libsrc)/make-fingerprint$(EXEEXT): \
|
$(libsrc)/make-docfile$(EXEEXT) $(libsrc)/make-fingerprint$(EXEEXT): \
|
||||||
$(lib)/libgnu.a
|
$(hostlib)/libgnu.a
|
||||||
$(MAKE) -C $(dir $@) $(notdir $@)
|
$(MAKE) -C $(dir $@) $(notdir $@)
|
||||||
|
|
||||||
buildobj.h: Makefile
|
buildobj.h: Makefile
|
||||||
|
|
@ -719,6 +737,27 @@ ifeq ($(DUMPING),unexec)
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(XCONFIGURE),android)
|
||||||
|
## The Android package internally links to and communicates with a
|
||||||
|
## shared library named `libemacs.so' at startup. This is built
|
||||||
|
## almost the same way temacs is. But it is position independent. It
|
||||||
|
## is not dumped here. Instead, it dumps itself the first time it
|
||||||
|
## starts on the user's device.
|
||||||
|
|
||||||
|
libemacs.so: $(ALLOBJS) $(LIBEGNU_ARCHIVE) $(EMACSRES) \
|
||||||
|
$(MAKE_PDUMPER_FINGERPRINT)
|
||||||
|
$(AM_V_CCLD)$(CC) -o $@ $(ALL_CFLAGS) $(TEMACS_LDFLAGS) \
|
||||||
|
$(LDFLAGS) -shared $(ALLOBJS) $(LIBEGNU_ARCHIVE) $(LIBES)
|
||||||
|
$(AM_V_at)$(MAKE_PDUMPER_FINGERPRINT) $@
|
||||||
|
|
||||||
|
# There is also a binary named `android-emacs' which simply calls
|
||||||
|
# emacs.so.
|
||||||
|
|
||||||
|
android-emacs: libemacs.so android-emacs.o
|
||||||
|
$(AM_V_CCLD)$(CC) -o $@ $(ALL_CFLAGS) $(LDFLAGS) \
|
||||||
|
-L. "-l:libemacs.so" android-emacs.o
|
||||||
|
endif
|
||||||
|
|
||||||
## The following oldxmenu-related rules are only (possibly) used if
|
## The following oldxmenu-related rules are only (possibly) used if
|
||||||
## HAVE_X11 && !USE_GTK, but there is no harm in always defining them.
|
## HAVE_X11 && !USE_GTK, but there is no harm in always defining them.
|
||||||
$(lwlibdir)/liblw.a: $(config_h) globals.h lisp.h FORCE
|
$(lwlibdir)/liblw.a: $(config_h) globals.h lisp.h FORCE
|
||||||
|
|
@ -747,6 +786,7 @@ ns-app: emacs$(EXEEXT) $(pdmp)
|
||||||
.PHONY: versionclean
|
.PHONY: versionclean
|
||||||
|
|
||||||
mostlyclean:
|
mostlyclean:
|
||||||
|
rm -f aemacs emacs.so
|
||||||
rm -f temacs$(EXEEXT) core ./*.core \#* ./*.o
|
rm -f temacs$(EXEEXT) core ./*.core \#* ./*.o
|
||||||
rm -f dmpstruct.h
|
rm -f dmpstruct.h
|
||||||
rm -f emacs.pdmp
|
rm -f emacs.pdmp
|
||||||
|
|
|
||||||
12
src/alloc.c
12
src/alloc.c
|
|
@ -3342,6 +3342,14 @@ cleanup_vector (struct Lisp_Vector *vector)
|
||||||
drv->close_font (font);
|
drv->close_font (font);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
|
||||||
|
/* The Android font driver needs the ability to associate extra
|
||||||
|
information with font entities. */
|
||||||
|
if ((vector->header.size & PSEUDOVECTOR_SIZE_MASK)
|
||||||
|
== FONT_ENTITY_MAX)
|
||||||
|
android_finalize_font_entity (PSEUDOVEC_STRUCT (vector, font_entity));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_THREAD))
|
else if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_THREAD))
|
||||||
finalize_one_thread (PSEUDOVEC_STRUCT (vector, thread_state));
|
finalize_one_thread (PSEUDOVEC_STRUCT (vector, thread_state));
|
||||||
|
|
@ -6467,6 +6475,10 @@ garbage_collect (void)
|
||||||
mark_xselect ();
|
mark_xselect ();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_ANDROID
|
||||||
|
mark_androidterm ();
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_NS
|
#ifdef HAVE_NS
|
||||||
mark_nsterm ();
|
mark_nsterm ();
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
30
src/android-emacs.c
Normal file
30
src/android-emacs.c
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
/* Android initialization for GNU Emacs.
|
||||||
|
|
||||||
|
Copyright (C) 2023 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GNU Emacs.
|
||||||
|
|
||||||
|
GNU Emacs is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
your option) any later version.
|
||||||
|
|
||||||
|
GNU Emacs is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
#include "android.h"
|
||||||
|
|
||||||
|
/* android-emacs is a wrapper around libemacs. It simply calls
|
||||||
|
android_emacs_init with the argv and argc given to it. */
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
return android_emacs_init (argc, argv);
|
||||||
|
}
|
||||||
2335
src/android.c
Normal file
2335
src/android.c
Normal file
File diff suppressed because it is too large
Load diff
70
src/android.h
Normal file
70
src/android.h
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
/* Android initialization for GNU Emacs.
|
||||||
|
|
||||||
|
Copyright (C) 2023 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GNU Emacs.
|
||||||
|
|
||||||
|
GNU Emacs is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
your option) any later version.
|
||||||
|
|
||||||
|
GNU Emacs is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* On Android, Emacs is built as a shared library loaded from Java
|
||||||
|
using the Java Native Interface. Emacs's `main' function is
|
||||||
|
renamed `android_emacs_init', and runs with some modifications
|
||||||
|
inside a separate thread, communicating with the Java code through
|
||||||
|
a table of function pointers. */
|
||||||
|
|
||||||
|
#ifndef _ANDROID_H_
|
||||||
|
#ifndef ANDROID_STUBIFY
|
||||||
|
#include <jni.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* This must be used in every symbol declaration to export it to the
|
||||||
|
JNI Emacs wrapper. */
|
||||||
|
#define ANDROID_EXPORT __attribute__ ((visibility ("default")))
|
||||||
|
|
||||||
|
extern bool ANDROID_EXPORT android_init_gui;
|
||||||
|
extern int ANDROID_EXPORT android_emacs_init (int, char **);
|
||||||
|
|
||||||
|
#ifndef ANDROID_STUBIFY
|
||||||
|
|
||||||
|
extern int android_select (int, fd_set *, fd_set *, fd_set *,
|
||||||
|
struct timespec *, const sigset_t *);
|
||||||
|
|
||||||
|
extern bool android_file_access_p (const char *, int);
|
||||||
|
extern int android_open (const char *, int, int);
|
||||||
|
extern char *android_user_full_name (struct passwd *);
|
||||||
|
extern int android_fstat (int, struct stat *);
|
||||||
|
extern int android_fstatat (int, const char *restrict,
|
||||||
|
struct stat *restrict, int);
|
||||||
|
extern int android_close (int);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* JNI functions should not be built when Emacs is stubbed out for the
|
||||||
|
build. These should be documented in EmacsNative.java. */
|
||||||
|
|
||||||
|
#ifndef ANDROID_STUBIFY
|
||||||
|
#include <jni.h>
|
||||||
|
|
||||||
|
extern JNIEnv *android_java_env;
|
||||||
|
|
||||||
|
#define ANDROID_DELETE_LOCAL_REF(ref) \
|
||||||
|
((*android_java_env)->DeleteLocalRef (android_java_env, \
|
||||||
|
(ref)))
|
||||||
|
|
||||||
|
#define NATIVE_NAME(name) Java_org_gnu_emacs_EmacsNative_##name
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif /* _ANDROID_H_ */
|
||||||
1779
src/androidfns.c
Normal file
1779
src/androidfns.c
Normal file
File diff suppressed because it is too large
Load diff
955
src/androidfont.c
Normal file
955
src/androidfont.c
Normal file
|
|
@ -0,0 +1,955 @@
|
||||||
|
/* Communication module for Android terminals.
|
||||||
|
|
||||||
|
Copyright (C) 2023 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GNU Emacs.
|
||||||
|
|
||||||
|
GNU Emacs is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
your option) any later version.
|
||||||
|
|
||||||
|
GNU Emacs is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include "lisp.h"
|
||||||
|
#include "dispextern.h"
|
||||||
|
#include "composite.h"
|
||||||
|
#include "blockinput.h"
|
||||||
|
#include "charset.h"
|
||||||
|
#include "frame.h"
|
||||||
|
#include "window.h"
|
||||||
|
#include "fontset.h"
|
||||||
|
#include "androidterm.h"
|
||||||
|
#include "character.h"
|
||||||
|
#include "coding.h"
|
||||||
|
#include "font.h"
|
||||||
|
#include "termchar.h"
|
||||||
|
#include "pdumper.h"
|
||||||
|
#include "android.h"
|
||||||
|
|
||||||
|
#ifndef ANDROID_STUBIFY
|
||||||
|
|
||||||
|
#include <android/log.h>
|
||||||
|
|
||||||
|
struct android_emacs_font_driver
|
||||||
|
{
|
||||||
|
jclass class;
|
||||||
|
jmethodID list;
|
||||||
|
jmethodID match;
|
||||||
|
jmethodID list_families;
|
||||||
|
jmethodID open_font;
|
||||||
|
jmethodID has_char;
|
||||||
|
jmethodID text_extents;
|
||||||
|
jmethodID encode_char;
|
||||||
|
|
||||||
|
/* Static methods. */
|
||||||
|
jmethodID create_font_driver;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct android_emacs_font_spec
|
||||||
|
{
|
||||||
|
jclass class;
|
||||||
|
jfieldID foundry;
|
||||||
|
jfieldID family;
|
||||||
|
jfieldID adstyle;
|
||||||
|
jfieldID registry;
|
||||||
|
jfieldID width;
|
||||||
|
jfieldID weight;
|
||||||
|
jfieldID slant;
|
||||||
|
jfieldID size;
|
||||||
|
jfieldID spacing;
|
||||||
|
jfieldID avgwidth;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct android_emacs_font_metrics
|
||||||
|
{
|
||||||
|
jclass class;
|
||||||
|
jfieldID lbearing;
|
||||||
|
jfieldID rbearing;
|
||||||
|
jfieldID width;
|
||||||
|
jfieldID ascent;
|
||||||
|
jfieldID descent;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct android_emacs_font_object
|
||||||
|
{
|
||||||
|
jclass class;
|
||||||
|
jfieldID min_width;
|
||||||
|
jfieldID max_width;
|
||||||
|
jfieldID pixel_size;
|
||||||
|
jfieldID height;
|
||||||
|
jfieldID space_width;
|
||||||
|
jfieldID average_width;
|
||||||
|
jfieldID ascent;
|
||||||
|
jfieldID descent;
|
||||||
|
jfieldID underline_thickness;
|
||||||
|
jfieldID underline_position;
|
||||||
|
jfieldID baseline_offset;
|
||||||
|
jfieldID relative_compose;
|
||||||
|
jfieldID default_ascent;
|
||||||
|
jfieldID encoding_charset;
|
||||||
|
jfieldID repertory_charset;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct android_integer
|
||||||
|
{
|
||||||
|
jclass class;
|
||||||
|
jmethodID constructor;
|
||||||
|
jmethodID int_value;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct androidfont_info
|
||||||
|
{
|
||||||
|
/* The font pseudo-vector object. */
|
||||||
|
struct font font;
|
||||||
|
|
||||||
|
/* The Java-side font. */
|
||||||
|
jobject object;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct androidfont_entity
|
||||||
|
{
|
||||||
|
/* The font entity pvec. */
|
||||||
|
struct font_entity font;
|
||||||
|
|
||||||
|
/* The Java-side font entity. */
|
||||||
|
jobject object;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Method and class identifiers associated with the EmacsFontDriver
|
||||||
|
class. */
|
||||||
|
|
||||||
|
struct android_emacs_font_driver font_driver_class;
|
||||||
|
|
||||||
|
/* Field and class identifiers associated with the
|
||||||
|
EmacsFontDriver$FontSpec class. */
|
||||||
|
|
||||||
|
struct android_emacs_font_spec font_spec_class;
|
||||||
|
|
||||||
|
/* Method and class identifiers associated with the Integer class. */
|
||||||
|
|
||||||
|
struct android_integer integer_class;
|
||||||
|
|
||||||
|
/* Field and class identifiers associated with the
|
||||||
|
EmacsFontDriver$FontMetrics class. */
|
||||||
|
|
||||||
|
struct android_emacs_font_metrics font_metrics_class;
|
||||||
|
|
||||||
|
/* Field and class identifiers associated with the
|
||||||
|
EmacsFontDriver$FontObject class. */
|
||||||
|
|
||||||
|
struct android_emacs_font_object font_object_class;
|
||||||
|
|
||||||
|
/* The font cache. */
|
||||||
|
|
||||||
|
static Lisp_Object font_cache;
|
||||||
|
|
||||||
|
/* The Java-side font driver. */
|
||||||
|
|
||||||
|
static jobject font_driver;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Initialize the class and method identifiers for functions in the
|
||||||
|
EmacsFontDriver class, and place them in `font_driver_class'. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
android_init_font_driver (void)
|
||||||
|
{
|
||||||
|
jclass old;
|
||||||
|
|
||||||
|
font_driver_class.class
|
||||||
|
= (*android_java_env)->FindClass (android_java_env,
|
||||||
|
"org/gnu/emacs/EmacsFontDriver");
|
||||||
|
eassert (font_driver_class.class);
|
||||||
|
|
||||||
|
old = font_driver_class.class;
|
||||||
|
font_driver_class.class
|
||||||
|
= (jclass) (*android_java_env)->NewGlobalRef (android_java_env,
|
||||||
|
(jobject) old);
|
||||||
|
ANDROID_DELETE_LOCAL_REF (old);
|
||||||
|
|
||||||
|
if (!font_driver_class.class)
|
||||||
|
emacs_abort ();
|
||||||
|
|
||||||
|
#define FIND_METHOD(c_name, name, signature) \
|
||||||
|
font_driver_class.c_name \
|
||||||
|
= (*android_java_env)->GetMethodID (android_java_env, \
|
||||||
|
font_driver_class.class, \
|
||||||
|
name, signature); \
|
||||||
|
eassert (font_driver_class.c_name);
|
||||||
|
|
||||||
|
FIND_METHOD (list, "list", "(Lorg/gnu/emacs/EmacsFontDriver$FontSpec;)"
|
||||||
|
"[Lorg/gnu/emacs/EmacsFontDriver$FontEntity;");
|
||||||
|
FIND_METHOD (match, "match", "(Lorg/gnu/emacs/EmacsFontDriver$FontSpec;)"
|
||||||
|
"Lorg/gnu/emacs/EmacsFontDriver$FontEntity;");
|
||||||
|
FIND_METHOD (list_families, "listFamilies", "()[Ljava/lang/String;");
|
||||||
|
FIND_METHOD (open_font, "openFont", "(Lorg/gnu/emacs/EmacsFontDriver$Font"
|
||||||
|
"Entity;I)Lorg/gnu/emacs/EmacsFontDriver$FontObject;");
|
||||||
|
FIND_METHOD (has_char, "hasChar", "(Lorg/gnu/emacs/EmacsFontDriver$Font"
|
||||||
|
"Spec;C)I");
|
||||||
|
FIND_METHOD (text_extents, "textExtents", "(Lorg/gnu/emacs/EmacsFontDriver"
|
||||||
|
"$FontObject;[I[Lorg/gnu/emacs/EmacsFontDriver$FontMetrics;)V");
|
||||||
|
FIND_METHOD (encode_char, "encodeChar", "(Lorg/gnu/emacs/EmacsFontDriver"
|
||||||
|
"$FontObject;C)I");
|
||||||
|
|
||||||
|
font_driver_class.create_font_driver
|
||||||
|
= (*android_java_env)->GetStaticMethodID (android_java_env,
|
||||||
|
font_driver_class.class,
|
||||||
|
"createFontDriver",
|
||||||
|
"()Lorg/gnu/emacs/"
|
||||||
|
"EmacsFontDriver;");
|
||||||
|
eassert (font_driver_class.create_font_driver);
|
||||||
|
#undef FIND_METHOD
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize the class and field identifiers for functions in the
|
||||||
|
EmacsFontDriver$FontSpec class, and place them in
|
||||||
|
`font_spec_class'. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
android_init_font_spec (void)
|
||||||
|
{
|
||||||
|
jclass old;
|
||||||
|
|
||||||
|
font_spec_class.class
|
||||||
|
= (*android_java_env)->FindClass (android_java_env,
|
||||||
|
"org/gnu/emacs/EmacsFontDriver"
|
||||||
|
"$FontSpec");
|
||||||
|
eassert (font_spec_class.class);
|
||||||
|
|
||||||
|
old = font_spec_class.class;
|
||||||
|
font_spec_class.class
|
||||||
|
= (jclass) (*android_java_env)->NewGlobalRef (android_java_env,
|
||||||
|
(jobject) old);
|
||||||
|
ANDROID_DELETE_LOCAL_REF (old);
|
||||||
|
|
||||||
|
if (!font_spec_class.class)
|
||||||
|
emacs_abort ();
|
||||||
|
|
||||||
|
#define FIND_FIELD(c_name, name, signature) \
|
||||||
|
font_spec_class.c_name \
|
||||||
|
= (*android_java_env)->GetFieldID (android_java_env, \
|
||||||
|
font_spec_class.class, \
|
||||||
|
name, signature); \
|
||||||
|
eassert (font_spec_class.c_name);
|
||||||
|
|
||||||
|
FIND_FIELD (foundry, "foundry", "Ljava/lang/String;");
|
||||||
|
FIND_FIELD (family, "family", "Ljava/lang/String;");
|
||||||
|
FIND_FIELD (adstyle, "adstyle", "Ljava/lang/String;");
|
||||||
|
FIND_FIELD (registry, "registry", "Ljava/lang/String;");
|
||||||
|
FIND_FIELD (width, "width", "Ljava/lang/Integer;");
|
||||||
|
FIND_FIELD (weight, "weight", "Ljava/lang/Integer;");
|
||||||
|
FIND_FIELD (slant, "slant", "Ljava/lang/Integer;");
|
||||||
|
FIND_FIELD (size, "size", "Ljava/lang/Integer;");
|
||||||
|
FIND_FIELD (spacing, "spacing", "Ljava/lang/Integer;");
|
||||||
|
FIND_FIELD (avgwidth, "avgwidth", "Ljava/lang/Integer;");
|
||||||
|
#undef FIND_FIELD
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
android_init_font_metrics (void)
|
||||||
|
{
|
||||||
|
jclass old;
|
||||||
|
|
||||||
|
font_metrics_class.class
|
||||||
|
= (*android_java_env)->FindClass (android_java_env,
|
||||||
|
"org/gnu/emacs/EmacsFontDriver"
|
||||||
|
"$FontMetrics");
|
||||||
|
eassert (font_metrics_class.class);
|
||||||
|
|
||||||
|
old = font_metrics_class.class;
|
||||||
|
font_metrics_class.class
|
||||||
|
= (jclass) (*android_java_env)->NewGlobalRef (android_java_env,
|
||||||
|
(jobject) old);
|
||||||
|
ANDROID_DELETE_LOCAL_REF (old);
|
||||||
|
|
||||||
|
if (!font_metrics_class.class)
|
||||||
|
emacs_abort ();
|
||||||
|
|
||||||
|
#define FIND_FIELD(c_name, name, signature) \
|
||||||
|
font_metrics_class.c_name \
|
||||||
|
= (*android_java_env)->GetFieldID (android_java_env, \
|
||||||
|
font_metrics_class.class, \
|
||||||
|
name, signature); \
|
||||||
|
eassert (font_metrics_class.c_name);
|
||||||
|
|
||||||
|
FIND_FIELD (lbearing, "lbearing", "S");
|
||||||
|
FIND_FIELD (rbearing, "rbearing", "S");
|
||||||
|
FIND_FIELD (width, "width", "S");
|
||||||
|
FIND_FIELD (ascent, "ascent", "S");
|
||||||
|
FIND_FIELD (descent, "descent", "S");
|
||||||
|
#undef FIND_FIELD
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
android_init_integer (void)
|
||||||
|
{
|
||||||
|
jclass old;
|
||||||
|
|
||||||
|
integer_class.class
|
||||||
|
= (*android_java_env)->FindClass (android_java_env,
|
||||||
|
"java/lang/Integer");
|
||||||
|
eassert (integer_class.class);
|
||||||
|
|
||||||
|
old = integer_class.class;
|
||||||
|
integer_class.class
|
||||||
|
= (jclass) (*android_java_env)->NewGlobalRef (android_java_env,
|
||||||
|
(jobject) old);
|
||||||
|
ANDROID_DELETE_LOCAL_REF (old);
|
||||||
|
|
||||||
|
if (!integer_class.class)
|
||||||
|
emacs_abort ();
|
||||||
|
|
||||||
|
#define FIND_METHOD(c_name, name, signature) \
|
||||||
|
integer_class.c_name \
|
||||||
|
= (*android_java_env)->GetMethodID (android_java_env, \
|
||||||
|
integer_class.class, \
|
||||||
|
name, signature); \
|
||||||
|
eassert (integer_class.c_name);
|
||||||
|
|
||||||
|
FIND_METHOD (constructor, "<init>", "(I)V");
|
||||||
|
FIND_METHOD (int_value, "intValue", "()I");
|
||||||
|
#undef FIND_METHOD
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
android_init_font_object (void)
|
||||||
|
{
|
||||||
|
jclass old;
|
||||||
|
|
||||||
|
font_object_class.class
|
||||||
|
= (*android_java_env)->FindClass (android_java_env,
|
||||||
|
"org/gnu/emacs/EmacsFontDriver"
|
||||||
|
"$FontObject");
|
||||||
|
eassert (font_object_class.class);
|
||||||
|
|
||||||
|
old = font_object_class.class;
|
||||||
|
font_object_class.class
|
||||||
|
= (jclass) (*android_java_env)->NewGlobalRef (android_java_env,
|
||||||
|
(jobject) old);
|
||||||
|
ANDROID_DELETE_LOCAL_REF (old);
|
||||||
|
|
||||||
|
if (!font_object_class.class)
|
||||||
|
emacs_abort ();
|
||||||
|
|
||||||
|
#define FIND_FIELD(c_name, name, signature) \
|
||||||
|
font_object_class.c_name \
|
||||||
|
= (*android_java_env)->GetFieldID (android_java_env, \
|
||||||
|
font_object_class.class, \
|
||||||
|
name, signature); \
|
||||||
|
eassert (font_object_class.c_name);
|
||||||
|
|
||||||
|
FIND_FIELD (min_width, "minWidth", "I");
|
||||||
|
FIND_FIELD (max_width, "maxWidth", "I");
|
||||||
|
FIND_FIELD (pixel_size, "pixelSize", "I");
|
||||||
|
FIND_FIELD (height, "height", "I");
|
||||||
|
FIND_FIELD (space_width, "spaceWidth", "I");
|
||||||
|
FIND_FIELD (average_width, "averageWidth", "I");
|
||||||
|
FIND_FIELD (ascent, "ascent", "I");
|
||||||
|
FIND_FIELD (descent, "descent", "I");
|
||||||
|
FIND_FIELD (underline_thickness, "underlineThickness", "I");
|
||||||
|
FIND_FIELD (underline_position, "underlinePosition", "I");
|
||||||
|
FIND_FIELD (baseline_offset, "baselineOffset", "I");
|
||||||
|
FIND_FIELD (relative_compose, "relativeCompose", "I");
|
||||||
|
FIND_FIELD (default_ascent, "defaultAscent", "I");
|
||||||
|
FIND_FIELD (encoding_charset, "encodingCharset", "I");
|
||||||
|
FIND_FIELD (repertory_charset, "repertoryCharset", "I");
|
||||||
|
#undef FIND_FIELD
|
||||||
|
}
|
||||||
|
|
||||||
|
static Lisp_Object
|
||||||
|
androidfont_get_cache (struct frame *frame)
|
||||||
|
{
|
||||||
|
return font_cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return a local reference to an instance of EmacsFontDriver$FontSpec
|
||||||
|
with the same values as FONT. */
|
||||||
|
|
||||||
|
static jobject
|
||||||
|
androidfont_from_lisp (Lisp_Object font)
|
||||||
|
{
|
||||||
|
jobject spec, integer;
|
||||||
|
jstring string;
|
||||||
|
Lisp_Object tem;
|
||||||
|
|
||||||
|
spec = (*android_java_env)->AllocObject (android_java_env,
|
||||||
|
font_spec_class.class);
|
||||||
|
|
||||||
|
if (!spec)
|
||||||
|
{
|
||||||
|
(*android_java_env)->ExceptionClear (android_java_env);
|
||||||
|
memory_full (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DO_SYMBOL_FIELD(field, index) \
|
||||||
|
tem = AREF (font, index); \
|
||||||
|
if (SYMBOLP (tem)) \
|
||||||
|
{ \
|
||||||
|
/* Java seems to DTRT with the Emacs string encoding, so this does \
|
||||||
|
not matter at all. */ \
|
||||||
|
string = (*android_java_env)->NewStringUTF (android_java_env, \
|
||||||
|
SSDATA (SYMBOL_NAME (tem))); \
|
||||||
|
if (!string) \
|
||||||
|
{ \
|
||||||
|
(*android_java_env)->ExceptionClear (android_java_env); \
|
||||||
|
memory_full (0); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
(*android_java_env)->SetObjectField (android_java_env, spec, \
|
||||||
|
font_spec_class.field, \
|
||||||
|
string); \
|
||||||
|
ANDROID_DELETE_LOCAL_REF (string); \
|
||||||
|
} \
|
||||||
|
|
||||||
|
DO_SYMBOL_FIELD (foundry, FONT_FOUNDRY_INDEX);
|
||||||
|
DO_SYMBOL_FIELD (family, FONT_FAMILY_INDEX);
|
||||||
|
DO_SYMBOL_FIELD (adstyle, FONT_ADSTYLE_INDEX);
|
||||||
|
DO_SYMBOL_FIELD (registry, FONT_REGISTRY_INDEX);
|
||||||
|
|
||||||
|
#undef DO_SYMBOL_FIELD
|
||||||
|
|
||||||
|
#define DO_CARDINAL_FIELD(field, value) \
|
||||||
|
if (value != -1) \
|
||||||
|
{ \
|
||||||
|
integer = (*android_java_env)->NewObject (android_java_env, \
|
||||||
|
integer_class.class, \
|
||||||
|
integer_class.constructor, \
|
||||||
|
(jint) value); \
|
||||||
|
if (!integer) \
|
||||||
|
{ \
|
||||||
|
(*android_java_env)->ExceptionClear (android_java_env); \
|
||||||
|
memory_full (0); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
(*android_java_env)->SetObjectField (android_java_env, spec, \
|
||||||
|
font_spec_class.field, \
|
||||||
|
integer); \
|
||||||
|
ANDROID_DELETE_LOCAL_REF (integer); \
|
||||||
|
}
|
||||||
|
|
||||||
|
DO_CARDINAL_FIELD (width, FONT_WIDTH_NUMERIC (font));
|
||||||
|
DO_CARDINAL_FIELD (weight, FONT_WEIGHT_NUMERIC (font));
|
||||||
|
DO_CARDINAL_FIELD (slant, FONT_SLANT_NUMERIC (font));
|
||||||
|
DO_CARDINAL_FIELD (size, (FIXNUMP (AREF (font, FONT_SIZE_INDEX))
|
||||||
|
? XFIXNUM (AREF (font, FONT_SIZE_INDEX))
|
||||||
|
: -1));
|
||||||
|
DO_CARDINAL_FIELD (spacing, (FIXNUMP (AREF (font, FONT_SPACING_INDEX))
|
||||||
|
? XFIXNUM (AREF (font, FONT_SPACING_INDEX))
|
||||||
|
: -1));
|
||||||
|
DO_CARDINAL_FIELD (avgwidth, (FIXNUMP (AREF (font, FONT_AVGWIDTH_INDEX))
|
||||||
|
? XFIXNUM (AREF (font, FONT_AVGWIDTH_INDEX))
|
||||||
|
: -1));
|
||||||
|
|
||||||
|
#undef DO_CARDINAL_FIELD
|
||||||
|
|
||||||
|
return spec;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
androidfont_from_java (jobject spec, Lisp_Object entity)
|
||||||
|
{
|
||||||
|
jobject tem;
|
||||||
|
jint value;
|
||||||
|
const char *string;
|
||||||
|
|
||||||
|
#define DO_SYMBOL_FIELD(field, index) \
|
||||||
|
tem = (*android_java_env)->GetObjectField (android_java_env, \
|
||||||
|
spec, \
|
||||||
|
font_spec_class.field); \
|
||||||
|
if (tem) \
|
||||||
|
{ \
|
||||||
|
string = (*android_java_env)->GetStringUTFChars (android_java_env, \
|
||||||
|
tem, NULL); \
|
||||||
|
if (!string) \
|
||||||
|
memory_full (0); \
|
||||||
|
ASET (entity, index, intern (string)); \
|
||||||
|
(*android_java_env)->ReleaseStringUTFChars (android_java_env, \
|
||||||
|
tem, string); \
|
||||||
|
ANDROID_DELETE_LOCAL_REF (tem); \
|
||||||
|
}
|
||||||
|
|
||||||
|
DO_SYMBOL_FIELD (foundry, FONT_FOUNDRY_INDEX);
|
||||||
|
DO_SYMBOL_FIELD (family, FONT_FAMILY_INDEX);
|
||||||
|
DO_SYMBOL_FIELD (adstyle, FONT_ADSTYLE_INDEX);
|
||||||
|
DO_SYMBOL_FIELD (registry, FONT_REGISTRY_INDEX);
|
||||||
|
|
||||||
|
#undef DO_SYMBOL_FIELD
|
||||||
|
#define DO_CARDINAL_FIELD(field, index, is_style) \
|
||||||
|
tem = (*android_java_env)->GetObjectField (android_java_env, \
|
||||||
|
spec, \
|
||||||
|
font_spec_class.field); \
|
||||||
|
if (tem) \
|
||||||
|
{ \
|
||||||
|
value \
|
||||||
|
= (*android_java_env)->CallIntMethod (android_java_env, \
|
||||||
|
tem, \
|
||||||
|
integer_class.int_value); \
|
||||||
|
if (!is_style) \
|
||||||
|
ASET (entity, index, make_fixnum (value)); \
|
||||||
|
else \
|
||||||
|
FONT_SET_STYLE (entity, index, make_fixnum (value)); \
|
||||||
|
ANDROID_DELETE_LOCAL_REF (tem); \
|
||||||
|
}
|
||||||
|
|
||||||
|
DO_CARDINAL_FIELD (width, FONT_WIDTH_INDEX, true);
|
||||||
|
DO_CARDINAL_FIELD (weight, FONT_WEIGHT_INDEX, true);
|
||||||
|
DO_CARDINAL_FIELD (slant, FONT_SLANT_INDEX, true);
|
||||||
|
DO_CARDINAL_FIELD (size, FONT_SIZE_INDEX, false);
|
||||||
|
DO_CARDINAL_FIELD (spacing, FONT_SPACING_INDEX, false);
|
||||||
|
DO_CARDINAL_FIELD (avgwidth, FONT_AVGWIDTH_INDEX, false);
|
||||||
|
#undef DO_CARDINAL_FIELD
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Transfer the values from FONT, which must be some kind of font
|
||||||
|
entity, */
|
||||||
|
|
||||||
|
static Lisp_Object
|
||||||
|
androidfont_list (struct frame *f, Lisp_Object font_spec)
|
||||||
|
{
|
||||||
|
jobject spec, array, tem;
|
||||||
|
jarray entities;
|
||||||
|
jsize i, size;
|
||||||
|
Lisp_Object value, entity;
|
||||||
|
struct androidfont_entity *info;
|
||||||
|
|
||||||
|
spec = androidfont_from_lisp (font_spec);
|
||||||
|
array = (*android_java_env)->CallObjectMethod (android_java_env,
|
||||||
|
font_driver,
|
||||||
|
font_driver_class.list,
|
||||||
|
spec);
|
||||||
|
(*android_java_env)->ExceptionClear (android_java_env);
|
||||||
|
ANDROID_DELETE_LOCAL_REF (spec);
|
||||||
|
|
||||||
|
if (!array)
|
||||||
|
memory_full (0);
|
||||||
|
|
||||||
|
entities = (jarray) array;
|
||||||
|
size = (*android_java_env)->GetArrayLength (android_java_env,
|
||||||
|
entities);
|
||||||
|
value = Qnil;
|
||||||
|
|
||||||
|
for (i = 0; i < size; ++i)
|
||||||
|
{
|
||||||
|
entity = font_make_entity_android (VECSIZE (struct androidfont_entity));
|
||||||
|
info = (struct androidfont_entity *) XFONT_ENTITY (entity);
|
||||||
|
|
||||||
|
/* The type must be set correctly, or font_open_entity won't be
|
||||||
|
able to find the right font driver. */
|
||||||
|
ASET (entity, FONT_TYPE_INDEX, Qandroid);
|
||||||
|
|
||||||
|
/* Clear this now in case GC happens without it set, which can
|
||||||
|
happen if androidfont_from_java runs out of memory. */
|
||||||
|
info->object = NULL;
|
||||||
|
|
||||||
|
tem = (*android_java_env)->GetObjectArrayElement (android_java_env,
|
||||||
|
entities, i);
|
||||||
|
androidfont_from_java (tem, entity);
|
||||||
|
|
||||||
|
/* Now, make a global reference to the Java font entity. */
|
||||||
|
info->object = (*android_java_env)->NewGlobalRef (android_java_env,
|
||||||
|
(jobject) tem);
|
||||||
|
(*android_java_env)->ExceptionClear (android_java_env);
|
||||||
|
ANDROID_DELETE_LOCAL_REF (tem);
|
||||||
|
|
||||||
|
if (!info->object)
|
||||||
|
memory_full (0);
|
||||||
|
|
||||||
|
value = Fcons (entity, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
ANDROID_DELETE_LOCAL_REF (entities);
|
||||||
|
return Fnreverse (value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Lisp_Object
|
||||||
|
androidfont_match (struct frame *f, Lisp_Object font_spec)
|
||||||
|
{
|
||||||
|
jobject spec, result;
|
||||||
|
Lisp_Object entity;
|
||||||
|
struct androidfont_entity *info;
|
||||||
|
|
||||||
|
spec = androidfont_from_lisp (font_spec);
|
||||||
|
result = (*android_java_env)->CallObjectMethod (android_java_env,
|
||||||
|
font_driver,
|
||||||
|
font_driver_class.match,
|
||||||
|
spec);
|
||||||
|
(*android_java_env)->ExceptionClear (android_java_env);
|
||||||
|
ANDROID_DELETE_LOCAL_REF (spec);
|
||||||
|
|
||||||
|
if (!result)
|
||||||
|
memory_full (0);
|
||||||
|
|
||||||
|
entity = font_make_entity_android (VECSIZE (struct androidfont_entity));
|
||||||
|
info = (struct androidfont_entity *) XFONT_ENTITY (entity);
|
||||||
|
|
||||||
|
/* The type must be set correctly, or font_open_entity won't be able
|
||||||
|
to find the right font driver. */
|
||||||
|
ASET (entity, FONT_TYPE_INDEX, Qandroid);
|
||||||
|
|
||||||
|
info->object = NULL;
|
||||||
|
androidfont_from_java (result, entity);
|
||||||
|
info->object = (*android_java_env)->NewGlobalRef (android_java_env,
|
||||||
|
(jobject) result);
|
||||||
|
(*android_java_env)->ExceptionClear (android_java_env);
|
||||||
|
ANDROID_DELETE_LOCAL_REF (result);
|
||||||
|
|
||||||
|
if (!info->object)
|
||||||
|
memory_full (0);
|
||||||
|
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
androidfont_draw (struct glyph_string *s, int from, int to,
|
||||||
|
int x, int y, bool with_background)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Lisp_Object
|
||||||
|
androidfont_open_font (struct frame *f, Lisp_Object font_entity, int x)
|
||||||
|
{
|
||||||
|
struct androidfont_info *font_info;
|
||||||
|
struct androidfont_entity *entity;
|
||||||
|
struct font *font;
|
||||||
|
Lisp_Object font_object, tem;
|
||||||
|
jobject old;
|
||||||
|
jint value;
|
||||||
|
|
||||||
|
if (x <= 0)
|
||||||
|
{
|
||||||
|
/* Get pixel size from frame instead. */
|
||||||
|
tem = get_frame_param (f, Qfontsize);
|
||||||
|
x = NILP (tem) ? 0 : XFIXNAT (tem);
|
||||||
|
}
|
||||||
|
|
||||||
|
__android_log_print (ANDROID_LOG_DEBUG, __func__,
|
||||||
|
"opening font entity %"pI"x:%d",
|
||||||
|
(EMACS_INT) font_entity, x);
|
||||||
|
|
||||||
|
entity = (struct androidfont_entity *) XFONT_ENTITY (font_entity);
|
||||||
|
|
||||||
|
block_input ();
|
||||||
|
font_object = font_make_object (VECSIZE (struct androidfont_info),
|
||||||
|
font_entity, x);
|
||||||
|
ASET (font_object, FONT_TYPE_INDEX, Qandroid);
|
||||||
|
font_info = (struct androidfont_info *) XFONT_OBJECT (font_object);
|
||||||
|
font = &font_info->font;
|
||||||
|
font->driver = &androidfont_driver;
|
||||||
|
|
||||||
|
/* Clear font_info->object early in case GC happens later on! */
|
||||||
|
font_info->object = NULL;
|
||||||
|
unblock_input ();
|
||||||
|
|
||||||
|
font_info->object
|
||||||
|
= (*android_java_env)->CallObjectMethod (android_java_env,
|
||||||
|
font_driver,
|
||||||
|
font_driver_class.open_font,
|
||||||
|
entity->object, (jint) x);
|
||||||
|
if (!font_info->object)
|
||||||
|
{
|
||||||
|
(*android_java_env)->ExceptionClear (android_java_env);
|
||||||
|
return Qnil;
|
||||||
|
}
|
||||||
|
|
||||||
|
old = font_info->object;
|
||||||
|
font_info->object
|
||||||
|
= (*android_java_env)->NewGlobalRef (android_java_env, old);
|
||||||
|
(*android_java_env)->ExceptionClear (android_java_env);
|
||||||
|
ANDROID_DELETE_LOCAL_REF (old);
|
||||||
|
|
||||||
|
if (!font_info->object)
|
||||||
|
return Qnil;
|
||||||
|
|
||||||
|
/* Copy the font attributes from the Java object. */
|
||||||
|
androidfont_from_java (font_info->object, font_object);
|
||||||
|
|
||||||
|
/* Copy font attributes inside EmacsFontDriver$FontObject. */
|
||||||
|
#define DO_CARDINAL_FIELD(field) \
|
||||||
|
value \
|
||||||
|
= (*android_java_env)->GetIntField (android_java_env, \
|
||||||
|
font_info->object, \
|
||||||
|
font_object_class.field); \
|
||||||
|
font->field = value;
|
||||||
|
|
||||||
|
DO_CARDINAL_FIELD (min_width);
|
||||||
|
DO_CARDINAL_FIELD (max_width);
|
||||||
|
DO_CARDINAL_FIELD (pixel_size);
|
||||||
|
DO_CARDINAL_FIELD (height);
|
||||||
|
DO_CARDINAL_FIELD (space_width);
|
||||||
|
DO_CARDINAL_FIELD (average_width);
|
||||||
|
DO_CARDINAL_FIELD (ascent);
|
||||||
|
DO_CARDINAL_FIELD (descent);
|
||||||
|
DO_CARDINAL_FIELD (underline_thickness);
|
||||||
|
DO_CARDINAL_FIELD (underline_position);
|
||||||
|
DO_CARDINAL_FIELD (baseline_offset);
|
||||||
|
DO_CARDINAL_FIELD (relative_compose);
|
||||||
|
DO_CARDINAL_FIELD (default_ascent);
|
||||||
|
DO_CARDINAL_FIELD (encoding_charset);
|
||||||
|
DO_CARDINAL_FIELD (repertory_charset);
|
||||||
|
|
||||||
|
#undef DO_CARDINAL_FIELD
|
||||||
|
|
||||||
|
/* This should eventually become unnecessary. */
|
||||||
|
font->props[FONT_NAME_INDEX] = Ffont_xlfd_name (font_object, Qnil);
|
||||||
|
|
||||||
|
return font_object;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
androidfont_close_font (struct font *font)
|
||||||
|
{
|
||||||
|
struct androidfont_info *info;
|
||||||
|
|
||||||
|
info = (struct androidfont_info *) font;
|
||||||
|
|
||||||
|
/* If info->object is NULL, then FONT was unsuccessfully created,
|
||||||
|
and there is no global reference that has to be deleted. */
|
||||||
|
|
||||||
|
if (!info->object)
|
||||||
|
return;
|
||||||
|
|
||||||
|
(*android_java_env)->DeleteGlobalRef (android_java_env,
|
||||||
|
info->object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
androidfont_has_char (Lisp_Object font, int c)
|
||||||
|
{
|
||||||
|
struct androidfont_info *info;
|
||||||
|
struct androidfont_entity *entity;
|
||||||
|
|
||||||
|
if (FONT_ENTITY_P (font))
|
||||||
|
{
|
||||||
|
entity = (struct androidfont_entity *) XFONT_ENTITY (font);
|
||||||
|
|
||||||
|
return (*android_java_env)->CallIntMethod (android_java_env,
|
||||||
|
font_driver,
|
||||||
|
font_driver_class.has_char,
|
||||||
|
entity->object, (jint) c);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
info = (struct androidfont_info *) XFONT_OBJECT (font);
|
||||||
|
|
||||||
|
return (*android_java_env)->CallIntMethod (android_java_env,
|
||||||
|
font_driver,
|
||||||
|
font_driver_class.has_char,
|
||||||
|
info->object, (jint) c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned
|
||||||
|
androidfont_encode_char (struct font *font, int c)
|
||||||
|
{
|
||||||
|
struct androidfont_info *info;
|
||||||
|
|
||||||
|
info = (struct androidfont_info *) font;
|
||||||
|
|
||||||
|
return (*android_java_env)->CallIntMethod (android_java_env,
|
||||||
|
font_driver,
|
||||||
|
font_driver_class.encode_char,
|
||||||
|
info->object, (jchar) c);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
androidfont_text_extents (struct font *font, const unsigned int *code,
|
||||||
|
int nglyphs, struct font_metrics *metrics)
|
||||||
|
{
|
||||||
|
struct androidfont_info *info;
|
||||||
|
jarray codepoint_array, metrics_array;
|
||||||
|
jobject metrics_object;
|
||||||
|
int i;
|
||||||
|
short value;
|
||||||
|
|
||||||
|
info = (struct androidfont_info *) font;
|
||||||
|
|
||||||
|
/* Allocate the arrays of code points and font metrics. */
|
||||||
|
codepoint_array
|
||||||
|
= (*android_java_env)->NewIntArray (android_java_env,
|
||||||
|
nglyphs);
|
||||||
|
if (!codepoint_array)
|
||||||
|
{
|
||||||
|
(*android_java_env)->ExceptionClear (android_java_env);
|
||||||
|
memory_full (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
metrics_array
|
||||||
|
= (*android_java_env)->NewObjectArray (android_java_env,
|
||||||
|
nglyphs,
|
||||||
|
font_metrics_class.class,
|
||||||
|
NULL);
|
||||||
|
if (!metrics_array)
|
||||||
|
{
|
||||||
|
(*android_java_env)->ExceptionClear (android_java_env);
|
||||||
|
ANDROID_DELETE_LOCAL_REF (metrics_array);
|
||||||
|
memory_full (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sizeof (unsigned int) == sizeof (jint))
|
||||||
|
/* Always true on every Android device. */
|
||||||
|
(*android_java_env)->SetIntArrayRegion (android_java_env,
|
||||||
|
codepoint_array,
|
||||||
|
0, nglyphs,
|
||||||
|
(jint *) code);
|
||||||
|
else
|
||||||
|
emacs_abort ();
|
||||||
|
|
||||||
|
for (i = 0; i < nglyphs; ++i)
|
||||||
|
{
|
||||||
|
metrics_object
|
||||||
|
= (*android_java_env)->AllocObject (android_java_env,
|
||||||
|
font_metrics_class.class);
|
||||||
|
|
||||||
|
if (!metrics_object)
|
||||||
|
{
|
||||||
|
(*android_java_env)->ExceptionClear (android_java_env);
|
||||||
|
ANDROID_DELETE_LOCAL_REF (metrics_array);
|
||||||
|
ANDROID_DELETE_LOCAL_REF (codepoint_array);
|
||||||
|
memory_full (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
(*android_java_env)->SetObjectArrayElement (android_java_env,
|
||||||
|
metrics_array, i,
|
||||||
|
metrics_object);
|
||||||
|
ANDROID_DELETE_LOCAL_REF (metrics_object);
|
||||||
|
}
|
||||||
|
|
||||||
|
(*android_java_env)->CallVoidMethod (android_java_env,
|
||||||
|
font_driver,
|
||||||
|
font_driver_class.text_extents,
|
||||||
|
info->object, codepoint_array,
|
||||||
|
metrics_array);
|
||||||
|
|
||||||
|
if ((*android_java_env)->ExceptionCheck (android_java_env))
|
||||||
|
{
|
||||||
|
(*android_java_env)->ExceptionClear (android_java_env);
|
||||||
|
ANDROID_DELETE_LOCAL_REF (metrics_array);
|
||||||
|
ANDROID_DELETE_LOCAL_REF (codepoint_array);
|
||||||
|
memory_full (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < nglyphs; ++i)
|
||||||
|
{
|
||||||
|
metrics_object
|
||||||
|
= (*android_java_env)->GetObjectArrayElement (android_java_env,
|
||||||
|
metrics_array, i);
|
||||||
|
#define DO_CARDINAL_FIELD(field) \
|
||||||
|
value \
|
||||||
|
= (*android_java_env)->GetShortField (android_java_env, \
|
||||||
|
metrics_object, \
|
||||||
|
font_metrics_class.field); \
|
||||||
|
metrics[i].field = value;
|
||||||
|
|
||||||
|
DO_CARDINAL_FIELD (lbearing);
|
||||||
|
DO_CARDINAL_FIELD (rbearing);
|
||||||
|
DO_CARDINAL_FIELD (width);
|
||||||
|
DO_CARDINAL_FIELD (ascent);
|
||||||
|
DO_CARDINAL_FIELD (descent);
|
||||||
|
|
||||||
|
#undef DO_CARDINAL_FIELD
|
||||||
|
|
||||||
|
ANDROID_DELETE_LOCAL_REF (metrics_object);
|
||||||
|
}
|
||||||
|
|
||||||
|
ANDROID_DELETE_LOCAL_REF (metrics_array);
|
||||||
|
ANDROID_DELETE_LOCAL_REF (codepoint_array);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Lisp_Object
|
||||||
|
androidfont_list_family (struct frame *f)
|
||||||
|
{
|
||||||
|
return Qnil;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct font_driver androidfont_driver =
|
||||||
|
{
|
||||||
|
.type = LISPSYM_INITIALLY (Qandroid),
|
||||||
|
.case_sensitive = true,
|
||||||
|
.get_cache = androidfont_get_cache,
|
||||||
|
.list = androidfont_list,
|
||||||
|
.match = androidfont_match,
|
||||||
|
.draw = androidfont_draw,
|
||||||
|
.open_font = androidfont_open_font,
|
||||||
|
.close_font = androidfont_close_font,
|
||||||
|
.has_char = androidfont_has_char,
|
||||||
|
.encode_char = androidfont_encode_char,
|
||||||
|
.text_extents = androidfont_text_extents,
|
||||||
|
.list_family = androidfont_list_family,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
syms_of_androidfont_for_pdumper (void)
|
||||||
|
{
|
||||||
|
register_font_driver (&androidfont_driver, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
syms_of_androidfont (void)
|
||||||
|
{
|
||||||
|
DEFSYM (Qfontsize, "fontsize");
|
||||||
|
|
||||||
|
pdumper_do_now_and_after_load (syms_of_androidfont_for_pdumper);
|
||||||
|
|
||||||
|
font_cache = list (Qnil);
|
||||||
|
staticpro (&font_cache);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
init_androidfont (void)
|
||||||
|
{
|
||||||
|
jmethodID method;
|
||||||
|
jobject old;
|
||||||
|
|
||||||
|
android_init_font_driver ();
|
||||||
|
android_init_font_spec ();
|
||||||
|
android_init_font_metrics ();
|
||||||
|
android_init_font_object ();
|
||||||
|
android_init_integer ();
|
||||||
|
|
||||||
|
method = font_driver_class.create_font_driver;
|
||||||
|
|
||||||
|
/* Initialize the font driver on the Java side. */
|
||||||
|
font_driver
|
||||||
|
= (*android_java_env)->CallStaticObjectMethod (android_java_env,
|
||||||
|
font_driver_class.class,
|
||||||
|
method);
|
||||||
|
|
||||||
|
if (!font_driver)
|
||||||
|
memory_full (0);
|
||||||
|
|
||||||
|
old = font_driver;
|
||||||
|
font_driver
|
||||||
|
= (*android_java_env)->NewGlobalRef (android_java_env, font_driver);
|
||||||
|
ANDROID_DELETE_LOCAL_REF (old);
|
||||||
|
|
||||||
|
if (!font_driver)
|
||||||
|
memory_full (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
android_finalize_font_entity (struct font_entity *entity)
|
||||||
|
{
|
||||||
|
struct androidfont_entity *info;
|
||||||
|
|
||||||
|
info = (struct androidfont_entity *) entity;
|
||||||
|
|
||||||
|
if (info->object)
|
||||||
|
(*android_java_env)->DeleteGlobalRef (android_java_env,
|
||||||
|
info->object);
|
||||||
|
|
||||||
|
/* Not sure if this can be called twice. */
|
||||||
|
info->object = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
315
src/androidgui.h
Normal file
315
src/androidgui.h
Normal file
|
|
@ -0,0 +1,315 @@
|
||||||
|
/* Android window system support.
|
||||||
|
Copyright (C) 2023 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GNU Emacs.
|
||||||
|
|
||||||
|
GNU Emacs is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
your option) any later version.
|
||||||
|
|
||||||
|
GNU Emacs is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef _ANDROID_GUI_H_
|
||||||
|
#define _ANDROID_GUI_H_
|
||||||
|
|
||||||
|
struct android_char_struct
|
||||||
|
{
|
||||||
|
int rbearing;
|
||||||
|
int lbearing;
|
||||||
|
int width;
|
||||||
|
int ascent;
|
||||||
|
int descent;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct android_char_struct XCharStruct;
|
||||||
|
|
||||||
|
typedef unsigned short android_handle;
|
||||||
|
|
||||||
|
typedef android_handle android_pixmap, Emacs_Pixmap;
|
||||||
|
typedef android_handle android_window, Emacs_Window;
|
||||||
|
typedef android_handle android_gcontext, GContext;
|
||||||
|
typedef android_handle android_drawable, Drawable;
|
||||||
|
|
||||||
|
typedef unsigned int android_time;
|
||||||
|
|
||||||
|
struct android_rectangle
|
||||||
|
{
|
||||||
|
int x, y;
|
||||||
|
unsigned width, height;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct android_point
|
||||||
|
{
|
||||||
|
int x, y;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Keep this in sync with EmacsGC.java! */
|
||||||
|
|
||||||
|
enum android_gc_function
|
||||||
|
{
|
||||||
|
ANDROID_GC_COPY = 0,
|
||||||
|
ANDROID_GC_XOR = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum android_gc_value_mask
|
||||||
|
{
|
||||||
|
ANDROID_GC_FOREGROUND = (1 << 0),
|
||||||
|
ANDROID_GC_BACKGROUND = (1 << 1),
|
||||||
|
ANDROID_GC_FUNCTION = (1 << 2),
|
||||||
|
ANDROID_GC_CLIP_X_ORIGIN = (1 << 3),
|
||||||
|
ANDROID_GC_CLIP_Y_ORIGIN = (1 << 4),
|
||||||
|
ANDROID_GC_CLIP_MASK = (1 << 5),
|
||||||
|
ANDROID_GC_STIPPLE = (1 << 6),
|
||||||
|
ANDROID_GC_FILL_STYLE = (1 << 7),
|
||||||
|
ANDROID_GC_TILE_STIP_X_ORIGIN = (1 << 8),
|
||||||
|
ANDROID_GC_TILE_STIP_Y_ORIGIN = (1 << 9),
|
||||||
|
};
|
||||||
|
|
||||||
|
enum android_fill_style
|
||||||
|
{
|
||||||
|
ANDROID_FILL_SOLID = 0,
|
||||||
|
ANDROID_FILL_OPAQUE_STIPPLED = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum android_window_value_mask
|
||||||
|
{
|
||||||
|
ANDROID_CW_BACK_PIXEL = (1 << 1),
|
||||||
|
};
|
||||||
|
|
||||||
|
struct android_set_window_attributes
|
||||||
|
{
|
||||||
|
/* The background pixel. */
|
||||||
|
unsigned long background_pixel;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct android_gc_values
|
||||||
|
{
|
||||||
|
/* The foreground and background. */
|
||||||
|
unsigned long foreground, background;
|
||||||
|
|
||||||
|
/* The function. */
|
||||||
|
enum android_gc_function function;
|
||||||
|
|
||||||
|
/* The fill style. */
|
||||||
|
enum android_fill_style fill_style;
|
||||||
|
|
||||||
|
/* The clip X and Y origin. */
|
||||||
|
int clip_x_origin, clip_y_origin;
|
||||||
|
|
||||||
|
/* The clip mask image and stipple. */
|
||||||
|
android_pixmap clip_mask, stipple;
|
||||||
|
|
||||||
|
/* The tile-stipple X and Y origins. */
|
||||||
|
int ts_x_origin, ts_y_origin;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* X-like graphics context structure. This is implemented in
|
||||||
|
EmacsGC.java, but a copy is kept here to avoid sending changes all
|
||||||
|
the time. */
|
||||||
|
|
||||||
|
struct android_gc
|
||||||
|
{
|
||||||
|
/* The Java-side handle. */
|
||||||
|
android_gcontext gcontext;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum android_swap_action
|
||||||
|
{
|
||||||
|
ANDROID_COPIED,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum android_shape
|
||||||
|
{
|
||||||
|
ANDROID_CONVEX,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum android_coord_mode
|
||||||
|
{
|
||||||
|
ANDROID_COORD_MODE_ORIGIN,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct android_swap_info
|
||||||
|
{
|
||||||
|
/* The window to swap. */
|
||||||
|
android_window swap_window;
|
||||||
|
|
||||||
|
/* Unused field present only for consistency with X. */
|
||||||
|
enum android_swap_action swap_action;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Android doesn't support cursors, so define this to something
|
||||||
|
unused. */
|
||||||
|
typedef char Emacs_Cursor;
|
||||||
|
|
||||||
|
#define NativeRectangle Emacs_Rectangle
|
||||||
|
#define CONVERT_TO_NATIVE_RECT(xr, nr) ((xr) = (nr))
|
||||||
|
#define CONVERT_FROM_EMACS_RECT(xr, nr) ((nr) = (xr))
|
||||||
|
|
||||||
|
#define STORE_NATIVE_RECT(nr, rx, ry, rwidth, rheight) \
|
||||||
|
((nr).x = (rx), (nr).y = (ry), \
|
||||||
|
(nr).width = (rwidth), (nr).height = (rheight)) \
|
||||||
|
|
||||||
|
#define ForgetGravity 0
|
||||||
|
#define NorthWestGravity 1
|
||||||
|
#define NorthGravity 2
|
||||||
|
#define NorthEastGravity 3
|
||||||
|
#define WestGravity 4
|
||||||
|
#define CenterGravity 5
|
||||||
|
#define EastGravity 6
|
||||||
|
#define SouthWestGravity 7
|
||||||
|
#define SouthGravity 8
|
||||||
|
#define SouthEastGravity 9
|
||||||
|
#define StaticGravity 10
|
||||||
|
|
||||||
|
#define NoValue 0x0000
|
||||||
|
#define XValue 0x0001
|
||||||
|
#define YValue 0x0002
|
||||||
|
#define WidthValue 0x0004
|
||||||
|
#define HeightValue 0x0008
|
||||||
|
#define AllValues 0x000F
|
||||||
|
#define XNegative 0x0010
|
||||||
|
#define YNegative 0x0020
|
||||||
|
|
||||||
|
#define USPosition (1L << 0) /* user specified x, y */
|
||||||
|
#define USSize (1L << 1) /* user specified width, height */
|
||||||
|
#define PPosition (1L << 2) /* program specified position */
|
||||||
|
#define PSize (1L << 3) /* program specified size */
|
||||||
|
#define PMinSize (1L << 4) /* program specified minimum size */
|
||||||
|
#define PMaxSize (1L << 5) /* program specified maximum size */
|
||||||
|
#define PResizeInc (1L << 6) /* program specified resize increments */
|
||||||
|
#define PAspect (1L << 7) /* program specified min, max aspect ratios */
|
||||||
|
#define PBaseSize (1L << 8) /* program specified base for incrementing */
|
||||||
|
#define PWinGravity (1L << 9) /* program specified window gravity */
|
||||||
|
|
||||||
|
#ifndef ANDROID_STUBIFY
|
||||||
|
|
||||||
|
/* Universal NULL handle. */
|
||||||
|
static const int ANDROID_NONE;
|
||||||
|
|
||||||
|
/* Keep these as conceptually close to X as possible: that makes
|
||||||
|
synchronizing code between the ports much easier. */
|
||||||
|
|
||||||
|
enum android_event_type
|
||||||
|
{
|
||||||
|
ANDROID_KEY_PRESS,
|
||||||
|
ANDROID_KEY_RELEASE,
|
||||||
|
ANDROID_CONFIGURE_NOTIFY,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct android_any_event
|
||||||
|
{
|
||||||
|
enum android_event_type type;
|
||||||
|
android_window window;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct android_key_event
|
||||||
|
{
|
||||||
|
enum android_event_type type;
|
||||||
|
android_window window;
|
||||||
|
android_time time;
|
||||||
|
unsigned int state;
|
||||||
|
unsigned int keycode;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct android_configure_event
|
||||||
|
{
|
||||||
|
enum android_event_type type;
|
||||||
|
android_window window;
|
||||||
|
android_time time;
|
||||||
|
int x, y;
|
||||||
|
int width, height;
|
||||||
|
};
|
||||||
|
|
||||||
|
union android_event
|
||||||
|
{
|
||||||
|
enum android_event_type type;
|
||||||
|
struct android_any_event xany;
|
||||||
|
struct android_key_event xkey;
|
||||||
|
struct android_configure_event xconfigure;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern int android_pending (void);
|
||||||
|
extern void android_next_event (union android_event *);
|
||||||
|
|
||||||
|
extern android_window android_create_window (android_window, int,
|
||||||
|
int, int, int,
|
||||||
|
enum android_window_value_mask,
|
||||||
|
struct
|
||||||
|
android_set_window_attributes *);
|
||||||
|
extern void android_change_window_attributes (android_window,
|
||||||
|
enum android_window_value_mask,
|
||||||
|
struct
|
||||||
|
android_set_window_attributes *);
|
||||||
|
extern void android_set_window_background (android_window, unsigned long);
|
||||||
|
extern void android_destroy_window (android_window);
|
||||||
|
extern void android_reparent_window (android_window, android_window,
|
||||||
|
int, int);
|
||||||
|
extern void android_set_clip_rectangles (struct android_gc *,
|
||||||
|
int, int,
|
||||||
|
struct android_rectangle *,
|
||||||
|
int);
|
||||||
|
extern void android_change_gc (struct android_gc *,
|
||||||
|
enum android_gc_value_mask,
|
||||||
|
struct android_gc_values *);
|
||||||
|
|
||||||
|
extern void android_clear_window (android_window);
|
||||||
|
extern void android_map_window (android_window);
|
||||||
|
extern void android_unmap_window (android_window);
|
||||||
|
extern void android_resize_window (android_window, unsigned int,
|
||||||
|
unsigned int);
|
||||||
|
extern void android_move_window (android_window, int, int);
|
||||||
|
extern void android_swap_buffers (struct android_swap_info *, int);
|
||||||
|
extern void android_get_gc_values (struct android_gc *,
|
||||||
|
enum android_gc_value_mask,
|
||||||
|
struct android_gc_values *);
|
||||||
|
extern void android_set_foreground (struct android_gc *,
|
||||||
|
unsigned long);
|
||||||
|
extern void android_fill_rectangle (android_drawable, struct android_gc *,
|
||||||
|
int, int, unsigned int, unsigned int);
|
||||||
|
extern android_pixmap android_create_pixmap_from_bitmap_data (char *,
|
||||||
|
unsigned int,
|
||||||
|
unsigned int,
|
||||||
|
unsigned long,
|
||||||
|
unsigned long,
|
||||||
|
unsigned int);
|
||||||
|
extern void android_set_clip_mask (struct android_gc *, android_pixmap);
|
||||||
|
extern void android_set_fill_style (struct android_gc *,
|
||||||
|
enum android_fill_style);
|
||||||
|
extern void android_copy_area (android_drawable, android_drawable,
|
||||||
|
struct android_gc *, int, int,
|
||||||
|
unsigned int, unsigned int, int, int);
|
||||||
|
extern void android_free_pixmap (android_drawable);
|
||||||
|
|
||||||
|
extern void android_set_background (struct android_gc *, unsigned long);
|
||||||
|
extern void android_fill_polygon (android_drawable, struct android_gc *,
|
||||||
|
struct android_point *, int,
|
||||||
|
enum android_shape,
|
||||||
|
enum android_coord_mode);
|
||||||
|
extern void android_draw_rectangle (android_drawable, struct android_gc *,
|
||||||
|
int, int, unsigned int, unsigned int);
|
||||||
|
extern void android_draw_point (android_window, struct android_gc *,
|
||||||
|
int, int);
|
||||||
|
extern void android_draw_line (android_window, struct android_gc *,
|
||||||
|
int, int, int, int);
|
||||||
|
extern android_pixmap android_create_pixmap (unsigned int, unsigned int,
|
||||||
|
int);
|
||||||
|
extern void android_set_ts_origin (struct android_gc *, int, int);
|
||||||
|
extern void android_clear_area (android_window, int, int, unsigned int,
|
||||||
|
unsigned int);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* X emulation stuff also needed while building stubs. */
|
||||||
|
|
||||||
|
extern struct android_gc *android_create_gc (enum android_gc_value_mask,
|
||||||
|
struct android_gc_values *);
|
||||||
|
extern void android_free_gc (struct android_gc *);
|
||||||
|
|
||||||
|
#endif /* _ANDROID_GUI_H_ */
|
||||||
3161
src/androidterm.c
Normal file
3161
src/androidterm.c
Normal file
File diff suppressed because it is too large
Load diff
366
src/androidterm.h
Normal file
366
src/androidterm.h
Normal file
|
|
@ -0,0 +1,366 @@
|
||||||
|
/* Communication module for Android terminals.
|
||||||
|
|
||||||
|
Copyright (C) 2023 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GNU Emacs.
|
||||||
|
|
||||||
|
GNU Emacs is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
your option) any later version.
|
||||||
|
|
||||||
|
GNU Emacs is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef _ANDROID_TERM_H_
|
||||||
|
#define _ANDROID_TERM_H_
|
||||||
|
|
||||||
|
#include "androidgui.h"
|
||||||
|
#include "frame.h"
|
||||||
|
#include "character.h"
|
||||||
|
#include "dispextern.h"
|
||||||
|
#include "font.h"
|
||||||
|
|
||||||
|
struct android_bitmap_record
|
||||||
|
{
|
||||||
|
/* The image backing the bitmap. */
|
||||||
|
Emacs_Pixmap img;
|
||||||
|
|
||||||
|
/* The file from which it comes. */
|
||||||
|
char *file;
|
||||||
|
|
||||||
|
/* The number of references to it. */
|
||||||
|
int refcount;
|
||||||
|
|
||||||
|
/* The height and width. */
|
||||||
|
int height, width;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct android_display_info
|
||||||
|
{
|
||||||
|
/* Chain of all struct android_display_info structures. */
|
||||||
|
struct android_display_info *next;
|
||||||
|
|
||||||
|
/* The terminal. */
|
||||||
|
struct terminal *terminal;
|
||||||
|
|
||||||
|
/* The root window. This field is unused. */
|
||||||
|
Emacs_Window root_window;
|
||||||
|
|
||||||
|
/* List possibly used only for the font cache but probably used for
|
||||||
|
something else too. */
|
||||||
|
Lisp_Object name_list_element;
|
||||||
|
|
||||||
|
/* List of predefined X colors. */
|
||||||
|
Lisp_Object color_map;
|
||||||
|
|
||||||
|
/* DPI of the display. */
|
||||||
|
double resx, resy;
|
||||||
|
|
||||||
|
/* Scratch GC for drawing a cursor in a non-default face. */
|
||||||
|
struct android_gc *scratch_cursor_gc;
|
||||||
|
|
||||||
|
/* Mouse highlight information. */
|
||||||
|
Mouse_HLInfo mouse_highlight;
|
||||||
|
|
||||||
|
/* Number of planes on this screen. Always 24. */
|
||||||
|
int n_planes;
|
||||||
|
|
||||||
|
/* Mask of things causing the mouse to be grabbed. */
|
||||||
|
int grabbed;
|
||||||
|
|
||||||
|
/* Minimum width over all characters in all fonts in font_table. */
|
||||||
|
int smallest_char_width;
|
||||||
|
|
||||||
|
/* Minimum font height over all fonts in font_table. */
|
||||||
|
int smallest_font_height;
|
||||||
|
|
||||||
|
/* The number of fonts opened for this display. */
|
||||||
|
int n_fonts;
|
||||||
|
|
||||||
|
/* Pointer to bitmap records. */
|
||||||
|
struct android_bitmap_record *bitmaps;
|
||||||
|
|
||||||
|
/* Allocated size of bitmaps field. */
|
||||||
|
ptrdiff_t bitmaps_size;
|
||||||
|
|
||||||
|
/* Last used bitmap index. */
|
||||||
|
ptrdiff_t bitmaps_last;
|
||||||
|
|
||||||
|
/* The frame currently with the input focus. */
|
||||||
|
struct frame *focus_frame;
|
||||||
|
|
||||||
|
/* The frame which currently has the visual highlight, and should
|
||||||
|
get keyboard input. It points to the focus frame's selected
|
||||||
|
window's frame, but can differ. */
|
||||||
|
struct frame *highlight_frame;
|
||||||
|
|
||||||
|
/* The frame waiting to be auto-raised in android_read_socket. */
|
||||||
|
struct frame *pending_autoraise_frame;
|
||||||
|
|
||||||
|
/* The frame where the mouse was the last time a button event
|
||||||
|
happened. */
|
||||||
|
struct frame *last_mouse_frame;
|
||||||
|
|
||||||
|
/* The frame where the mouse was the last time the mouse glyph
|
||||||
|
changed. */
|
||||||
|
struct frame *last_mouse_glyph_frame;
|
||||||
|
|
||||||
|
/* The frame where the mouse was the last time mouse motion
|
||||||
|
happened. */
|
||||||
|
struct frame *last_mouse_motion_frame;
|
||||||
|
|
||||||
|
/* Position where the mouse was last time we reported a motion.
|
||||||
|
This is a position on last_mouse_motion_frame. It is used in to
|
||||||
|
report the mouse position as well: see
|
||||||
|
android_mouse_position. */
|
||||||
|
int last_mouse_motion_x, last_mouse_motion_y;
|
||||||
|
|
||||||
|
/* Where the mouse was the last time the mouse moved. */
|
||||||
|
Emacs_Rectangle last_mouse_glyph;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct android_output
|
||||||
|
{
|
||||||
|
/* Graphics contexts for the default font. */
|
||||||
|
struct android_gc *normal_gc, *reverse_gc, *cursor_gc;
|
||||||
|
|
||||||
|
/* The window used for this frame. */
|
||||||
|
Emacs_Window window;
|
||||||
|
|
||||||
|
/* Unused field. */
|
||||||
|
Emacs_Window parent_desc;
|
||||||
|
|
||||||
|
/* Default ASCII font of this frame. */
|
||||||
|
struct font *font;
|
||||||
|
|
||||||
|
/* The baseline offset of the default ASCII font. */
|
||||||
|
int baseline_offset;
|
||||||
|
|
||||||
|
/* If a fontset is specified for this frame instead of font, this
|
||||||
|
value contains an ID of the fontset, else -1. */
|
||||||
|
int fontset;
|
||||||
|
|
||||||
|
/* Various colors. */
|
||||||
|
unsigned long cursor_pixel;
|
||||||
|
unsigned long cursor_foreground_pixel;
|
||||||
|
|
||||||
|
/* Foreground color for scroll bars. A value of -1 means use the
|
||||||
|
default (black for non-toolkit scroll bars). */
|
||||||
|
unsigned long scroll_bar_foreground_pixel;
|
||||||
|
|
||||||
|
/* Background color for scroll bars. A value of -1 means use the
|
||||||
|
default (background color of the frame for non-toolkit scroll
|
||||||
|
bars). */
|
||||||
|
unsigned long scroll_bar_background_pixel;
|
||||||
|
|
||||||
|
/* Unused stuff (cursors). */
|
||||||
|
Emacs_Cursor text_cursor;
|
||||||
|
Emacs_Cursor nontext_cursor;
|
||||||
|
Emacs_Cursor modeline_cursor;
|
||||||
|
Emacs_Cursor hand_cursor;
|
||||||
|
Emacs_Cursor hourglass_cursor;
|
||||||
|
Emacs_Cursor horizontal_drag_cursor;
|
||||||
|
Emacs_Cursor vertical_drag_cursor;
|
||||||
|
Emacs_Cursor current_cursor;
|
||||||
|
Emacs_Cursor left_edge_cursor;
|
||||||
|
Emacs_Cursor top_left_corner_cursor;
|
||||||
|
Emacs_Cursor top_edge_cursor;
|
||||||
|
Emacs_Cursor top_right_corner_cursor;
|
||||||
|
Emacs_Cursor right_edge_cursor;
|
||||||
|
Emacs_Cursor bottom_right_corner_cursor;
|
||||||
|
Emacs_Cursor bottom_edge_cursor;
|
||||||
|
Emacs_Cursor bottom_left_corner_cursor;
|
||||||
|
|
||||||
|
/* This is the Emacs structure for the display this frame is on. */
|
||||||
|
struct android_display_info *display_info;
|
||||||
|
|
||||||
|
/* True if this frame was ever previously visible. */
|
||||||
|
bool_bf has_been_visible : 1;
|
||||||
|
|
||||||
|
/* True if this frame's alpha value is the same for both the active
|
||||||
|
and inactive states. */
|
||||||
|
bool_bf alpha_identical_p : 1;
|
||||||
|
|
||||||
|
/* Flag that indicates whether we've modified the back buffer and
|
||||||
|
need to publish our modifications to the front buffer at a
|
||||||
|
convenient time. */
|
||||||
|
bool_bf need_buffer_flip : 1;
|
||||||
|
|
||||||
|
/* Flag that indicates whether or not the frame contents are
|
||||||
|
complete and can be safely flushed while handling async
|
||||||
|
input. */
|
||||||
|
bool_bf complete : 1;
|
||||||
|
|
||||||
|
/* Relief GCs, colors etc. */
|
||||||
|
struct relief {
|
||||||
|
struct android_gc *gc;
|
||||||
|
unsigned long pixel;
|
||||||
|
} black_relief, white_relief;
|
||||||
|
|
||||||
|
/* The background for which the above relief GCs were set up.
|
||||||
|
They are changed only when a different background is involved. */
|
||||||
|
unsigned long relief_background;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Return the Android output data for frame F. */
|
||||||
|
#define FRAME_ANDROID_OUTPUT(f) ((f)->output_data.android)
|
||||||
|
#define FRAME_OUTPUT_DATA(f) ((f)->output_data.android)
|
||||||
|
|
||||||
|
/* Return the Android window used for displaying data in frame F. */
|
||||||
|
#define FRAME_ANDROID_WINDOW(f) ((f)->output_data.android->window)
|
||||||
|
#define FRAME_NATIVE_WINDOW(f) ((f)->output_data.android->window)
|
||||||
|
|
||||||
|
/* Return the need-buffer-flip flag for frame F. */
|
||||||
|
#define FRAME_ANDROID_NEED_BUFFER_FLIP(f) \
|
||||||
|
((f)->output_data.android->need_buffer_flip)
|
||||||
|
|
||||||
|
/* Return whether or not the frame F has been completely drawn. Used
|
||||||
|
while handling async input. */
|
||||||
|
#define FRAME_ANDROID_COMPLETE_P(f) \
|
||||||
|
((f)->output_data.android->complete)
|
||||||
|
|
||||||
|
#define FRAME_FONT(f) ((f)->output_data.android->font)
|
||||||
|
#define FRAME_FONTSET(f) ((f)->output_data.android->fontset)
|
||||||
|
|
||||||
|
#define FRAME_BASELINE_OFFSET(f) \
|
||||||
|
((f)->output_data.android->baseline_offset)
|
||||||
|
|
||||||
|
/* This gives the android_display_info structure for the display F is
|
||||||
|
on. */
|
||||||
|
#define FRAME_DISPLAY_INFO(f) ((f)->output_data.android->display_info)
|
||||||
|
|
||||||
|
/* Some things for X compatibility. */
|
||||||
|
#define BLACK_PIX_DEFAULT(f) 0
|
||||||
|
#define WHITE_PIX_DEFAULT(f) 0xffffffff
|
||||||
|
|
||||||
|
/* Android-specific scroll bar stuff. */
|
||||||
|
|
||||||
|
/* We represent scroll bars as lisp vectors. This allows us to place
|
||||||
|
references to them in windows without worrying about whether we'll
|
||||||
|
end up with windows referring to dead scroll bars; the garbage
|
||||||
|
collector will free it when its time comes.
|
||||||
|
|
||||||
|
We use struct scroll_bar as a template for accessing fields of the
|
||||||
|
vector. */
|
||||||
|
|
||||||
|
struct scroll_bar
|
||||||
|
{
|
||||||
|
/* These fields are shared by all vectors. */
|
||||||
|
union vectorlike_header header;
|
||||||
|
|
||||||
|
/* The window we're a scroll bar for. */
|
||||||
|
Lisp_Object window;
|
||||||
|
|
||||||
|
/* The next and previous in the chain of scroll bars in this frame. */
|
||||||
|
Lisp_Object next, prev;
|
||||||
|
|
||||||
|
/* Fields after 'prev' are not traced by the GC. */
|
||||||
|
|
||||||
|
/* The X window representing this scroll bar. */
|
||||||
|
Emacs_Window x_window;
|
||||||
|
|
||||||
|
/* The position and size of the scroll bar in pixels, relative to the
|
||||||
|
frame. */
|
||||||
|
int top, left, width, height;
|
||||||
|
|
||||||
|
/* The starting and ending positions of the handle, relative to the
|
||||||
|
handle area (i.e. zero is the top position, not
|
||||||
|
SCROLL_BAR_TOP_BORDER). If they're equal, that means the handle
|
||||||
|
hasn't been drawn yet.
|
||||||
|
|
||||||
|
These are not actually the locations where the beginning and end
|
||||||
|
are drawn; in order to keep handles from becoming invisible when
|
||||||
|
editing large files, we establish a minimum height by always
|
||||||
|
drawing handle bottoms VERTICAL_SCROLL_BAR_MIN_HANDLE pixels below
|
||||||
|
where they would be normally; the bottom and top are in a
|
||||||
|
different coordinate system. */
|
||||||
|
int start, end;
|
||||||
|
|
||||||
|
/* If the scroll bar handle is currently being dragged by the user,
|
||||||
|
this is the number of pixels from the top of the handle to the
|
||||||
|
place where the user grabbed it. If the handle isn't currently
|
||||||
|
being dragged, this is -1. */
|
||||||
|
int dragging;
|
||||||
|
|
||||||
|
/* True if the scroll bar is horizontal. */
|
||||||
|
bool horizontal;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Turning a lisp vector value into a pointer to a struct scroll_bar. */
|
||||||
|
#define XSCROLL_BAR(vec) ((struct scroll_bar *) XVECTOR (vec))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* This is a chain of structures for all the Android displays
|
||||||
|
currently in use. There is only ever one, but the rest of Emacs is
|
||||||
|
written with systems on which there can be many in mind. */
|
||||||
|
extern struct android_display_info *x_display_list;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Start of function definitions. These should be a neat subset of
|
||||||
|
the same ones in xterm.h, and come in the same order. */
|
||||||
|
|
||||||
|
/* From androidfns.c. */
|
||||||
|
|
||||||
|
extern void android_free_gcs (struct frame *);
|
||||||
|
extern void android_default_font_parameter (struct frame *, Lisp_Object);
|
||||||
|
|
||||||
|
/* Defined in androidterm.c. */
|
||||||
|
|
||||||
|
extern void android_term_init (void);
|
||||||
|
extern void android_set_window_size (struct frame *, bool, int, int);
|
||||||
|
extern void android_iconify_frame (struct frame *);
|
||||||
|
extern void android_make_frame_visible (struct frame *);
|
||||||
|
extern void android_make_frame_invisible (struct frame *);
|
||||||
|
extern void android_free_frame_resources (struct frame *);
|
||||||
|
|
||||||
|
extern int android_parse_color (struct frame *, const char *,
|
||||||
|
Emacs_Color *);
|
||||||
|
extern bool android_alloc_nearest_color (struct frame *, Emacs_Color *);
|
||||||
|
extern void android_query_colors (struct frame *, Emacs_Color *, int);
|
||||||
|
extern void android_clear_under_internal_border (struct frame *);
|
||||||
|
|
||||||
|
extern void syms_of_androidterm (void);
|
||||||
|
extern void mark_androidterm (void);
|
||||||
|
|
||||||
|
/* Defined in androidfns.c. */
|
||||||
|
|
||||||
|
extern void android_change_tab_bar_height (struct frame *, int);
|
||||||
|
extern void android_change_tool_bar_height (struct frame *, int);
|
||||||
|
extern void android_set_scroll_bar_default_width (struct frame *);
|
||||||
|
extern void android_set_scroll_bar_default_height (struct frame *);
|
||||||
|
extern bool android_defined_color (struct frame *, const char *,
|
||||||
|
Emacs_Color *, bool, bool);
|
||||||
|
extern void android_implicitly_set_name (struct frame *, Lisp_Object,
|
||||||
|
Lisp_Object);
|
||||||
|
extern void android_explicitly_set_name (struct frame *, Lisp_Object,
|
||||||
|
Lisp_Object);
|
||||||
|
|
||||||
|
extern void syms_of_androidfns (void);
|
||||||
|
|
||||||
|
/* Defined in androidfont.c. */
|
||||||
|
|
||||||
|
extern struct font_driver androidfont_driver;
|
||||||
|
|
||||||
|
extern void init_androidfont (void);
|
||||||
|
extern void syms_of_androidfont (void);
|
||||||
|
|
||||||
|
extern void android_finalize_font_entity (struct font_entity *);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define RGB_TO_ULONG(r, g, b) (((r) << 16) | ((g) << 8) | (b))
|
||||||
|
#define RED_FROM_ULONG(color) (((color) >> 16) & 0xff)
|
||||||
|
#define GREEN_FROM_ULONG(color) (((color) >> 8) & 0xff)
|
||||||
|
#define BLUE_FROM_ULONG(color) ((color) & 0xff)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _ANDROID_TERM_H_ */
|
||||||
|
|
@ -979,14 +979,15 @@ file_attributes (int fd, char const *name,
|
||||||
|
|
||||||
int err = EINVAL;
|
int err = EINVAL;
|
||||||
|
|
||||||
#if defined O_PATH && !defined HAVE_CYGWIN_O_PATH_BUG
|
#if defined O_PATH && !defined HAVE_CYGWIN_O_PATH_BUG \
|
||||||
|
&& !(defined HAVE_ANDROID && !defined ANDROID_STUBIFY)
|
||||||
int namefd = emacs_openat (fd, name, O_PATH | O_CLOEXEC | O_NOFOLLOW, 0);
|
int namefd = emacs_openat (fd, name, O_PATH | O_CLOEXEC | O_NOFOLLOW, 0);
|
||||||
if (namefd < 0)
|
if (namefd < 0)
|
||||||
err = errno;
|
err = errno;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
record_unwind_protect_int (close_file_unwind, namefd);
|
record_unwind_protect_int (close_file_unwind, namefd);
|
||||||
if (fstat (namefd, &s) != 0)
|
if (sys_fstat (namefd, &s) != 0)
|
||||||
{
|
{
|
||||||
err = errno;
|
err = errno;
|
||||||
/* The Linux kernel before version 3.6 does not support
|
/* The Linux kernel before version 3.6 does not support
|
||||||
|
|
|
||||||
|
|
@ -53,8 +53,15 @@ typedef struct
|
||||||
unsigned short red, green, blue;
|
unsigned short red, green, blue;
|
||||||
} Emacs_Color;
|
} Emacs_Color;
|
||||||
|
|
||||||
|
#ifndef HAVE_ANDROID
|
||||||
/* Accommodate X's usage of None as a null resource ID. */
|
/* Accommodate X's usage of None as a null resource ID. */
|
||||||
#define No_Cursor (NULL)
|
#define No_Cursor (NULL)
|
||||||
|
#else
|
||||||
|
/* Android doesn't support cursors and also uses handles. */
|
||||||
|
#define No_Cursor 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE_ANDROID
|
||||||
|
|
||||||
/* XRectangle-like struct used by non-X GUI code. */
|
/* XRectangle-like struct used by non-X GUI code. */
|
||||||
typedef struct
|
typedef struct
|
||||||
|
|
@ -63,6 +70,12 @@ typedef struct
|
||||||
unsigned width, height;
|
unsigned width, height;
|
||||||
} Emacs_Rectangle;
|
} Emacs_Rectangle;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
typedef struct android_rectangle Emacs_Rectangle;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/* XGCValues-like struct used by non-X GUI code. */
|
/* XGCValues-like struct used by non-X GUI code. */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
|
@ -144,6 +157,13 @@ typedef Emacs_Pixmap Emacs_Pix_Container;
|
||||||
typedef Emacs_Pixmap Emacs_Pix_Context;
|
typedef Emacs_Pixmap Emacs_Pix_Context;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_ANDROID
|
||||||
|
#include "androidgui.h"
|
||||||
|
typedef struct android_display_info Display_Info;
|
||||||
|
typedef Emacs_Pixmap Emacs_Pix_Container;
|
||||||
|
typedef Emacs_Pixmap Emacs_Pix_Context;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_WINDOW_SYSTEM
|
#ifdef HAVE_WINDOW_SYSTEM
|
||||||
# include <time.h>
|
# include <time.h>
|
||||||
# include "fontset.h"
|
# include "fontset.h"
|
||||||
|
|
@ -1401,6 +1421,8 @@ struct glyph_string
|
||||||
/* The GC to use for drawing this glyph string. */
|
/* The GC to use for drawing this glyph string. */
|
||||||
#if defined (HAVE_X_WINDOWS)
|
#if defined (HAVE_X_WINDOWS)
|
||||||
GC gc;
|
GC gc;
|
||||||
|
#elif defined HAVE_ANDROID
|
||||||
|
struct android_gc *gc;
|
||||||
#endif
|
#endif
|
||||||
#if defined (HAVE_NTGUI)
|
#if defined (HAVE_NTGUI)
|
||||||
Emacs_GC *gc;
|
Emacs_GC *gc;
|
||||||
|
|
@ -1681,6 +1703,8 @@ struct face
|
||||||
drawing the characters in this face. */
|
drawing the characters in this face. */
|
||||||
# ifdef HAVE_X_WINDOWS
|
# ifdef HAVE_X_WINDOWS
|
||||||
GC gc;
|
GC gc;
|
||||||
|
# elif defined HAVE_ANDROID
|
||||||
|
struct android_gc *gc;
|
||||||
# else
|
# else
|
||||||
Emacs_GC *gc;
|
Emacs_GC *gc;
|
||||||
# endif
|
# endif
|
||||||
|
|
@ -3502,9 +3526,11 @@ extern void gui_clear_window_mouse_face (struct window *);
|
||||||
extern void cancel_mouse_face (struct frame *);
|
extern void cancel_mouse_face (struct frame *);
|
||||||
extern bool clear_mouse_face (Mouse_HLInfo *);
|
extern bool clear_mouse_face (Mouse_HLInfo *);
|
||||||
extern bool cursor_in_mouse_face_p (struct window *w);
|
extern bool cursor_in_mouse_face_p (struct window *w);
|
||||||
|
#ifndef HAVE_ANDROID
|
||||||
extern void tty_draw_row_with_mouse_face (struct window *, struct glyph_row *,
|
extern void tty_draw_row_with_mouse_face (struct window *, struct glyph_row *,
|
||||||
int, int, enum draw_glyphs_face);
|
int, int, enum draw_glyphs_face);
|
||||||
extern void display_tty_menu_item (const char *, int, int, int, int, bool);
|
extern void display_tty_menu_item (const char *, int, int, int, int, bool);
|
||||||
|
#endif
|
||||||
extern struct glyph *x_y_to_hpos_vpos (struct window *, int, int, int *, int *,
|
extern struct glyph *x_y_to_hpos_vpos (struct window *, int, int, int *, int *,
|
||||||
int *, int *, int *);
|
int *, int *, int *);
|
||||||
/* Flags passed to try_window. */
|
/* Flags passed to try_window. */
|
||||||
|
|
@ -3566,7 +3592,7 @@ void prepare_image_for_display (struct frame *, struct image *);
|
||||||
ptrdiff_t lookup_image (struct frame *, Lisp_Object, int);
|
ptrdiff_t lookup_image (struct frame *, Lisp_Object, int);
|
||||||
|
|
||||||
#if defined HAVE_X_WINDOWS || defined USE_CAIRO || defined HAVE_NS \
|
#if defined HAVE_X_WINDOWS || defined USE_CAIRO || defined HAVE_NS \
|
||||||
|| defined HAVE_HAIKU
|
|| defined HAVE_HAIKU || defined HAVE_ANDROID
|
||||||
#define RGB_PIXEL_COLOR unsigned long
|
#define RGB_PIXEL_COLOR unsigned long
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -3647,6 +3673,9 @@ void gamma_correct (struct frame *, COLORREF *);
|
||||||
#ifdef HAVE_HAIKU
|
#ifdef HAVE_HAIKU
|
||||||
void gamma_correct (struct frame *, Emacs_Color *);
|
void gamma_correct (struct frame *, Emacs_Color *);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_ANDROID
|
||||||
|
extern void gamma_correct (struct frame *, Emacs_Color *);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_WINDOW_SYSTEM
|
#ifdef HAVE_WINDOW_SYSTEM
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
#include "xwidget.h"
|
#include "xwidget.h"
|
||||||
#include "pdumper.h"
|
#include "pdumper.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_ANDROID
|
||||||
|
#include "android.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_WINDOW_SYSTEM
|
#ifdef HAVE_WINDOW_SYSTEM
|
||||||
#include TERM_HEADER
|
#include TERM_HEADER
|
||||||
#endif /* HAVE_WINDOW_SYSTEM */
|
#endif /* HAVE_WINDOW_SYSTEM */
|
||||||
|
|
@ -788,7 +792,7 @@ clear_current_matrices (register struct frame *f)
|
||||||
if (f->current_matrix)
|
if (f->current_matrix)
|
||||||
clear_glyph_matrix (f->current_matrix);
|
clear_glyph_matrix (f->current_matrix);
|
||||||
|
|
||||||
#if defined (HAVE_X_WINDOWS) && ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
|
#if defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR
|
||||||
/* Clear the matrix of the menu bar window, if such a window exists.
|
/* Clear the matrix of the menu bar window, if such a window exists.
|
||||||
The menu bar window is currently used to display menus on X when
|
The menu bar window is currently used to display menus on X when
|
||||||
no toolkit support is compiled in. */
|
no toolkit support is compiled in. */
|
||||||
|
|
@ -822,7 +826,7 @@ clear_desired_matrices (register struct frame *f)
|
||||||
if (f->desired_matrix)
|
if (f->desired_matrix)
|
||||||
clear_glyph_matrix (f->desired_matrix);
|
clear_glyph_matrix (f->desired_matrix);
|
||||||
|
|
||||||
#if defined (HAVE_X_WINDOWS) && ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
|
#if defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR
|
||||||
if (WINDOWP (f->menu_bar_window))
|
if (WINDOWP (f->menu_bar_window))
|
||||||
clear_glyph_matrix (XWINDOW (f->menu_bar_window)->desired_matrix);
|
clear_glyph_matrix (XWINDOW (f->menu_bar_window)->desired_matrix);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1156,6 +1160,7 @@ prepare_desired_row (struct window *w, struct glyph_row *row, bool mode_line_p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef HAVE_ANDROID
|
||||||
|
|
||||||
/* Return a hash code for glyph row ROW, which may
|
/* Return a hash code for glyph row ROW, which may
|
||||||
be from current or desired matrix of frame F. */
|
be from current or desired matrix of frame F. */
|
||||||
|
|
@ -1248,6 +1253,7 @@ line_draw_cost (struct frame *f, struct glyph_matrix *matrix, int vpos)
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Return true if the glyph rows A and B have equal contents.
|
/* Return true if the glyph rows A and B have equal contents.
|
||||||
MOUSE_FACE_P means compare the mouse_face_p flags of A and B, too. */
|
MOUSE_FACE_P means compare the mouse_face_p flags of A and B, too. */
|
||||||
|
|
@ -2160,7 +2166,7 @@ adjust_frame_glyphs_for_window_redisplay (struct frame *f)
|
||||||
/* Allocate/reallocate window matrices. */
|
/* Allocate/reallocate window matrices. */
|
||||||
allocate_matrices_for_window_redisplay (XWINDOW (FRAME_ROOT_WINDOW (f)));
|
allocate_matrices_for_window_redisplay (XWINDOW (FRAME_ROOT_WINDOW (f)));
|
||||||
|
|
||||||
#if defined (HAVE_X_WINDOWS) && ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
|
#if defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR
|
||||||
/* Allocate/ reallocate matrices of the dummy window used to display
|
/* Allocate/ reallocate matrices of the dummy window used to display
|
||||||
the menu bar under X when no X toolkit support is available. */
|
the menu bar under X when no X toolkit support is available. */
|
||||||
{
|
{
|
||||||
|
|
@ -2296,7 +2302,7 @@ free_glyphs (struct frame *f)
|
||||||
if (!NILP (f->root_window))
|
if (!NILP (f->root_window))
|
||||||
free_window_matrices (XWINDOW (f->root_window));
|
free_window_matrices (XWINDOW (f->root_window));
|
||||||
|
|
||||||
#if defined (HAVE_X_WINDOWS) && ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
|
#if defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR
|
||||||
/* Free the dummy window for menu bars without X toolkit and its
|
/* Free the dummy window for menu bars without X toolkit and its
|
||||||
glyph matrices. */
|
glyph matrices. */
|
||||||
if (!NILP (f->menu_bar_window))
|
if (!NILP (f->menu_bar_window))
|
||||||
|
|
@ -3234,7 +3240,7 @@ update_frame (struct frame *f, bool force_p, bool inhibit_hairy_id_p)
|
||||||
when pending input is detected. */
|
when pending input is detected. */
|
||||||
update_begin (f);
|
update_begin (f);
|
||||||
|
|
||||||
#if defined (HAVE_X_WINDOWS) && ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
|
#if defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR
|
||||||
/* Update the menu bar on X frames that don't have toolkit
|
/* Update the menu bar on X frames that don't have toolkit
|
||||||
support. */
|
support. */
|
||||||
if (WINDOWP (f->menu_bar_window))
|
if (WINDOWP (f->menu_bar_window))
|
||||||
|
|
@ -5059,6 +5065,10 @@ update_frame_1 (struct frame *f, bool force_p, bool inhibit_id_p,
|
||||||
static bool
|
static bool
|
||||||
scrolling (struct frame *frame)
|
scrolling (struct frame *frame)
|
||||||
{
|
{
|
||||||
|
/* In fact this code should never be reached at all under
|
||||||
|
Android. */
|
||||||
|
|
||||||
|
#ifndef HAVE_ANDROID
|
||||||
int unchanged_at_top, unchanged_at_bottom;
|
int unchanged_at_top, unchanged_at_bottom;
|
||||||
int window_size;
|
int window_size;
|
||||||
int changed_lines;
|
int changed_lines;
|
||||||
|
|
@ -5149,6 +5159,7 @@ scrolling (struct frame *frame)
|
||||||
free_at_end_vpos - unchanged_at_top);
|
free_at_end_vpos - unchanged_at_top);
|
||||||
|
|
||||||
SAFE_FREE ();
|
SAFE_FREE ();
|
||||||
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5190,7 +5201,9 @@ count_match (struct glyph *str1, struct glyph *end1, struct glyph *str2, struct
|
||||||
|
|
||||||
/* Char insertion/deletion cost vector, from term.c */
|
/* Char insertion/deletion cost vector, from term.c */
|
||||||
|
|
||||||
|
#ifndef HAVE_ANDROID
|
||||||
#define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_TOTAL_COLS ((f))])
|
#define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_TOTAL_COLS ((f))])
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Perform a frame-based update on line VPOS in frame FRAME. */
|
/* Perform a frame-based update on line VPOS in frame FRAME. */
|
||||||
|
|
@ -5395,7 +5408,10 @@ update_frame_line (struct frame *f, int vpos, bool updating_menu_p)
|
||||||
tem = (nlen - nsp) - (olen - osp);
|
tem = (nlen - nsp) - (olen - osp);
|
||||||
if (endmatch && tem
|
if (endmatch && tem
|
||||||
&& (!FRAME_CHAR_INS_DEL_OK (f)
|
&& (!FRAME_CHAR_INS_DEL_OK (f)
|
||||||
|| endmatch <= char_ins_del_cost (f)[tem]))
|
#ifndef HAVE_ANDROID
|
||||||
|
|| endmatch <= char_ins_del_cost (f)[tem]
|
||||||
|
#endif
|
||||||
|
))
|
||||||
endmatch = 0;
|
endmatch = 0;
|
||||||
|
|
||||||
/* nsp - osp is the distance to insert or delete.
|
/* nsp - osp is the distance to insert or delete.
|
||||||
|
|
@ -5405,7 +5421,10 @@ update_frame_line (struct frame *f, int vpos, bool updating_menu_p)
|
||||||
|
|
||||||
if (nsp != osp
|
if (nsp != osp
|
||||||
&& (!FRAME_CHAR_INS_DEL_OK (f)
|
&& (!FRAME_CHAR_INS_DEL_OK (f)
|
||||||
|| begmatch + endmatch <= char_ins_del_cost (f)[nsp - osp]))
|
#ifndef HAVE_ANDROID
|
||||||
|
|| begmatch + endmatch <= char_ins_del_cost (f)[nsp - osp]
|
||||||
|
#endif
|
||||||
|
))
|
||||||
{
|
{
|
||||||
begmatch = 0;
|
begmatch = 0;
|
||||||
endmatch = 0;
|
endmatch = 0;
|
||||||
|
|
@ -6528,6 +6547,15 @@ init_display_interactive (void)
|
||||||
}
|
}
|
||||||
#endif /* HAVE_X_WINDOWS */
|
#endif /* HAVE_X_WINDOWS */
|
||||||
|
|
||||||
|
#ifdef HAVE_ANDROID
|
||||||
|
if (!inhibit_window_system && android_init_gui)
|
||||||
|
{
|
||||||
|
Vinitial_window_system = Qandroid;
|
||||||
|
android_term_init ();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_NTGUI
|
#ifdef HAVE_NTGUI
|
||||||
if (!inhibit_window_system)
|
if (!inhibit_window_system)
|
||||||
{
|
{
|
||||||
|
|
@ -6582,6 +6610,7 @@ init_display_interactive (void)
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef HAVE_ANDROID
|
||||||
{
|
{
|
||||||
struct terminal *t;
|
struct terminal *t;
|
||||||
struct frame *f = XFRAME (selected_frame);
|
struct frame *f = XFRAME (selected_frame);
|
||||||
|
|
@ -6624,6 +6653,11 @@ init_display_interactive (void)
|
||||||
: Qnil));
|
: Qnil));
|
||||||
Fmodify_frame_parameters (selected_frame, tty_arg);
|
Fmodify_frame_parameters (selected_frame, tty_arg);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
fatal ("Could not establish a connection to the Android application.\n"
|
||||||
|
"Emacs does not work on text terminals when built to run as"
|
||||||
|
" part of an Android application package.");
|
||||||
|
#endif
|
||||||
|
|
||||||
{
|
{
|
||||||
struct frame *sf = SELECTED_FRAME ();
|
struct frame *sf = SELECTED_FRAME ();
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
#include <sys/utsname.h>
|
#include <sys/utsname.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_ANDROID
|
||||||
|
#include "android.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "lisp.h"
|
#include "lisp.h"
|
||||||
|
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
|
|
@ -1264,7 +1268,11 @@ is in general a comma-separated list. */)
|
||||||
if (!pw)
|
if (!pw)
|
||||||
return Qnil;
|
return Qnil;
|
||||||
|
|
||||||
|
#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
|
||||||
|
p = android_user_full_name (pw);
|
||||||
|
#else
|
||||||
p = USER_FULL_NAME;
|
p = USER_FULL_NAME;
|
||||||
|
#endif
|
||||||
/* Chop off everything after the first comma, since 'pw_gecos' is a
|
/* Chop off everything after the first comma, since 'pw_gecos' is a
|
||||||
comma-separated list. */
|
comma-separated list. */
|
||||||
q = strchr (p, ',');
|
q = strchr (p, ',');
|
||||||
|
|
|
||||||
37
src/emacs.c
37
src/emacs.c
|
|
@ -33,6 +33,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
#include "lisp.h"
|
#include "lisp.h"
|
||||||
#include "sysstdio.h"
|
#include "sysstdio.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_ANDROID
|
||||||
|
#include "androidterm.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef WINDOWSNT
|
#ifdef WINDOWSNT
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
|
@ -137,6 +141,10 @@ extern char etext;
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
|
||||||
|
#include "android.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/* We don't guard this with HAVE_TREE_SITTER because treesit.o is
|
/* We don't guard this with HAVE_TREE_SITTER because treesit.o is
|
||||||
always compiled (to provide treesit-available-p). */
|
always compiled (to provide treesit-available-p). */
|
||||||
#include "treesit.h"
|
#include "treesit.h"
|
||||||
|
|
@ -1123,7 +1131,7 @@ load_seccomp (const char *file)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
struct stat stat;
|
struct stat stat;
|
||||||
if (fstat (fd, &stat) != 0)
|
if (sys_fstat (fd, &stat) != 0)
|
||||||
{
|
{
|
||||||
emacs_perror ("fstat");
|
emacs_perror ("fstat");
|
||||||
goto out;
|
goto out;
|
||||||
|
|
@ -1225,12 +1233,18 @@ maybe_load_seccomp (int argc, char **argv)
|
||||||
|
|
||||||
#endif /* SECCOMP_USABLE */
|
#endif /* SECCOMP_USABLE */
|
||||||
|
|
||||||
|
#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
|
||||||
|
int
|
||||||
|
android_emacs_init (int argc, char **argv)
|
||||||
|
#else
|
||||||
int
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
/* Variable near the bottom of the stack, and aligned appropriately
|
/* Variable near the bottom of the stack, and aligned appropriately
|
||||||
for pointers. */
|
for pointers. */
|
||||||
void *stack_bottom_variable;
|
void *stack_bottom_variable;
|
||||||
|
int old_argc;
|
||||||
|
|
||||||
/* First, check whether we should apply a seccomp filter. This
|
/* First, check whether we should apply a seccomp filter. This
|
||||||
should come at the very beginning to allow the filter to protect
|
should come at the very beginning to allow the filter to protect
|
||||||
|
|
@ -1425,8 +1439,10 @@ main (int argc, char **argv)
|
||||||
|
|
||||||
bool only_version = false;
|
bool only_version = false;
|
||||||
sort_args (argc, argv);
|
sort_args (argc, argv);
|
||||||
argc = 0;
|
old_argc = argc, argc = 0;
|
||||||
while (argv[argc]) argc++;
|
while (argv[argc]
|
||||||
|
/* Don't allow going past argv. */
|
||||||
|
&& argc < old_argc) argc++;
|
||||||
|
|
||||||
skip_args = 0;
|
skip_args = 0;
|
||||||
if (argmatch (argv, argc, "-version", "--version", 3, NULL, &skip_args))
|
if (argmatch (argv, argc, "-version", "--version", 3, NULL, &skip_args))
|
||||||
|
|
@ -2375,6 +2391,14 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
|
||||||
#endif
|
#endif
|
||||||
syms_of_fontset ();
|
syms_of_fontset ();
|
||||||
#endif /* HAVE_HAIKU */
|
#endif /* HAVE_HAIKU */
|
||||||
|
#ifdef HAVE_ANDROID
|
||||||
|
syms_of_androidterm ();
|
||||||
|
syms_of_androidfns ();
|
||||||
|
syms_of_fontset ();
|
||||||
|
#if !defined ANDROID_STUBIFY
|
||||||
|
syms_of_androidfont ();
|
||||||
|
#endif /* !ANDROID_STUBIFY */
|
||||||
|
#endif /* HAVE_ANDROID */
|
||||||
|
|
||||||
syms_of_gnutls ();
|
syms_of_gnutls ();
|
||||||
|
|
||||||
|
|
@ -2436,6 +2460,10 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
|
||||||
init_haiku_select ();
|
init_haiku_select ();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
|
||||||
|
init_androidfont ();
|
||||||
|
#endif
|
||||||
|
|
||||||
init_charset ();
|
init_charset ();
|
||||||
|
|
||||||
/* This calls putenv and so must precede init_process_emacs. */
|
/* This calls putenv and so must precede init_process_emacs. */
|
||||||
|
|
@ -2950,7 +2978,7 @@ shut_down_emacs (int sig, Lisp_Object stuff)
|
||||||
Vinhibit_redisplay = Qt;
|
Vinhibit_redisplay = Qt;
|
||||||
|
|
||||||
/* If we are controlling the terminal, reset terminal modes. */
|
/* If we are controlling the terminal, reset terminal modes. */
|
||||||
#ifndef DOS_NT
|
#if !defined DOS_NT && !(defined HAVE_ANDROID && !defined ANDROID_STUBIFY)
|
||||||
pid_t tpgrp = tcgetpgrp (STDIN_FILENO);
|
pid_t tpgrp = tcgetpgrp (STDIN_FILENO);
|
||||||
if (tpgrp != -1 && tpgrp == getpgrp ())
|
if (tpgrp != -1 && tpgrp == getpgrp ())
|
||||||
{
|
{
|
||||||
|
|
@ -3469,6 +3497,7 @@ Special values:
|
||||||
`windows-nt' compiled as a native W32 application.
|
`windows-nt' compiled as a native W32 application.
|
||||||
`cygwin' compiled using the Cygwin library.
|
`cygwin' compiled using the Cygwin library.
|
||||||
`haiku' compiled for a Haiku system.
|
`haiku' compiled for a Haiku system.
|
||||||
|
`android' compiled for Android.
|
||||||
Anything else (in Emacs 26, the possibilities are: aix, berkeley-unix,
|
Anything else (in Emacs 26, the possibilities are: aix, berkeley-unix,
|
||||||
hpux, usg-unix-v) indicates some sort of Unix system. */);
|
hpux, usg-unix-v) indicates some sort of Unix system. */);
|
||||||
Vsystem_type = intern_c_string (SYSTEM_TYPE);
|
Vsystem_type = intern_c_string (SYSTEM_TYPE);
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ GNU General Public License for more details.
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#if !defined HAVE_ANDROID || defined ANDROID_STUBIFY
|
||||||
|
|
||||||
/* Together with PATH_SITELOADSEARCH, this gives the default value of
|
/* Together with PATH_SITELOADSEARCH, this gives the default value of
|
||||||
load-path, which is the search path for the Lisp function "load".
|
load-path, which is the search path for the Lisp function "load".
|
||||||
|
|
@ -79,3 +80,24 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
/* Where Emacs should look for the application default file. */
|
/* Where Emacs should look for the application default file. */
|
||||||
#define PATH_X_DEFAULTS "/usr/lib/X11/%L/%T/%N%C%S:/usr/lib/X11/%l/%T/%N%C%S:/usr/lib/X11/%T/%N%C%S:/usr/lib/X11/%L/%T/%N%S:/usr/lib/X11/%l/%T/%N%S:/usr/lib/X11/%T/%N%S"
|
#define PATH_X_DEFAULTS "/usr/lib/X11/%L/%T/%N%C%S:/usr/lib/X11/%l/%T/%N%C%S:/usr/lib/X11/%T/%N%C%S:/usr/lib/X11/%L/%T/%N%S:/usr/lib/X11/%l/%T/%N%S:/usr/lib/X11/%T/%N%S"
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* Replace the defines above with links to files in the assets
|
||||||
|
pseudo-directory. Preserve the extra spaces, or epaths.in will not
|
||||||
|
be generated correctly. */
|
||||||
|
|
||||||
|
# define PATH_EXEC (android_lib_dir)
|
||||||
|
# define PATH_LOADSEARCH "/assets/lisp/"
|
||||||
|
# define PATH_SITELOADSEARCH (android_site_load_path)
|
||||||
|
# define PATH_DUMPLOADSEARCH "/assets/lisp/"
|
||||||
|
# define PATH_DATA "/assets/etc/"
|
||||||
|
# define PATH_DOC "/assets/etc/"
|
||||||
|
# define PATH_INFO "/assets/info/"
|
||||||
|
# define PATH_GAME ""
|
||||||
|
# define PATH_BITMAPS ""
|
||||||
|
|
||||||
|
extern char *android_site_load_path;
|
||||||
|
extern char *android_lib_dir;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
||||||
25
src/fileio.c
25
src/fileio.c
|
|
@ -56,6 +56,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
#include "region-cache.h"
|
#include "region-cache.h"
|
||||||
#include "frame.h"
|
#include "frame.h"
|
||||||
|
|
||||||
|
#if defined HAVE_ANDROID
|
||||||
|
#include "android.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_LINUX_FS_H
|
#ifdef HAVE_LINUX_FS_H
|
||||||
# include <sys/ioctl.h>
|
# include <sys/ioctl.h>
|
||||||
# include <linux/fs.h>
|
# include <linux/fs.h>
|
||||||
|
|
@ -135,7 +139,6 @@ static dev_t timestamp_file_system;
|
||||||
static Lisp_Object Vwrite_region_annotation_buffers;
|
static Lisp_Object Vwrite_region_annotation_buffers;
|
||||||
|
|
||||||
static Lisp_Object emacs_readlinkat (int, char const *);
|
static Lisp_Object emacs_readlinkat (int, char const *);
|
||||||
static Lisp_Object file_name_directory (Lisp_Object);
|
|
||||||
static bool a_write (int, Lisp_Object, ptrdiff_t, ptrdiff_t,
|
static bool a_write (int, Lisp_Object, ptrdiff_t, ptrdiff_t,
|
||||||
Lisp_Object *, struct coding_system *);
|
Lisp_Object *, struct coding_system *);
|
||||||
static bool e_write (int, Lisp_Object, ptrdiff_t, ptrdiff_t,
|
static bool e_write (int, Lisp_Object, ptrdiff_t, ptrdiff_t,
|
||||||
|
|
@ -160,6 +163,12 @@ file_access_p (char const *file, int amode)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
|
||||||
|
/* FILE may be some kind of special Android file. */
|
||||||
|
if (android_file_access_p (file, amode))
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (faccessat (AT_FDCWD, file, amode, AT_EACCESS) == 0)
|
if (faccessat (AT_FDCWD, file, amode, AT_EACCESS) == 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
@ -370,7 +379,7 @@ Given a Unix syntax file name, returns a string ending in slash. */)
|
||||||
/* Return the directory component of FILENAME, or nil if FILENAME does
|
/* Return the directory component of FILENAME, or nil if FILENAME does
|
||||||
not contain a directory component. */
|
not contain a directory component. */
|
||||||
|
|
||||||
static Lisp_Object
|
Lisp_Object
|
||||||
file_name_directory (Lisp_Object filename)
|
file_name_directory (Lisp_Object filename)
|
||||||
{
|
{
|
||||||
char *beg = SSDATA (filename);
|
char *beg = SSDATA (filename);
|
||||||
|
|
@ -2227,7 +2236,7 @@ permissions. */)
|
||||||
|
|
||||||
record_unwind_protect_int (close_file_unwind, ifd);
|
record_unwind_protect_int (close_file_unwind, ifd);
|
||||||
|
|
||||||
if (fstat (ifd, &st) != 0)
|
if (sys_fstat (ifd, &st) != 0)
|
||||||
report_file_error ("Input file status", file);
|
report_file_error ("Input file status", file);
|
||||||
|
|
||||||
if (!NILP (preserve_permissions))
|
if (!NILP (preserve_permissions))
|
||||||
|
|
@ -2273,7 +2282,7 @@ permissions. */)
|
||||||
if (already_exists)
|
if (already_exists)
|
||||||
{
|
{
|
||||||
struct stat out_st;
|
struct stat out_st;
|
||||||
if (fstat (ofd, &out_st) != 0)
|
if (sys_fstat (ofd, &out_st) != 0)
|
||||||
report_file_error ("Output file status", newname);
|
report_file_error ("Output file status", newname);
|
||||||
if (st.st_dev == out_st.st_dev && st.st_ino == out_st.st_ino)
|
if (st.st_dev == out_st.st_dev && st.st_ino == out_st.st_ino)
|
||||||
report_file_errno ("Input and output files are the same",
|
report_file_errno ("Input and output files are the same",
|
||||||
|
|
@ -3078,7 +3087,7 @@ file_directory_p (Lisp_Object file)
|
||||||
errno = ENOTDIR; /* like the non-DOS_NT branch below does */
|
errno = ENOTDIR; /* like the non-DOS_NT branch below does */
|
||||||
return retval;
|
return retval;
|
||||||
#else
|
#else
|
||||||
# ifdef O_PATH
|
# if defined O_PATH && !(defined HAVE_ANDROID && !defined ANDROID_STUBIFY)
|
||||||
/* Use O_PATH if available, as it avoids races and EOVERFLOW issues. */
|
/* Use O_PATH if available, as it avoids races and EOVERFLOW issues. */
|
||||||
int fd = emacs_openat (AT_FDCWD, SSDATA (file),
|
int fd = emacs_openat (AT_FDCWD, SSDATA (file),
|
||||||
O_PATH | O_CLOEXEC | O_DIRECTORY, 0);
|
O_PATH | O_CLOEXEC | O_DIRECTORY, 0);
|
||||||
|
|
@ -4002,7 +4011,7 @@ by calling `format-decode', which see. */)
|
||||||
XCAR (XCAR (window_markers)));
|
XCAR (XCAR (window_markers)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fstat (fd, &st) != 0)
|
if (sys_fstat (fd, &st) != 0)
|
||||||
report_file_error ("Input file status", orig_filename);
|
report_file_error ("Input file status", orig_filename);
|
||||||
mtime = get_stat_mtime (&st);
|
mtime = get_stat_mtime (&st);
|
||||||
|
|
||||||
|
|
@ -5394,7 +5403,7 @@ write_region (Lisp_Object start, Lisp_Object end, Lisp_Object filename,
|
||||||
modtime = invalid_timespec ();
|
modtime = invalid_timespec ();
|
||||||
if (visiting)
|
if (visiting)
|
||||||
{
|
{
|
||||||
if (fstat (desc, &st) == 0)
|
if (sys_fstat (desc, &st) == 0)
|
||||||
modtime = get_stat_mtime (&st);
|
modtime = get_stat_mtime (&st);
|
||||||
else
|
else
|
||||||
ok = 0, save_errno = errno;
|
ok = 0, save_errno = errno;
|
||||||
|
|
@ -5432,7 +5441,7 @@ write_region (Lisp_Object start, Lisp_Object end, Lisp_Object filename,
|
||||||
if (desc1 >= 0)
|
if (desc1 >= 0)
|
||||||
{
|
{
|
||||||
struct stat st1;
|
struct stat st1;
|
||||||
if (fstat (desc1, &st1) == 0
|
if (sys_fstat (desc1, &st1) == 0
|
||||||
&& st.st_dev == st1.st_dev && st.st_ino == st1.st_ino)
|
&& st.st_dev == st1.st_dev && st.st_ino == st1.st_ino)
|
||||||
{
|
{
|
||||||
/* Use the heuristic if it appears to be valid. With neither
|
/* Use the heuristic if it appears to be valid. With neither
|
||||||
|
|
|
||||||
|
|
@ -120,6 +120,12 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
* Non-forced locks on non-MS-Windows systems that support neither
|
* Non-forced locks on non-MS-Windows systems that support neither
|
||||||
hard nor symbolic links. */
|
hard nor symbolic links. */
|
||||||
|
|
||||||
|
/* Boot time is not available on Android. */
|
||||||
|
|
||||||
|
#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
|
||||||
|
#undef BOOT_TIME
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Return the time of the last system boot. */
|
/* Return the time of the last system boot. */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3519,6 +3519,10 @@ The data read from the system are decoded using `locale-coding-system'. */)
|
||||||
(Lisp_Object item)
|
(Lisp_Object item)
|
||||||
{
|
{
|
||||||
char *str = NULL;
|
char *str = NULL;
|
||||||
|
|
||||||
|
/* STR is apparently unused on Android. */
|
||||||
|
((void) str);
|
||||||
|
|
||||||
#ifdef HAVE_LANGINFO_CODESET
|
#ifdef HAVE_LANGINFO_CODESET
|
||||||
if (EQ (item, Qcodeset))
|
if (EQ (item, Qcodeset))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
16
src/font.c
16
src/font.c
|
|
@ -180,6 +180,22 @@ font_make_entity (void)
|
||||||
return font_entity;
|
return font_entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_ANDROID
|
||||||
|
|
||||||
|
Lisp_Object
|
||||||
|
font_make_entity_android (int size)
|
||||||
|
{
|
||||||
|
Lisp_Object font_entity;
|
||||||
|
struct font_entity *entity
|
||||||
|
= ((struct font_entity *)
|
||||||
|
allocate_pseudovector (size, FONT_ENTITY_MAX, FONT_ENTITY_MAX,
|
||||||
|
PVEC_FONT));
|
||||||
|
XSETFONT (font_entity, entity);
|
||||||
|
return font_entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Create a font-object whose structure size is SIZE. If ENTITY is
|
/* Create a font-object whose structure size is SIZE. If ENTITY is
|
||||||
not nil, copy properties from ENTITY to the font-object. If
|
not nil, copy properties from ENTITY to the font-object. If
|
||||||
PIXELSIZE is positive, set the `size' property to PIXELSIZE. */
|
PIXELSIZE is positive, set the `size' property to PIXELSIZE. */
|
||||||
|
|
|
||||||
|
|
@ -823,6 +823,9 @@ extern Lisp_Object copy_font_spec (Lisp_Object);
|
||||||
extern Lisp_Object merge_font_spec (Lisp_Object, Lisp_Object);
|
extern Lisp_Object merge_font_spec (Lisp_Object, Lisp_Object);
|
||||||
|
|
||||||
extern Lisp_Object font_make_entity (void);
|
extern Lisp_Object font_make_entity (void);
|
||||||
|
#ifdef HAVE_ANDROID
|
||||||
|
extern Lisp_Object font_make_entity_android (int);
|
||||||
|
#endif
|
||||||
extern Lisp_Object font_make_object (int, Lisp_Object, int);
|
extern Lisp_Object font_make_object (int, Lisp_Object, int);
|
||||||
#if defined (HAVE_XFT) || defined (HAVE_FREETYPE) || defined (HAVE_NS)
|
#if defined (HAVE_XFT) || defined (HAVE_FREETYPE) || defined (HAVE_NS)
|
||||||
extern Lisp_Object font_build_object (int, Lisp_Object, Lisp_Object, double);
|
extern Lisp_Object font_build_object (int, Lisp_Object, Lisp_Object, double);
|
||||||
|
|
|
||||||
30
src/frame.c
30
src/frame.c
|
|
@ -228,6 +228,7 @@ Value is:
|
||||||
`pc' for a direct-write MS-DOS frame,
|
`pc' for a direct-write MS-DOS frame,
|
||||||
`pgtk' for an Emacs frame running on pure GTK.
|
`pgtk' for an Emacs frame running on pure GTK.
|
||||||
`haiku' for an Emacs frame running in Haiku.
|
`haiku' for an Emacs frame running in Haiku.
|
||||||
|
`android' for an Emacs frame running in Android.
|
||||||
See also `frame-live-p'. */)
|
See also `frame-live-p'. */)
|
||||||
(Lisp_Object object)
|
(Lisp_Object object)
|
||||||
{
|
{
|
||||||
|
|
@ -250,6 +251,8 @@ See also `frame-live-p'. */)
|
||||||
return Qpgtk;
|
return Qpgtk;
|
||||||
case output_haiku:
|
case output_haiku:
|
||||||
return Qhaiku;
|
return Qhaiku;
|
||||||
|
case output_android:
|
||||||
|
return Qandroid;
|
||||||
default:
|
default:
|
||||||
emacs_abort ();
|
emacs_abort ();
|
||||||
}
|
}
|
||||||
|
|
@ -279,6 +282,7 @@ The value is a symbol:
|
||||||
`pc' for a direct-write MS-DOS frame.
|
`pc' for a direct-write MS-DOS frame.
|
||||||
`pgtk' for an Emacs frame using pure GTK facilities.
|
`pgtk' for an Emacs frame using pure GTK facilities.
|
||||||
`haiku' for an Emacs frame running in Haiku.
|
`haiku' for an Emacs frame running in Haiku.
|
||||||
|
`android' for an Emacs frame running in Android/
|
||||||
|
|
||||||
FRAME defaults to the currently selected frame.
|
FRAME defaults to the currently selected frame.
|
||||||
|
|
||||||
|
|
@ -1228,6 +1232,7 @@ make_initial_frame (void)
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef HAVE_ANDROID
|
||||||
|
|
||||||
static struct frame *
|
static struct frame *
|
||||||
make_terminal_frame (struct terminal *terminal)
|
make_terminal_frame (struct terminal *terminal)
|
||||||
|
|
@ -1317,6 +1322,8 @@ get_future_frame_param (Lisp_Object parameter,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
DEFUN ("make-terminal-frame", Fmake_terminal_frame, Smake_terminal_frame,
|
DEFUN ("make-terminal-frame", Fmake_terminal_frame, Smake_terminal_frame,
|
||||||
1, 1, 0,
|
1, 1, 0,
|
||||||
doc: /* Create an additional terminal frame, possibly on another terminal.
|
doc: /* Create an additional terminal frame, possibly on another terminal.
|
||||||
|
|
@ -1336,6 +1343,10 @@ Note that changing the size of one terminal frame automatically
|
||||||
affects all frames on the same terminal device. */)
|
affects all frames on the same terminal device. */)
|
||||||
(Lisp_Object parms)
|
(Lisp_Object parms)
|
||||||
{
|
{
|
||||||
|
#ifdef HAVE_ANDROID
|
||||||
|
error ("Text terminals are not supported on this platform");
|
||||||
|
return Qnil;
|
||||||
|
#else
|
||||||
struct frame *f;
|
struct frame *f;
|
||||||
struct terminal *t = NULL;
|
struct terminal *t = NULL;
|
||||||
Lisp_Object frame;
|
Lisp_Object frame;
|
||||||
|
|
@ -1436,6 +1447,7 @@ affects all frames on the same terminal device. */)
|
||||||
f->after_make_frame = true;
|
f->after_make_frame = true;
|
||||||
|
|
||||||
return frame;
|
return frame;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -5303,16 +5315,23 @@ gui_display_get_resource (Display_Info *dpyinfo, Lisp_Object attribute,
|
||||||
*nz++ = '.';
|
*nz++ = '.';
|
||||||
lispstpcpy (nz, attribute);
|
lispstpcpy (nz, attribute);
|
||||||
|
|
||||||
const char *value =
|
#ifndef HAVE_ANDROID
|
||||||
dpyinfo->terminal->get_string_resource_hook (&dpyinfo->rdb,
|
const char *value
|
||||||
name_key,
|
= dpyinfo->terminal->get_string_resource_hook (&dpyinfo->rdb,
|
||||||
class_key);
|
name_key,
|
||||||
SAFE_FREE();
|
class_key);
|
||||||
|
|
||||||
|
SAFE_FREE ();
|
||||||
|
|
||||||
if (value && *value)
|
if (value && *value)
|
||||||
return build_string (value);
|
return build_string (value);
|
||||||
else
|
else
|
||||||
return Qnil;
|
return Qnil;
|
||||||
|
#else
|
||||||
|
|
||||||
|
SAFE_FREE ();
|
||||||
|
return Qnil;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -6218,6 +6237,7 @@ syms_of_frame (void)
|
||||||
DEFSYM (Qns, "ns");
|
DEFSYM (Qns, "ns");
|
||||||
DEFSYM (Qpgtk, "pgtk");
|
DEFSYM (Qpgtk, "pgtk");
|
||||||
DEFSYM (Qhaiku, "haiku");
|
DEFSYM (Qhaiku, "haiku");
|
||||||
|
DEFSYM (Qandroid, "android");
|
||||||
DEFSYM (Qvisible, "visible");
|
DEFSYM (Qvisible, "visible");
|
||||||
DEFSYM (Qbuffer_predicate, "buffer-predicate");
|
DEFSYM (Qbuffer_predicate, "buffer-predicate");
|
||||||
DEFSYM (Qbuffer_list, "buffer-list");
|
DEFSYM (Qbuffer_list, "buffer-list");
|
||||||
|
|
|
||||||
35
src/frame.h
35
src/frame.h
|
|
@ -181,7 +181,7 @@ struct frame
|
||||||
most recently buried buffer is first. For last-buffer. */
|
most recently buried buffer is first. For last-buffer. */
|
||||||
Lisp_Object buried_buffer_list;
|
Lisp_Object buried_buffer_list;
|
||||||
|
|
||||||
#if defined (HAVE_X_WINDOWS) && ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
|
#if defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR
|
||||||
/* A dummy window used to display menu bars under X when no X
|
/* A dummy window used to display menu bars under X when no X
|
||||||
toolkit support is available. */
|
toolkit support is available. */
|
||||||
Lisp_Object menu_bar_window;
|
Lisp_Object menu_bar_window;
|
||||||
|
|
@ -377,7 +377,7 @@ struct frame
|
||||||
/* The output method says how the contents of this frame are
|
/* The output method says how the contents of this frame are
|
||||||
displayed. It could be using termcap, or using an X window.
|
displayed. It could be using termcap, or using an X window.
|
||||||
This must be the same as the terminal->type. */
|
This must be the same as the terminal->type. */
|
||||||
ENUM_BF (output_method) output_method : 3;
|
ENUM_BF (output_method) output_method : 4;
|
||||||
|
|
||||||
#ifdef HAVE_WINDOW_SYSTEM
|
#ifdef HAVE_WINDOW_SYSTEM
|
||||||
/* True if this frame is a tooltip frame. */
|
/* True if this frame is a tooltip frame. */
|
||||||
|
|
@ -586,12 +586,13 @@ struct frame
|
||||||
well. */
|
well. */
|
||||||
union output_data
|
union output_data
|
||||||
{
|
{
|
||||||
struct tty_output *tty; /* From termchar.h. */
|
struct tty_output *tty; /* From termchar.h. */
|
||||||
struct x_output *x; /* From xterm.h. */
|
struct x_output *x; /* From xterm.h. */
|
||||||
struct w32_output *w32; /* From w32term.h. */
|
struct w32_output *w32; /* From w32term.h. */
|
||||||
struct ns_output *ns; /* From nsterm.h. */
|
struct ns_output *ns; /* From nsterm.h. */
|
||||||
struct pgtk_output *pgtk; /* From pgtkterm.h. */
|
struct pgtk_output *pgtk; /* From pgtkterm.h. */
|
||||||
struct haiku_output *haiku; /* From haikuterm.h. */
|
struct haiku_output *haiku; /* From haikuterm.h. */
|
||||||
|
struct android_output *android; /* From androidterm.h. */
|
||||||
}
|
}
|
||||||
output_data;
|
output_data;
|
||||||
|
|
||||||
|
|
@ -713,7 +714,7 @@ fset_menu_bar_vector (struct frame *f, Lisp_Object val)
|
||||||
{
|
{
|
||||||
f->menu_bar_vector = val;
|
f->menu_bar_vector = val;
|
||||||
}
|
}
|
||||||
#if defined (HAVE_X_WINDOWS) && ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
|
#if defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR
|
||||||
INLINE void
|
INLINE void
|
||||||
fset_menu_bar_window (struct frame *f, Lisp_Object val)
|
fset_menu_bar_window (struct frame *f, Lisp_Object val)
|
||||||
{
|
{
|
||||||
|
|
@ -872,6 +873,11 @@ default_pixels_per_inch_y (void)
|
||||||
#else
|
#else
|
||||||
#define FRAME_HAIKU_P(f) ((f)->output_method == output_haiku)
|
#define FRAME_HAIKU_P(f) ((f)->output_method == output_haiku)
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef HAVE_ANDROID
|
||||||
|
#define FRAME_ANDROID_P(f) false
|
||||||
|
#else
|
||||||
|
#define FRAME_ANDROID_P(f) ((f)->output_method == output_android)
|
||||||
|
#endif
|
||||||
|
|
||||||
/* FRAME_WINDOW_P tests whether the frame is a graphical window system
|
/* FRAME_WINDOW_P tests whether the frame is a graphical window system
|
||||||
frame. */
|
frame. */
|
||||||
|
|
@ -890,6 +896,9 @@ default_pixels_per_inch_y (void)
|
||||||
#ifdef HAVE_HAIKU
|
#ifdef HAVE_HAIKU
|
||||||
#define FRAME_WINDOW_P(f) FRAME_HAIKU_P (f)
|
#define FRAME_WINDOW_P(f) FRAME_HAIKU_P (f)
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_ANDROID
|
||||||
|
#define FRAME_WINDOW_P(f) FRAME_ANDROID_P (f)
|
||||||
|
#endif
|
||||||
#ifndef FRAME_WINDOW_P
|
#ifndef FRAME_WINDOW_P
|
||||||
#define FRAME_WINDOW_P(f) ((void) (f), false)
|
#define FRAME_WINDOW_P(f) ((void) (f), false)
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -917,11 +926,17 @@ default_pixels_per_inch_y (void)
|
||||||
frame F. We need to define two versions because a TTY-only build
|
frame F. We need to define two versions because a TTY-only build
|
||||||
does not have FRAME_DISPLAY_INFO. */
|
does not have FRAME_DISPLAY_INFO. */
|
||||||
#ifdef HAVE_WINDOW_SYSTEM
|
#ifdef HAVE_WINDOW_SYSTEM
|
||||||
|
#ifndef HAVE_ANDROID
|
||||||
# define MOUSE_HL_INFO(F) \
|
# define MOUSE_HL_INFO(F) \
|
||||||
(FRAME_WINDOW_P(F) \
|
(FRAME_WINDOW_P (F) \
|
||||||
? &FRAME_DISPLAY_INFO(F)->mouse_highlight \
|
? &FRAME_DISPLAY_INFO(F)->mouse_highlight \
|
||||||
: &(F)->output_data.tty->display_info->mouse_highlight)
|
: &(F)->output_data.tty->display_info->mouse_highlight)
|
||||||
#else
|
#else
|
||||||
|
/* There is no "struct tty_output" on Android at all. */
|
||||||
|
# define MOUSE_HL_INFO(F) \
|
||||||
|
(&FRAME_DISPLAY_INFO(F)->mouse_highlight)
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
# define MOUSE_HL_INFO(F) \
|
# define MOUSE_HL_INFO(F) \
|
||||||
(&(F)->output_data.tty->display_info->mouse_highlight)
|
(&(F)->output_data.tty->display_info->mouse_highlight)
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
88
src/image.c
88
src/image.c
|
|
@ -175,6 +175,28 @@ typedef struct haiku_bitmap_record Bitmap_Record;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_ANDROID
|
||||||
|
#include "androidterm.h"
|
||||||
|
typedef struct android_bitmap_record Bitmap_Record;
|
||||||
|
|
||||||
|
/* TODO: implement images on Android. */
|
||||||
|
#define GET_PIXEL(ximg, x, y) 0
|
||||||
|
#define PUT_PIXEL(ximg, x, y, pixel) ((void) (pixel))
|
||||||
|
#define NO_PIXMAP 0
|
||||||
|
|
||||||
|
#define PIX_MASK_RETAIN 0
|
||||||
|
#define PIX_MASK_DRAW 1
|
||||||
|
|
||||||
|
#define RGB_TO_ULONG(r, g, b) (((r) << 16) | ((g) << 8) | (b))
|
||||||
|
#define RED_FROM_ULONG(color) (((color) >> 16) & 0xff)
|
||||||
|
#define GREEN_FROM_ULONG(color) (((color) >> 8) & 0xff)
|
||||||
|
#define BLUE_FROM_ULONG(color) ((color) & 0xff)
|
||||||
|
#define RED16_FROM_ULONG(color) (RED_FROM_ULONG (color) * 0x101)
|
||||||
|
#define GREEN16_FROM_ULONG(color) (GREEN_FROM_ULONG (color) * 0x101)
|
||||||
|
#define BLUE16_FROM_ULONG(color) (BLUE_FROM_ULONG (color) * 0x101)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
static void image_disable_image (struct frame *, struct image *);
|
static void image_disable_image (struct frame *, struct image *);
|
||||||
static void image_edge_detection (struct frame *, struct image *, Lisp_Object,
|
static void image_edge_detection (struct frame *, struct image *, Lisp_Object,
|
||||||
Lisp_Object);
|
Lisp_Object);
|
||||||
|
|
@ -831,6 +853,18 @@ image_create_bitmap_from_file (struct frame *f, Lisp_Object file)
|
||||||
xfree (contents);
|
xfree (contents);
|
||||||
return id;
|
return id;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_ANDROID
|
||||||
|
#ifdef ANDROID_STUBIFY
|
||||||
|
((void) dpyinfo);
|
||||||
|
|
||||||
|
/* This function should never be called when building stubs. */
|
||||||
|
emacs_abort ();
|
||||||
|
#else
|
||||||
|
/* you lose, not yet implemented TODO */
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free bitmap B. */
|
/* Free bitmap B. */
|
||||||
|
|
@ -3338,6 +3372,16 @@ image_create_x_image_and_pixmap_1 (struct frame *f, int width, int height, int d
|
||||||
Emacs_Pix_Container *pimg,
|
Emacs_Pix_Container *pimg,
|
||||||
Emacs_Pixmap *pixmap, Picture *picture)
|
Emacs_Pixmap *pixmap, Picture *picture)
|
||||||
{
|
{
|
||||||
|
#ifdef HAVE_ANDROID
|
||||||
|
#ifdef ANDROID_STUBIFY
|
||||||
|
/* This function should never be called when building stubs. */
|
||||||
|
emacs_abort ();
|
||||||
|
#else
|
||||||
|
/* you lose, not yet implemented TODO */
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef USE_CAIRO
|
#ifdef USE_CAIRO
|
||||||
eassert (input_blocked_p ());
|
eassert (input_blocked_p ());
|
||||||
|
|
||||||
|
|
@ -3646,6 +3690,16 @@ image_unget_x_image_or_dc (struct image *img, bool mask_p,
|
||||||
static Emacs_Pix_Container
|
static Emacs_Pix_Container
|
||||||
image_get_x_image (struct frame *f, struct image *img, bool mask_p)
|
image_get_x_image (struct frame *f, struct image *img, bool mask_p)
|
||||||
{
|
{
|
||||||
|
#ifdef HAVE_ANDROID
|
||||||
|
#ifdef ANDROID_STUBIFY
|
||||||
|
/* This function should never be called when building stubs. */
|
||||||
|
emacs_abort ();
|
||||||
|
#else
|
||||||
|
/* you lose, not yet implemented TODO */
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined USE_CAIRO || defined (HAVE_HAIKU)
|
#if defined USE_CAIRO || defined (HAVE_HAIKU)
|
||||||
return !mask_p ? img->pixmap : img->mask;
|
return !mask_p ? img->pixmap : img->mask;
|
||||||
#elif defined HAVE_X_WINDOWS
|
#elif defined HAVE_X_WINDOWS
|
||||||
|
|
@ -3756,7 +3810,7 @@ slurp_file (int fd, ptrdiff_t *size)
|
||||||
specpdl_ref count = SPECPDL_INDEX ();
|
specpdl_ref count = SPECPDL_INDEX ();
|
||||||
record_unwind_protect_ptr (fclose_unwind, fp);
|
record_unwind_protect_ptr (fclose_unwind, fp);
|
||||||
|
|
||||||
if (fstat (fileno (fp), &st) == 0
|
if (sys_fstat (fileno (fp), &st) == 0
|
||||||
&& 0 <= st.st_size && st.st_size < min (PTRDIFF_MAX, SIZE_MAX))
|
&& 0 <= st.st_size && st.st_size < min (PTRDIFF_MAX, SIZE_MAX))
|
||||||
{
|
{
|
||||||
/* Report an error if we read past the purported EOF.
|
/* Report an error if we read past the purported EOF.
|
||||||
|
|
@ -6074,7 +6128,8 @@ lookup_rgb_color (struct frame *f, int r, int g, int b)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_NTGUI
|
#ifdef HAVE_NTGUI
|
||||||
return PALETTERGB (r >> 8, g >> 8, b >> 8);
|
return PALETTERGB (r >> 8, g >> 8, b >> 8);
|
||||||
#elif defined USE_CAIRO || defined HAVE_NS || defined HAVE_HAIKU
|
#elif defined USE_CAIRO || defined HAVE_NS || defined HAVE_HAIKU \
|
||||||
|
|| defined HAVE_ANDROID
|
||||||
return RGB_TO_ULONG (r >> 8, g >> 8, b >> 8);
|
return RGB_TO_ULONG (r >> 8, g >> 8, b >> 8);
|
||||||
#else
|
#else
|
||||||
xsignal1 (Qfile_error,
|
xsignal1 (Qfile_error,
|
||||||
|
|
@ -6147,7 +6202,8 @@ image_to_emacs_colors (struct frame *f, struct image *img, bool rgb_p)
|
||||||
p = colors;
|
p = colors;
|
||||||
for (y = 0; y < img->height; ++y)
|
for (y = 0; y < img->height; ++y)
|
||||||
{
|
{
|
||||||
#if !defined USE_CAIRO && !defined HAVE_NS && !defined HAVE_HAIKU
|
#if !defined USE_CAIRO && !defined HAVE_NS && !defined HAVE_HAIKU \
|
||||||
|
&& !defined HAVE_ANDROID
|
||||||
Emacs_Color *row = p;
|
Emacs_Color *row = p;
|
||||||
for (x = 0; x < img->width; ++x, ++p)
|
for (x = 0; x < img->width; ++x, ++p)
|
||||||
p->pixel = GET_PIXEL (ximg, x, y);
|
p->pixel = GET_PIXEL (ximg, x, y);
|
||||||
|
|
@ -6155,7 +6211,7 @@ image_to_emacs_colors (struct frame *f, struct image *img, bool rgb_p)
|
||||||
{
|
{
|
||||||
FRAME_TERMINAL (f)->query_colors (f, row, img->width);
|
FRAME_TERMINAL (f)->query_colors (f, row, img->width);
|
||||||
}
|
}
|
||||||
#else /* USE_CAIRO || HAVE_NS || HAVE_HAIKU */
|
#else /* USE_CAIRO || HAVE_NS || HAVE_HAIKU || HAVE_ANDROID */
|
||||||
for (x = 0; x < img->width; ++x, ++p)
|
for (x = 0; x < img->width; ++x, ++p)
|
||||||
{
|
{
|
||||||
p->pixel = GET_PIXEL (ximg, x, y);
|
p->pixel = GET_PIXEL (ximg, x, y);
|
||||||
|
|
@ -6166,7 +6222,7 @@ image_to_emacs_colors (struct frame *f, struct image *img, bool rgb_p)
|
||||||
p->blue = BLUE16_FROM_ULONG (p->pixel);
|
p->blue = BLUE16_FROM_ULONG (p->pixel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* USE_CAIRO || HAVE_NS */
|
#endif /* USE_CAIRO || HAVE_NS || HAVE_ANDROID */
|
||||||
}
|
}
|
||||||
|
|
||||||
image_unget_x_image_or_dc (img, 0, ximg, prev);
|
image_unget_x_image_or_dc (img, 0, ximg, prev);
|
||||||
|
|
@ -6231,7 +6287,11 @@ image_from_emacs_colors (struct frame *f, struct image *img, Emacs_Color *colors
|
||||||
Emacs_Pix_Container ximage;
|
Emacs_Pix_Container ximage;
|
||||||
Emacs_Color *p;
|
Emacs_Color *p;
|
||||||
|
|
||||||
|
#ifndef HAVE_ANDROID
|
||||||
ximage = NULL;
|
ximage = NULL;
|
||||||
|
#else
|
||||||
|
ximage = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
init_color_table ();
|
init_color_table ();
|
||||||
|
|
||||||
|
|
@ -6393,7 +6453,9 @@ image_edge_detection (struct frame *f, struct image *img,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if defined HAVE_X_WINDOWS || defined USE_CAIRO || defined HAVE_HAIKU
|
#if defined HAVE_X_WINDOWS || defined USE_CAIRO || defined HAVE_HAIKU \
|
||||||
|
|| defined HAVE_ANDROID
|
||||||
|
|
||||||
static void
|
static void
|
||||||
image_pixmap_draw_cross (struct frame *f, Emacs_Pixmap pixmap,
|
image_pixmap_draw_cross (struct frame *f, Emacs_Pixmap pixmap,
|
||||||
int x, int y, unsigned int width, unsigned int height,
|
int x, int y, unsigned int width, unsigned int height,
|
||||||
|
|
@ -6429,8 +6491,16 @@ image_pixmap_draw_cross (struct frame *f, Emacs_Pixmap pixmap,
|
||||||
XFreeGC (dpy, gc);
|
XFreeGC (dpy, gc);
|
||||||
#elif HAVE_HAIKU
|
#elif HAVE_HAIKU
|
||||||
be_draw_cross_on_pixmap (pixmap, x, y, width, height, color);
|
be_draw_cross_on_pixmap (pixmap, x, y, width, height, color);
|
||||||
|
#elif HAVE_ANDROID
|
||||||
|
#ifdef ANDROID_STUBIFY
|
||||||
|
/* This function should never be called when building stubs. */
|
||||||
|
emacs_abort ();
|
||||||
|
#else
|
||||||
|
/* you lose, not yet implemented TODO */
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* HAVE_X_WINDOWS || USE_CAIRO || HAVE_HAIKU */
|
#endif /* HAVE_X_WINDOWS || USE_CAIRO || HAVE_HAIKU */
|
||||||
|
|
||||||
/* Transform image IMG on frame F so that it looks disabled. */
|
/* Transform image IMG on frame F so that it looks disabled. */
|
||||||
|
|
@ -6474,7 +6544,7 @@ image_disable_image (struct frame *f, struct image *img)
|
||||||
#ifndef HAVE_NTGUI
|
#ifndef HAVE_NTGUI
|
||||||
#ifndef HAVE_NS /* TODO: NS support, however this not needed for toolbars */
|
#ifndef HAVE_NS /* TODO: NS support, however this not needed for toolbars */
|
||||||
|
|
||||||
#if !defined USE_CAIRO && !defined HAVE_HAIKU
|
#if !defined USE_CAIRO && !defined HAVE_HAIKU && !defined HAVE_ANDROID
|
||||||
#define CrossForeground(f) BLACK_PIX_DEFAULT (f)
|
#define CrossForeground(f) BLACK_PIX_DEFAULT (f)
|
||||||
#define MaskForeground(f) WHITE_PIX_DEFAULT (f)
|
#define MaskForeground(f) WHITE_PIX_DEFAULT (f)
|
||||||
#else /* USE_CAIRO || HAVE_HAIKU */
|
#else /* USE_CAIRO || HAVE_HAIKU */
|
||||||
|
|
@ -6482,7 +6552,7 @@ image_disable_image (struct frame *f, struct image *img)
|
||||||
#define MaskForeground(f) PIX_MASK_DRAW
|
#define MaskForeground(f) PIX_MASK_DRAW
|
||||||
#endif /* USE_CAIRO || HAVE_HAIKU */
|
#endif /* USE_CAIRO || HAVE_HAIKU */
|
||||||
|
|
||||||
#if !defined USE_CAIRO && !defined HAVE_HAIKU
|
#if !defined USE_CAIRO && !defined HAVE_HAIKU && !defined HAVE_ANDROID
|
||||||
image_sync_to_pixmaps (f, img);
|
image_sync_to_pixmaps (f, img);
|
||||||
#endif /* !USE_CAIRO && !HAVE_HAIKU */
|
#endif /* !USE_CAIRO && !HAVE_HAIKU */
|
||||||
image_pixmap_draw_cross (f, img->pixmap, 0, 0, img->width, img->height,
|
image_pixmap_draw_cross (f, img->pixmap, 0, 0, img->width, img->height,
|
||||||
|
|
@ -9099,7 +9169,7 @@ gif_load (struct frame *f, struct image *img)
|
||||||
`image-cache-size'. */
|
`image-cache-size'. */
|
||||||
struct stat st;
|
struct stat st;
|
||||||
FILE *fp = fopen (SSDATA (encoded_file), "rb");
|
FILE *fp = fopen (SSDATA (encoded_file), "rb");
|
||||||
if (fstat (fileno (fp), &st) == 0)
|
if (sys_fstat (fileno (fp), &st) == 0)
|
||||||
byte_size = st.st_size;
|
byte_size = st.st_size;
|
||||||
fclose (fp);
|
fclose (fp);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
12
src/lisp.h
12
src/lisp.h
|
|
@ -30,6 +30,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_SYS_STAT_H
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <attribute.h>
|
#include <attribute.h>
|
||||||
#include <intprops.h>
|
#include <intprops.h>
|
||||||
#include <verify.h>
|
#include <verify.h>
|
||||||
|
|
@ -4726,6 +4730,7 @@ extern void syms_of_marker (void);
|
||||||
|
|
||||||
/* Defined in fileio.c. */
|
/* Defined in fileio.c. */
|
||||||
|
|
||||||
|
extern Lisp_Object file_name_directory (Lisp_Object);
|
||||||
extern char *splice_dir_file (char *, char const *, char const *)
|
extern char *splice_dir_file (char *, char const *, char const *)
|
||||||
ATTRIBUTE_RETURNS_NONNULL;
|
ATTRIBUTE_RETURNS_NONNULL;
|
||||||
extern bool file_name_absolute_p (const char *);
|
extern bool file_name_absolute_p (const char *);
|
||||||
|
|
@ -5063,7 +5068,12 @@ extern void init_random (void);
|
||||||
extern void emacs_backtrace (int);
|
extern void emacs_backtrace (int);
|
||||||
extern AVOID emacs_abort (void) NO_INLINE;
|
extern AVOID emacs_abort (void) NO_INLINE;
|
||||||
extern int emacs_fstatat (int, char const *, void *, int);
|
extern int emacs_fstatat (int, char const *, void *, int);
|
||||||
|
#ifdef HAVE_SYS_STAT_H
|
||||||
|
extern int sys_fstat (int, struct stat *);
|
||||||
|
#endif
|
||||||
|
#if !(defined HAVE_ANDROID && !defined ANDROID_STUBIFY)
|
||||||
extern int emacs_openat (int, char const *, int, int);
|
extern int emacs_openat (int, char const *, int, int);
|
||||||
|
#endif
|
||||||
extern int emacs_open (const char *, int, int);
|
extern int emacs_open (const char *, int, int);
|
||||||
extern int emacs_open_noquit (const char *, int, int);
|
extern int emacs_open_noquit (const char *, int, int);
|
||||||
extern int emacs_pipe (int[2]);
|
extern int emacs_pipe (int[2]);
|
||||||
|
|
@ -5101,7 +5111,9 @@ extern Lisp_Object directory_files_internal (Lisp_Object, Lisp_Object,
|
||||||
bool, Lisp_Object, Lisp_Object);
|
bool, Lisp_Object, Lisp_Object);
|
||||||
|
|
||||||
/* Defined in term.c. */
|
/* Defined in term.c. */
|
||||||
|
#ifndef HAVE_ANDROID
|
||||||
extern int *char_ins_del_vector;
|
extern int *char_ins_del_vector;
|
||||||
|
#endif
|
||||||
extern void syms_of_term (void);
|
extern void syms_of_term (void);
|
||||||
extern AVOID fatal (const char *msgid, ...) ATTRIBUTE_FORMAT_PRINTF (1, 2);
|
extern AVOID fatal (const char *msgid, ...) ATTRIBUTE_FORMAT_PRINTF (1, 2);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1047,7 +1047,7 @@ safe_to_load_version (Lisp_Object file, int fd)
|
||||||
|
|
||||||
/* If the file is not regular, then we cannot safely seek it.
|
/* If the file is not regular, then we cannot safely seek it.
|
||||||
Assume that it is not safe to load as a compiled file. */
|
Assume that it is not safe to load as a compiled file. */
|
||||||
if (fstat (fd, &st) == 0 && !S_ISREG (st.st_mode))
|
if (sys_fstat (fd, &st) == 0 && !S_ISREG (st.st_mode))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Read the first few bytes from the file, and look for a line
|
/* Read the first few bytes from the file, and look for a line
|
||||||
|
|
@ -1676,7 +1676,7 @@ maybe_swap_for_eln1 (Lisp_Object src_name, Lisp_Object eln_name,
|
||||||
|
|
||||||
if (eln_fd > 0)
|
if (eln_fd > 0)
|
||||||
{
|
{
|
||||||
if (fstat (eln_fd, &eln_st) || S_ISDIR (eln_st.st_mode))
|
if (sys_fstat (eln_fd, &eln_st) || S_ISDIR (eln_st.st_mode))
|
||||||
emacs_close (eln_fd);
|
emacs_close (eln_fd);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -1998,7 +1998,7 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int err = (fstat (fd, &st) != 0 ? errno
|
int err = (sys_fstat (fd, &st) != 0 ? errno
|
||||||
: S_ISDIR (st.st_mode) ? EISDIR : 0);
|
: S_ISDIR (st.st_mode) ? EISDIR : 0);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -5620,7 +5620,7 @@ pdumper_load (const char *dump_filename, char *argv0)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = PDUMPER_LOAD_FILE_NOT_FOUND;
|
err = PDUMPER_LOAD_FILE_NOT_FOUND;
|
||||||
if (fstat (dump_fd, &stat) < 0)
|
if (sys_fstat (dump_fd, &stat) < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
err = PDUMPER_LOAD_BAD_FILE_TYPE;
|
err = PDUMPER_LOAD_BAD_FILE_TYPE;
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,10 @@ static struct rlimit nofile_limit;
|
||||||
#include "gnutls.h"
|
#include "gnutls.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_ANDROID
|
||||||
|
#include "android.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_WINDOW_SYSTEM
|
#ifdef HAVE_WINDOW_SYSTEM
|
||||||
#include TERM_HEADER
|
#include TERM_HEADER
|
||||||
#endif /* HAVE_WINDOW_SYSTEM */
|
#endif /* HAVE_WINDOW_SYSTEM */
|
||||||
|
|
@ -5679,7 +5683,17 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
|
||||||
timeout = short_timeout;
|
timeout = short_timeout;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Non-macOS HAVE_GLIB builds call thread_select in xgselect.c. */
|
/* Android doesn't support threads and requires using a
|
||||||
|
replacement for pselect in android.c to poll for
|
||||||
|
events. */
|
||||||
|
#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
|
||||||
|
nfds = android_select (max_desc + 1,
|
||||||
|
&Available, (check_write ? &Writeok : 0),
|
||||||
|
NULL, &timeout, NULL);
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* Non-macOS HAVE_GLIB builds call thread_select in
|
||||||
|
xgselect.c. */
|
||||||
#if defined HAVE_GLIB && !defined HAVE_NS
|
#if defined HAVE_GLIB && !defined HAVE_NS
|
||||||
nfds = xg_select (max_desc + 1,
|
nfds = xg_select (max_desc + 1,
|
||||||
&Available, (check_write ? &Writeok : 0),
|
&Available, (check_write ? &Writeok : 0),
|
||||||
|
|
@ -5695,6 +5709,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
|
||||||
(check_write ? &Writeok : 0),
|
(check_write ? &Writeok : 0),
|
||||||
NULL, &timeout, NULL);
|
NULL, &timeout, NULL);
|
||||||
#endif /* !HAVE_GLIB */
|
#endif /* !HAVE_GLIB */
|
||||||
|
#endif /* HAVE_ANDROID && !ANDROID_STUBIFY */
|
||||||
|
|
||||||
#ifdef HAVE_GNUTLS
|
#ifdef HAVE_GNUTLS
|
||||||
/* Merge tls_available into Available. */
|
/* Merge tls_available into Available. */
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,11 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
|
/* The entire file is defined out under Android, where there is no
|
||||||
|
text terminal support of any kind. */
|
||||||
|
|
||||||
|
#ifndef HAVE_ANDROID
|
||||||
|
|
||||||
#include "lisp.h"
|
#include "lisp.h"
|
||||||
#include "termchar.h"
|
#include "termchar.h"
|
||||||
#include "dispextern.h"
|
#include "dispextern.h"
|
||||||
|
|
@ -984,3 +989,5 @@ do_line_insertion_deletion_costs (struct frame *frame,
|
||||||
FRAME_DELETE_COST (frame), FRAME_DELETEN_COST (frame),
|
FRAME_DELETE_COST (frame), FRAME_DELETEN_COST (frame),
|
||||||
coefficient);
|
coefficient);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
||||||
98
src/sysdep.c
98
src/sysdep.c
|
|
@ -134,6 +134,10 @@ int _cdecl _spawnlp (int, const char *, const char *, ...);
|
||||||
# include <sys/socket.h>
|
# include <sys/socket.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_ANDROID
|
||||||
|
#include "android.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Declare here, including term.h is problematic on some systems. */
|
/* Declare here, including term.h is problematic on some systems. */
|
||||||
extern void tputs (const char *, int, int (*)(int));
|
extern void tputs (const char *, int, int (*)(int));
|
||||||
|
|
||||||
|
|
@ -790,6 +794,7 @@ init_sigio (int fd)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef HAVE_ANDROID
|
||||||
#ifndef DOS_NT
|
#ifndef DOS_NT
|
||||||
#ifdef F_SETOWN
|
#ifdef F_SETOWN
|
||||||
static void
|
static void
|
||||||
|
|
@ -801,6 +806,7 @@ reset_sigio (int fd)
|
||||||
}
|
}
|
||||||
#endif /* F_SETOWN */
|
#endif /* F_SETOWN */
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
request_sigio (void)
|
request_sigio (void)
|
||||||
|
|
@ -972,6 +978,8 @@ narrow_foreground_group (int fd)
|
||||||
tcsetpgrp_without_stopping (fd, getpid ());
|
tcsetpgrp_without_stopping (fd, getpid ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef HAVE_ANDROID
|
||||||
|
|
||||||
/* Set the tty to our original foreground group. */
|
/* Set the tty to our original foreground group. */
|
||||||
static void
|
static void
|
||||||
widen_foreground_group (int fd)
|
widen_foreground_group (int fd)
|
||||||
|
|
@ -979,6 +987,9 @@ widen_foreground_group (int fd)
|
||||||
if (inherited_pgroup && setpgid (0, inherited_pgroup) == 0)
|
if (inherited_pgroup && setpgid (0, inherited_pgroup) == 0)
|
||||||
tcsetpgrp_without_stopping (fd, inherited_pgroup);
|
tcsetpgrp_without_stopping (fd, inherited_pgroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Getting and setting emacs_tty structures. */
|
/* Getting and setting emacs_tty structures. */
|
||||||
|
|
||||||
|
|
@ -1496,6 +1507,8 @@ reset_sys_modes (struct tty_display_info *tty_out)
|
||||||
fflush (stdout);
|
fflush (stdout);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef HAVE_ANDROID
|
||||||
if (!tty_out->term_initted)
|
if (!tty_out->term_initted)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -1552,6 +1565,7 @@ reset_sys_modes (struct tty_display_info *tty_out)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
widen_foreground_group (fileno (tty_out->input));
|
widen_foreground_group (fileno (tty_out->input));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_PTYS
|
#ifdef HAVE_PTYS
|
||||||
|
|
@ -1802,7 +1816,11 @@ handle_arith_signal (int sig)
|
||||||
xsignal0 (Qarith_error);
|
xsignal0 (Qarith_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined HAVE_STACK_OVERFLOW_HANDLING && !defined WINDOWSNT
|
/* This does not work on Android and interferes with the system
|
||||||
|
tombstone generation. */
|
||||||
|
|
||||||
|
#if defined HAVE_STACK_OVERFLOW_HANDLING && !defined WINDOWSNT \
|
||||||
|
&& (!defined HAVE_ANDROID || defined ANDROID_STUBIFY)
|
||||||
|
|
||||||
/* Alternate stack used by SIGSEGV handler below. */
|
/* Alternate stack used by SIGSEGV handler below. */
|
||||||
|
|
||||||
|
|
@ -1914,12 +1932,16 @@ init_sigsegv (void)
|
||||||
|
|
||||||
#else /* not HAVE_STACK_OVERFLOW_HANDLING or WINDOWSNT */
|
#else /* not HAVE_STACK_OVERFLOW_HANDLING or WINDOWSNT */
|
||||||
|
|
||||||
|
#if !defined HAVE_ANDROID || defined ANDROID_STUBIFY
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
init_sigsegv (void)
|
init_sigsegv (void)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* HAVE_STACK_OVERFLOW_HANDLING && !WINDOWSNT */
|
#endif /* HAVE_STACK_OVERFLOW_HANDLING && !WINDOWSNT */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -2020,12 +2042,17 @@ init_signals (void)
|
||||||
sigaction (SIGFPE, &action, 0);
|
sigaction (SIGFPE, &action, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* SIGUSR1 and SIGUSR2 are used internally by the android_select
|
||||||
|
function. */
|
||||||
|
#if !defined HAVE_ANDROID
|
||||||
#ifdef SIGUSR1
|
#ifdef SIGUSR1
|
||||||
add_user_signal (SIGUSR1, "sigusr1");
|
add_user_signal (SIGUSR1, "sigusr1");
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGUSR2
|
#ifdef SIGUSR2
|
||||||
add_user_signal (SIGUSR2, "sigusr2");
|
add_user_signal (SIGUSR2, "sigusr2");
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
sigaction (SIGABRT, &thread_fatal_action, 0);
|
sigaction (SIGABRT, &thread_fatal_action, 0);
|
||||||
#ifdef SIGPRE
|
#ifdef SIGPRE
|
||||||
sigaction (SIGPRE, &thread_fatal_action, 0);
|
sigaction (SIGPRE, &thread_fatal_action, 0);
|
||||||
|
|
@ -2051,8 +2078,10 @@ init_signals (void)
|
||||||
#ifdef SIGBUS
|
#ifdef SIGBUS
|
||||||
sigaction (SIGBUS, &thread_fatal_action, 0);
|
sigaction (SIGBUS, &thread_fatal_action, 0);
|
||||||
#endif
|
#endif
|
||||||
|
#if !defined HAVE_ANDROID || defined ANDROID_STUBIFY
|
||||||
if (!init_sigsegv ())
|
if (!init_sigsegv ())
|
||||||
sigaction (SIGSEGV, &thread_fatal_action, 0);
|
sigaction (SIGSEGV, &thread_fatal_action, 0);
|
||||||
|
#endif
|
||||||
#ifdef SIGSYS
|
#ifdef SIGSYS
|
||||||
sigaction (SIGSYS, &thread_fatal_action, 0);
|
sigaction (SIGSYS, &thread_fatal_action, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -2328,11 +2357,20 @@ int
|
||||||
emacs_fstatat (int dirfd, char const *filename, void *st, int flags)
|
emacs_fstatat (int dirfd, char const *filename, void *st, int flags)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
while ((r = fstatat (dirfd, filename, st, flags)) != 0 && errno == EINTR)
|
#if !(defined HAVE_ANDROID && !defined ANDROID_STUBIFY)
|
||||||
|
while ((r = fstatat (dirfd, filename, st, flags)) != 0
|
||||||
|
&& errno == EINTR)
|
||||||
maybe_quit ();
|
maybe_quit ();
|
||||||
|
#else
|
||||||
|
while ((r = android_fstatat (dirfd, filename, st, flags)) != 0
|
||||||
|
&& errno == EINTR)
|
||||||
|
maybe_quit ();
|
||||||
|
#endif
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !(defined HAVE_ANDROID && !defined ANDROID_STUBIFY)
|
||||||
|
|
||||||
static int
|
static int
|
||||||
sys_openat (int dirfd, char const *file, int oflags, int mode)
|
sys_openat (int dirfd, char const *file, int oflags, int mode)
|
||||||
{
|
{
|
||||||
|
|
@ -2347,6 +2385,18 @@ sys_openat (int dirfd, char const *file, int oflags, int mode)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int
|
||||||
|
sys_fstat (int fd, struct stat *statb)
|
||||||
|
{
|
||||||
|
#if !(defined HAVE_ANDROID && !defined ANDROID_STUBIFY)
|
||||||
|
return fstat (fd, statb);
|
||||||
|
#else
|
||||||
|
return android_fstat (fd, statb);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/* Assuming the directory DIRFD, open FILE for Emacs use,
|
/* Assuming the directory DIRFD, open FILE for Emacs use,
|
||||||
using open flags OFLAGS and mode MODE.
|
using open flags OFLAGS and mode MODE.
|
||||||
Use binary I/O on systems that care about text vs binary I/O.
|
Use binary I/O on systems that care about text vs binary I/O.
|
||||||
|
|
@ -2355,6 +2405,8 @@ sys_openat (int dirfd, char const *file, int oflags, int mode)
|
||||||
Do not fail merely because the open was interrupted by a signal.
|
Do not fail merely because the open was interrupted by a signal.
|
||||||
Allow the user to quit. */
|
Allow the user to quit. */
|
||||||
|
|
||||||
|
#if !(defined HAVE_ANDROID && !defined ANDROID_STUBIFY)
|
||||||
|
|
||||||
int
|
int
|
||||||
emacs_openat (int dirfd, char const *file, int oflags, int mode)
|
emacs_openat (int dirfd, char const *file, int oflags, int mode)
|
||||||
{
|
{
|
||||||
|
|
@ -2367,10 +2419,23 @@ emacs_openat (int dirfd, char const *file, int oflags, int mode)
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
int
|
int
|
||||||
emacs_open (char const *file, int oflags, int mode)
|
emacs_open (char const *file, int oflags, int mode)
|
||||||
{
|
{
|
||||||
|
#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
|
||||||
|
int fd;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !(defined HAVE_ANDROID && !defined ANDROID_STUBIFY)
|
||||||
return emacs_openat (AT_FDCWD, file, oflags, mode);
|
return emacs_openat (AT_FDCWD, file, oflags, mode);
|
||||||
|
#else
|
||||||
|
while ((fd = android_open (file, oflags, mode)) < 0 && errno == EINTR)
|
||||||
|
maybe_quit ();
|
||||||
|
|
||||||
|
return fd;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Same as above, but doesn't allow the user to quit. */
|
/* Same as above, but doesn't allow the user to quit. */
|
||||||
|
|
@ -2382,9 +2447,15 @@ emacs_open_noquit (char const *file, int oflags, int mode)
|
||||||
if (! (oflags & O_TEXT))
|
if (! (oflags & O_TEXT))
|
||||||
oflags |= O_BINARY;
|
oflags |= O_BINARY;
|
||||||
oflags |= O_CLOEXEC;
|
oflags |= O_CLOEXEC;
|
||||||
|
#if !(defined HAVE_ANDROID && !defined ANDROID_STUBIFY)
|
||||||
do
|
do
|
||||||
fd = open (file, oflags, mode);
|
fd = open (file, oflags, mode);
|
||||||
while (fd < 0 && errno == EINTR);
|
while (fd < 0 && errno == EINTR);
|
||||||
|
#else
|
||||||
|
do
|
||||||
|
fd = android_open (file, oflags, mode);
|
||||||
|
while (fd < 0 && errno == EINTR);
|
||||||
|
#endif
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2434,6 +2505,8 @@ emacs_pipe (int fd[2])
|
||||||
For the background behind this mess, please see Austin Group defect 529
|
For the background behind this mess, please see Austin Group defect 529
|
||||||
<https://austingroupbugs.net/view.php?id=529>. */
|
<https://austingroupbugs.net/view.php?id=529>. */
|
||||||
|
|
||||||
|
#if !(defined HAVE_ANDROID && !defined ANDROID_STUBIFY)
|
||||||
|
|
||||||
#ifndef POSIX_CLOSE_RESTART
|
#ifndef POSIX_CLOSE_RESTART
|
||||||
# define POSIX_CLOSE_RESTART 1
|
# define POSIX_CLOSE_RESTART 1
|
||||||
static int
|
static int
|
||||||
|
|
@ -2460,6 +2533,8 @@ posix_close (int fd, int flag)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Close FD, retrying if interrupted. If successful, return 0;
|
/* Close FD, retrying if interrupted. If successful, return 0;
|
||||||
otherwise, return -1 and set errno to a non-EINTR value. Consider
|
otherwise, return -1 and set errno to a non-EINTR value. Consider
|
||||||
an EINPROGRESS error to be successful, as that's merely a signal
|
an EINPROGRESS error to be successful, as that's merely a signal
|
||||||
|
|
@ -2472,9 +2547,17 @@ posix_close (int fd, int flag)
|
||||||
int
|
int
|
||||||
emacs_close (int fd)
|
emacs_close (int fd)
|
||||||
{
|
{
|
||||||
|
int r;
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
int r = posix_close (fd, POSIX_CLOSE_RESTART);
|
#if !(defined HAVE_ANDROID && !defined ANDROID_STUBIFY)
|
||||||
|
r = posix_close (fd, POSIX_CLOSE_RESTART);
|
||||||
|
#else
|
||||||
|
r = android_close (fd) == 0 || errno == EINTR ? 0 : -1;
|
||||||
|
#define POSIX_CLOSE_RESTART 1
|
||||||
|
#endif
|
||||||
|
|
||||||
if (r == 0)
|
if (r == 0)
|
||||||
return r;
|
return r;
|
||||||
if (!POSIX_CLOSE_RESTART || errno != EINTR)
|
if (!POSIX_CLOSE_RESTART || errno != EINTR)
|
||||||
|
|
@ -2729,6 +2812,15 @@ errwrite (void const *buf, ptrdiff_t nbuf)
|
||||||
void
|
void
|
||||||
close_output_streams (void)
|
close_output_streams (void)
|
||||||
{
|
{
|
||||||
|
/* Android comes with some kind of ``file descriptor sanitizer''
|
||||||
|
that aborts when stdout or stderr is closed. */
|
||||||
|
|
||||||
|
#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
|
||||||
|
fflush (stderr);
|
||||||
|
fflush (stdout);
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (close_stream (stdout) != 0)
|
if (close_stream (stdout) != 0)
|
||||||
{
|
{
|
||||||
emacs_perror ("Write error to standard output");
|
emacs_perror ("Write error to standard output");
|
||||||
|
|
|
||||||
135
src/term.c
135
src/term.c
|
|
@ -62,6 +62,8 @@ static int been_here = -1;
|
||||||
#include "w32term.h"
|
#include "w32term.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE_ANDROID
|
||||||
|
|
||||||
static void tty_set_scroll_region (struct frame *f, int start, int stop);
|
static void tty_set_scroll_region (struct frame *f, int start, int stop);
|
||||||
static void turn_on_face (struct frame *, int face_id);
|
static void turn_on_face (struct frame *, int face_id);
|
||||||
static void turn_off_face (struct frame *, int face_id);
|
static void turn_off_face (struct frame *, int face_id);
|
||||||
|
|
@ -73,11 +75,15 @@ static void clear_tty_hooks (struct terminal *terminal);
|
||||||
static void set_tty_hooks (struct terminal *terminal);
|
static void set_tty_hooks (struct terminal *terminal);
|
||||||
static void dissociate_if_controlling_tty (int fd);
|
static void dissociate_if_controlling_tty (int fd);
|
||||||
static void delete_tty (struct terminal *);
|
static void delete_tty (struct terminal *);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
static AVOID maybe_fatal (bool, struct terminal *, const char *, const char *,
|
static AVOID maybe_fatal (bool, struct terminal *, const char *, const char *,
|
||||||
...)
|
...)
|
||||||
ATTRIBUTE_FORMAT_PRINTF (3, 5) ATTRIBUTE_FORMAT_PRINTF (4, 5);
|
ATTRIBUTE_FORMAT_PRINTF (3, 5) ATTRIBUTE_FORMAT_PRINTF (4, 5);
|
||||||
static AVOID vfatal (const char *, va_list) ATTRIBUTE_FORMAT_PRINTF (1, 0);
|
static AVOID vfatal (const char *, va_list) ATTRIBUTE_FORMAT_PRINTF (1, 0);
|
||||||
|
|
||||||
|
#ifndef HAVE_ANDROID
|
||||||
|
|
||||||
#define OUTPUT(tty, a) \
|
#define OUTPUT(tty, a) \
|
||||||
emacs_tputs ((tty), a, \
|
emacs_tputs ((tty), a, \
|
||||||
|
|
@ -95,6 +101,8 @@ static AVOID vfatal (const char *, va_list) ATTRIBUTE_FORMAT_PRINTF (1, 0);
|
||||||
|
|
||||||
#define OUTPUT1_IF(tty, a) do { if (a) emacs_tputs ((tty), a, 1, cmputc); } while (0)
|
#define OUTPUT1_IF(tty, a) do { if (a) emacs_tputs ((tty), a, 1, cmputc); } while (0)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Display space properties. */
|
/* Display space properties. */
|
||||||
|
|
||||||
/* Chain of all tty device parameters. */
|
/* Chain of all tty device parameters. */
|
||||||
|
|
@ -117,10 +125,14 @@ enum no_color_bit
|
||||||
|
|
||||||
/* internal state */
|
/* internal state */
|
||||||
|
|
||||||
|
#ifndef HAVE_ANDROID
|
||||||
|
|
||||||
/* The largest frame width in any call to calculate_costs. */
|
/* The largest frame width in any call to calculate_costs. */
|
||||||
|
|
||||||
static int max_frame_cols;
|
static int max_frame_cols;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_GPM
|
#ifdef HAVE_GPM
|
||||||
|
|
@ -133,6 +145,8 @@ struct tty_display_info *gpm_tty = NULL;
|
||||||
static int last_mouse_x, last_mouse_y;
|
static int last_mouse_x, last_mouse_y;
|
||||||
#endif /* HAVE_GPM */
|
#endif /* HAVE_GPM */
|
||||||
|
|
||||||
|
#ifndef HAVE_ANDROID
|
||||||
|
|
||||||
/* Ring the bell on a tty. */
|
/* Ring the bell on a tty. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -718,7 +732,20 @@ encode_terminal_code (struct glyph *src, int src_len,
|
||||||
return (encode_terminal_dst);
|
return (encode_terminal_dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else /* !HAVE_ANDROID */
|
||||||
|
|
||||||
|
unsigned char *
|
||||||
|
encode_terminal_code (struct glyph *src, int src_len,
|
||||||
|
struct coding_system *coding)
|
||||||
|
{
|
||||||
|
/* Text terminals are simply not supported on Android. */
|
||||||
|
coding->produced = 0;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* HAVE_ANDROID */
|
||||||
|
|
||||||
|
#ifndef HAVE_ANDROID
|
||||||
|
|
||||||
/* An implementation of write_glyphs for termcap frames. */
|
/* An implementation of write_glyphs for termcap frames. */
|
||||||
|
|
||||||
|
|
@ -1046,8 +1073,10 @@ int
|
||||||
string_cost (const char *str)
|
string_cost (const char *str)
|
||||||
{
|
{
|
||||||
cost = 0;
|
cost = 0;
|
||||||
|
#ifndef HAVE_ANDROID
|
||||||
if (str)
|
if (str)
|
||||||
tputs (str, 0, evalcost);
|
tputs (str, 0, evalcost);
|
||||||
|
#endif
|
||||||
return cost;
|
return cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1058,8 +1087,10 @@ static int
|
||||||
string_cost_one_line (const char *str)
|
string_cost_one_line (const char *str)
|
||||||
{
|
{
|
||||||
cost = 0;
|
cost = 0;
|
||||||
|
#ifndef HAVE_ANDROID
|
||||||
if (str)
|
if (str)
|
||||||
tputs (str, 1, evalcost);
|
tputs (str, 1, evalcost);
|
||||||
|
#endif
|
||||||
return cost;
|
return cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1070,11 +1101,13 @@ int
|
||||||
per_line_cost (const char *str)
|
per_line_cost (const char *str)
|
||||||
{
|
{
|
||||||
cost = 0;
|
cost = 0;
|
||||||
|
#ifndef HAVE_ANDROID
|
||||||
if (str)
|
if (str)
|
||||||
tputs (str, 0, evalcost);
|
tputs (str, 0, evalcost);
|
||||||
cost = - cost;
|
cost = - cost;
|
||||||
if (str)
|
if (str)
|
||||||
tputs (str, 10, evalcost);
|
tputs (str, 10, evalcost);
|
||||||
|
#endif
|
||||||
return cost;
|
return cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1147,11 +1180,14 @@ calculate_ins_del_char_costs (struct frame *f)
|
||||||
*p++ = (ins_startup_cost += ins_cost_per_char);
|
*p++ = (ins_startup_cost += ins_cost_per_char);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
calculate_costs (struct frame *frame)
|
calculate_costs (struct frame *frame)
|
||||||
{
|
{
|
||||||
FRAME_COST_BAUD_RATE (frame) = baud_rate;
|
FRAME_COST_BAUD_RATE (frame) = baud_rate;
|
||||||
|
|
||||||
|
#ifndef HAVE_ANDROID
|
||||||
if (FRAME_TERMCAP_P (frame))
|
if (FRAME_TERMCAP_P (frame))
|
||||||
{
|
{
|
||||||
struct tty_display_info *tty = FRAME_TTY (frame);
|
struct tty_display_info *tty = FRAME_TTY (frame);
|
||||||
|
|
@ -1206,13 +1242,15 @@ calculate_costs (struct frame *frame)
|
||||||
|
|
||||||
cmcostinit (FRAME_TTY (frame)); /* set up cursor motion costs */
|
cmcostinit (FRAME_TTY (frame)); /* set up cursor motion costs */
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
struct fkey_table {
|
struct fkey_table
|
||||||
|
{
|
||||||
const char *cap, *name;
|
const char *cap, *name;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef DOS_NT
|
#if !defined DOS_NT && !defined HAVE_ANDROID
|
||||||
/* Termcap capability names that correspond directly to X keysyms.
|
/* Termcap capability names that correspond directly to X keysyms.
|
||||||
Some of these (marked "terminfo") aren't supplied by old-style
|
Some of these (marked "terminfo") aren't supplied by old-style
|
||||||
(Berkeley) termcap entries. They're listed in X keysym order;
|
(Berkeley) termcap entries. They're listed in X keysym order;
|
||||||
|
|
@ -1443,6 +1481,9 @@ term_get_fkeys_1 (void)
|
||||||
#endif /* not DOS_NT */
|
#endif /* not DOS_NT */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef HAVE_ANDROID
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
Character Display Information
|
Character Display Information
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
@ -1519,14 +1560,17 @@ append_glyph (struct it *it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/* For external use. */
|
/* For external use. */
|
||||||
void
|
void
|
||||||
tty_append_glyph (struct it *it)
|
tty_append_glyph (struct it *it)
|
||||||
{
|
{
|
||||||
|
#ifndef HAVE_ANDROID
|
||||||
append_glyph (it);
|
append_glyph (it);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Produce glyphs for the display element described by IT. *IT
|
/* Produce glyphs for the display element described by IT. *IT
|
||||||
specifies what we want to produce a glyph for (character, image, ...),
|
specifies what we want to produce a glyph for (character, image, ...),
|
||||||
and where in the glyph matrix we currently are (glyph row and hpos).
|
and where in the glyph matrix we currently are (glyph row and hpos).
|
||||||
|
|
@ -1549,6 +1593,7 @@ tty_append_glyph (struct it *it)
|
||||||
void
|
void
|
||||||
produce_glyphs (struct it *it)
|
produce_glyphs (struct it *it)
|
||||||
{
|
{
|
||||||
|
#ifndef HAVE_ANDROID
|
||||||
/* If a hook is installed, let it do the work. */
|
/* If a hook is installed, let it do the work. */
|
||||||
|
|
||||||
/* Nothing but characters are supported on terminal frames. */
|
/* Nothing but characters are supported on terminal frames. */
|
||||||
|
|
@ -1661,8 +1706,11 @@ produce_glyphs (struct it *it)
|
||||||
it->current_x += it->pixel_width;
|
it->current_x += it->pixel_width;
|
||||||
it->ascent = it->max_ascent = it->phys_ascent = it->max_phys_ascent = 0;
|
it->ascent = it->max_ascent = it->phys_ascent = it->max_phys_ascent = 0;
|
||||||
it->descent = it->max_descent = it->phys_descent = it->max_phys_descent = 1;
|
it->descent = it->max_descent = it->phys_descent = it->max_phys_descent = 1;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef HAVE_ANDROID
|
||||||
|
|
||||||
/* Append glyphs to IT's glyph_row for the composition IT->cmp_id.
|
/* Append glyphs to IT's glyph_row for the composition IT->cmp_id.
|
||||||
Called from produce_composite_glyph for terminal frames if
|
Called from produce_composite_glyph for terminal frames if
|
||||||
IT->glyph_row != NULL. IT->face_id contains the character's
|
IT->glyph_row != NULL. IT->face_id contains the character's
|
||||||
|
|
@ -2020,6 +2068,7 @@ turn_off_face (struct frame *f, int face_id)
|
||||||
OUTPUT1_IF (tty, tty->TS_orig_pair);
|
OUTPUT1_IF (tty, tty->TS_orig_pair);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* !HAVE_ANDROID */
|
||||||
|
|
||||||
/* Return true if the terminal on frame F supports all of the
|
/* Return true if the terminal on frame F supports all of the
|
||||||
capabilities in CAPS simultaneously. */
|
capabilities in CAPS simultaneously. */
|
||||||
|
|
@ -2027,8 +2076,9 @@ turn_off_face (struct frame *f, int face_id)
|
||||||
bool
|
bool
|
||||||
tty_capable_p (struct tty_display_info *tty, unsigned int caps)
|
tty_capable_p (struct tty_display_info *tty, unsigned int caps)
|
||||||
{
|
{
|
||||||
|
#ifndef HAVE_ANDROID
|
||||||
#define TTY_CAPABLE_P_TRY(tty, cap, TS, NC_bit) \
|
#define TTY_CAPABLE_P_TRY(tty, cap, TS, NC_bit) \
|
||||||
if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(tty, NC_bit))) \
|
if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P (tty, NC_bit))) \
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
TTY_CAPABLE_P_TRY (tty,
|
TTY_CAPABLE_P_TRY (tty,
|
||||||
|
|
@ -2048,6 +2098,9 @@ tty_capable_p (struct tty_display_info *tty, unsigned int caps)
|
||||||
|
|
||||||
/* We can do it! */
|
/* We can do it! */
|
||||||
return 1;
|
return 1;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return non-zero if the terminal is capable to display colors. */
|
/* Return non-zero if the terminal is capable to display colors. */
|
||||||
|
|
@ -2081,7 +2134,7 @@ TERMINAL does not refer to a text terminal. */)
|
||||||
return make_fixnum (t ? t->display_info.tty->TN_max_colors : 0);
|
return make_fixnum (t ? t->display_info.tty->TN_max_colors : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef DOS_NT
|
#if !defined DOS_NT && !defined HAVE_ANDROID
|
||||||
|
|
||||||
/* Declare here rather than in the function, as in the rest of Emacs,
|
/* Declare here rather than in the function, as in the rest of Emacs,
|
||||||
to work around an HPUX compiler bug (?). See
|
to work around an HPUX compiler bug (?). See
|
||||||
|
|
@ -2186,7 +2239,7 @@ set_tty_color_mode (struct tty_display_info *tty, struct frame *f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* !DOS_NT */
|
#endif /* !DOS_NT && !HAVE_ANDROID */
|
||||||
|
|
||||||
char *
|
char *
|
||||||
tty_type_name (Lisp_Object terminal)
|
tty_type_name (Lisp_Object terminal)
|
||||||
|
|
@ -2278,6 +2331,7 @@ suspended.
|
||||||
A suspended tty may be resumed by calling `resume-tty' on it. */)
|
A suspended tty may be resumed by calling `resume-tty' on it. */)
|
||||||
(Lisp_Object tty)
|
(Lisp_Object tty)
|
||||||
{
|
{
|
||||||
|
#ifndef HAVE_ANDROID
|
||||||
struct terminal *t = decode_tty_terminal (tty);
|
struct terminal *t = decode_tty_terminal (tty);
|
||||||
FILE *f;
|
FILE *f;
|
||||||
|
|
||||||
|
|
@ -2314,6 +2368,10 @@ A suspended tty may be resumed by calling `resume-tty' on it. */)
|
||||||
|
|
||||||
/* Clear display hooks to prevent further output. */
|
/* Clear display hooks to prevent further output. */
|
||||||
clear_tty_hooks (t);
|
clear_tty_hooks (t);
|
||||||
|
#else
|
||||||
|
/* This will always signal on Android. */
|
||||||
|
decode_tty_terminal (tty);
|
||||||
|
#endif
|
||||||
|
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
|
|
@ -2337,9 +2395,12 @@ TTY may be a terminal object, a frame, or nil (meaning the selected
|
||||||
frame's terminal). */)
|
frame's terminal). */)
|
||||||
(Lisp_Object tty)
|
(Lisp_Object tty)
|
||||||
{
|
{
|
||||||
struct terminal *t = decode_tty_terminal (tty);
|
#ifndef HAVE_ANDROID
|
||||||
|
struct terminal *t;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
|
t = decode_tty_terminal (tty);
|
||||||
|
|
||||||
if (!t)
|
if (!t)
|
||||||
error ("Attempt to resume a non-text terminal device");
|
error ("Attempt to resume a non-text terminal device");
|
||||||
|
|
||||||
|
|
@ -2396,10 +2457,15 @@ frame's terminal). */)
|
||||||
}
|
}
|
||||||
|
|
||||||
set_tty_hooks (t);
|
set_tty_hooks (t);
|
||||||
|
#else
|
||||||
|
decode_tty_terminal (tty);
|
||||||
|
#endif
|
||||||
|
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef HAVE_ANDROID
|
||||||
|
|
||||||
DEFUN ("tty--set-output-buffer-size", Ftty__set_output_buffer_size,
|
DEFUN ("tty--set-output-buffer-size", Ftty__set_output_buffer_size,
|
||||||
Stty__set_output_buffer_size, 1, 2, 0, doc:
|
Stty__set_output_buffer_size, 1, 2, 0, doc:
|
||||||
/* Set the output buffer size for a TTY.
|
/* Set the output buffer size for a TTY.
|
||||||
|
|
@ -2438,12 +2504,14 @@ A value of zero means TTY uses the system's default value. */)
|
||||||
error ("Not a tty terminal");
|
error ("Not a tty terminal");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
Mouse
|
Mouse
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
#ifndef DOS_NT
|
#if !defined DOS_NT && !defined HAVE_ANDROID
|
||||||
|
|
||||||
/* Implementation of draw_row_with_mouse_face for TTY/GPM and macOS. */
|
/* Implementation of draw_row_with_mouse_face for TTY/GPM and macOS. */
|
||||||
void
|
void
|
||||||
|
|
@ -2713,7 +2781,7 @@ DEFUN ("gpm-mouse-stop", Fgpm_mouse_stop, Sgpm_mouse_stop,
|
||||||
Menus
|
Menus
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
#if !defined (MSDOS)
|
#if !defined (MSDOS) && !defined HAVE_ANDROID
|
||||||
|
|
||||||
/* TTY menu implementation and main ideas are borrowed from msdos.c.
|
/* TTY menu implementation and main ideas are borrowed from msdos.c.
|
||||||
|
|
||||||
|
|
@ -3813,10 +3881,12 @@ tty_menu_show (struct frame *f, int x, int y, int menuflags,
|
||||||
return SAFE_FREE_UNBIND_TO (specpdl_count, entry);
|
return SAFE_FREE_UNBIND_TO (specpdl_count, entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* !MSDOS */
|
#endif /* !MSDOS && !defined HAVE_ANDROID */
|
||||||
|
|
||||||
|
|
||||||
#ifndef MSDOS
|
|
||||||
|
#if !defined MSDOS && !defined HAVE_ANDROID
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
Initialization
|
Initialization
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
@ -3846,7 +3916,7 @@ tty_free_frame_resources (struct frame *f)
|
||||||
xfree (f->output_data.tty);
|
xfree (f->output_data.tty);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* MSDOS */
|
#elif defined MSDOS
|
||||||
|
|
||||||
/* Delete frame F's face cache. */
|
/* Delete frame F's face cache. */
|
||||||
|
|
||||||
|
|
@ -3856,8 +3926,13 @@ tty_free_frame_resources (struct frame *f)
|
||||||
eassert (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f));
|
eassert (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f));
|
||||||
free_frame_faces (f);
|
free_frame_faces (f);
|
||||||
}
|
}
|
||||||
#endif /* MSDOS */
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef HAVE_ANDROID
|
||||||
|
|
||||||
/* Reset the hooks in TERMINAL. */
|
/* Reset the hooks in TERMINAL. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -3952,6 +4027,8 @@ dissociate_if_controlling_tty (int fd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* !HAVE_ANDROID */
|
||||||
|
|
||||||
/* Create a termcap display on the tty device with the given name and
|
/* Create a termcap display on the tty device with the given name and
|
||||||
type.
|
type.
|
||||||
|
|
||||||
|
|
@ -3961,11 +4038,23 @@ dissociate_if_controlling_tty (int fd)
|
||||||
|
|
||||||
TERMINAL_TYPE is the termcap type of the device, e.g. "vt100".
|
TERMINAL_TYPE is the termcap type of the device, e.g. "vt100".
|
||||||
|
|
||||||
If MUST_SUCCEED is true, then all errors are fatal. */
|
If MUST_SUCCEED is true, then all errors are fatal. This function
|
||||||
|
always signals on Android, where text terminals are prohibited by
|
||||||
|
system policy (and the required libraries are usually not
|
||||||
|
available.) */
|
||||||
|
|
||||||
|
#ifdef HAVE_ANDROID
|
||||||
|
_Noreturn
|
||||||
|
#endif
|
||||||
|
|
||||||
struct terminal *
|
struct terminal *
|
||||||
init_tty (const char *name, const char *terminal_type, bool must_succeed)
|
init_tty (const char *name, const char *terminal_type, bool must_succeed)
|
||||||
{
|
{
|
||||||
|
#ifdef HAVE_ANDROID
|
||||||
|
maybe_fatal (must_succeed, 0, "Text terminals are not supported"
|
||||||
|
" under Android", "Text terminals are not supported"
|
||||||
|
" under Android");
|
||||||
|
#else
|
||||||
struct tty_display_info *tty = NULL;
|
struct tty_display_info *tty = NULL;
|
||||||
struct terminal *terminal = NULL;
|
struct terminal *terminal = NULL;
|
||||||
#ifndef DOS_NT
|
#ifndef DOS_NT
|
||||||
|
|
@ -4447,6 +4536,7 @@ use the Bourne shell command 'TERM=...; export TERM' (C-shell:\n\
|
||||||
init_sys_modes (tty);
|
init_sys_modes (tty);
|
||||||
|
|
||||||
return terminal;
|
return terminal;
|
||||||
|
#endif /* !HAVE_ANDROID */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -4471,8 +4561,13 @@ maybe_fatal (bool must_succeed, struct terminal *terminal,
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start (ap, str2);
|
va_start (ap, str2);
|
||||||
|
|
||||||
|
#ifndef HAVE_ANDROID
|
||||||
if (terminal)
|
if (terminal)
|
||||||
delete_tty (terminal);
|
delete_tty (terminal);
|
||||||
|
#else
|
||||||
|
eassert (terminal == NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (must_succeed)
|
if (must_succeed)
|
||||||
vfatal (str2, ap);
|
vfatal (str2, ap);
|
||||||
|
|
@ -4490,6 +4585,8 @@ fatal (const char *str, ...)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef HAVE_ANDROID
|
||||||
|
|
||||||
/* Delete the given tty terminal, closing all frames on it. */
|
/* Delete the given tty terminal, closing all frames on it. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -4547,6 +4644,8 @@ delete_tty (struct terminal *terminal)
|
||||||
xfree (tty);
|
xfree (tty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
syms_of_term (void)
|
syms_of_term (void)
|
||||||
{
|
{
|
||||||
|
|
@ -4594,21 +4693,25 @@ trigger redisplay. */);
|
||||||
defsubr (&Stty_top_frame);
|
defsubr (&Stty_top_frame);
|
||||||
defsubr (&Ssuspend_tty);
|
defsubr (&Ssuspend_tty);
|
||||||
defsubr (&Sresume_tty);
|
defsubr (&Sresume_tty);
|
||||||
|
#ifndef HAVE_ANDROID
|
||||||
defsubr (&Stty__set_output_buffer_size);
|
defsubr (&Stty__set_output_buffer_size);
|
||||||
defsubr (&Stty__output_buffer_size);
|
defsubr (&Stty__output_buffer_size);
|
||||||
|
#endif /* !HAVE_ANDROID */
|
||||||
#ifdef HAVE_GPM
|
#ifdef HAVE_GPM
|
||||||
defsubr (&Sgpm_mouse_start);
|
defsubr (&Sgpm_mouse_start);
|
||||||
defsubr (&Sgpm_mouse_stop);
|
defsubr (&Sgpm_mouse_stop);
|
||||||
#endif /* HAVE_GPM */
|
#endif /* HAVE_GPM */
|
||||||
|
|
||||||
#ifndef DOS_NT
|
#if !defined DOS_NT && !defined HAVE_ANDROID
|
||||||
default_orig_pair = NULL;
|
default_orig_pair = NULL;
|
||||||
default_set_foreground = NULL;
|
default_set_foreground = NULL;
|
||||||
default_set_background = NULL;
|
default_set_background = NULL;
|
||||||
#endif /* !DOS_NT */
|
#endif /* !DOS_NT && !HAVE_ANDROID */
|
||||||
|
|
||||||
|
#ifndef HAVE_ANDROID
|
||||||
encode_terminal_src = NULL;
|
encode_terminal_src = NULL;
|
||||||
encode_terminal_dst = NULL;
|
encode_terminal_dst = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
DEFSYM (Qtty_mode_set_strings, "tty-mode-set-strings");
|
DEFSYM (Qtty_mode_set_strings, "tty-mode-set-strings");
|
||||||
DEFSYM (Qtty_mode_reset_strings, "tty-mode-reset-strings");
|
DEFSYM (Qtty_mode_reset_strings, "tty-mode-reset-strings");
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,8 @@ enum output_method
|
||||||
output_w32,
|
output_w32,
|
||||||
output_ns,
|
output_ns,
|
||||||
output_pgtk,
|
output_pgtk,
|
||||||
output_haiku
|
output_haiku,
|
||||||
|
output_android,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Input queue declarations and hooks. */
|
/* Input queue declarations and hooks. */
|
||||||
|
|
@ -516,12 +517,13 @@ struct terminal
|
||||||
/* Device-type dependent data shared amongst all frames on this terminal. */
|
/* Device-type dependent data shared amongst all frames on this terminal. */
|
||||||
union display_info
|
union display_info
|
||||||
{
|
{
|
||||||
struct tty_display_info *tty; /* termchar.h */
|
struct tty_display_info *tty; /* termchar.h */
|
||||||
struct x_display_info *x; /* xterm.h */
|
struct x_display_info *x; /* xterm.h */
|
||||||
struct w32_display_info *w32; /* w32term.h */
|
struct w32_display_info *w32; /* w32term.h */
|
||||||
struct ns_display_info *ns; /* nsterm.h */
|
struct ns_display_info *ns; /* nsterm.h */
|
||||||
struct pgtk_display_info *pgtk; /* pgtkterm.h */
|
struct pgtk_display_info *pgtk; /* pgtkterm.h */
|
||||||
struct haiku_display_info *haiku; /* haikuterm.h */
|
struct haiku_display_info *haiku; /* haikuterm.h */
|
||||||
|
struct android_display_info *android; /* androidterm.h */
|
||||||
} display_info;
|
} display_info;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -595,7 +597,8 @@ struct terminal
|
||||||
BGCOLOR. */
|
BGCOLOR. */
|
||||||
void (*query_frame_background_color) (struct frame *f, Emacs_Color *bgcolor);
|
void (*query_frame_background_color) (struct frame *f, Emacs_Color *bgcolor);
|
||||||
|
|
||||||
#if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI) || defined (HAVE_PGTK)
|
#if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI) || defined (HAVE_PGTK) \
|
||||||
|
|| defined (HAVE_ANDROID)
|
||||||
/* On frame F, translate pixel colors to RGB values for the NCOLORS
|
/* On frame F, translate pixel colors to RGB values for the NCOLORS
|
||||||
colors in COLORS. Use cached information, if available. */
|
colors in COLORS. Use cached information, if available. */
|
||||||
|
|
||||||
|
|
@ -930,6 +933,9 @@ extern struct terminal *terminal_list;
|
||||||
#elif defined (HAVE_HAIKU)
|
#elif defined (HAVE_HAIKU)
|
||||||
#define TERMINAL_FONT_CACHE(t) \
|
#define TERMINAL_FONT_CACHE(t) \
|
||||||
(t->type == output_haiku ? t->display_info.haiku->name_list_element : Qnil)
|
(t->type == output_haiku ? t->display_info.haiku->name_list_element : Qnil)
|
||||||
|
#elif defined (HAVE_ANDROID)
|
||||||
|
#define TERMINAL_FONT_CACHE(t) \
|
||||||
|
(t->type == output_android ? t->display_info.android->name_list_element : Qnil)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern struct terminal *decode_live_terminal (Lisp_Object);
|
extern struct terminal *decode_live_terminal (Lisp_Object);
|
||||||
|
|
|
||||||
|
|
@ -451,6 +451,8 @@ return values. */)
|
||||||
return Qpgtk;
|
return Qpgtk;
|
||||||
case output_haiku:
|
case output_haiku:
|
||||||
return Qhaiku;
|
return Qhaiku;
|
||||||
|
case output_android:
|
||||||
|
return Qandroid;
|
||||||
default:
|
default:
|
||||||
emacs_abort ();
|
emacs_abort ();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,10 @@ AM_V_GEN =
|
||||||
AM_V_GLOBALS =
|
AM_V_GLOBALS =
|
||||||
AM_V_NO_PD =
|
AM_V_NO_PD =
|
||||||
AM_V_RC =
|
AM_V_RC =
|
||||||
|
AM_V_JAVAC =
|
||||||
|
AM_V_DX =
|
||||||
|
AM_V_AAPT =
|
||||||
|
AM_V_ZIPALIGN =
|
||||||
else
|
else
|
||||||
|
|
||||||
# Whether $(info ...) works. This is to work around a bug in GNU Make
|
# Whether $(info ...) works. This is to work around a bug in GNU Make
|
||||||
|
|
@ -76,4 +80,8 @@ AM_V_GEN = @$(info $ GEN $@)
|
||||||
AM_V_GLOBALS = @$(info $ GEN globals.h)
|
AM_V_GLOBALS = @$(info $ GEN globals.h)
|
||||||
AM_V_NO_PD = --no-print-directory
|
AM_V_NO_PD = --no-print-directory
|
||||||
AM_V_RC = @$(info $ RC $@)
|
AM_V_RC = @$(info $ RC $@)
|
||||||
|
|
||||||
|
# These are used for the Android port.
|
||||||
|
AM_V_JAVAC = @$(info $ JAVAC $@)
|
||||||
|
AM_V_DX = @$(info $ DX $@)
|
||||||
endif
|
endif
|
||||||
|
|
|
||||||
26
src/xdisp.c
26
src/xdisp.c
|
|
@ -16415,7 +16415,7 @@ redisplay_internal (void)
|
||||||
display area, displaying a different frame means redisplay
|
display area, displaying a different frame means redisplay
|
||||||
the whole thing. */
|
the whole thing. */
|
||||||
SET_FRAME_GARBAGED (sf);
|
SET_FRAME_GARBAGED (sf);
|
||||||
#ifndef DOS_NT
|
#if !defined DOS_NT && !defined HAVE_ANDROID
|
||||||
set_tty_color_mode (FRAME_TTY (sf), sf);
|
set_tty_color_mode (FRAME_TTY (sf), sf);
|
||||||
#endif
|
#endif
|
||||||
FRAME_TTY (sf)->previous_frame = sf;
|
FRAME_TTY (sf)->previous_frame = sf;
|
||||||
|
|
@ -26320,7 +26320,7 @@ display_menu_bar (struct window *w)
|
||||||
init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
|
init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
|
||||||
it.first_visible_x = 0;
|
it.first_visible_x = 0;
|
||||||
it.last_visible_x = FRAME_PIXEL_WIDTH (f);
|
it.last_visible_x = FRAME_PIXEL_WIDTH (f);
|
||||||
#elif defined (HAVE_X_WINDOWS) /* X without toolkit. */
|
#elif defined (HAVE_X_WINDOWS) || defined (HAVE_ANDROID)
|
||||||
struct window *menu_window = NULL;
|
struct window *menu_window = NULL;
|
||||||
struct face *face = FACE_FROM_ID (f, MENU_FACE_ID);
|
struct face *face = FACE_FROM_ID (f, MENU_FACE_ID);
|
||||||
|
|
||||||
|
|
@ -26390,7 +26390,11 @@ display_menu_bar (struct window *w)
|
||||||
it.glyph_row->truncated_on_left_p = false;
|
it.glyph_row->truncated_on_left_p = false;
|
||||||
it.glyph_row->truncated_on_right_p = false;
|
it.glyph_row->truncated_on_right_p = false;
|
||||||
|
|
||||||
#if defined (HAVE_X_WINDOWS) && !defined (USE_X_TOOLKIT) && !defined (USE_GTK)
|
/* This will break the moment someone tries to add another window
|
||||||
|
system that uses the no toolkit menu bar. Oh well. At least
|
||||||
|
there will be an error, meaning he will correct the ifdef inside
|
||||||
|
which `face' is defined. */
|
||||||
|
#if defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR
|
||||||
/* Make a 3D menu bar have a shadow at its right end. */
|
/* Make a 3D menu bar have a shadow at its right end. */
|
||||||
extend_face_to_end_of_line (&it);
|
extend_face_to_end_of_line (&it);
|
||||||
if (face->box != FACE_NO_BOX)
|
if (face->box != FACE_NO_BOX)
|
||||||
|
|
@ -26431,6 +26435,11 @@ display_menu_bar (struct window *w)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This code is never used on Android where there are only GUI and
|
||||||
|
initial frames. */
|
||||||
|
|
||||||
|
#ifndef HAVE_ANDROID
|
||||||
|
|
||||||
/* Deep copy of a glyph row, including the glyphs. */
|
/* Deep copy of a glyph row, including the glyphs. */
|
||||||
static void
|
static void
|
||||||
deep_copy_glyph_row (struct glyph_row *to, struct glyph_row *from)
|
deep_copy_glyph_row (struct glyph_row *to, struct glyph_row *from)
|
||||||
|
|
@ -26551,6 +26560,9 @@ display_tty_menu_item (const char *item_text, int width, int face_id,
|
||||||
row->full_width_p = saved_width;
|
row->full_width_p = saved_width;
|
||||||
row->reversed_p = saved_reversed;
|
row->reversed_p = saved_reversed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
Mode Line
|
Mode Line
|
||||||
|
|
@ -33432,7 +33444,9 @@ draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE_ANDROID
|
||||||
tty_draw_row_with_mouse_face (w, row, start_hpos, end_hpos, draw);
|
tty_draw_row_with_mouse_face (w, row, start_hpos, end_hpos, draw);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Display the active region described by mouse_face_* according to DRAW. */
|
/* Display the active region described by mouse_face_* according to DRAW. */
|
||||||
|
|
@ -36104,14 +36118,10 @@ expose_frame (struct frame *f, int x, int y, int w, int h)
|
||||||
|= expose_window (XWINDOW (f->tool_bar_window), &r);
|
|= expose_window (XWINDOW (f->tool_bar_window), &r);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_X_WINDOWS
|
#if defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR
|
||||||
#ifndef MSDOS
|
|
||||||
#if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
|
|
||||||
if (WINDOWP (f->menu_bar_window))
|
if (WINDOWP (f->menu_bar_window))
|
||||||
mouse_face_overwritten_p
|
mouse_face_overwritten_p
|
||||||
|= expose_window (XWINDOW (f->menu_bar_window), &r);
|
|= expose_window (XWINDOW (f->menu_bar_window), &r);
|
||||||
#endif /* not USE_X_TOOLKIT and not USE_GTK */
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Some window managers support a focus-follows-mouse style with
|
/* Some window managers support a focus-follows-mouse style with
|
||||||
|
|
|
||||||
59
src/xfaces.c
59
src/xfaces.c
|
|
@ -254,6 +254,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
#ifdef HAVE_HAIKU
|
#ifdef HAVE_HAIKU
|
||||||
#define GCGraphicsExposures 0
|
#define GCGraphicsExposures 0
|
||||||
#endif /* HAVE_HAIKU */
|
#endif /* HAVE_HAIKU */
|
||||||
|
|
||||||
|
#ifdef HAVE_ANDROID
|
||||||
|
#define GCGraphicsExposures 0
|
||||||
|
#endif /* HAVE_ANDROID */
|
||||||
#endif /* HAVE_WINDOW_SYSTEM */
|
#endif /* HAVE_WINDOW_SYSTEM */
|
||||||
|
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
|
|
@ -607,6 +611,39 @@ x_free_gc (struct frame *f, Emacs_GC *gc)
|
||||||
}
|
}
|
||||||
#endif /* HAVE_NS */
|
#endif /* HAVE_NS */
|
||||||
|
|
||||||
|
#ifdef HAVE_ANDROID
|
||||||
|
|
||||||
|
/* Android real GCs. */
|
||||||
|
|
||||||
|
static struct android_gc *
|
||||||
|
x_create_gc (struct frame *f, unsigned long value_mask,
|
||||||
|
Emacs_GC *xgcv)
|
||||||
|
{
|
||||||
|
struct android_gc_values gcv;
|
||||||
|
unsigned long mask;
|
||||||
|
|
||||||
|
gcv.foreground = xgcv->foreground;
|
||||||
|
gcv.background = xgcv->background;
|
||||||
|
|
||||||
|
mask = 0;
|
||||||
|
|
||||||
|
if (value_mask & GCForeground)
|
||||||
|
mask |= ANDROID_GC_FOREGROUND;
|
||||||
|
|
||||||
|
if (value_mask & GCBackground)
|
||||||
|
mask |= ANDROID_GC_BACKGROUND;
|
||||||
|
|
||||||
|
return android_create_gc (mask, &gcv);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
x_free_gc (struct frame *f, struct android_gc *gc)
|
||||||
|
{
|
||||||
|
android_free_gc (gc);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
Frames and faces
|
Frames and faces
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
@ -6951,19 +6988,21 @@ where R,G,B are numbers between 0 and 255 and name is an arbitrary string. */)
|
||||||
int num;
|
int num;
|
||||||
|
|
||||||
while (fgets (buf, sizeof (buf), fp) != NULL)
|
while (fgets (buf, sizeof (buf), fp) != NULL)
|
||||||
if (sscanf (buf, "%d %d %d %n", &red, &green, &blue, &num) == 3)
|
{
|
||||||
{
|
if (sscanf (buf, "%d %d %d %n", &red, &green, &blue, &num) == 3)
|
||||||
|
{
|
||||||
#ifdef HAVE_NTGUI
|
#ifdef HAVE_NTGUI
|
||||||
int color = RGB (red, green, blue);
|
int color = RGB (red, green, blue);
|
||||||
#else
|
#else
|
||||||
int color = (red << 16) | (green << 8) | blue;
|
int color = (red << 16) | (green << 8) | blue;
|
||||||
#endif
|
#endif
|
||||||
char *name = buf + num;
|
char *name = buf + num;
|
||||||
ptrdiff_t len = strlen (name);
|
ptrdiff_t len = strlen (name);
|
||||||
len -= 0 < len && name[len - 1] == '\n';
|
len -= 0 < len && name[len - 1] == '\n';
|
||||||
cmap = Fcons (Fcons (make_string (name, len), make_fixnum (color)),
|
cmap = Fcons (Fcons (make_string (name, len), make_fixnum (color)),
|
||||||
cmap);
|
cmap);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
fclose (fp);
|
fclose (fp);
|
||||||
}
|
}
|
||||||
unblock_input ();
|
unblock_input ();
|
||||||
|
|
|
||||||
209
xcompile/Makefile.in
Normal file
209
xcompile/Makefile.in
Normal file
|
|
@ -0,0 +1,209 @@
|
||||||
|
### @configure_input@
|
||||||
|
|
||||||
|
# Copyright (C) 2023 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This file is part of GNU Emacs.
|
||||||
|
|
||||||
|
# GNU Emacs is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
# GNU Emacs is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
top_srcdir = @top_srcdir@
|
||||||
|
top_builddir = @top_builddir@
|
||||||
|
|
||||||
|
# Cross-compiling Emacs for Android.
|
||||||
|
|
||||||
|
# The cross compiled binaries are built by having ``variant''
|
||||||
|
# Makefiles generated at configure-time. First,
|
||||||
|
# $(top_builddir)/src/Makefile.android,
|
||||||
|
# $(top_builddir)/lib/Makefile.android,
|
||||||
|
# $(top_builddir)/lib/gnulib.mk.android and
|
||||||
|
# $(top_builddir)/lib-src/Makefile.android are copied to their usual
|
||||||
|
# locations in this directory.
|
||||||
|
|
||||||
|
# Finally, the following commands are executed in order, to produce
|
||||||
|
# libgnu.a, various binaries in lib-src, and src/aemacs:
|
||||||
|
# make -C lib libgnu.a
|
||||||
|
# make -C lib-src src/aemacs
|
||||||
|
# make -C src aemacs
|
||||||
|
|
||||||
|
# This is possibly the ugliest Makefile ever written!
|
||||||
|
|
||||||
|
LIB_SRCDIR = $(realpath $(top_srcdir)/lib)
|
||||||
|
LIB_TOP_SRCDIR = $(realpath $(top_srcdir))
|
||||||
|
|
||||||
|
SRC_SRCDIR = $(realpath $(top_srcdir)/src)
|
||||||
|
SRC_TOP_SRCDIR = $(realpath $(top_srcdir))
|
||||||
|
|
||||||
|
LIB_SRC_SRCDIR = $(realpath $(top_srcdir)/lib-src)
|
||||||
|
LIB_SRC_TOP_SRCDIR = $(realpath $(top_src))
|
||||||
|
|
||||||
|
# This is a list of binaries to build and install in lib-src.
|
||||||
|
|
||||||
|
LIBSRC_BINARIES = lib-src/etags lib-src/ctags lib-src/emacsclient \
|
||||||
|
lib-src/ebrowse lib-src/hexl lib-src/movemail
|
||||||
|
|
||||||
|
CLEAN_SUBDIRS=lib src lib-src
|
||||||
|
|
||||||
|
.PHONY: all
|
||||||
|
all: lib/libgnu.a src/libemacs.so src/android-emacs $(LIBSRC_BINARIES)
|
||||||
|
|
||||||
|
# This Makefile relies on builddir and top_builddir being relative
|
||||||
|
# paths in *.android.
|
||||||
|
|
||||||
|
# This file is used to trick lib/gnulib.mk, it is not actually useful.
|
||||||
|
config.status:
|
||||||
|
touch config.status
|
||||||
|
|
||||||
|
src/verbose.mk: verbose.mk.android
|
||||||
|
mkdir -p src
|
||||||
|
cp -f verbose.mk.android src/verbose.mk
|
||||||
|
|
||||||
|
UGLY_HOST_HEADERS = dirent.h stdlib.h sys/random.h limits.h \
|
||||||
|
string.h signal.h time.h inttypes.h assert.h \
|
||||||
|
stdint.h unistd.h stdlib.h sys/types.h sys/time.h \
|
||||||
|
sys/stat.h getopt.h fcntl.h sys/select.h alloca.h \
|
||||||
|
stdio.h sys/random.h
|
||||||
|
|
||||||
|
# Gnulib, make-fingerprint and make-docfile must be built before
|
||||||
|
# entering any of the rules below, or they will get the Android
|
||||||
|
# versions of many headers.
|
||||||
|
|
||||||
|
.PHONY: $(top_builddir)/lib/libgnu.a
|
||||||
|
$(top_builddir)/lib/libgnu.a:
|
||||||
|
+ make -C $(top_builddir)/lib libgnu.a
|
||||||
|
|
||||||
|
.PHONY: $(top_builddir)/lib-src/make-fingerprint
|
||||||
|
$(top_builddir)/lib-src/make-fingerprint:
|
||||||
|
make -C $(top_builddir)/lib-src make-fingerprint
|
||||||
|
|
||||||
|
.PHONY: $(top_builddir)/lib-src/make-docfile
|
||||||
|
$(top_builddir)/lib-src/make-docfile:
|
||||||
|
make -C $(top_builddir)/lib-src make-docfile
|
||||||
|
|
||||||
|
PRE_BUILD_DEPS=$(top_builddir)/lib/libgnu.a \
|
||||||
|
$(top_builddir)/lib-src/make-fingerprint \
|
||||||
|
$(top_builddir)/lib-src/make-docfile
|
||||||
|
|
||||||
|
.PHONY: lib/libgnu.a
|
||||||
|
lib/libgnu.a: src/verbose.mk config.status $(PRE_BUILD_DEPS)
|
||||||
|
mkdir -p lib/deps lib/deps/malloc
|
||||||
|
# Temporarily move config.h to config.h.bak and config.h.android to
|
||||||
|
# config.h
|
||||||
|
cp -f -p $(top_builddir)/src/config.h.android lib/config.h
|
||||||
|
# And the Makefiles.
|
||||||
|
cp -f -p $(top_builddir)/lib/gnulib.mk.android lib/gnulib.mk
|
||||||
|
cp -f -p $(top_builddir)/lib/Makefile.android lib/Makefile
|
||||||
|
# Next, move srcdir and top_srcdir in the Makefiles copied.
|
||||||
|
sed -i 's/srcdir =.*$$/srcdir = $(subst /,\/,$(LIB_SRCDIR))/g' lib/Makefile
|
||||||
|
sed -i 's/top_srcdir =.*$$/top_srcdir = $(subst /,\/,$(LIB_TOP_SRCDIR))/g' \
|
||||||
|
lib/Makefile
|
||||||
|
sed -i 's/srcdir =.*$$/srcdir = $(subst /,\/,$(LIB_SRCDIR))/g' lib/gnulib.mk
|
||||||
|
# Ugly hack: hide some troublesome headers in $(top_builddir)/lib
|
||||||
|
# while building lib. Otherwise, they will end up overriding the
|
||||||
|
# system headers used on Android through #include_next and cause
|
||||||
|
# trouble.
|
||||||
|
mkdir -p sys
|
||||||
|
for ugly_header in $(UGLY_HOST_HEADERS); do \
|
||||||
|
if [ -e "$(top_builddir)/lib/$$ugly_header" ]; then \
|
||||||
|
mv -f $(top_builddir)/lib/$$ugly_header $$ugly_header.bak; \
|
||||||
|
fi \
|
||||||
|
done
|
||||||
|
# And make libgnu.a. Restore config.h if it fails.
|
||||||
|
-make -C lib libgnu.a
|
||||||
|
# Move the hiden headers back
|
||||||
|
for ugly_header in $(UGLY_HOST_HEADERS); do \
|
||||||
|
if [ -e "$$ugly_header.bak" ]; then \
|
||||||
|
mv -f $$ugly_header.bak $(top_builddir)/lib/$$ugly_header; \
|
||||||
|
fi \
|
||||||
|
done
|
||||||
|
|
||||||
|
src/Makefile src/config.h &: $(top_builddir)/src/config.h.android \
|
||||||
|
$(top_builddir)/src/Makefile.android $(PRE_BUILD_DEPS)
|
||||||
|
mkdir -p src src/deps
|
||||||
|
# Copy config.h to src/
|
||||||
|
cp -f -p $(top_builddir)/src/config.h.android src/config.h
|
||||||
|
# And the Makefile.
|
||||||
|
cp -f -p $(top_builddir)/src/Makefile.android src/Makefile
|
||||||
|
# Next, edit srcdir and top_srcdir to the right location.
|
||||||
|
sed -i 's/srcdir =.*$$/srcdir = $(subst /,\/,$(SRC_SRCDIR))/g' src/Makefile
|
||||||
|
sed -i 's/top_srcdir =.*$$/top_srcdir = $(subst /,\/,$(LIB_TOP_SRCDIR))/g' \
|
||||||
|
src/Makefile
|
||||||
|
# Edit references to ../admin/unidata to read ../../admin/unidata.
|
||||||
|
sed -i 's/\.\.\/admin\/unidata/..\/..\/admin\/unidata/g' src/Makefile
|
||||||
|
sed -i 's/\.\.\/admin\/charsets/..\/..\/admin\/charsets/g' src/Makefile
|
||||||
|
# Next, edit libsrc to the location at top_srcdir! It is important
|
||||||
|
# that src/Makefile uses the binaries there, instead of any
|
||||||
|
# cross-compiled binaries at ./lib-src.
|
||||||
|
sed -i 's/libsrc =.*$$/libsrc = \.\.\/\.\.\/lib-src/g' src/Makefile
|
||||||
|
|
||||||
|
.PHONY: src/android-emacs src/libemacs.so
|
||||||
|
src/android-emacs src/libemacs.so &: src/Makefile src/config.h \
|
||||||
|
src/verbose.mk lib/libgnu.a $(PRE_BUILD_DEPS)
|
||||||
|
# Ugly hack: hide some troublesome headers in $(top_builddir)/lib
|
||||||
|
# while building lib. Otherwise, they will end up overriding the
|
||||||
|
# system headers used on Android through #include_next and cause
|
||||||
|
# trouble.
|
||||||
|
mkdir -p sys
|
||||||
|
for ugly_header in $(UGLY_HOST_HEADERS); do \
|
||||||
|
if [ -e "$(top_builddir)/lib/$$ugly_header" ]; then \
|
||||||
|
mv -f $(top_builddir)/lib/$$ugly_header $$ugly_header.bak; \
|
||||||
|
fi \
|
||||||
|
done
|
||||||
|
# Finally, go into src and make
|
||||||
|
+make -C src android-emacs libemacs.so
|
||||||
|
# Move the hidden headers back
|
||||||
|
for ugly_header in $(UGLY_HOST_HEADERS); do \
|
||||||
|
if [ -e "$$ugly_header.bak" ]; then \
|
||||||
|
mv -f $$ugly_header.bak $(top_builddir)/lib/$$ugly_header; \
|
||||||
|
fi \
|
||||||
|
done
|
||||||
|
|
||||||
|
lib-src/Makefile: $(top_builddir)/lib-src/Makefile.android
|
||||||
|
mkdir -p lib-src
|
||||||
|
cp -f -p $< $@
|
||||||
|
|
||||||
|
.PHONY: $(LIBSRC_BINARIES)
|
||||||
|
$(LIBSRC_BINARIES) &: src/verbose.mk $(top_builddir)/$@ lib/libgnu.a \
|
||||||
|
src/config.h lib-src/Makefile $(PRE_BUILD_DEPS)
|
||||||
|
mkdir -p src lib-src
|
||||||
|
# Next, edit srcdir and top_srcdir to the right location.
|
||||||
|
sed -i 's/srcdir=.*$$/srcdir = $(subst /,\/,$(LIB_SRC_SRCDIR))/g' \
|
||||||
|
lib-src/Makefile
|
||||||
|
sed -i 's/top_srcdir=.*$$/top_srcdir = $(subst /,\/,$(LIB_SRC_TOP_SRCDIR))/g' \
|
||||||
|
lib-src/Makefile
|
||||||
|
# Edit out SCRIPTS, it interferes with the build.
|
||||||
|
sed -i 's/^SCRIPTS=.*$$/SCRIPTS=/g' lib-src/Makefile
|
||||||
|
# Ugly hack: hide some troublesome headers in $(top_builddir)/lib
|
||||||
|
# while building lib. Otherwise, they will end up overriding the
|
||||||
|
# system headers used on Android through #include_next and cause
|
||||||
|
# trouble.
|
||||||
|
mkdir -p sys
|
||||||
|
for ugly_header in $(UGLY_HOST_HEADERS); do \
|
||||||
|
if [ -e "$(top_builddir)/lib/$$ugly_header" ]; then \
|
||||||
|
mv -f $(top_builddir)/lib/$$ugly_header $$ugly_header.bak; \
|
||||||
|
fi \
|
||||||
|
done
|
||||||
|
# Finally, go into lib-src and make everything being built
|
||||||
|
+make -C lib-src $(foreach bin,$(LIBSRC_BINARIES),$(notdir $(bin)))
|
||||||
|
# Move the hidden headers back
|
||||||
|
for ugly_header in $(UGLY_HOST_HEADERS); do \
|
||||||
|
if [ -e "$$ugly_header.bak" ]; then \
|
||||||
|
mv -f $$ugly_header.bak $(top_builddir)/lib/$$ugly_header; \
|
||||||
|
fi \
|
||||||
|
done
|
||||||
|
|
||||||
|
.PHONY: clean maintainer-clean
|
||||||
|
clean:
|
||||||
|
rm -rf $(CLEAN_SUBDIRS) *.bak sys
|
||||||
|
|
||||||
|
maintainer-clean: clean
|
||||||
7
xcompile/README
Normal file
7
xcompile/README
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
This directory holds Makefiles and other required assets to build an
|
||||||
|
Emacs binary independently for another toolchain, which is currently
|
||||||
|
required when building for Android.
|
||||||
|
|
||||||
|
The files here are extremely ugly, and contain rules that cannot be
|
||||||
|
interrupted without leaving the build tree in an unsafe state. At
|
||||||
|
some point that should be fixed!
|
||||||
20
xcompile/langinfo.h
Normal file
20
xcompile/langinfo.h
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
/* Replacement langinfo.h file for building GNU Emacs on Android.
|
||||||
|
|
||||||
|
Copyright (C) 2023 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GNU Emacs.
|
||||||
|
|
||||||
|
GNU Emacs is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
your option) any later version.
|
||||||
|
|
||||||
|
GNU Emacs is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#define nl_langinfo(ignore) "ASCII"
|
||||||
Loading…
Add table
Add a link
Reference in a new issue