summaryrefslogtreecommitdiff
path: root/src/emacs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/emacs.c')
-rw-r--r--src/emacs.c138
1 files changed, 128 insertions, 10 deletions
diff --git a/src/emacs.c b/src/emacs.c
index 80a013b68df..d75a83ab9d8 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -33,6 +33,14 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include "lisp.h"
#include "sysstdio.h"
+#ifdef HAVE_ANDROID
+#include "androidterm.h"
+#endif
+
+#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
+#include "sfntfont.h"
+#endif
+
#ifdef WINDOWSNT
#include <fcntl.h>
#include <sys/socket.h>
@@ -137,6 +145,10 @@ extern char etext;
#include <sys/resource.h>
#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
always compiled (to provide treesit-available-p). */
#include "treesit.h"
@@ -411,7 +423,15 @@ using_utf8 (void)
the result is known in advance anyway... */
#if defined HAVE_WCHAR_H && !defined WINDOWSNT
wchar_t wc;
+#ifndef HAVE_ANDROID
mbstate_t mbs = { 0 };
+#else
+ mbstate_t mbs;
+
+ /* Not sure how mbstate works on Android, but this seems to be
+ required. */
+ memset (&mbs, 0, sizeof mbs);
+#endif
return mbrtowc (&wc, "\xc4\x80", 2, &mbs) == 2 && wc == 0x100;
#else
return false;
@@ -511,7 +531,8 @@ init_cmdargs (int argc, char **argv, int skip_args, char const *original_pwd)
{
Lisp_Object found;
int yes = openp (Vexec_path, Vinvocation_name, Vexec_suffixes,
- &found, make_fixnum (X_OK), false, false);
+ &found, make_fixnum (X_OK), false, false,
+ NULL);
if (yes == 1)
{
/* Add /: to the front of the name
@@ -724,6 +745,8 @@ argmatch (char **argv, int argc, const char *sstr, const char *lstr,
}
}
+#if !defined HAVE_ANDROID || defined ANDROID_STUBIFY
+
/* Find a name (absolute or relative) of the Emacs executable whose
name (as passed into this program) is ARGV0. Called early in
initialization by portable dumper loading code, so avoid Lisp and
@@ -823,6 +846,8 @@ find_emacs_executable (char const *argv0, ptrdiff_t *candidate_size)
#endif /* !WINDOWSNT */
}
+#endif
+
#ifdef HAVE_PDUMPER
static const char *
@@ -851,10 +876,38 @@ dump_error_to_string (int result)
}
}
-/* This function returns the Emacs executable. */
+/* This function returns the Emacs executable. DUMP_FILE is ignored
+ outside of Android. Otherwise, it is the name of the dump file to
+ use, or NULL if Emacs should look for a ``--dump-file'' argument
+ instead. */
+
static char *
-load_pdump (int argc, char **argv)
+load_pdump (int argc, char **argv, char *dump_file)
{
+#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
+ int skip_args = 0, result;
+
+ while (skip_args < argc - 1)
+ {
+ if (argmatch (argv, argc, "-dump-file", "--dump-file",
+ 6, &dump_file, &skip_args)
+ || argmatch (argv, argc, "--", NULL, 2, NULL,
+ &skip_args))
+ break;
+ skip_args++;
+ }
+
+ if (!dump_file)
+ return argv[0];
+
+ result = pdumper_load (dump_file, argv[0]);
+
+ if (result != PDUMPER_LOAD_SUCCESS)
+ fatal ("could not load dump file \"%s\": %s",
+ dump_file, dump_error_to_string (result));
+ return argv[0];
+#else
+
const char *const suffix = ".pdmp";
int result;
char *emacs_executable = argv[0];
@@ -885,7 +938,7 @@ load_pdump (int argc, char **argv)
/* Look for an explicitly-specified dump file. */
const char *path_exec = PATH_EXEC;
- char *dump_file = NULL;
+ dump_file = NULL;
int skip_args = 0;
while (skip_args < argc - 1)
{
@@ -1047,6 +1100,7 @@ load_pdump (int argc, char **argv)
xfree (dump_file);
return emacs_executable;
+#endif
}
#endif /* HAVE_PDUMPER */
@@ -1123,7 +1177,7 @@ load_seccomp (const char *file)
goto out;
}
struct stat stat;
- if (fstat (fd, &stat) != 0)
+ if (sys_fstat (fd, &stat) != 0)
{
emacs_perror ("fstat");
goto out;
@@ -1225,12 +1279,24 @@ maybe_load_seccomp (int argc, char **argv)
#endif /* SECCOMP_USABLE */
+#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
+int
+android_emacs_init (int argc, char **argv, char *dump_file)
+#else
int
main (int argc, char **argv)
+#endif
{
/* Variable near the bottom of the stack, and aligned appropriately
for pointers. */
void *stack_bottom_variable;
+ int old_argc;
+#if !(defined HAVE_ANDROID && !defined ANDROID_STUBIFY)
+ char *dump_file;
+
+ /* This is just a dummy argument used to avoid extra defines. */
+ dump_file = NULL;
+#endif
/* First, check whether we should apply a seccomp filter. This
should come at the very beginning to allow the filter to protect
@@ -1360,7 +1426,7 @@ main (int argc, char **argv)
#ifdef HAVE_PDUMPER
if (attempt_load_pdump)
- initial_emacs_executable = load_pdump (argc, argv);
+ initial_emacs_executable = load_pdump (argc, argv, dump_file);
#else
ptrdiff_t bufsize;
initial_emacs_executable = find_emacs_executable (argv[0], &bufsize);
@@ -1425,8 +1491,9 @@ main (int argc, char **argv)
bool only_version = false;
sort_args (argc, argv);
- argc = 0;
- while (argv[argc]) argc++;
+ old_argc = argc, argc = 0;
+ /* Don't allow going past argv. */
+ while (argc < old_argc && argv[argc]) argc++;
skip_args = 0;
if (argmatch (argv, argc, "-version", "--version", 3, NULL, &skip_args))
@@ -1934,6 +2001,9 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
#ifdef HAVE_WINDOW_SYSTEM
init_fringe_once (); /* Swap bitmaps if necessary. */
#endif /* HAVE_WINDOW_SYSTEM */
+#ifdef HAVE_TEXT_CONVERSION
+ syms_of_textconv ();
+#endif
}
init_alloc ();
@@ -2375,6 +2445,18 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
#endif
syms_of_fontset ();
#endif /* HAVE_HAIKU */
+#ifdef HAVE_ANDROID
+ syms_of_androidterm ();
+ syms_of_androidfns ();
+ syms_of_androidmenu ();
+ syms_of_fontset ();
+#if !defined ANDROID_STUBIFY
+ syms_of_androidfont ();
+ syms_of_androidselect ();
+ syms_of_sfntfont ();
+ syms_of_sfntfont_android ();
+#endif /* !ANDROID_STUBIFY */
+#endif /* HAVE_ANDROID */
syms_of_gnutls ();
@@ -2471,6 +2553,17 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
init_window ();
init_font ();
+#ifdef HAVE_ANDROID
+ init_androidmenu ();
+#endif
+
+#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
+ init_androidfont ();
+ init_androidselect ();
+ init_sfntfont ();
+ init_sfntfont_android ();
+#endif
+
if (!initialized)
{
char *file;
@@ -2525,6 +2618,16 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
safe_run_hooks (Qafter_pdump_load_hook);
#endif
+#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY && 0
+ /* This comes very late in the startup process because it requires
+ most of lisp/international to be loaded. This approach doesn't
+ work because normal-top-level runs and creates the initial frame
+ before fonts are initialized. So this is done in
+ normal-top-level instead. */
+ Vtop_level = list3 (Qprogn, Vtop_level,
+ list1 (Qandroid_enumerate_fonts));
+#endif
+
/* Enter editor command loop. This never returns. */
set_initial_minibuffer_mode ();
Frecursive_edit ();
@@ -2850,7 +2953,14 @@ killed. */
#ifndef WINDOWSNT
/* Do some checking before shutting down Emacs, because errors
can't be meaningfully reported afterwards. */
- if (!NILP (restart))
+ if (!NILP (restart)
+ /* Don't perform the following checks when Emacs is running as
+ an Android GUI application, because there the system is
+ relied on to restart Emacs. */
+#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
+ && !android_init_gui
+#endif
+ )
{
/* This is very unlikely, but it's possible to execute a binary
(on some systems) with no argv. */
@@ -2912,6 +3022,13 @@ killed. */
if (!NILP (restart))
{
turn_on_atimers (false);
+#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
+ /* Re-executing the Emacs process created by the system doesn't
+ work. Instead, schedule a restart for a few hundered
+ milliseconds and exit Emacs. */
+ if (android_init_gui)
+ android_restart_emacs ();
+#endif
#ifdef WINDOWSNT
if (w32_reexec_emacs (initial_cmdline, initial_wd) < 0)
#else
@@ -2952,7 +3069,7 @@ shut_down_emacs (int sig, Lisp_Object stuff)
Vinhibit_redisplay = Qt;
/* 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);
if (tpgrp != -1 && tpgrp == getpgrp ())
{
@@ -3471,6 +3588,7 @@ Special values:
`windows-nt' compiled as a native W32 application.
`cygwin' compiled using the Cygwin library.
`haiku' compiled for a Haiku system.
+ `android' compiled for Android.
Anything else (in Emacs 26, the possibilities are: aix, berkeley-unix,
hpux, usg-unix-v) indicates some sort of Unix system. */);
Vsystem_type = intern_c_string (SYSTEM_TYPE);