aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/callproc.c17
-rw-r--r--src/emacs.c32
-rw-r--r--src/w32.c53
-rw-r--r--src/w32fns.c104
4 files changed, 157 insertions, 49 deletions
diff --git a/src/callproc.c b/src/callproc.c
index 3317c1203bc..2966711978b 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -1606,17 +1606,24 @@ init_callproc (void)
1606 source directory. */ 1606 source directory. */
1607 if (data_dir == 0) 1607 if (data_dir == 0)
1608 { 1608 {
1609 Lisp_Object tem, tem1, srcdir; 1609 Lisp_Object tem, tem1, tem2, srcdir;
1610#ifdef WINDOWSNT
1611 /* PATH_DUMPLOADSEARCH is in ANSI codepage; convert to UTF-8. */
1612 char dumpload_dir[MAX_UTF8_PATH];
1613
1614 filename_from_ansi (PATH_DUMPLOADSEARCH, dumpload_dir);
1615 tem2 = build_unibyte_string (dumpload_dir);
1616#else
1617 tem2 = build_unibyte_string (PATH_DUMPLOADSEARCH);
1618#endif
1610 1619
1611 srcdir = Fexpand_file_name (build_string ("../src/"), 1620 srcdir = Fexpand_file_name (build_string ("../src/"), tem2);
1612 build_unibyte_string (PATH_DUMPLOADSEARCH));
1613 tem = Fexpand_file_name (build_string ("GNU"), Vdata_directory); 1621 tem = Fexpand_file_name (build_string ("GNU"), Vdata_directory);
1614 tem1 = Ffile_exists_p (tem); 1622 tem1 = Ffile_exists_p (tem);
1615 if (!NILP (Fequal (srcdir, Vinvocation_directory)) || NILP (tem1)) 1623 if (!NILP (Fequal (srcdir, Vinvocation_directory)) || NILP (tem1))
1616 { 1624 {
1617 Lisp_Object newdir; 1625 Lisp_Object newdir;
1618 newdir = Fexpand_file_name (build_string ("../etc/"), 1626 newdir = Fexpand_file_name (build_string ("../etc/"), tem2);
1619 build_unibyte_string (PATH_DUMPLOADSEARCH));
1620 tem = Fexpand_file_name (build_string ("GNU"), newdir); 1627 tem = Fexpand_file_name (build_string ("GNU"), newdir);
1621 tem1 = Ffile_exists_p (tem); 1628 tem1 = Ffile_exists_p (tem);
1622 if (!NILP (tem1)) 1629 if (!NILP (tem1))
diff --git a/src/emacs.c b/src/emacs.c
index 9f41bc251ea..22be1d82949 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -394,7 +394,20 @@ init_cmdargs (int argc, char **argv, int skip_args, char *original_pwd)
394 initial_argv = argv; 394 initial_argv = argv;
395 initial_argc = argc; 395 initial_argc = argc;
396 396
397#ifdef WINDOWSNT
398 /* Must use argv[0] converted to UTF-8, as it begets many standard
399 file and directory names. */
400 {
401 char argv0[MAX_UTF8_PATH];
402
403 if (filename_from_ansi (argv[0], argv0) == 0)
404 raw_name = build_unibyte_string (argv0);
405 else
406 raw_name = build_unibyte_string (argv[0]);
407 }
408#else
397 raw_name = build_unibyte_string (argv[0]); 409 raw_name = build_unibyte_string (argv[0]);
410#endif
398 411
399 /* Add /: to the front of the name 412 /* Add /: to the front of the name
400 if it would otherwise be treated as magic. */ 413 if it would otherwise be treated as magic. */
@@ -796,6 +809,14 @@ main (int argc, char **argv)
796 809
797 if (argmatch (argv, argc, "-chdir", "--chdir", 4, &ch_to_dir, &skip_args)) 810 if (argmatch (argv, argc, "-chdir", "--chdir", 4, &ch_to_dir, &skip_args))
798 { 811 {
812#ifdef WINDOWSNT
813 /* argv[] array is kept in its original ANSI codepage encoding,
814 we need to convert to UTF-8, for chdir to work. */
815 char newdir[MAX_UTF8_PATH];
816
817 filename_from_ansi (ch_to_dir, newdir);
818 ch_to_dir = newdir;
819#endif
799 original_pwd = get_current_dir_name (); 820 original_pwd = get_current_dir_name ();
800 if (chdir (ch_to_dir) != 0) 821 if (chdir (ch_to_dir) != 0)
801 { 822 {
@@ -1531,7 +1552,16 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1531 char *file; 1552 char *file;
1532 /* Handle -l loadup, args passed by Makefile. */ 1553 /* Handle -l loadup, args passed by Makefile. */
1533 if (argmatch (argv, argc, "-l", "--load", 3, &file, &skip_args)) 1554 if (argmatch (argv, argc, "-l", "--load", 3, &file, &skip_args))
1534 Vtop_level = list2 (intern_c_string ("load"), build_string (file)); 1555 {
1556#ifdef WINDOWSNT
1557 char file_utf8[MAX_UTF8_PATH];
1558
1559 if (filename_from_ansi (file, file_utf8) == 0)
1560 file = file_utf8;
1561#endif
1562 Vtop_level = list2 (intern_c_string ("load"),
1563 build_unibyte_string (file));
1564 }
1535 /* Unless next switch is -nl, load "loadup.el" first thing. */ 1565 /* Unless next switch is -nl, load "loadup.el" first thing. */
1536 if (! no_loadup) 1566 if (! no_loadup)
1537 Vtop_level = list2 (intern_c_string ("load"), 1567 Vtop_level = list2 (intern_c_string ("load"),
diff --git a/src/w32.c b/src/w32.c
index 0f13703b933..e2649167aee 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -1333,7 +1333,8 @@ w32_valid_pointer_p (void *p, int size)
1333 encoding when w32-unicode-filenames is t; this is similar to 1333 encoding when w32-unicode-filenames is t; this is similar to
1334 selection-coding-system. 1334 selection-coding-system.
1335 1335
1336 This arrangement works very well, but it has a few gotchas: 1336 This arrangement works very well, but it has a few gotchas and
1337 limitations:
1337 1338
1338 . Lisp code that encodes or decodes file names manually should 1339 . Lisp code that encodes or decodes file names manually should
1339 normally use 'utf-8' as the coding-system on Windows, 1340 normally use 'utf-8' as the coding-system on Windows,
@@ -1351,6 +1352,12 @@ w32_valid_pointer_p (void *p, int size)
1351 name sfrom UTF-8 to either UTF-16 or ANSI codepage, or going 1352 name sfrom UTF-8 to either UTF-16 or ANSI codepage, or going
1352 through some shadowing function defined here. 1353 through some shadowing function defined here.
1353 1354
1355 . Environment variables stored in Vprocess_environment are encoded
1356 in the ANSI codepage, so if getenv/egetenv is used for a variable
1357 whose value is a file name or a list of directories, it needs to
1358 be converted to UTF-8, before it is used as argument to functions
1359 or decoded into a Lisp string.
1360
1354 . File names passed to external libraries, like the image libraries 1361 . File names passed to external libraries, like the image libraries
1355 and GnuTLS, need special handling. These libraries generally 1362 and GnuTLS, need special handling. These libraries generally
1356 don't support UTF-16 or UTF-8 file names, so they must get file 1363 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)
1378 . For similar reasons, server.el and emacsclient are also limited 1385 . For similar reasons, server.el and emacsclient are also limited
1379 to the current ANSI codepage for now. 1386 to the current ANSI codepage for now.
1380 1387
1381*/ 1388 . Emacs itself can only handle command-line arguments encoded in
1389 the current codepage.
1390
1391 . Turning on w32-unicode-filename on Windows 9X (if it at all
1392 works) requires UNICOWS.DLL, which is currently loaded only in a
1393 GUI session. */
1382 1394
1383 1395
1384 1396
@@ -2365,6 +2377,8 @@ w32_get_resource (char *key, LPDWORD lpdwtype)
2365 return (NULL); 2377 return (NULL);
2366} 2378}
2367 2379
2380/* The argv[] array holds ANSI-encoded strings, and so this function
2381 works with ANS_encoded strings. */
2368void 2382void
2369init_environment (char ** argv) 2383init_environment (char ** argv)
2370{ 2384{
@@ -2508,7 +2522,7 @@ init_environment (char ** argv)
2508 char *p; 2522 char *p;
2509 char modname[MAX_PATH]; 2523 char modname[MAX_PATH];
2510 2524
2511 if (!GetModuleFileName (NULL, modname, MAX_PATH)) 2525 if (!GetModuleFileNameA (NULL, modname, MAX_PATH))
2512 emacs_abort (); 2526 emacs_abort ();
2513 if ((p = _mbsrchr (modname, '\\')) == NULL) 2527 if ((p = _mbsrchr (modname, '\\')) == NULL)
2514 emacs_abort (); 2528 emacs_abort ();
@@ -2672,7 +2686,7 @@ init_environment (char ** argv)
2672 { 2686 {
2673 static char modname[MAX_PATH]; 2687 static char modname[MAX_PATH];
2674 2688
2675 if (!GetModuleFileName (NULL, modname, MAX_PATH)) 2689 if (!GetModuleFileNameA (NULL, modname, MAX_PATH))
2676 emacs_abort (); 2690 emacs_abort ();
2677 argv[0] = modname; 2691 argv[0] = modname;
2678 } 2692 }
@@ -8434,10 +8448,10 @@ check_windows_init_file (void)
8434 8448
8435 /* Implementation note: this function runs early during Emacs 8449 /* Implementation note: this function runs early during Emacs
8436 startup, before startup.el is run. So Vload_path is still in 8450 startup, before startup.el is run. So Vload_path is still in
8437 its initial unibyte form, holding ANSI-encoded file names. 8451 its initial unibyte form, but it holds UTF-8 encoded file
8438 That is why we never bother to ENCODE_FILE here, nor use wide 8452 names, since init_callproc was already called. So we do not
8439 APIs for file names: we will never get UTF-8 encoded file 8453 need to ENCODE_FILE here, but we do need to convert the file
8440 names here. */ 8454 names from UTF-8 to ANSI. */
8441 init_file = build_string ("term/w32-win"); 8455 init_file = build_string ("term/w32-win");
8442 fd = openp (Vload_path, init_file, Fget_load_suffixes (), NULL, Qnil); 8456 fd = openp (Vload_path, init_file, Fget_load_suffixes (), NULL, Qnil);
8443 if (fd < 0) 8457 if (fd < 0)
@@ -8448,6 +8462,8 @@ check_windows_init_file (void)
8448 char *buffer = alloca (1024 8462 char *buffer = alloca (1024
8449 + strlen (init_file_name) 8463 + strlen (init_file_name)
8450 + strlen (load_path)); 8464 + strlen (load_path));
8465 char *msg = buffer;
8466 int needed;
8451 8467
8452 sprintf (buffer, 8468 sprintf (buffer,
8453 "The Emacs Windows initialization file \"%s.el\" " 8469 "The Emacs Windows initialization file \"%s.el\" "
@@ -8459,8 +8475,27 @@ check_windows_init_file (void)
8459 "not unpacked properly.\nSee the README.W32 file in the " 8475 "not unpacked properly.\nSee the README.W32 file in the "
8460 "top-level Emacs directory for more information.", 8476 "top-level Emacs directory for more information.",
8461 init_file_name, load_path); 8477 init_file_name, load_path);
8478 needed = MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, buffer,
8479 -1, NULL, 0);
8480 if (needed > 0)
8481 {
8482 wchar_t *msg_w = alloca ((needed + 1) * sizeof (wchar_t));
8483
8484 MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, buffer, -1,
8485 msg_w, needed);
8486 needed = WideCharToMultiByte (CP_ACP, 0, msg_w, -1,
8487 NULL, 0, NULL, NULL);
8488 if (needed > 0)
8489 {
8490 char *msg_a = alloca (needed + 1);
8491
8492 WideCharToMultiByte (CP_ACP, 0, msg_w, -1, msg_a, needed,
8493 NULL, NULL);
8494 msg = msg_a;
8495 }
8496 }
8462 MessageBox (NULL, 8497 MessageBox (NULL,
8463 buffer, 8498 msg,
8464 "Emacs Abort Dialog", 8499 "Emacs Abort Dialog",
8465 MB_OK | MB_ICONEXCLAMATION | MB_TASKMODAL); 8500 MB_OK | MB_ICONEXCLAMATION | MB_TASKMODAL);
8466 /* Use the low-level system abort. */ 8501 /* Use the low-level system abort. */
diff --git a/src/w32fns.c b/src/w32fns.c
index 9b630679c39..71ea908374d 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -7428,8 +7428,11 @@ DEFUN ("default-printer-name", Fdefault_printer_name, Sdefault_printer_name,
7428 static char pname_buf[256]; 7428 static char pname_buf[256];
7429 int err; 7429 int err;
7430 HANDLE hPrn; 7430 HANDLE hPrn;
7431 PRINTER_INFO_2 *ppi2 = NULL; 7431 PRINTER_INFO_2W *ppi2w = NULL;
7432 PRINTER_INFO_2A *ppi2a = NULL;
7432 DWORD dwNeeded = 0, dwReturned = 0; 7433 DWORD dwNeeded = 0, dwReturned = 0;
7434 char server_name[MAX_UTF8_PATH], share_name[MAX_UTF8_PATH];
7435 char port_name[MAX_UTF8_PATH];
7433 7436
7434 /* Retrieve the default string from Win.ini (the registry). 7437 /* Retrieve the default string from Win.ini (the registry).
7435 * String will be in form "printername,drivername,portname". 7438 * String will be in form "printername,drivername,portname".
@@ -7441,54 +7444,87 @@ DEFUN ("default-printer-name", Fdefault_printer_name, Sdefault_printer_name,
7441 /* We want to know more than the printer name */ 7444 /* We want to know more than the printer name */
7442 if (!OpenPrinter (pname_buf, &hPrn, NULL)) 7445 if (!OpenPrinter (pname_buf, &hPrn, NULL))
7443 return Qnil; 7446 return Qnil;
7444 GetPrinter (hPrn, 2, NULL, 0, &dwNeeded); 7447 /* GetPrinterW is not supported by unicows.dll. */
7448 if (w32_unicode_filenames && os_subtype != OS_9X)
7449 GetPrinterW (hPrn, 2, NULL, 0, &dwNeeded);
7450 else
7451 GetPrinterA (hPrn, 2, NULL, 0, &dwNeeded);
7445 if (dwNeeded == 0) 7452 if (dwNeeded == 0)
7446 { 7453 {
7447 ClosePrinter (hPrn); 7454 ClosePrinter (hPrn);
7448 return Qnil; 7455 return Qnil;
7449 } 7456 }
7450 /* Allocate memory for the PRINTER_INFO_2 struct */ 7457 /* Call GetPrinter again with big enough memory block. */
7451 ppi2 = xmalloc (dwNeeded); 7458 if (w32_unicode_filenames && os_subtype != OS_9X)
7452 if (!ppi2)
7453 { 7459 {
7460 /* Allocate memory for the PRINTER_INFO_2 struct. */
7461 ppi2w = xmalloc (dwNeeded);
7462 err = GetPrinterW (hPrn, 2, (LPBYTE)ppi2w, dwNeeded, &dwReturned);
7454 ClosePrinter (hPrn); 7463 ClosePrinter (hPrn);
7455 return Qnil; 7464 if (!err)
7465 {
7466 xfree (ppi2w);
7467 return Qnil;
7468 }
7469
7470 if ((ppi2w->Attributes & PRINTER_ATTRIBUTE_SHARED)
7471 && ppi2w->pServerName)
7472 {
7473 filename_from_utf16 (ppi2w->pServerName, server_name);
7474 filename_from_utf16 (ppi2w->pShareName, share_name);
7475 }
7476 else
7477 {
7478 server_name[0] = '\0';
7479 filename_from_utf16 (ppi2w->pPortName, port_name);
7480 }
7456 } 7481 }
7457 /* Call GetPrinter again with big enough memory block. */ 7482 else
7458 err = GetPrinter (hPrn, 2, (LPBYTE)ppi2, dwNeeded, &dwReturned);
7459 ClosePrinter (hPrn);
7460 if (!err)
7461 { 7483 {
7462 xfree (ppi2); 7484 ppi2a = xmalloc (dwNeeded);
7463 return Qnil; 7485 err = GetPrinterA (hPrn, 2, (LPBYTE)ppi2a, dwNeeded, &dwReturned);
7464 } 7486 ClosePrinter (hPrn);
7487 if (!err)
7488 {
7489 xfree (ppi2a);
7490 return Qnil;
7491 }
7465 7492
7466 if (ppi2) 7493 if ((ppi2a->Attributes & PRINTER_ATTRIBUTE_SHARED)
7467 { 7494 && ppi2a->pServerName)
7468 if (ppi2->Attributes & PRINTER_ATTRIBUTE_SHARED && ppi2->pServerName) 7495 {
7469 { 7496 filename_from_ansi (ppi2a->pServerName, server_name);
7470 /* a remote printer */ 7497 filename_from_ansi (ppi2a->pShareName, share_name);
7471 if (*ppi2->pServerName == '\\')
7472 snprintf (pname_buf, sizeof (pname_buf), "%s\\%s", ppi2->pServerName,
7473 ppi2->pShareName);
7474 else
7475 snprintf (pname_buf, sizeof (pname_buf), "\\\\%s\\%s", ppi2->pServerName,
7476 ppi2->pShareName);
7477 pname_buf[sizeof (pname_buf) - 1] = '\0';
7478 } 7498 }
7479 else 7499 else
7480 { 7500 {
7481 /* a local printer */ 7501 server_name[0] = '\0';
7482 strncpy (pname_buf, ppi2->pPortName, sizeof (pname_buf)); 7502 filename_from_ansi (ppi2a->pPortName, port_name);
7483 pname_buf[sizeof (pname_buf) - 1] = '\0';
7484 /* `pPortName' can include several ports, delimited by ','.
7485 * we only use the first one. */
7486 strtok (pname_buf, ",");
7487 } 7503 }
7488 xfree (ppi2);
7489 } 7504 }
7490 7505
7491 return build_string (pname_buf); 7506 if (server_name[0])
7507 {
7508 /* a remote printer */
7509 if (server_name[0] == '\\')
7510 snprintf (pname_buf, sizeof (pname_buf), "%s\\%s", server_name,
7511 share_name);
7512 else
7513 snprintf (pname_buf, sizeof (pname_buf), "\\\\%s\\%s", server_name,
7514 share_name);
7515 pname_buf[sizeof (pname_buf) - 1] = '\0';
7516 }
7517 else
7518 {
7519 /* a local printer */
7520 strncpy (pname_buf, port_name, sizeof (pname_buf));
7521 pname_buf[sizeof (pname_buf) - 1] = '\0';
7522 /* `pPortName' can include several ports, delimited by ','.
7523 * we only use the first one. */
7524 strtok (pname_buf, ",");
7525 }
7526
7527 return DECODE_FILE (build_unibyte_string (pname_buf));
7492} 7528}
7493 7529
7494 7530