Update Android port

* etc/PROBLEMS: Document problem with default monospace font.
* src/fileio.c (check_mutable_filename): Check /content as well.
(Fcopy_file, Fdelete_directory_internal, Fdelete_file)
(Frename_file, Fadd_name_to_file, Fmake_symbolic_link)
(Fset_file_modes, Fset_file_times, Ffile_newer_than_file_p)
(write_region): Adjust accordingly.
(Fset_visited_file_modtime): Remove unnecessary restriction.
* src/filelock.c (make_lock_file_name): Don't interlock files
under /assets and /content.
* src/inotify.c (Finotify_add_watch): Fix typo.
This commit is contained in:
Po Lu 2023-03-05 14:53:12 +08:00
parent e0f4002161
commit 0760d5cc98
4 changed files with 106 additions and 20 deletions

View file

@ -3265,6 +3265,56 @@ Compose key to stop working.
On X Windows, users should not use Emacs configured with PGTK, since
this and many other problems do not exist on the regular X builds.
* Runtime problems specific to Android
** Text displayed in the default monospace font looks horrible.
Droid Sans Mono (the default Monospace font which comes with Android)
comes with instruction code designed for Microsoft's proprietary
TrueType font scaler. When this code is executed by Emacs to instruct
a glyph containing more than one component, it tries to address
"reference points" which are set to the values of two extra "phantom
points" in the glyph, that are a proprietary extension of the MS font
scaler.
Emacs does not support these extensions, and as a result characters
such as
ĥ
display incorrectly, with the right most edge of the `h' component
stretched very far out to the right, on some low density displays.
The solution is to replace the MS-specific hinting code in Droid Sans
Mono with automatically generated code from the FreeType project's
"ttfautohint" program. First, extract
'/system/fonts/DroidSansMono.ttf' from your device:
$ adb pull /system/fonts/DroidSansMono.ttf
/system/fonts/DroidSansMono.ttf: 1 file pulled, 0 skipped.
23.1 MB/s (90208 bytes in 0.004s)
install the "ttfautohint" program:
http://freetype.org/ttfautohint/
generate a font file with new hinting instructions:
$ ttfautohint DroidSansMono.ttf > DroidSansMono.ttf.rpl
and upload them to your device, either back to /system/fonts (which is
allowed by free versions of Android, such as Replicant):
$ adb root
$ adb remount
$ adb push DroidSansMono.ttf.rpl /system/fonts/DroidSansMono.ttf
or to the user fonts directory described in the "Android Fonts" node
of the Emacs manual. You may want to perform this procedure even if
you are not seeing problems with character display, as the
automatically generated instructions result in superior display
results that are easier to read.
* Build-time problems
** Configuration

View file

@ -147,18 +147,31 @@ static bool e_write (int, Lisp_Object, ptrdiff_t, ptrdiff_t,
/* Check that ENCODED does not lie on any special directory whose
contents are read only. Signal a `file-error' if it does. */
contents are read only. Signal a `file-error' if it does.
If WRITE, then don't check that the file lies on `/content' on
Android. This special exception allows writing to content
provider-supplied files. */
static void
check_mutable_filename (Lisp_Object encoded)
check_mutable_filename (Lisp_Object encoded, bool write)
{
#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
if (!strcmp (SSDATA (encoded), "/assets")
|| !strncmp (SSDATA (encoded), "/assets/",
sizeof "/assets/" - 1))
xsignal2 (Qfile_error,
build_string ("File lies on read-"
"only directory"),
build_string ("File lies on read-only directory"),
encoded);
if (write)
return;
if (!strcmp (SSDATA (encoded), "/content")
|| !strncmp (SSDATA (encoded), "/content/",
sizeof "/content/" - 1))
xsignal2 (Qfile_error,
build_string ("File lies on read-only directory"),
encoded);
#endif
}
@ -2228,7 +2241,7 @@ permissions. */)
encoded_file = ENCODE_FILE (file);
encoded_newname = ENCODE_FILE (newname);
check_mutable_filename (encoded_newname);
check_mutable_filename (encoded_newname, true);
#ifdef WINDOWSNT
if (NILP (ok_if_already_exists)
@ -2488,7 +2501,7 @@ DEFUN ("delete-directory-internal", Fdelete_directory_internal,
encoded_dir = ENCODE_FILE (directory);
dir = SSDATA (encoded_dir);
check_mutable_filename (encoded_dir);
check_mutable_filename (encoded_dir, false);
if (rmdir (dir) != 0)
report_file_error ("Removing directory", directory);
@ -2529,7 +2542,7 @@ With a prefix argument, TRASH is nil. */)
return call1 (Qmove_file_to_trash, filename);
encoded_file = ENCODE_FILE (filename);
check_mutable_filename (encoded_file);
check_mutable_filename (encoded_file, false);
if (unlink (SSDATA (encoded_file)) != 0 && errno != ENOENT)
report_file_error ("Removing old name", filename);
@ -2687,8 +2700,8 @@ This is what happens in interactive use with M-x. */)
encoded_file = ENCODE_FILE (file);
encoded_newname = ENCODE_FILE (newname);
check_mutable_filename (encoded_file);
check_mutable_filename (encoded_newname);
check_mutable_filename (encoded_file, false);
check_mutable_filename (encoded_newname, false);
bool plain_rename = (case_only_rename
|| (!NILP (ok_if_already_exists)
@ -2800,8 +2813,8 @@ This is what happens in interactive use with M-x. */)
encoded_file = ENCODE_FILE (file);
encoded_newname = ENCODE_FILE (newname);
check_mutable_filename (encoded_file);
check_mutable_filename (encoded_newname);
check_mutable_filename (encoded_file, false);
check_mutable_filename (encoded_newname, false);
if (link (SSDATA (encoded_file), SSDATA (encoded_newname)) == 0)
return Qnil;
@ -2855,8 +2868,8 @@ This happens for interactive use with M-x. */)
encoded_target = ENCODE_FILE (target);
encoded_linkname = ENCODE_FILE (linkname);
check_mutable_filename (encoded_target);
check_mutable_filename (encoded_linkname);
check_mutable_filename (encoded_target, false);
check_mutable_filename (encoded_linkname, false);
if (symlink (SSDATA (encoded_target), SSDATA (encoded_linkname)) == 0)
return Qnil;
@ -3598,7 +3611,7 @@ command from GNU Coreutils. */)
return call4 (handler, Qset_file_modes, absname, mode, flag);
encoded = ENCODE_FILE (absname);
check_mutable_filename (encoded);
check_mutable_filename (encoded, false);
char *fname = SSDATA (encoded);
mode_t imode = XFIXNUM (mode) & 07777;
if (fchmodat (AT_FDCWD, fname, imode, nofollow) != 0)
@ -3671,7 +3684,7 @@ TIMESTAMP is in the format of `current-time'. */)
return call4 (handler, Qset_file_times, absname, timestamp, flag);
Lisp_Object encoded_absname = ENCODE_FILE (absname);
check_mutable_filename (encoded_absname);
check_mutable_filename (encoded_absname, false);
if (utimensat (AT_FDCWD, SSDATA (encoded_absname), ts, nofollow) != 0)
{
@ -3722,7 +3735,6 @@ otherwise, if FILE2 does not exist, the answer is t. */)
return call3 (handler, Qfile_newer_than_file_p, absname1, absname2);
encoded = ENCODE_FILE (absname1);
check_mutable_filename (encoded);
int err1;
if (emacs_fstatat (AT_FDCWD, SSDATA (encoded), &st1, 0) == 0)
@ -5368,6 +5380,8 @@ write_region (Lisp_Object start, Lisp_Object end, Lisp_Object filename,
}
encoded_filename = ENCODE_FILE (filename);
check_mutable_filename (encoded_filename, false);
fn = SSDATA (encoded_filename);
open_flags = O_WRONLY | O_CREAT;
open_flags |= EQ (mustbenew, Qexcl) ? O_EXCL : !NILP (append) ? 0 : O_TRUNC;
@ -5942,7 +5956,6 @@ in `current-time' or an integer flag as returned by `visited-file-modtime'. */)
return call2 (handler, Qset_visited_file_modtime, Qnil);
encoded = ENCODE_FILE (filename);
check_mutable_filename (encoded);
if (emacs_fstatat (AT_FDCWD, SSDATA (encoded), &st, 0)
== 0)

View file

@ -659,8 +659,31 @@ lock_if_free (lock_info_type *clasher, Lisp_Object lfname)
static Lisp_Object
make_lock_file_name (Lisp_Object fn)
{
Lisp_Object lock_file_name = call1 (Qmake_lock_file_name,
Fexpand_file_name (fn, Qnil));
Lisp_Object lock_file_name;
#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
char *name;
#endif
fn = Fexpand_file_name (fn, Qnil);
#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
/* Files in /assets and /contents can't have lock files on Android
as these directories are fabrications of android.c, and backed by
read only data. */
name = SSDATA (fn);
if (strcmp (name, "/assets")
|| strcmp (name, "/assets/")
|| strcmp (name, "/content")
|| strcmp (name, "/content/")
|| strncmp (name, "/assets/", sizeof "/assets")
|| strncmp (name, "/content/", sizeof "/content"))
return Qnil;
#endif
lock_file_name = call1 (Qmake_lock_file_name, fn);
return !NILP (lock_file_name) ? ENCODE_FILE (lock_file_name) : Qnil;
}

View file

@ -445,7 +445,7 @@ IN_ONESHOT */)
|| strcmp (name, "/content")
|| strcmp (name, "/content/")
|| strncmp (name, "/assets/", sizeof "/assets")
|| strncmp (name, "/content", sizeof "/content"))
|| strncmp (name, "/content/", sizeof "/content"))
return Qnil;
#endif