diff options
Diffstat (limited to 'src/w32.c')
-rw-r--r-- | src/w32.c | 131 |
1 files changed, 123 insertions, 8 deletions
diff --git a/src/w32.c b/src/w32.c index a3c247b8b0d..0eb69d4b1d1 100644 --- a/src/w32.c +++ b/src/w32.c @@ -346,6 +346,7 @@ static BOOL g_b_init_get_adapters_addresses; static BOOL g_b_init_reg_open_key_ex_w; static BOOL g_b_init_reg_query_value_ex_w; static BOOL g_b_init_expand_environment_strings_w; +static BOOL g_b_init_get_user_default_ui_language; BOOL g_b_init_compare_string_w; BOOL g_b_init_debug_break_process; @@ -533,6 +534,7 @@ DWORD multiByteToWideCharFlags; typedef LONG (WINAPI *RegOpenKeyExW_Proc) (HKEY,LPCWSTR,DWORD,REGSAM,PHKEY); typedef LONG (WINAPI *RegQueryValueExW_Proc) (HKEY,LPCWSTR,LPDWORD,LPDWORD,LPBYTE,LPDWORD); typedef DWORD (WINAPI *ExpandEnvironmentStringsW_Proc) (LPCWSTR,LPWSTR,DWORD); +typedef LANGID (WINAPI *GetUserDefaultUILanguage_Proc) (void); /* ** A utility function ** */ static BOOL @@ -1489,6 +1491,28 @@ expand_environment_strings_w (LPCWSTR lpSrc, LPWSTR lpDst, DWORD nSize) return s_pfn_Expand_Environment_Strings_w (lpSrc, lpDst, nSize); } +static LANGID WINAPI +get_user_default_ui_language (void) +{ + static GetUserDefaultUILanguage_Proc s_pfn_GetUserDefaultUILanguage = NULL; + HMODULE hm_kernel32 = NULL; + + if (is_windows_9x () == TRUE) + return 0; + + if (g_b_init_get_user_default_ui_language == 0) + { + g_b_init_get_user_default_ui_language = 1; + hm_kernel32 = LoadLibrary ("Kernel32.dll"); + if (hm_kernel32) + s_pfn_GetUserDefaultUILanguage = (GetUserDefaultUILanguage_Proc) + get_proc_addr (hm_kernel32, "GetUserDefaultUILanguage"); + } + if (s_pfn_GetUserDefaultUILanguage == NULL) + return 0; + return s_pfn_GetUserDefaultUILanguage (); +} + /* Return 1 if P is a valid pointer to an object of size SIZE. Return @@ -1917,11 +1941,10 @@ buf_prev (int from) return prev_idx; } -static void -sample_system_load (ULONGLONG *idle, ULONGLONG *kernel, ULONGLONG *user) +unsigned +w32_get_nproc (void) { SYSTEM_INFO sysinfo; - FILETIME ft_idle, ft_user, ft_kernel; /* Initialize the number of processors on this machine. */ if (num_of_processors <= 0) @@ -1936,6 +1959,15 @@ sample_system_load (ULONGLONG *idle, ULONGLONG *kernel, ULONGLONG *user) if (num_of_processors <= 0) num_of_processors = 1; } + return num_of_processors; +} + +static void +sample_system_load (ULONGLONG *idle, ULONGLONG *kernel, ULONGLONG *user) +{ + FILETIME ft_idle, ft_user, ft_kernel; + + (void) w32_get_nproc (); /* TODO: Take into account threads that are ready to run, by sampling the "\System\Processor Queue Length" performance @@ -2357,8 +2389,13 @@ rand_as183 (void) int random (void) { - /* rand_as183 () gives us 15 random bits...hack together 30 bits. */ + /* rand_as183 () gives us 15 random bits...hack together 30 bits for + Emacs with 32-bit EMACS_INT, and at least 31 bit for wider EMACS_INT. */ +#if EMACS_INT_MAX > INT_MAX + return ((rand_as183 () << 30) | (rand_as183 () << 15) | rand_as183 ()); +#else return ((rand_as183 () << 15) | rand_as183 ()); +#endif } void @@ -2947,6 +2984,32 @@ init_environment (char ** argv) LOCALE_SABBREVLANGNAME | LOCALE_USE_CP_ACP, locale_name, sizeof (locale_name))) { + /* Microsoft are migrating away of locale IDs, replacing them + with locale names, such as "en-US", and are therefore + deprecating the APIs which use LCID etc. As part of that + deprecation, they don't bother inventing LCID and LANGID + codes for new locales and language/culture combinations; + instead, those get LCID of 0xC000 and LANGID of 0x2000, for + which the LCID/LANGID oriented APIs return "ZZZ" as the + "language name". Such "language name" is useless for our + purposes. So we instead use the default UI language, in the + hope of getting something usable. */ + if (strcmp (locale_name, "ZZZ") == 0) + { + LANGID lang_id = get_user_default_ui_language (); + + if (lang_id != 0) + { + /* Disregard the sorting order differences between cultures. */ + LCID def_lcid = MAKELCID (lang_id, SORT_DEFAULT); + char locale_name_def[32]; + + if (GetLocaleInfo (def_lcid, + LOCALE_SABBREVLANGNAME | LOCALE_USE_CP_ACP, + locale_name_def, sizeof (locale_name_def))) + strcpy (locale_name, locale_name_def); + } + } for (i = 0; i < N_ENV_VARS; i++) { if (strcmp (env_vars[i].name, "LANG") == 0) @@ -4689,7 +4752,7 @@ sys_rename_replace (const char *oldname, const char *newname, BOOL force) /* volume_info is set indirectly by map_w32_filename. */ oldname_dev = volume_info.serialnum; - if (os_subtype == OS_9X) + if (os_subtype == OS_SUBTYPE_9X) { char * o; char * p; @@ -8695,7 +8758,7 @@ int _sys_read_ahead (int fd) { child_process * cp; - int rc; + int rc = 0; if (fd < 0 || fd >= MAXDESC) return STATUS_READ_ERROR; @@ -10197,7 +10260,8 @@ check_windows_init_file (void) need to ENCODE_FILE here, but we do need to convert the file names from UTF-8 to ANSI. */ init_file = build_string ("term/w32-win"); - fd = openp (Vload_path, init_file, Fget_load_suffixes (), NULL, Qnil, 0); + fd = + openp (Vload_path, init_file, Fget_load_suffixes (), NULL, Qnil, 0, 0); if (fd < 0) { Lisp_Object load_path_print = Fprin1_to_string (Vload_path, Qnil); @@ -10389,6 +10453,13 @@ shutdown_handler (DWORD type) || type == CTRL_LOGOFF_EVENT /* User logs off. */ || type == CTRL_SHUTDOWN_EVENT) /* User shutsdown. */ { + /* If we are being shut down in noninteractive mode, we don't + care about the message stack, so clear it to avoid abort in + shut_down_emacs. This happens when an noninteractive Emacs + is invoked as a subprocess of Emacs, and the parent wants to + kill us, e.g. because it's about to exit. */ + if (noninteractive) + clear_message_stack (); /* Shut down cleanly, making sure autosave files are up to date. */ shut_down_emacs (0, Qnil); } @@ -10402,7 +10473,7 @@ shutdown_handler (DWORD type) HANDLE maybe_load_unicows_dll (void) { - if (os_subtype == OS_9X) + if (os_subtype == OS_SUBTYPE_9X) { HANDLE ret = LoadLibrary ("Unicows.dll"); if (ret) @@ -10521,6 +10592,45 @@ w32_my_exename (void) return exename; } +/* Emulate Posix 'realpath'. This is needed in + comp-el-to-eln-rel-filename. */ +char * +realpath (const char *file_name, char *resolved_name) +{ + char *tgt = chase_symlinks (file_name); + char target[MAX_UTF8_PATH]; + + if (tgt == file_name) + { + /* If FILE_NAME is not a symlink, chase_symlinks returns its + argument, possibly not in canonical absolute form. Make sure + we return a canonical file name. */ + if (w32_unicode_filenames) + { + wchar_t file_w[MAX_PATH], tgt_w[MAX_PATH]; + + filename_to_utf16 (file_name, file_w); + if (GetFullPathNameW (file_w, MAX_PATH, tgt_w, NULL) == 0) + return NULL; + filename_from_utf16 (tgt_w, target); + } + else + { + char file_a[MAX_PATH], tgt_a[MAX_PATH]; + + filename_to_ansi (file_name, file_a); + if (GetFullPathNameA (file_a, MAX_PATH, tgt_a, NULL) == 0) + return NULL; + filename_from_ansi (tgt_a, target); + } + tgt = target; + } + + if (resolved_name) + return strcpy (resolved_name, tgt); + return xstrdup (tgt); +} + /* globals_of_w32 is used to initialize those global variables that must always be initialized on startup even when the global variable @@ -10580,6 +10690,7 @@ globals_of_w32 (void) g_b_init_expand_environment_strings_w = 0; g_b_init_compare_string_w = 0; g_b_init_debug_break_process = 0; + g_b_init_get_user_default_ui_language = 0; num_of_processors = 0; /* The following sets a handler for shutdown notifications for console apps. This actually applies to Emacs in both console and @@ -10606,6 +10717,10 @@ globals_of_w32 (void) #endif w32_crypto_hprov = (HCRYPTPROV)0; + + /* We need to forget about libraries that were loaded during the + dumping process (e.g. libgccjit) */ + Vlibrary_cache = Qnil; } /* For make-serial-process */ |