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 /src/w32.c | |
| 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.
Diffstat (limited to 'src/w32.c')
| -rw-r--r-- | src/w32.c | 60 |
1 files changed, 40 insertions, 20 deletions
| @@ -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 | /* |