diff options
| author | Eli Zaretskii | 2014-02-06 17:27:46 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2014-02-06 17:27:46 +0200 |
| commit | 829f4f2256d11c0336618269b45b2eea299ed2ce (patch) | |
| tree | 74fbee3b06e4efad9bd218713188d73a86fa447d | |
| parent | 629de968455d2b4632fbe9db860ae4ac7e933b9b (diff) | |
| download | emacs-829f4f2256d11c0336618269b45b2eea299ed2ce.tar.gz emacs-829f4f2256d11c0336618269b45b2eea299ed2ce.zip | |
Another fix for handling of file names on Windows 9X.
src/w32.c (pMultiByteToWideChar, pWideCharToMultiByte): New
variables: pointers through which to call the respective APIs.
(filename_to_utf16, filename_from_utf16, filename_to_ansi)
(filename_from_ansi, sys_link, check_windows_init_file): Call
MultiByteToWideChar and WideCharToMultiByte through pointers.
This is required on Windows 9X, where we dynamically load
UNICOWS.DLL which has their non-stub implementations.
(maybe_load_unicows_dll): Assign addresses to these 2 function
pointers after loading UNICOWS.DLL.
src/w32fns.c (Fx_file_dialog, Fw32_shell_execute) [!CYGWIN]: Call
MultiByteToWideChar and WideCharToMultiByte through function
pointers.
src/w32.h (pMultiByteToWideChar, pWideCharToMultiByte): New
declarations.
| -rw-r--r-- | src/ChangeLog | 19 | ||||
| -rw-r--r-- | src/w32.c | 60 | ||||
| -rw-r--r-- | src/w32.h | 3 | ||||
| -rw-r--r-- | src/w32fns.c | 28 |
4 files changed, 76 insertions, 34 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 8a7dfae4864..e19b6d8781d 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,22 @@ | |||
| 1 | 2014-02-06 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | * w32.c (pMultiByteToWideChar, pWideCharToMultiByte): New | ||
| 4 | variables: pointers through which to call the respective APIs. | ||
| 5 | (filename_to_utf16, filename_from_utf16, filename_to_ansi) | ||
| 6 | (filename_from_ansi, sys_link, check_windows_init_file): Call | ||
| 7 | MultiByteToWideChar and WideCharToMultiByte through pointers. | ||
| 8 | This is required on Windows 9X, where we dynamically load | ||
| 9 | UNICOWS.DLL which has their non-stub implementations. | ||
| 10 | (maybe_load_unicows_dll): Assign addresses to these 2 function | ||
| 11 | pointers after loading UNICOWS.DLL. | ||
| 12 | |||
| 13 | * w32fns.c (Fx_file_dialog, Fw32_shell_execute) [!CYGWIN]: Call | ||
| 14 | MultiByteToWideChar and WideCharToMultiByte through function | ||
| 15 | pointers. | ||
| 16 | |||
| 17 | * w32.h (pMultiByteToWideChar, pWideCharToMultiByte): New | ||
| 18 | declarations. | ||
| 19 | |||
| 1 | 2014-02-06 Jan Djärv <jan.h.d@swipnet.se> | 20 | 2014-02-06 Jan Djärv <jan.h.d@swipnet.se> |
| 2 | 21 | ||
| 3 | * nsterm.m (toggleFullScreen:): Hide menubar on secondary monitor | 22 | * nsterm.m (toggleFullScreen:): Hide menubar on secondary monitor |
| @@ -478,6 +478,9 @@ typedef DWORD (WINAPI *GetAdaptersInfo_Proc) ( | |||
| 478 | PIP_ADAPTER_INFO pAdapterInfo, | 478 | PIP_ADAPTER_INFO pAdapterInfo, |
| 479 | PULONG pOutBufLen); | 479 | PULONG pOutBufLen); |
| 480 | 480 | ||
| 481 | int (WINAPI *pMultiByteToWideChar)(UINT,DWORD,LPCSTR,int,LPWSTR,int); | ||
| 482 | int (WINAPI *pWideCharToMultiByte)(UINT,DWORD,LPCWSTR,int,LPSTR,int,LPCSTR,LPBOOL); | ||
| 483 | |||
| 481 | /* ** A utility function ** */ | 484 | /* ** A utility function ** */ |
| 482 | static BOOL | 485 | static BOOL |
| 483 | is_windows_9x (void) | 486 | is_windows_9x (void) |
| @@ -1543,8 +1546,8 @@ codepage_for_filenames (CPINFO *cp_info) | |||
| 1543 | int | 1546 | int |
| 1544 | filename_to_utf16 (const char *fn_in, wchar_t *fn_out) | 1547 | filename_to_utf16 (const char *fn_in, wchar_t *fn_out) |
| 1545 | { | 1548 | { |
| 1546 | int result = MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, fn_in, -1, | 1549 | int result = pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, fn_in, -1, |
| 1547 | fn_out, MAX_PATH); | 1550 | fn_out, MAX_PATH); |
| 1548 | 1551 | ||
| 1549 | if (!result) | 1552 | if (!result) |
| 1550 | { | 1553 | { |
| @@ -1570,8 +1573,8 @@ filename_to_utf16 (const char *fn_in, wchar_t *fn_out) | |||
| 1570 | int | 1573 | int |
| 1571 | filename_from_utf16 (const wchar_t *fn_in, char *fn_out) | 1574 | filename_from_utf16 (const wchar_t *fn_in, char *fn_out) |
| 1572 | { | 1575 | { |
| 1573 | int result = WideCharToMultiByte (CP_UTF8, 0, fn_in, -1, | 1576 | int result = pWideCharToMultiByte (CP_UTF8, 0, fn_in, -1, |
| 1574 | fn_out, MAX_UTF8_PATH, NULL, NULL); | 1577 | fn_out, MAX_UTF8_PATH, NULL, NULL); |
| 1575 | 1578 | ||
| 1576 | if (!result) | 1579 | if (!result) |
| 1577 | { | 1580 | { |
| @@ -1604,8 +1607,8 @@ filename_to_ansi (const char *fn_in, char *fn_out) | |||
| 1604 | int result; | 1607 | int result; |
| 1605 | int codepage = codepage_for_filenames (NULL); | 1608 | int codepage = codepage_for_filenames (NULL); |
| 1606 | 1609 | ||
| 1607 | result = WideCharToMultiByte (codepage, 0, fn_utf16, -1, | 1610 | result = pWideCharToMultiByte (codepage, 0, fn_utf16, -1, |
| 1608 | fn_out, MAX_PATH, NULL, NULL); | 1611 | fn_out, MAX_PATH, NULL, NULL); |
| 1609 | if (!result) | 1612 | if (!result) |
| 1610 | { | 1613 | { |
| 1611 | DWORD err = GetLastError (); | 1614 | DWORD err = GetLastError (); |
| @@ -1634,8 +1637,8 @@ filename_from_ansi (const char *fn_in, char *fn_out) | |||
| 1634 | { | 1637 | { |
| 1635 | wchar_t fn_utf16[MAX_PATH]; | 1638 | wchar_t fn_utf16[MAX_PATH]; |
| 1636 | int codepage = codepage_for_filenames (NULL); | 1639 | int codepage = codepage_for_filenames (NULL); |
| 1637 | int result = MultiByteToWideChar (codepage, MB_ERR_INVALID_CHARS, fn_in, -1, | 1640 | int result = pMultiByteToWideChar (codepage, MB_ERR_INVALID_CHARS, fn_in, -1, |
| 1638 | fn_utf16, MAX_PATH); | 1641 | fn_utf16, MAX_PATH); |
| 1639 | 1642 | ||
| 1640 | if (!result) | 1643 | if (!result) |
| 1641 | { | 1644 | { |
| @@ -4033,8 +4036,8 @@ sys_link (const char * old, const char * new) | |||
| 4033 | /* We used to pass MB_PRECOMPOSED as the 2nd arg here, but MSDN | 4036 | /* We used to pass MB_PRECOMPOSED as the 2nd arg here, but MSDN |
| 4034 | indicates that flag is unsupported for CP_UTF8, and OTOH says | 4037 | indicates that flag is unsupported for CP_UTF8, and OTOH says |
| 4035 | it is the default anyway. */ | 4038 | it is the default anyway. */ |
| 4036 | wlen = MultiByteToWideChar (CP_UTF8, 0, newname, -1, | 4039 | wlen = pMultiByteToWideChar (CP_UTF8, 0, newname, -1, |
| 4037 | data.wid.cStreamName, MAX_PATH); | 4040 | data.wid.cStreamName, MAX_PATH); |
| 4038 | if (wlen > 0) | 4041 | if (wlen > 0) |
| 4039 | { | 4042 | { |
| 4040 | LPVOID context = NULL; | 4043 | LPVOID context = NULL; |
| @@ -8749,22 +8752,22 @@ check_windows_init_file (void) | |||
| 8749 | "not unpacked properly.\nSee the README.W32 file in the " | 8752 | "not unpacked properly.\nSee the README.W32 file in the " |
| 8750 | "top-level Emacs directory for more information.", | 8753 | "top-level Emacs directory for more information.", |
| 8751 | init_file_name, load_path); | 8754 | init_file_name, load_path); |
| 8752 | needed = MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, buffer, | 8755 | needed = pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, buffer, |
| 8753 | -1, NULL, 0); | 8756 | -1, NULL, 0); |
| 8754 | if (needed > 0) | 8757 | if (needed > 0) |
| 8755 | { | 8758 | { |
| 8756 | wchar_t *msg_w = alloca ((needed + 1) * sizeof (wchar_t)); | 8759 | wchar_t *msg_w = alloca ((needed + 1) * sizeof (wchar_t)); |
| 8757 | 8760 | ||
| 8758 | MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, buffer, -1, | 8761 | pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, buffer, -1, |
| 8759 | msg_w, needed); | 8762 | msg_w, needed); |
| 8760 | needed = WideCharToMultiByte (CP_ACP, 0, msg_w, -1, | 8763 | needed = pWideCharToMultiByte (CP_ACP, 0, msg_w, -1, |
| 8761 | NULL, 0, NULL, NULL); | 8764 | NULL, 0, NULL, NULL); |
| 8762 | if (needed > 0) | 8765 | if (needed > 0) |
| 8763 | { | 8766 | { |
| 8764 | char *msg_a = alloca (needed + 1); | 8767 | char *msg_a = alloca (needed + 1); |
| 8765 | 8768 | ||
| 8766 | WideCharToMultiByte (CP_ACP, 0, msg_w, -1, msg_a, needed, | 8769 | pWideCharToMultiByte (CP_ACP, 0, msg_w, -1, msg_a, needed, |
| 8767 | NULL, NULL); | 8770 | NULL, NULL); |
| 8768 | msg = msg_a; | 8771 | msg = msg_a; |
| 8769 | } | 8772 | } |
| 8770 | } | 8773 | } |
| @@ -8932,7 +8935,17 @@ maybe_load_unicows_dll (void) | |||
| 8932 | { | 8935 | { |
| 8933 | HANDLE ret = LoadLibrary ("Unicows.dll"); | 8936 | HANDLE ret = LoadLibrary ("Unicows.dll"); |
| 8934 | if (ret) | 8937 | if (ret) |
| 8935 | return ret; | 8938 | { |
| 8939 | /* These two functions are present on Windows 9X as stubs | ||
| 8940 | that always fail. We need the real implementations from | ||
| 8941 | UNICOWS.DLL, so we must call these functions through | ||
| 8942 | pointers, and assign the correct addresses to these | ||
| 8943 | pointers at program startup (see emacs.c, which calls | ||
| 8944 | this function early on). */ | ||
| 8945 | pMultiByteToWideChar = GetProcAddress (ret, "MultiByteToWideChar"); | ||
| 8946 | pWideCharToMultiByte = GetProcAddress (ret, "WideCharToMultiByte"); | ||
| 8947 | return ret; | ||
| 8948 | } | ||
| 8936 | else | 8949 | else |
| 8937 | { | 8950 | { |
| 8938 | int button; | 8951 | int button; |
| @@ -8954,7 +8967,14 @@ maybe_load_unicows_dll (void) | |||
| 8954 | } | 8967 | } |
| 8955 | } | 8968 | } |
| 8956 | else | 8969 | else |
| 8957 | return LoadLibrary ("Gdi32.dll"); | 8970 | { |
| 8971 | /* On NT family of Windows, these two functions are always | ||
| 8972 | linked in, so we just assign their addresses to the 2 | ||
| 8973 | pointers; no need for the LoadLibrary dance. */ | ||
| 8974 | pMultiByteToWideChar = MultiByteToWideChar; | ||
| 8975 | pWideCharToMultiByte = WideCharToMultiByte; | ||
| 8976 | return LoadLibrary ("Gdi32.dll"); | ||
| 8977 | } | ||
| 8958 | } | 8978 | } |
| 8959 | 8979 | ||
| 8960 | /* | 8980 | /* |
| @@ -175,6 +175,9 @@ extern int _sys_wait_accept (int fd); | |||
| 175 | extern Lisp_Object QCloaded_from; | 175 | extern Lisp_Object QCloaded_from; |
| 176 | extern HMODULE w32_delayed_load (Lisp_Object); | 176 | extern HMODULE w32_delayed_load (Lisp_Object); |
| 177 | 177 | ||
| 178 | extern int (WINAPI *pMultiByteToWideChar)(UINT,DWORD,LPCSTR,int,LPWSTR,int); | ||
| 179 | extern int (WINAPI *pWideCharToMultiByte)(UINT,DWORD,LPCWSTR,int,LPSTR,int,LPCSTR,LPBOOL); | ||
| 180 | |||
| 178 | extern void init_environment (char **); | 181 | extern void init_environment (char **); |
| 179 | extern void check_windows_init_file (void); | 182 | extern void check_windows_init_file (void); |
| 180 | extern void syms_of_ntproc (void); | 183 | extern void syms_of_ntproc (void); |
diff --git a/src/w32fns.c b/src/w32fns.c index 7aca7fde3ad..66f532c3721 100644 --- a/src/w32fns.c +++ b/src/w32fns.c | |||
| @@ -6538,13 +6538,13 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */) | |||
| 6538 | if (errno == ENOENT && filename_buf_w[MAX_PATH - 1] != 0) | 6538 | if (errno == ENOENT && filename_buf_w[MAX_PATH - 1] != 0) |
| 6539 | report_file_error ("filename too long", default_filename); | 6539 | report_file_error ("filename too long", default_filename); |
| 6540 | } | 6540 | } |
| 6541 | len = MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, | 6541 | len = pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, |
| 6542 | SSDATA (prompt), -1, NULL, 0); | 6542 | SSDATA (prompt), -1, NULL, 0); |
| 6543 | if (len > 32768) | 6543 | if (len > 32768) |
| 6544 | len = 32768; | 6544 | len = 32768; |
| 6545 | prompt_w = alloca (len * sizeof (wchar_t)); | 6545 | prompt_w = alloca (len * sizeof (wchar_t)); |
| 6546 | MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, | 6546 | pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, |
| 6547 | SSDATA (prompt), -1, prompt_w, len); | 6547 | SSDATA (prompt), -1, prompt_w, len); |
| 6548 | } | 6548 | } |
| 6549 | else | 6549 | else |
| 6550 | { | 6550 | { |
| @@ -6556,18 +6556,18 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */) | |||
| 6556 | if (errno == ENOENT && filename_buf_a[MAX_PATH - 1] != 0) | 6556 | if (errno == ENOENT && filename_buf_a[MAX_PATH - 1] != 0) |
| 6557 | report_file_error ("filename too long", default_filename); | 6557 | report_file_error ("filename too long", default_filename); |
| 6558 | } | 6558 | } |
| 6559 | len = MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, | 6559 | len = pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, |
| 6560 | SSDATA (prompt), -1, NULL, 0); | 6560 | SSDATA (prompt), -1, NULL, 0); |
| 6561 | if (len > 32768) | 6561 | if (len > 32768) |
| 6562 | len = 32768; | 6562 | len = 32768; |
| 6563 | prompt_w = alloca (len * sizeof (wchar_t)); | 6563 | prompt_w = alloca (len * sizeof (wchar_t)); |
| 6564 | MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, | 6564 | pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, |
| 6565 | SSDATA (prompt), -1, prompt_w, len); | 6565 | SSDATA (prompt), -1, prompt_w, len); |
| 6566 | len = WideCharToMultiByte (CP_ACP, 0, prompt_w, -1, NULL, 0, NULL, NULL); | 6566 | len = pWideCharToMultiByte (CP_ACP, 0, prompt_w, -1, NULL, 0, NULL, NULL); |
| 6567 | if (len > 32768) | 6567 | if (len > 32768) |
| 6568 | len = 32768; | 6568 | len = 32768; |
| 6569 | prompt_a = alloca (len); | 6569 | prompt_a = alloca (len); |
| 6570 | WideCharToMultiByte (CP_ACP, 0, prompt_w, -1, prompt_a, len, NULL, NULL); | 6570 | pWideCharToMultiByte (CP_ACP, 0, prompt_w, -1, prompt_a, len, NULL, NULL); |
| 6571 | } | 6571 | } |
| 6572 | #endif /* NTGUI_UNICODE */ | 6572 | #endif /* NTGUI_UNICODE */ |
| 6573 | 6573 | ||
| @@ -6974,13 +6974,13 @@ a ShowWindow flag: | |||
| 6974 | int len; | 6974 | int len; |
| 6975 | 6975 | ||
| 6976 | parameters = ENCODE_SYSTEM (parameters); | 6976 | parameters = ENCODE_SYSTEM (parameters); |
| 6977 | len = MultiByteToWideChar (CP_ACP, MB_ERR_INVALID_CHARS, | 6977 | len = pMultiByteToWideChar (CP_ACP, MB_ERR_INVALID_CHARS, |
| 6978 | SSDATA (parameters), -1, NULL, 0); | 6978 | SSDATA (parameters), -1, NULL, 0); |
| 6979 | if (len > 32768) | 6979 | if (len > 32768) |
| 6980 | len = 32768; | 6980 | len = 32768; |
| 6981 | params_w = alloca (len * sizeof (wchar_t)); | 6981 | params_w = alloca (len * sizeof (wchar_t)); |
| 6982 | MultiByteToWideChar (CP_ACP, MB_ERR_INVALID_CHARS, | 6982 | pMultiByteToWideChar (CP_ACP, MB_ERR_INVALID_CHARS, |
| 6983 | SSDATA (parameters), -1, params_w, len); | 6983 | SSDATA (parameters), -1, params_w, len); |
| 6984 | } | 6984 | } |
| 6985 | if (STRINGP (operation)) | 6985 | if (STRINGP (operation)) |
| 6986 | { | 6986 | { |