diff options
| author | Yuuki Harano | 2021-07-04 22:37:03 +0900 |
|---|---|---|
| committer | Yuuki Harano | 2021-07-04 22:37:03 +0900 |
| commit | 492a0ae5927eda83b65dd08d3e1655a62fc2c43d (patch) | |
| tree | 8bb6a39483236c3a4574c93b37b0a81b8f639bb0 /src | |
| parent | 01b0a909b5ca858a09484821cc866127652f4153 (diff) | |
| parent | 2f2afa0b310bbce43a8703f5467b2638082abdd9 (diff) | |
| download | emacs-492a0ae5927eda83b65dd08d3e1655a62fc2c43d.tar.gz emacs-492a0ae5927eda83b65dd08d3e1655a62fc2c43d.zip | |
Merge branch 'master' of git.sv.gnu.org:/srv/git/emacs into feature/pgtk
Diffstat (limited to 'src')
| -rw-r--r-- | src/Makefile.in | 2 | ||||
| -rw-r--r-- | src/callproc.c | 61 | ||||
| -rw-r--r-- | src/comp.c | 28 | ||||
| -rw-r--r-- | src/emacs.c | 16 | ||||
| -rw-r--r-- | src/lread.c | 8 | ||||
| -rw-r--r-- | src/minibuf.c | 2 | ||||
| -rw-r--r-- | src/nsfont.m | 46 | ||||
| -rw-r--r-- | src/nsmenu.m | 69 | ||||
| -rw-r--r-- | src/nsterm.h | 8 | ||||
| -rw-r--r-- | src/nsterm.m | 143 | ||||
| -rw-r--r-- | src/process.c | 2 | ||||
| -rw-r--r-- | src/process.h | 2 | ||||
| -rw-r--r-- | src/sysdep.c | 2 | ||||
| -rw-r--r-- | src/thread.c | 17 | ||||
| -rw-r--r-- | src/xgselect.c | 16 |
15 files changed, 225 insertions, 197 deletions
diff --git a/src/Makefile.in b/src/Makefile.in index 40a423d6a1e..8c28e825da2 100644 --- a/src/Makefile.in +++ b/src/Makefile.in | |||
| @@ -55,7 +55,7 @@ lwlibdir = ../lwlib | |||
| 55 | # Configuration files for .o files to depend on. | 55 | # Configuration files for .o files to depend on. |
| 56 | config_h = config.h $(srcdir)/conf_post.h | 56 | config_h = config.h $(srcdir)/conf_post.h |
| 57 | 57 | ||
| 58 | ## ns-app if HAVE_NS, else empty. | 58 | ## ns-app if NS self contained app, else empty. |
| 59 | OTHER_FILES = @OTHER_FILES@ | 59 | OTHER_FILES = @OTHER_FILES@ |
| 60 | 60 | ||
| 61 | ## Flags to pass for profiling builds | 61 | ## Flags to pass for profiling builds |
diff --git a/src/callproc.c b/src/callproc.c index e44e243680d..675b78daf3e 100644 --- a/src/callproc.c +++ b/src/callproc.c | |||
| @@ -116,11 +116,13 @@ static CHILD_SETUP_TYPE child_setup (int, int, int, char **, char **, | |||
| 116 | const char *); | 116 | const char *); |
| 117 | 117 | ||
| 118 | /* Return the current buffer's working directory, or the home | 118 | /* Return the current buffer's working directory, or the home |
| 119 | directory if it's unreachable, as a string suitable for a system call. | 119 | directory if it's unreachable. If ENCODE is true, return as a string |
| 120 | Signal an error if the result would not be an accessible directory. */ | 120 | suitable for a system call; otherwise, return a string in its |
| 121 | internal representation. Signal an error if the result would not be | ||
| 122 | an accessible directory. */ | ||
| 121 | 123 | ||
| 122 | Lisp_Object | 124 | Lisp_Object |
| 123 | encode_current_directory (void) | 125 | get_current_directory (bool encode) |
| 124 | { | 126 | { |
| 125 | Lisp_Object curdir = BVAR (current_buffer, directory); | 127 | Lisp_Object curdir = BVAR (current_buffer, directory); |
| 126 | Lisp_Object dir = Funhandled_file_name_directory (curdir); | 128 | Lisp_Object dir = Funhandled_file_name_directory (curdir); |
| @@ -131,12 +133,12 @@ encode_current_directory (void) | |||
| 131 | dir = build_string ("~"); | 133 | dir = build_string ("~"); |
| 132 | 134 | ||
| 133 | dir = expand_and_dir_to_file (dir); | 135 | dir = expand_and_dir_to_file (dir); |
| 134 | dir = ENCODE_FILE (remove_slash_colon (dir)); | 136 | Lisp_Object encoded_dir = ENCODE_FILE (remove_slash_colon (dir)); |
| 135 | 137 | ||
| 136 | if (! file_accessible_directory_p (dir)) | 138 | if (! file_accessible_directory_p (encoded_dir)) |
| 137 | report_file_error ("Setting current directory", curdir); | 139 | report_file_error ("Setting current directory", curdir); |
| 138 | 140 | ||
| 139 | return dir; | 141 | return encode ? encoded_dir : dir; |
| 140 | } | 142 | } |
| 141 | 143 | ||
| 142 | /* If P is reapable, record it as a deleted process and kill it. | 144 | /* If P is reapable, record it as a deleted process and kill it. |
| @@ -225,8 +227,9 @@ DEFUN ("call-process", Fcall_process, Scall_process, 1, MANY, 0, | |||
| 225 | The remaining arguments are optional. | 227 | The remaining arguments are optional. |
| 226 | 228 | ||
| 227 | The program's input comes from file INFILE (nil means `null-device'). | 229 | The program's input comes from file INFILE (nil means `null-device'). |
| 228 | If you want to make the input come from an Emacs buffer, use | 230 | If INFILE is a relative path, it will be looked for relative to the |
| 229 | `call-process-region' instead. | 231 | directory where the process is run (see below). If you want to make the |
| 232 | input come from an Emacs buffer, use `call-process-region' instead. | ||
| 230 | 233 | ||
| 231 | Third argument DESTINATION specifies how to handle program's output. | 234 | Third argument DESTINATION specifies how to handle program's output. |
| 232 | If DESTINATION is a buffer, or t that stands for the current buffer, | 235 | If DESTINATION is a buffer, or t that stands for the current buffer, |
| @@ -270,7 +273,9 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 270 | 273 | ||
| 271 | if (nargs >= 2 && ! NILP (args[1])) | 274 | if (nargs >= 2 && ! NILP (args[1])) |
| 272 | { | 275 | { |
| 273 | infile = Fexpand_file_name (args[1], BVAR (current_buffer, directory)); | 276 | /* Expand infile relative to the current buffer's current |
| 277 | directory, or its unhandled equivalent ("~"). */ | ||
| 278 | infile = Fexpand_file_name (args[1], get_current_directory (false)); | ||
| 274 | CHECK_STRING (infile); | 279 | CHECK_STRING (infile); |
| 275 | } | 280 | } |
| 276 | else | 281 | else |
| @@ -439,7 +444,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, | |||
| 439 | buffer's current directory, or its unhandled equivalent. We | 444 | buffer's current directory, or its unhandled equivalent. We |
| 440 | can't just have the child check for an error when it does the | 445 | can't just have the child check for an error when it does the |
| 441 | chdir, since it's in a vfork. */ | 446 | chdir, since it's in a vfork. */ |
| 442 | current_dir = encode_current_directory (); | 447 | current_dir = get_current_directory (true); |
| 443 | 448 | ||
| 444 | if (STRINGP (error_file)) | 449 | if (STRINGP (error_file)) |
| 445 | { | 450 | { |
| @@ -1661,32 +1666,15 @@ make_environment_block (Lisp_Object current_dir) | |||
| 1661 | void | 1666 | void |
| 1662 | init_callproc_1 (void) | 1667 | init_callproc_1 (void) |
| 1663 | { | 1668 | { |
| 1664 | #ifdef HAVE_NS | 1669 | Vdata_directory = decode_env_path ("EMACSDATA", PATH_DATA, 0); |
| 1665 | const char *etc_dir = ns_etc_directory (); | ||
| 1666 | const char *path_exec = ns_exec_path (); | ||
| 1667 | #endif | ||
| 1668 | |||
| 1669 | Vdata_directory = decode_env_path ("EMACSDATA", | ||
| 1670 | #ifdef HAVE_NS | ||
| 1671 | etc_dir ? etc_dir : | ||
| 1672 | #endif | ||
| 1673 | PATH_DATA, 0); | ||
| 1674 | Vdata_directory = Ffile_name_as_directory (Fcar (Vdata_directory)); | 1670 | Vdata_directory = Ffile_name_as_directory (Fcar (Vdata_directory)); |
| 1675 | 1671 | ||
| 1676 | Vdoc_directory = decode_env_path ("EMACSDOC", | 1672 | Vdoc_directory = decode_env_path ("EMACSDOC", PATH_DOC, 0); |
| 1677 | #ifdef HAVE_NS | ||
| 1678 | etc_dir ? etc_dir : | ||
| 1679 | #endif | ||
| 1680 | PATH_DOC, 0); | ||
| 1681 | Vdoc_directory = Ffile_name_as_directory (Fcar (Vdoc_directory)); | 1673 | Vdoc_directory = Ffile_name_as_directory (Fcar (Vdoc_directory)); |
| 1682 | 1674 | ||
| 1683 | /* Check the EMACSPATH environment variable, defaulting to the | 1675 | /* Check the EMACSPATH environment variable, defaulting to the |
| 1684 | PATH_EXEC path from epaths.h. */ | 1676 | PATH_EXEC path from epaths.h. */ |
| 1685 | Vexec_path = decode_env_path ("EMACSPATH", | 1677 | Vexec_path = decode_env_path ("EMACSPATH", PATH_EXEC, 0); |
| 1686 | #ifdef HAVE_NS | ||
| 1687 | path_exec ? path_exec : | ||
| 1688 | #endif | ||
| 1689 | PATH_EXEC, 0); | ||
| 1690 | Vexec_directory = Ffile_name_as_directory (Fcar (Vexec_path)); | 1678 | Vexec_directory = Ffile_name_as_directory (Fcar (Vexec_path)); |
| 1691 | /* FIXME? For ns, path_exec should go at the front? */ | 1679 | /* FIXME? For ns, path_exec should go at the front? */ |
| 1692 | Vexec_path = nconc2 (decode_env_path ("PATH", "", 0), Vexec_path); | 1680 | Vexec_path = nconc2 (decode_env_path ("PATH", "", 0), Vexec_path); |
| @@ -1701,10 +1689,6 @@ init_callproc (void) | |||
| 1701 | 1689 | ||
| 1702 | char *sh; | 1690 | char *sh; |
| 1703 | Lisp_Object tempdir; | 1691 | Lisp_Object tempdir; |
| 1704 | #ifdef HAVE_NS | ||
| 1705 | if (data_dir == 0) | ||
| 1706 | data_dir = ns_etc_directory () != 0; | ||
| 1707 | #endif | ||
| 1708 | 1692 | ||
| 1709 | if (!NILP (Vinstallation_directory)) | 1693 | if (!NILP (Vinstallation_directory)) |
| 1710 | { | 1694 | { |
| @@ -1716,15 +1700,8 @@ init_callproc (void) | |||
| 1716 | /* MSDOS uses wrapped binaries, so don't do this. */ | 1700 | /* MSDOS uses wrapped binaries, so don't do this. */ |
| 1717 | if (NILP (Fmember (tem, Vexec_path))) | 1701 | if (NILP (Fmember (tem, Vexec_path))) |
| 1718 | { | 1702 | { |
| 1719 | #ifdef HAVE_NS | ||
| 1720 | const char *path_exec = ns_exec_path (); | ||
| 1721 | #endif | ||
| 1722 | /* Running uninstalled, so default to tem rather than PATH_EXEC. */ | 1703 | /* Running uninstalled, so default to tem rather than PATH_EXEC. */ |
| 1723 | Vexec_path = decode_env_path ("EMACSPATH", | 1704 | Vexec_path = decode_env_path ("EMACSPATH", SSDATA (tem), 0); |
| 1724 | #ifdef HAVE_NS | ||
| 1725 | path_exec ? path_exec : | ||
| 1726 | #endif | ||
| 1727 | SSDATA (tem), 0); | ||
| 1728 | Vexec_path = nconc2 (decode_env_path ("PATH", "", 0), Vexec_path); | 1705 | Vexec_path = nconc2 (decode_env_path ("PATH", "", 0), Vexec_path); |
| 1729 | } | 1706 | } |
| 1730 | 1707 | ||
diff --git a/src/comp.c b/src/comp.c index ea059526274..c3803464827 100644 --- a/src/comp.c +++ b/src/comp.c | |||
| @@ -744,8 +744,34 @@ hash_native_abi (void) | |||
| 744 | Vsystem_configuration_options), | 744 | Vsystem_configuration_options), |
| 745 | Fmapconcat (intern_c_string ("comp--subr-signature"), | 745 | Fmapconcat (intern_c_string ("comp--subr-signature"), |
| 746 | Vcomp_subr_list, build_string ("")))); | 746 | Vcomp_subr_list, build_string ("")))); |
| 747 | |||
| 748 | Lisp_Object version = Vemacs_version; | ||
| 749 | |||
| 750 | #ifdef NS_SELF_CONTAINED | ||
| 751 | /* MacOS self contained app bundles do not like having dots in the | ||
| 752 | directory names under the Contents/Frameworks directory, so | ||
| 753 | convert them to underscores. */ | ||
| 754 | version = STRING_MULTIBYTE (Vemacs_version) | ||
| 755 | ? make_uninit_multibyte_string (SCHARS (Vemacs_version), | ||
| 756 | SBYTES (Vemacs_version)) | ||
| 757 | : make_uninit_string (SBYTES (Vemacs_version)); | ||
| 758 | |||
| 759 | const unsigned char *from = SDATA (Vemacs_version); | ||
| 760 | unsigned char *to = SDATA (version); | ||
| 761 | |||
| 762 | while (from < SDATA (Vemacs_version) + SBYTES (Vemacs_version)) | ||
| 763 | { | ||
| 764 | unsigned char c = *from++; | ||
| 765 | |||
| 766 | if (c == '.') | ||
| 767 | c = '_'; | ||
| 768 | |||
| 769 | *to++ = c; | ||
| 770 | } | ||
| 771 | #endif | ||
| 772 | |||
| 747 | Vcomp_native_version_dir = | 773 | Vcomp_native_version_dir = |
| 748 | concat3 (Vemacs_version, build_string ("-"), Vcomp_abi_hash); | 774 | concat3 (version, build_string ("-"), Vcomp_abi_hash); |
| 749 | } | 775 | } |
| 750 | 776 | ||
| 751 | static void | 777 | static void |
diff --git a/src/emacs.c b/src/emacs.c index c8bc0ba4bec..fd265b41b03 100644 --- a/src/emacs.c +++ b/src/emacs.c | |||
| @@ -835,7 +835,13 @@ load_pdump (int argc, char **argv) | |||
| 835 | NULL | 835 | NULL |
| 836 | #endif | 836 | #endif |
| 837 | ; | 837 | ; |
| 838 | const char *argv0_base = "emacs"; | 838 | const char *argv0_base = |
| 839 | #ifdef NS_SELF_CONTAINED | ||
| 840 | "Emacs" | ||
| 841 | #else | ||
| 842 | "emacs" | ||
| 843 | #endif | ||
| 844 | ; | ||
| 839 | 845 | ||
| 840 | /* TODO: maybe more thoroughly scrub process environment in order to | 846 | /* TODO: maybe more thoroughly scrub process environment in order to |
| 841 | make this use case (loading a dump file in an unexeced emacs) | 847 | make this use case (loading a dump file in an unexeced emacs) |
| @@ -912,6 +918,8 @@ load_pdump (int argc, char **argv) | |||
| 912 | /* On MS-Windows, PATH_EXEC normally starts with a literal | 918 | /* On MS-Windows, PATH_EXEC normally starts with a literal |
| 913 | "%emacs_dir%", so it will never work without some tweaking. */ | 919 | "%emacs_dir%", so it will never work without some tweaking. */ |
| 914 | path_exec = w32_relocate (path_exec); | 920 | path_exec = w32_relocate (path_exec); |
| 921 | #elif defined (HAVE_NS) | ||
| 922 | path_exec = ns_relocate (path_exec); | ||
| 915 | #endif | 923 | #endif |
| 916 | 924 | ||
| 917 | /* Look for "emacs.pdmp" in PATH_EXEC. We hardcode "emacs" in | 925 | /* Look for "emacs.pdmp" in PATH_EXEC. We hardcode "emacs" in |
| @@ -929,6 +937,7 @@ load_pdump (int argc, char **argv) | |||
| 929 | } | 937 | } |
| 930 | sprintf (dump_file, "%s%c%s%s", | 938 | sprintf (dump_file, "%s%c%s%s", |
| 931 | path_exec, DIRECTORY_SEP, argv0_base, suffix); | 939 | path_exec, DIRECTORY_SEP, argv0_base, suffix); |
| 940 | #if !defined (NS_SELF_CONTAINED) | ||
| 932 | /* Assume the Emacs binary lives in a sibling directory as set up by | 941 | /* Assume the Emacs binary lives in a sibling directory as set up by |
| 933 | the default installation configuration. */ | 942 | the default installation configuration. */ |
| 934 | const char *go_up = "../../../../bin/"; | 943 | const char *go_up = "../../../../bin/"; |
| @@ -943,6 +952,7 @@ load_pdump (int argc, char **argv) | |||
| 943 | sprintf (emacs_executable, "%s%c%s%s%s", | 952 | sprintf (emacs_executable, "%s%c%s%s%s", |
| 944 | path_exec, DIRECTORY_SEP, go_up, argv0_base, | 953 | path_exec, DIRECTORY_SEP, go_up, argv0_base, |
| 945 | strip_suffix ? strip_suffix : ""); | 954 | strip_suffix ? strip_suffix : ""); |
| 955 | #endif | ||
| 946 | result = pdumper_load (dump_file, emacs_executable); | 956 | result = pdumper_load (dump_file, emacs_executable); |
| 947 | 957 | ||
| 948 | if (result == PDUMPER_LOAD_FILE_NOT_FOUND) | 958 | if (result == PDUMPER_LOAD_FILE_NOT_FOUND) |
| @@ -2975,7 +2985,11 @@ decode_env_path (const char *evarname, const char *defalt, bool empty) | |||
| 2975 | path = 0; | 2985 | path = 0; |
| 2976 | if (!path) | 2986 | if (!path) |
| 2977 | { | 2987 | { |
| 2988 | #ifdef NS_SELF_CONTAINED | ||
| 2989 | path = ns_relocate (defalt); | ||
| 2990 | #else | ||
| 2978 | path = defalt; | 2991 | path = defalt; |
| 2992 | #endif | ||
| 2979 | #ifdef WINDOWSNT | 2993 | #ifdef WINDOWSNT |
| 2980 | defaulted = 1; | 2994 | defaulted = 1; |
| 2981 | #endif | 2995 | #endif |
diff --git a/src/lread.c b/src/lread.c index 0b33fd0f254..a6c2db5d994 100644 --- a/src/lread.c +++ b/src/lread.c | |||
| @@ -4769,14 +4769,8 @@ load_path_default (void) | |||
| 4769 | return decode_env_path (0, PATH_DUMPLOADSEARCH, 0); | 4769 | return decode_env_path (0, PATH_DUMPLOADSEARCH, 0); |
| 4770 | 4770 | ||
| 4771 | Lisp_Object lpath = Qnil; | 4771 | Lisp_Object lpath = Qnil; |
| 4772 | const char *normal = PATH_LOADSEARCH; | ||
| 4773 | const char *loadpath = NULL; | ||
| 4774 | 4772 | ||
| 4775 | #ifdef HAVE_NS | 4773 | lpath = decode_env_path (0, PATH_LOADSEARCH, 0); |
| 4776 | loadpath = ns_load_path (); | ||
| 4777 | #endif | ||
| 4778 | |||
| 4779 | lpath = decode_env_path (0, loadpath ? loadpath : normal, 0); | ||
| 4780 | 4774 | ||
| 4781 | if (!NILP (Vinstallation_directory)) | 4775 | if (!NILP (Vinstallation_directory)) |
| 4782 | { | 4776 | { |
diff --git a/src/minibuf.c b/src/minibuf.c index 00069eabbe5..1b842b77211 100644 --- a/src/minibuf.c +++ b/src/minibuf.c | |||
| @@ -1210,7 +1210,7 @@ read_minibuf_unwind (void) | |||
| 1210 | WINDOW_FRAME (XWINDOW (minibuf_window)))) | 1210 | WINDOW_FRAME (XWINDOW (minibuf_window)))) |
| 1211 | Fset_frame_selected_window (selected_frame, prev, Qnil); | 1211 | Fset_frame_selected_window (selected_frame, prev, Qnil); |
| 1212 | } | 1212 | } |
| 1213 | else | 1213 | else if (WINDOW_LIVE_P (calling_window)) |
| 1214 | Fset_frame_selected_window (calling_frame, calling_window, Qnil); | 1214 | Fset_frame_selected_window (calling_frame, calling_window, Qnil); |
| 1215 | } | 1215 | } |
| 1216 | 1216 | ||
diff --git a/src/nsfont.m b/src/nsfont.m index f4f0d281674..5a9cdfebc01 100644 --- a/src/nsfont.m +++ b/src/nsfont.m | |||
| @@ -277,30 +277,36 @@ ns_ascii_average_width (NSFont *sfont) | |||
| 277 | 277 | ||
| 278 | 278 | ||
| 279 | /* Return whether set1 covers set2 to a reasonable extent given by pct. | 279 | /* Return whether set1 covers set2 to a reasonable extent given by pct. |
| 280 | We check, out of each 16 Unicode char range containing chars in set2, | 280 | |
| 281 | whether at least one character is present in set1. | 281 | The GNUstep bitmap representation doesn't match Apple's |
| 282 | This must be true for pct of the pairs to consider it covering. */ | 282 | description. It appears to be a single block of bytes, not broken |
| 283 | up into planes, where the last byte contains the highest character | ||
| 284 | the character set supports. */ | ||
| 283 | static BOOL | 285 | static BOOL |
| 284 | ns_charset_covers(NSCharacterSet *set1, NSCharacterSet *set2, float pct) | 286 | ns_charset_covers(NSCharacterSet *set1, NSCharacterSet *set2, float pct) |
| 285 | { | 287 | { |
| 286 | const unsigned short *bytes1 = [[set1 bitmapRepresentation] bytes]; | 288 | NSData *font = [set1 bitmapRepresentation]; |
| 287 | const unsigned short *bytes2 = [[set2 bitmapRepresentation] bytes]; | 289 | NSData *script = [set2 bitmapRepresentation]; |
| 288 | int i, off = 0, tot = 0; | ||
| 289 | 290 | ||
| 290 | /* Work around what appears to be a GNUstep bug. | 291 | uint8_t *fontPlane = (uint8_t *)[font bytes]; |
| 291 | See <https://bugs.gnu.org/11853>. */ | 292 | uint8_t *scriptPlane = (uint8_t *)[script bytes]; |
| 292 | if (! (bytes1 && bytes2)) | ||
| 293 | return NO; | ||
| 294 | 293 | ||
| 295 | for (i=0; i<4096; i++, bytes1++, bytes2++) | 294 | int covered = 0, total = 0; |
| 296 | if (*bytes2) | 295 | |
| 297 | { | 296 | for (ptrdiff_t b = 0 ; b < [script length] ; b++) |
| 298 | tot++; | 297 | for (int i = 0 ; i < 8 ; i++) |
| 299 | if (*bytes1 == 0) // *bytes1 & *bytes2 != *bytes2 | 298 | { |
| 300 | off++; | 299 | if (*(scriptPlane + b) & (1 << i)) |
| 301 | } | 300 | { |
| 302 | // fprintf(stderr, "off = %d\ttot = %d\n", off,tot); | 301 | total++; |
| 303 | return (float)off / tot < 1.0F - pct; | 302 | |
| 303 | if (b < [font length] | ||
| 304 | && *(fontPlane + b) & (1 << i)) | ||
| 305 | covered++; | ||
| 306 | } | ||
| 307 | } | ||
| 308 | |||
| 309 | return (float)covered / total >= 1.0F - pct; | ||
| 304 | } | 310 | } |
| 305 | 311 | ||
| 306 | 312 | ||
| @@ -700,7 +706,7 @@ nsfont_open (struct frame *f, Lisp_Object font_entity, int pixel_size) | |||
| 700 | when setting family in ns_spec_to_descriptor(). */ | 706 | when setting family in ns_spec_to_descriptor(). */ |
| 701 | if (ns_attribute_fvalue (fontDesc, NSFontWeightTrait) > 0.50F) | 707 | if (ns_attribute_fvalue (fontDesc, NSFontWeightTrait) > 0.50F) |
| 702 | traits |= NSBoldFontMask; | 708 | traits |= NSBoldFontMask; |
| 703 | if (fabs (ns_attribute_fvalue (fontDesc, NSFontSlantTrait) > 0.05F)) | 709 | if (ns_attribute_fvalue (fontDesc, NSFontSlantTrait) > 0.05F) |
| 704 | traits |= NSItalicFontMask; | 710 | traits |= NSItalicFontMask; |
| 705 | 711 | ||
| 706 | /* see https://web.archive.org/web/20100201175731/http://cocoadev.com/forums/comments.php?DiscussionID=74 */ | 712 | /* see https://web.archive.org/web/20100201175731/http://cocoadev.com/forums/comments.php?DiscussionID=74 */ |
diff --git a/src/nsmenu.m b/src/nsmenu.m index 24aa5a0ac11..1b03fe91a8b 100644 --- a/src/nsmenu.m +++ b/src/nsmenu.m | |||
| @@ -73,7 +73,7 @@ free_frame_menubar (struct frame *f) | |||
| 73 | id menu = [NSApp mainMenu]; | 73 | id menu = [NSApp mainMenu]; |
| 74 | for (int i = [menu numberOfItems] - 1 ; i >= 0; i--) | 74 | for (int i = [menu numberOfItems] - 1 ; i >= 0; i--) |
| 75 | { | 75 | { |
| 76 | NSMenuItem *item = [menu itemAtIndex:i]; | 76 | NSMenuItem *item = (NSMenuItem *)[menu itemAtIndex:i]; |
| 77 | NSString *title = [item title]; | 77 | NSString *title = [item title]; |
| 78 | 78 | ||
| 79 | if ([ns_app_name isEqualToString:title]) | 79 | if ([ns_app_name isEqualToString:title]) |
| @@ -358,8 +358,12 @@ ns_update_menubar (struct frame *f, bool deep_p) | |||
| 358 | if (i < [menu numberOfItems]) | 358 | if (i < [menu numberOfItems]) |
| 359 | { | 359 | { |
| 360 | NSString *titleStr = [NSString stringWithUTF8String: wv->name]; | 360 | NSString *titleStr = [NSString stringWithUTF8String: wv->name]; |
| 361 | NSMenuItem *item = [menu itemAtIndex:i]; | 361 | NSMenuItem *item = (NSMenuItem *)[menu itemAtIndex:i]; |
| 362 | submenu = (EmacsMenu*)[item submenu]; | 362 | submenu = (EmacsMenu *)[item submenu]; |
| 363 | |||
| 364 | #ifdef NS_IMPL_GNUSTEP | ||
| 365 | [submenu close]; | ||
| 366 | #endif | ||
| 363 | 367 | ||
| 364 | [item setTitle:titleStr]; | 368 | [item setTitle:titleStr]; |
| 365 | [submenu setTitle:titleStr]; | 369 | [submenu setTitle:titleStr]; |
| @@ -368,8 +372,10 @@ ns_update_menubar (struct frame *f, bool deep_p) | |||
| 368 | else | 372 | else |
| 369 | submenu = [menu addSubmenuWithTitle: wv->name]; | 373 | submenu = [menu addSubmenuWithTitle: wv->name]; |
| 370 | 374 | ||
| 375 | #ifdef NS_IMPL_COCOA | ||
| 371 | if ([[submenu title] isEqualToString:@"Help"]) | 376 | if ([[submenu title] isEqualToString:@"Help"]) |
| 372 | [NSApp setHelpMenu:submenu]; | 377 | [NSApp setHelpMenu:submenu]; |
| 378 | #endif | ||
| 373 | 379 | ||
| 374 | if (deep_p) | 380 | if (deep_p) |
| 375 | [submenu fillWithWidgetValue: wv->contents]; | 381 | [submenu fillWithWidgetValue: wv->contents]; |
| @@ -380,6 +386,12 @@ ns_update_menubar (struct frame *f, bool deep_p) | |||
| 380 | while (i < [menu numberOfItems]) | 386 | while (i < [menu numberOfItems]) |
| 381 | { | 387 | { |
| 382 | /* Remove any extra items. */ | 388 | /* Remove any extra items. */ |
| 389 | #ifdef NS_IMPL_GNUSTEP | ||
| 390 | NSMenuItem *item = (NSMenuItem *)[menu itemAtIndex:i]; | ||
| 391 | EmacsMenu *submenu = (EmacsMenu *)[item submenu]; | ||
| 392 | [submenu close]; | ||
| 393 | #endif | ||
| 394 | |||
| 383 | [menu removeItemAtIndex:i]; | 395 | [menu removeItemAtIndex:i]; |
| 384 | } | 396 | } |
| 385 | 397 | ||
| @@ -472,7 +484,7 @@ set_frame_menubar (struct frame *f, bool deep_p) | |||
| 472 | 484 | ||
| 473 | if (menu_separator_name_p (wv->name)) | 485 | if (menu_separator_name_p (wv->name)) |
| 474 | { | 486 | { |
| 475 | item = [NSMenuItem separatorItem]; | 487 | item = (NSMenuItem *)[NSMenuItem separatorItem]; |
| 476 | } | 488 | } |
| 477 | else | 489 | else |
| 478 | { | 490 | { |
| @@ -534,7 +546,7 @@ set_frame_menubar (struct frame *f, bool deep_p) | |||
| 534 | needsUpdate = YES; | 546 | needsUpdate = YES; |
| 535 | } | 547 | } |
| 536 | 548 | ||
| 537 | 549 | #ifdef NS_IMPL_COCOA | |
| 538 | typedef struct { | 550 | typedef struct { |
| 539 | const char *from, *to; | 551 | const char *from, *to; |
| 540 | } subst_t; | 552 | } subst_t; |
| @@ -591,17 +603,18 @@ prettify_key (const char *key) | |||
| 591 | xfree (buf); | 603 | xfree (buf); |
| 592 | return SSDATA (result); | 604 | return SSDATA (result); |
| 593 | } | 605 | } |
| 606 | #endif /* NS_IMPL_COCOA */ | ||
| 594 | 607 | ||
| 595 | - (void)fillWithWidgetValue: (void *)wvptr | 608 | - (void)fillWithWidgetValue: (void *)wvptr |
| 596 | { | 609 | { |
| 597 | widget_value *first_wv = (widget_value *)wvptr; | 610 | widget_value *first_wv = (widget_value *)wvptr; |
| 598 | NSFont *menuFont = [NSFont menuFontOfSize:0]; | ||
| 599 | NSDictionary *attributes = nil; | 611 | NSDictionary *attributes = nil; |
| 600 | 612 | ||
| 601 | #ifdef NS_IMPL_COCOA | 613 | #ifdef NS_IMPL_COCOA |
| 602 | /* Cocoa doesn't allow multi-key sequences in its menu display, so | 614 | /* Cocoa doesn't allow multi-key sequences in its menu display, so |
| 603 | work around it by using tabs to split the title into two | 615 | work around it by using tabs to split the title into two |
| 604 | columns. */ | 616 | columns. */ |
| 617 | NSFont *menuFont = [NSFont menuFontOfSize:0]; | ||
| 605 | NSDictionary *font_attribs = @{NSFontAttributeName: menuFont}; | 618 | NSDictionary *font_attribs = @{NSFontAttributeName: menuFont}; |
| 606 | CGFloat maxNameWidth = 0; | 619 | CGFloat maxNameWidth = 0; |
| 607 | CGFloat maxKeyWidth = 0; | 620 | CGFloat maxKeyWidth = 0; |
| @@ -672,9 +685,9 @@ prettify_key (const char *key) | |||
| 672 | - (EmacsMenu *)addSubmenuWithTitle: (const char *)title | 685 | - (EmacsMenu *)addSubmenuWithTitle: (const char *)title |
| 673 | { | 686 | { |
| 674 | NSString *titleStr = [NSString stringWithUTF8String: title]; | 687 | NSString *titleStr = [NSString stringWithUTF8String: title]; |
| 675 | NSMenuItem *item = [self addItemWithTitle: titleStr | 688 | NSMenuItem *item = (NSMenuItem *)[self addItemWithTitle: titleStr |
| 676 | action: (SEL)nil /*@selector (menuDown:) */ | 689 | action: (SEL)nil |
| 677 | keyEquivalent: @""]; | 690 | keyEquivalent: @""]; |
| 678 | EmacsMenu *submenu = [[EmacsMenu alloc] initWithTitle: titleStr]; | 691 | EmacsMenu *submenu = [[EmacsMenu alloc] initWithTitle: titleStr]; |
| 679 | [self setSubmenu: submenu forItem: item]; | 692 | [self setSubmenu: submenu forItem: item]; |
| 680 | [submenu release]; | 693 | [submenu release]; |
| @@ -711,6 +724,44 @@ prettify_key (const char *key) | |||
| 711 | : Qnil; | 724 | : Qnil; |
| 712 | } | 725 | } |
| 713 | 726 | ||
| 727 | #ifdef NS_IMPL_GNUSTEP | ||
| 728 | - (void) close | ||
| 729 | { | ||
| 730 | /* Close all the submenus. This has the unfortunate side-effect of | ||
| 731 | breaking tear-off menus, however if we don't do this then we get | ||
| 732 | a crash when the menus are removed during updates. */ | ||
| 733 | for (int i = 0 ; i < [self numberOfItems] ; i++) | ||
| 734 | { | ||
| 735 | NSMenuItem *item = [self itemAtIndex:i]; | ||
| 736 | if ([item hasSubmenu]) | ||
| 737 | [(EmacsMenu *)[item submenu] close]; | ||
| 738 | } | ||
| 739 | |||
| 740 | [super close]; | ||
| 741 | } | ||
| 742 | |||
| 743 | /* GNUstep seems to have a number of required methods in | ||
| 744 | NSMenuDelegate that are optional in Cocoa. */ | ||
| 745 | |||
| 746 | - (void) menuWillOpen:(NSMenu *)menu | ||
| 747 | { | ||
| 748 | } | ||
| 749 | |||
| 750 | - (void) menuDidClose:(NSMenu *)menu | ||
| 751 | { | ||
| 752 | } | ||
| 753 | |||
| 754 | - (NSRect)confinementRectForMenu:(NSMenu *)menu | ||
| 755 | onScreen:(NSScreen *)screen | ||
| 756 | { | ||
| 757 | return NSZeroRect; | ||
| 758 | } | ||
| 759 | |||
| 760 | - (void)menu:(NSMenu *)menu willHighlightItem:(NSMenuItem *)item | ||
| 761 | { | ||
| 762 | } | ||
| 763 | #endif | ||
| 764 | |||
| 714 | @end /* EmacsMenu */ | 765 | @end /* EmacsMenu */ |
| 715 | 766 | ||
| 716 | 767 | ||
diff --git a/src/nsterm.h b/src/nsterm.h index e7ea907569e..b29e76cc63f 100644 --- a/src/nsterm.h +++ b/src/nsterm.h | |||
| @@ -504,6 +504,10 @@ typedef id instancetype; | |||
| 504 | NSPoint grabOffset; | 504 | NSPoint grabOffset; |
| 505 | } | 505 | } |
| 506 | 506 | ||
| 507 | #ifdef NS_IMPL_GNUSTEP | ||
| 508 | - (NSInteger) orderedIndex; | ||
| 509 | #endif | ||
| 510 | |||
| 507 | - (BOOL)restackWindow:(NSWindow *)win above:(BOOL)above; | 511 | - (BOOL)restackWindow:(NSWindow *)win above:(BOOL)above; |
| 508 | - (void)setAppearance; | 512 | - (void)setAppearance; |
| 509 | @end | 513 | @end |
| @@ -1186,9 +1190,7 @@ extern void ns_run_ascript (void); | |||
| 1186 | #define NSAPP_DATA2_RUNFILEDIALOG 11 | 1190 | #define NSAPP_DATA2_RUNFILEDIALOG 11 |
| 1187 | extern void ns_run_file_dialog (void); | 1191 | extern void ns_run_file_dialog (void); |
| 1188 | 1192 | ||
| 1189 | extern const char *ns_etc_directory (void); | 1193 | extern const char *ns_relocate (const char *epath); |
| 1190 | extern const char *ns_exec_path (void); | ||
| 1191 | extern const char *ns_load_path (void); | ||
| 1192 | extern void syms_of_nsterm (void); | 1194 | extern void syms_of_nsterm (void); |
| 1193 | extern void syms_of_nsfns (void); | 1195 | extern void syms_of_nsfns (void); |
| 1194 | extern void syms_of_nsmenu (void); | 1196 | extern void syms_of_nsmenu (void); |
diff --git a/src/nsterm.m b/src/nsterm.m index 838c14d5abb..b9e2c9b6916 100644 --- a/src/nsterm.m +++ b/src/nsterm.m | |||
| @@ -277,11 +277,9 @@ static NSView *focus_view = NULL; | |||
| 277 | #endif | 277 | #endif |
| 278 | static int ns_window_num = 0; | 278 | static int ns_window_num = 0; |
| 279 | static BOOL gsaved = NO; | 279 | static BOOL gsaved = NO; |
| 280 | static BOOL ns_fake_keydown = NO; | ||
| 281 | #ifdef NS_IMPL_COCOA | 280 | #ifdef NS_IMPL_COCOA |
| 282 | static BOOL ns_menu_bar_is_hidden = NO; | 281 | static BOOL ns_menu_bar_is_hidden = NO; |
| 283 | #endif | 282 | #endif |
| 284 | /* static int debug_lock = 0; */ | ||
| 285 | 283 | ||
| 286 | /* event loop */ | 284 | /* event loop */ |
| 287 | static BOOL send_appdefined = YES; | 285 | static BOOL send_appdefined = YES; |
| @@ -499,118 +497,37 @@ append2 (Lisp_Object list, Lisp_Object item) | |||
| 499 | 497 | ||
| 500 | 498 | ||
| 501 | const char * | 499 | const char * |
| 502 | ns_etc_directory (void) | 500 | ns_relocate (const char *epath) |
| 503 | /* If running as a self-contained app bundle, return as a string the | 501 | /* If we're running in a self-contained app bundle some hard-coded |
| 504 | filename of the etc directory, if present; else nil. */ | 502 | paths are relative to the root of the bundle, so work out the full |
| 505 | { | 503 | path. |
| 506 | NSBundle *bundle = [NSBundle mainBundle]; | ||
| 507 | NSString *resourceDir = [bundle resourcePath]; | ||
| 508 | NSString *resourcePath; | ||
| 509 | NSFileManager *fileManager = [NSFileManager defaultManager]; | ||
| 510 | BOOL isDir; | ||
| 511 | |||
| 512 | resourcePath = [resourceDir stringByAppendingPathComponent: @"etc"]; | ||
| 513 | if ([fileManager fileExistsAtPath: resourcePath isDirectory: &isDir]) | ||
| 514 | { | ||
| 515 | if (isDir) return [resourcePath UTF8String]; | ||
| 516 | } | ||
| 517 | return NULL; | ||
| 518 | } | ||
| 519 | |||
| 520 | 504 | ||
| 521 | const char * | 505 | FIXME: I think this should be able to handle cases where multiple |
| 522 | ns_exec_path (void) | 506 | directories are separated by colons. */ |
| 523 | /* If running as a self-contained app bundle, return as a path string | ||
| 524 | the filenames of the libexec and bin directories, ie libexec:bin. | ||
| 525 | Otherwise, return nil. | ||
| 526 | Normally, Emacs does not add its own bin/ directory to the PATH. | ||
| 527 | However, a self-contained NS build has a different layout, with | ||
| 528 | bin/ and libexec/ subdirectories in the directory that contains | ||
| 529 | Emacs.app itself. | ||
| 530 | We put libexec first, because init_callproc_1 uses the first | ||
| 531 | element to initialize exec-directory. An alternative would be | ||
| 532 | for init_callproc to check for invocation-directory/libexec. | ||
| 533 | */ | ||
| 534 | { | 507 | { |
| 508 | #ifdef NS_SELF_CONTAINED | ||
| 535 | NSBundle *bundle = [NSBundle mainBundle]; | 509 | NSBundle *bundle = [NSBundle mainBundle]; |
| 536 | NSString *resourceDir = [bundle resourcePath]; | 510 | NSString *root = [bundle bundlePath]; |
| 537 | NSString *binDir = [bundle bundlePath]; | 511 | NSString *original = [NSString stringWithUTF8String:epath]; |
| 538 | NSString *resourcePath, *resourcePaths; | 512 | NSString *fixedPath = [NSString pathWithComponents: |
| 539 | NSRange range; | 513 | [NSArray arrayWithObjects: |
| 540 | NSString *pathSeparator = [NSString stringWithFormat: @"%c", SEPCHAR]; | 514 | root, original, nil]]; |
| 541 | NSFileManager *fileManager = [NSFileManager defaultManager]; | 515 | NSFileManager *fileManager = [NSFileManager defaultManager]; |
| 542 | NSArray *paths; | ||
| 543 | NSEnumerator *pathEnum; | ||
| 544 | BOOL isDir; | ||
| 545 | 516 | ||
| 546 | range = [resourceDir rangeOfString: @"Contents"]; | 517 | if (![original isAbsolutePath] |
| 547 | if (range.location != NSNotFound) | 518 | && [fileManager fileExistsAtPath:fixedPath isDirectory:NULL]) |
| 548 | { | 519 | return [fixedPath UTF8String]; |
| 549 | binDir = [binDir stringByAppendingPathComponent: @"Contents"]; | ||
| 550 | #ifdef NS_IMPL_COCOA | ||
| 551 | binDir = [binDir stringByAppendingPathComponent: @"MacOS"]; | ||
| 552 | #endif | ||
| 553 | } | ||
| 554 | |||
| 555 | paths = [binDir stringsByAppendingPaths: | ||
| 556 | [NSArray arrayWithObjects: @"libexec", @"bin", nil]]; | ||
| 557 | pathEnum = [paths objectEnumerator]; | ||
| 558 | resourcePaths = @""; | ||
| 559 | 520 | ||
| 560 | while ((resourcePath = [pathEnum nextObject])) | 521 | /* If we reach here either the path is absolute and therefore we |
| 561 | { | 522 | don't need to complete it, or we're unable to relocate the |
| 562 | if ([fileManager fileExistsAtPath: resourcePath isDirectory: &isDir]) | 523 | file/directory. If it's the latter it may be because the user is |
| 563 | if (isDir) | 524 | trying to use a bundled app as though it's a Unix style install |
| 564 | { | 525 | and we have no way to guess what was intended, so return the |
| 565 | if ([resourcePaths length] > 0) | 526 | original string unaltered. */ |
| 566 | resourcePaths | ||
| 567 | = [resourcePaths stringByAppendingString: pathSeparator]; | ||
| 568 | resourcePaths | ||
| 569 | = [resourcePaths stringByAppendingString: resourcePath]; | ||
| 570 | } | ||
| 571 | } | ||
| 572 | if ([resourcePaths length] > 0) return [resourcePaths UTF8String]; | ||
| 573 | 527 | ||
| 574 | return NULL; | 528 | #endif |
| 575 | } | ||
| 576 | |||
| 577 | |||
| 578 | const char * | ||
| 579 | ns_load_path (void) | ||
| 580 | /* If running as a self-contained app bundle, return as a path string | ||
| 581 | the filenames of the site-lisp and lisp directories. | ||
| 582 | Ie, site-lisp:lisp. Otherwise, return nil. */ | ||
| 583 | { | ||
| 584 | NSBundle *bundle = [NSBundle mainBundle]; | ||
| 585 | NSString *resourceDir = [bundle resourcePath]; | ||
| 586 | NSString *resourcePath, *resourcePaths; | ||
| 587 | NSString *pathSeparator = [NSString stringWithFormat: @"%c", SEPCHAR]; | ||
| 588 | NSFileManager *fileManager = [NSFileManager defaultManager]; | ||
| 589 | BOOL isDir; | ||
| 590 | NSArray *paths = [resourceDir stringsByAppendingPaths: | ||
| 591 | [NSArray arrayWithObjects: | ||
| 592 | @"site-lisp", @"lisp", nil]]; | ||
| 593 | NSEnumerator *pathEnum = [paths objectEnumerator]; | ||
| 594 | resourcePaths = @""; | ||
| 595 | |||
| 596 | /* Hack to skip site-lisp. */ | ||
| 597 | if (no_site_lisp) resourcePath = [pathEnum nextObject]; | ||
| 598 | |||
| 599 | while ((resourcePath = [pathEnum nextObject])) | ||
| 600 | { | ||
| 601 | if ([fileManager fileExistsAtPath: resourcePath isDirectory: &isDir]) | ||
| 602 | if (isDir) | ||
| 603 | { | ||
| 604 | if ([resourcePaths length] > 0) | ||
| 605 | resourcePaths | ||
| 606 | = [resourcePaths stringByAppendingString: pathSeparator]; | ||
| 607 | resourcePaths | ||
| 608 | = [resourcePaths stringByAppendingString: resourcePath]; | ||
| 609 | } | ||
| 610 | } | ||
| 611 | if ([resourcePaths length] > 0) return [resourcePaths UTF8String]; | ||
| 612 | 529 | ||
| 613 | return NULL; | 530 | return epath; |
| 614 | } | 531 | } |
| 615 | 532 | ||
| 616 | 533 | ||
| @@ -6374,9 +6291,7 @@ not_in_argv (NSString *arg) | |||
| 6374 | NSTRACE ("[EmacsView keyDown:]"); | 6291 | NSTRACE ("[EmacsView keyDown:]"); |
| 6375 | 6292 | ||
| 6376 | /* Rhapsody and macOS give up and down events for the arrow keys. */ | 6293 | /* Rhapsody and macOS give up and down events for the arrow keys. */ |
| 6377 | if (ns_fake_keydown == YES) | 6294 | if ([theEvent type] != NSEventTypeKeyDown) |
| 6378 | ns_fake_keydown = NO; | ||
| 6379 | else if ([theEvent type] != NSEventTypeKeyDown) | ||
| 6380 | return; | 6295 | return; |
| 6381 | 6296 | ||
| 6382 | if (!emacs_event) | 6297 | if (!emacs_event) |
| @@ -8763,6 +8678,16 @@ not_in_argv (NSString *arg) | |||
| 8763 | } | 8678 | } |
| 8764 | 8679 | ||
| 8765 | 8680 | ||
| 8681 | #ifdef NS_IMPL_GNUSTEP | ||
| 8682 | /* orderedIndex isn't yet available in GNUstep, but it seems pretty | ||
| 8683 | easy to implement. */ | ||
| 8684 | - (NSInteger) orderedIndex | ||
| 8685 | { | ||
| 8686 | return [[NSApp orderedWindows] indexOfObjectIdenticalTo:self]; | ||
| 8687 | } | ||
| 8688 | #endif | ||
| 8689 | |||
| 8690 | |||
| 8766 | /* The array returned by [NSWindow parentWindow] may already be | 8691 | /* The array returned by [NSWindow parentWindow] may already be |
| 8767 | sorted, but the documentation doesn't tell us whether or not it is, | 8692 | sorted, but the documentation doesn't tell us whether or not it is, |
| 8768 | so to be safe we'll sort it. */ | 8693 | so to be safe we'll sort it. */ |
diff --git a/src/process.c b/src/process.c index ce71545c117..cc1afa8dc3e 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -1755,7 +1755,7 @@ usage: (make-process &rest ARGS) */) | |||
| 1755 | buffer's current directory, or its unhandled equivalent. We | 1755 | buffer's current directory, or its unhandled equivalent. We |
| 1756 | can't just have the child check for an error when it does the | 1756 | can't just have the child check for an error when it does the |
| 1757 | chdir, since it's in a vfork. */ | 1757 | chdir, since it's in a vfork. */ |
| 1758 | current_dir = encode_current_directory (); | 1758 | current_dir = get_current_directory (true); |
| 1759 | 1759 | ||
| 1760 | name = Fplist_get (contact, QCname); | 1760 | name = Fplist_get (contact, QCname); |
| 1761 | CHECK_STRING (name); | 1761 | CHECK_STRING (name); |
diff --git a/src/process.h b/src/process.h index 0890f253a40..4a25d13d268 100644 --- a/src/process.h +++ b/src/process.h | |||
| @@ -264,7 +264,7 @@ enum | |||
| 264 | 264 | ||
| 265 | /* Defined in callproc.c. */ | 265 | /* Defined in callproc.c. */ |
| 266 | 266 | ||
| 267 | extern Lisp_Object encode_current_directory (void); | 267 | extern Lisp_Object get_current_directory (bool); |
| 268 | extern void record_kill_process (struct Lisp_Process *, Lisp_Object); | 268 | extern void record_kill_process (struct Lisp_Process *, Lisp_Object); |
| 269 | 269 | ||
| 270 | /* Defined in sysdep.c. */ | 270 | /* Defined in sysdep.c. */ |
diff --git a/src/sysdep.c b/src/sysdep.c index 51d8b5eeedc..b8ec22d9dd9 100644 --- a/src/sysdep.c +++ b/src/sysdep.c | |||
| @@ -657,7 +657,7 @@ sys_subshell (void) | |||
| 657 | #endif | 657 | #endif |
| 658 | pid_t pid; | 658 | pid_t pid; |
| 659 | struct save_signal saved_handlers[5]; | 659 | struct save_signal saved_handlers[5]; |
| 660 | char *str = SSDATA (encode_current_directory ()); | 660 | char *str = SSDATA (get_current_directory (true)); |
| 661 | 661 | ||
| 662 | #ifdef DOS_NT | 662 | #ifdef DOS_NT |
| 663 | pid = 0; | 663 | pid = 0; |
diff --git a/src/thread.c b/src/thread.c index f74f6111486..714b1cd903a 100644 --- a/src/thread.c +++ b/src/thread.c | |||
| @@ -28,6 +28,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 28 | #include "pdumper.h" | 28 | #include "pdumper.h" |
| 29 | #include "keyboard.h" | 29 | #include "keyboard.h" |
| 30 | 30 | ||
| 31 | #ifdef HAVE_NS | ||
| 32 | #include "nsterm.h" | ||
| 33 | #endif | ||
| 34 | |||
| 31 | #if defined HAVE_GLIB && ! defined (HAVE_NS) | 35 | #if defined HAVE_GLIB && ! defined (HAVE_NS) |
| 32 | #include <xgselect.h> | 36 | #include <xgselect.h> |
| 33 | #else | 37 | #else |
| @@ -735,6 +739,15 @@ run_thread (void *state) | |||
| 735 | struct thread_state *self = state; | 739 | struct thread_state *self = state; |
| 736 | struct thread_state **iter; | 740 | struct thread_state **iter; |
| 737 | 741 | ||
| 742 | #ifdef HAVE_NS | ||
| 743 | /* Allocate an autorelease pool in case this thread calls any | ||
| 744 | Objective C code. | ||
| 745 | |||
| 746 | FIXME: In long running threads we may want to drain the pool | ||
| 747 | regularly instead of just at the end. */ | ||
| 748 | void *pool = ns_alloc_autorelease_pool (); | ||
| 749 | #endif | ||
| 750 | |||
| 738 | self->m_stack_bottom = self->stack_top = &stack_pos.c; | 751 | self->m_stack_bottom = self->stack_top = &stack_pos.c; |
| 739 | self->thread_id = sys_thread_self (); | 752 | self->thread_id = sys_thread_self (); |
| 740 | 753 | ||
| @@ -777,6 +790,10 @@ run_thread (void *state) | |||
| 777 | current_thread = NULL; | 790 | current_thread = NULL; |
| 778 | sys_cond_broadcast (&self->thread_condvar); | 791 | sys_cond_broadcast (&self->thread_condvar); |
| 779 | 792 | ||
| 793 | #ifdef HAVE_NS | ||
| 794 | ns_release_autorelease_pool (pool); | ||
| 795 | #endif | ||
| 796 | |||
| 780 | /* Unlink this thread from the list of all threads. Note that we | 797 | /* Unlink this thread from the list of all threads. Note that we |
| 781 | have to do this very late, after broadcasting our death. | 798 | have to do this very late, after broadcasting our death. |
| 782 | Otherwise the GC may decide to reap the thread_state object, | 799 | Otherwise the GC may decide to reap the thread_state object, |
diff --git a/src/xgselect.c b/src/xgselect.c index 0d91d55bad6..92b118b9559 100644 --- a/src/xgselect.c +++ b/src/xgselect.c | |||
| @@ -34,12 +34,27 @@ static GMainContext *glib_main_context; | |||
| 34 | 34 | ||
| 35 | void release_select_lock (void) | 35 | void release_select_lock (void) |
| 36 | { | 36 | { |
| 37 | #if GNUC_PREREQ (4, 7, 0) | ||
| 38 | if (__atomic_sub_fetch (&threads_holding_glib_lock, 1, __ATOMIC_ACQ_REL) == 0) | ||
| 39 | g_main_context_release (glib_main_context); | ||
| 40 | #else | ||
| 37 | if (--threads_holding_glib_lock == 0) | 41 | if (--threads_holding_glib_lock == 0) |
| 38 | g_main_context_release (glib_main_context); | 42 | g_main_context_release (glib_main_context); |
| 43 | #endif | ||
| 39 | } | 44 | } |
| 40 | 45 | ||
| 41 | static void acquire_select_lock (GMainContext *context) | 46 | static void acquire_select_lock (GMainContext *context) |
| 42 | { | 47 | { |
| 48 | #if GNUC_PREREQ (4, 7, 0) | ||
| 49 | if (__atomic_fetch_add (&threads_holding_glib_lock, 1, __ATOMIC_ACQ_REL) == 0) | ||
| 50 | { | ||
| 51 | glib_main_context = context; | ||
| 52 | while (!g_main_context_acquire (context)) | ||
| 53 | { | ||
| 54 | /* Spin. */ | ||
| 55 | } | ||
| 56 | } | ||
| 57 | #else | ||
| 43 | if (threads_holding_glib_lock++ == 0) | 58 | if (threads_holding_glib_lock++ == 0) |
| 44 | { | 59 | { |
| 45 | glib_main_context = context; | 60 | glib_main_context = context; |
| @@ -48,6 +63,7 @@ static void acquire_select_lock (GMainContext *context) | |||
| 48 | /* Spin. */ | 63 | /* Spin. */ |
| 49 | } | 64 | } |
| 50 | } | 65 | } |
| 66 | #endif | ||
| 51 | } | 67 | } |
| 52 | 68 | ||
| 53 | /* `xg_select' is a `pselect' replacement. Why do we need a separate function? | 69 | /* `xg_select' is a `pselect' replacement. Why do we need a separate function? |