diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/callproc.c | 17 | ||||
| -rw-r--r-- | src/emacs.c | 32 | ||||
| -rw-r--r-- | src/w32.c | 53 | ||||
| -rw-r--r-- | src/w32fns.c | 104 |
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"), |
| @@ -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. */ | ||
| 2368 | void | 2382 | void |
| 2369 | init_environment (char ** argv) | 2383 | init_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 | ||