Commit 080fd649 authored by Eli Zaretskii's avatar Eli Zaretskii

Fixed initialization code and default-printer-name.

parent 94ae1542
......@@ -1606,17 +1606,24 @@ init_callproc (void)
source directory. */
if (data_dir == 0)
{
Lisp_Object tem, tem1, srcdir;
Lisp_Object tem, tem1, tem2, srcdir;
#ifdef WINDOWSNT
/* PATH_DUMPLOADSEARCH is in ANSI codepage; convert to UTF-8. */
char dumpload_dir[MAX_UTF8_PATH];
filename_from_ansi (PATH_DUMPLOADSEARCH, dumpload_dir);
tem2 = build_unibyte_string (dumpload_dir);
#else
tem2 = build_unibyte_string (PATH_DUMPLOADSEARCH);
#endif
srcdir = Fexpand_file_name (build_string ("../src/"),
build_unibyte_string (PATH_DUMPLOADSEARCH));
srcdir = Fexpand_file_name (build_string ("../src/"), tem2);
tem = Fexpand_file_name (build_string ("GNU"), Vdata_directory);
tem1 = Ffile_exists_p (tem);
if (!NILP (Fequal (srcdir, Vinvocation_directory)) || NILP (tem1))
{
Lisp_Object newdir;
newdir = Fexpand_file_name (build_string ("../etc/"),
build_unibyte_string (PATH_DUMPLOADSEARCH));
newdir = Fexpand_file_name (build_string ("../etc/"), tem2);
tem = Fexpand_file_name (build_string ("GNU"), newdir);
tem1 = Ffile_exists_p (tem);
if (!NILP (tem1))
......
......@@ -394,7 +394,20 @@ init_cmdargs (int argc, char **argv, int skip_args, char *original_pwd)
initial_argv = argv;
initial_argc = argc;
#ifdef WINDOWSNT
/* Must use argv[0] converted to UTF-8, as it begets many standard
file and directory names. */
{
char argv0[MAX_UTF8_PATH];
if (filename_from_ansi (argv[0], argv0) == 0)
raw_name = build_unibyte_string (argv0);
else
raw_name = build_unibyte_string (argv[0]);
}
#else
raw_name = build_unibyte_string (argv[0]);
#endif
/* Add /: to the front of the name
if it would otherwise be treated as magic. */
......@@ -796,6 +809,14 @@ main (int argc, char **argv)
if (argmatch (argv, argc, "-chdir", "--chdir", 4, &ch_to_dir, &skip_args))
{
#ifdef WINDOWSNT
/* argv[] array is kept in its original ANSI codepage encoding,
we need to convert to UTF-8, for chdir to work. */
char newdir[MAX_UTF8_PATH];
filename_from_ansi (ch_to_dir, newdir);
ch_to_dir = newdir;
#endif
original_pwd = get_current_dir_name ();
if (chdir (ch_to_dir) != 0)
{
......@@ -1531,7 +1552,16 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
char *file;
/* Handle -l loadup, args passed by Makefile. */
if (argmatch (argv, argc, "-l", "--load", 3, &file, &skip_args))
Vtop_level = list2 (intern_c_string ("load"), build_string (file));
{
#ifdef WINDOWSNT
char file_utf8[MAX_UTF8_PATH];
if (filename_from_ansi (file, file_utf8) == 0)
file = file_utf8;
#endif
Vtop_level = list2 (intern_c_string ("load"),
build_unibyte_string (file));
}
/* Unless next switch is -nl, load "loadup.el" first thing. */
if (! no_loadup)
Vtop_level = list2 (intern_c_string ("load"),
......
......@@ -1333,7 +1333,8 @@ w32_valid_pointer_p (void *p, int size)
encoding when w32-unicode-filenames is t; this is similar to
selection-coding-system.
This arrangement works very well, but it has a few gotchas:
This arrangement works very well, but it has a few gotchas and
limitations:
. Lisp code that encodes or decodes file names manually should
normally use 'utf-8' as the coding-system on Windows,
......@@ -1351,6 +1352,12 @@ w32_valid_pointer_p (void *p, int size)
name sfrom UTF-8 to either UTF-16 or ANSI codepage, or going
through some shadowing function defined here.
. Environment variables stored in Vprocess_environment are encoded
in the ANSI codepage, so if getenv/egetenv is used for a variable
whose value is a file name or a list of directories, it needs to
be converted to UTF-8, before it is used as argument to functions
or decoded into a Lisp string.
. File names passed to external libraries, like the image libraries
and GnuTLS, need special handling. These libraries generally
don't support UTF-16 or UTF-8 file names, so they must get file
......@@ -1378,7 +1385,12 @@ w32_valid_pointer_p (void *p, int size)
. For similar reasons, server.el and emacsclient are also limited
to the current ANSI codepage for now.
*/
. Emacs itself can only handle command-line arguments encoded in
the current codepage.
. Turning on w32-unicode-filename on Windows 9X (if it at all
works) requires UNICOWS.DLL, which is currently loaded only in a
GUI session. */
......@@ -2365,6 +2377,8 @@ w32_get_resource (char *key, LPDWORD lpdwtype)
return (NULL);
}
/* The argv[] array holds ANSI-encoded strings, and so this function
works with ANS_encoded strings. */
void
init_environment (char ** argv)
{
......@@ -2508,7 +2522,7 @@ init_environment (char ** argv)
char *p;
char modname[MAX_PATH];
if (!GetModuleFileName (NULL, modname, MAX_PATH))
if (!GetModuleFileNameA (NULL, modname, MAX_PATH))
emacs_abort ();
if ((p = _mbsrchr (modname, '\\')) == NULL)
emacs_abort ();
......@@ -2672,7 +2686,7 @@ init_environment (char ** argv)
{
static char modname[MAX_PATH];
if (!GetModuleFileName (NULL, modname, MAX_PATH))
if (!GetModuleFileNameA (NULL, modname, MAX_PATH))
emacs_abort ();
argv[0] = modname;
}
......@@ -8434,10 +8448,10 @@ check_windows_init_file (void)
/* Implementation note: this function runs early during Emacs
startup, before startup.el is run. So Vload_path is still in
its initial unibyte form, holding ANSI-encoded file names.
That is why we never bother to ENCODE_FILE here, nor use wide
APIs for file names: we will never get UTF-8 encoded file
names here. */
its initial unibyte form, but it holds UTF-8 encoded file
names, since init_callproc was already called. So we do not
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);
if (fd < 0)
......@@ -8448,6 +8462,8 @@ check_windows_init_file (void)
char *buffer = alloca (1024
+ strlen (init_file_name)
+ strlen (load_path));
char *msg = buffer;
int needed;
sprintf (buffer,
"The Emacs Windows initialization file \"%s.el\" "
......@@ -8459,8 +8475,27 @@ check_windows_init_file (void)
"not unpacked properly.\nSee the README.W32 file in the "
"top-level Emacs directory for more information.",
init_file_name, load_path);
needed = MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, buffer,
-1, NULL, 0);
if (needed > 0)
{
wchar_t *msg_w = alloca ((needed + 1) * sizeof (wchar_t));
MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, buffer, -1,
msg_w, needed);
needed = WideCharToMultiByte (CP_ACP, 0, msg_w, -1,
NULL, 0, NULL, NULL);
if (needed > 0)
{
char *msg_a = alloca (needed + 1);
WideCharToMultiByte (CP_ACP, 0, msg_w, -1, msg_a, needed,
NULL, NULL);
msg = msg_a;
}
}
MessageBox (NULL,
buffer,
msg,
"Emacs Abort Dialog",
MB_OK | MB_ICONEXCLAMATION | MB_TASKMODAL);
/* Use the low-level system abort. */
......
......@@ -7428,8 +7428,11 @@ DEFUN ("default-printer-name", Fdefault_printer_name, Sdefault_printer_name,
static char pname_buf[256];
int err;
HANDLE hPrn;
PRINTER_INFO_2 *ppi2 = NULL;
PRINTER_INFO_2W *ppi2w = NULL;
PRINTER_INFO_2A *ppi2a = NULL;
DWORD dwNeeded = 0, dwReturned = 0;
char server_name[MAX_UTF8_PATH], share_name[MAX_UTF8_PATH];
char port_name[MAX_UTF8_PATH];
/* Retrieve the default string from Win.ini (the registry).
* String will be in form "printername,drivername,portname".
......@@ -7441,54 +7444,87 @@ DEFUN ("default-printer-name", Fdefault_printer_name, Sdefault_printer_name,
/* We want to know more than the printer name */
if (!OpenPrinter (pname_buf, &hPrn, NULL))
return Qnil;
GetPrinter (hPrn, 2, NULL, 0, &dwNeeded);
/* GetPrinterW is not supported by unicows.dll. */
if (w32_unicode_filenames && os_subtype != OS_9X)
GetPrinterW (hPrn, 2, NULL, 0, &dwNeeded);
else
GetPrinterA (hPrn, 2, NULL, 0, &dwNeeded);
if (dwNeeded == 0)
{
ClosePrinter (hPrn);
return Qnil;
}
/* Allocate memory for the PRINTER_INFO_2 struct */
ppi2 = xmalloc (dwNeeded);
if (!ppi2)
/* Call GetPrinter again with big enough memory block. */
if (w32_unicode_filenames && os_subtype != OS_9X)
{
/* Allocate memory for the PRINTER_INFO_2 struct. */
ppi2w = xmalloc (dwNeeded);
err = GetPrinterW (hPrn, 2, (LPBYTE)ppi2w, dwNeeded, &dwReturned);
ClosePrinter (hPrn);
return Qnil;
if (!err)
{
xfree (ppi2w);
return Qnil;
}
if ((ppi2w->Attributes & PRINTER_ATTRIBUTE_SHARED)
&& ppi2w->pServerName)
{
filename_from_utf16 (ppi2w->pServerName, server_name);
filename_from_utf16 (ppi2w->pShareName, share_name);
}
else
{
server_name[0] = '\0';
filename_from_utf16 (ppi2w->pPortName, port_name);
}
}
/* Call GetPrinter again with big enough memory block. */
err = GetPrinter (hPrn, 2, (LPBYTE)ppi2, dwNeeded, &dwReturned);
ClosePrinter (hPrn);
if (!err)
else
{
xfree (ppi2);
return Qnil;
}
ppi2a = xmalloc (dwNeeded);
err = GetPrinterA (hPrn, 2, (LPBYTE)ppi2a, dwNeeded, &dwReturned);
ClosePrinter (hPrn);
if (!err)
{
xfree (ppi2a);
return Qnil;
}
if (ppi2)
{
if (ppi2->Attributes & PRINTER_ATTRIBUTE_SHARED && ppi2->pServerName)
{
/* a remote printer */
if (*ppi2->pServerName == '\\')
snprintf (pname_buf, sizeof (pname_buf), "%s\\%s", ppi2->pServerName,
ppi2->pShareName);
else
snprintf (pname_buf, sizeof (pname_buf), "\\\\%s\\%s", ppi2->pServerName,
ppi2->pShareName);
pname_buf[sizeof (pname_buf) - 1] = '\0';
if ((ppi2a->Attributes & PRINTER_ATTRIBUTE_SHARED)
&& ppi2a->pServerName)
{
filename_from_ansi (ppi2a->pServerName, server_name);
filename_from_ansi (ppi2a->pShareName, share_name);
}
else
{
/* a local printer */
strncpy (pname_buf, ppi2->pPortName, sizeof (pname_buf));
pname_buf[sizeof (pname_buf) - 1] = '\0';
/* `pPortName' can include several ports, delimited by ','.
* we only use the first one. */
strtok (pname_buf, ",");
{
server_name[0] = '\0';
filename_from_ansi (ppi2a->pPortName, port_name);
}
xfree (ppi2);
}
return build_string (pname_buf);
if (server_name[0])
{
/* a remote printer */
if (server_name[0] == '\\')
snprintf (pname_buf, sizeof (pname_buf), "%s\\%s", server_name,
share_name);
else
snprintf (pname_buf, sizeof (pname_buf), "\\\\%s\\%s", server_name,
share_name);
pname_buf[sizeof (pname_buf) - 1] = '\0';
}
else
{
/* a local printer */
strncpy (pname_buf, port_name, sizeof (pname_buf));
pname_buf[sizeof (pname_buf) - 1] = '\0';
/* `pPortName' can include several ports, delimited by ','.
* we only use the first one. */
strtok (pname_buf, ",");
}
return DECODE_FILE (build_unibyte_string (pname_buf));
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment