summaryrefslogtreecommitdiff
path: root/src/w32.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/w32.c')
-rw-r--r--src/w32.c131
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 */