summaryrefslogtreecommitdiff
path: root/src/w32menu.c
diff options
context:
space:
mode:
authorJason Rumney <jasonr@wanchan>2010-08-13 22:54:32 +0800
committerJason Rumney <jasonr@wanchan>2010-08-13 22:54:32 +0800
commit1c9b41290f206173f1031572094ec6373c265c0b (patch)
treeb02e826ace649c2bfdb908b6956c9b6f6b49e1f0 /src/w32menu.c
parent2b4e627726bc1dfcbf95f069fb97f932471efad8 (diff)
downloademacs-1c9b41290f206173f1031572094ec6373c265c0b.tar.gz
Fix for bug#5629: Use unicode message box if available.
* w32menu.c (simple_dialog_show): Use unicode message box if available. (MessageBoxW_Proc): New function typedef. (unicode-message-box): New function pointer. (globals_of_w32menu): Import it from user32.dll.
Diffstat (limited to 'src/w32menu.c')
-rw-r--r--src/w32menu.c84
1 files changed, 68 insertions, 16 deletions
diff --git a/src/w32menu.c b/src/w32menu.c
index 0aaca5e234e..1146843bec8 100644
--- a/src/w32menu.c
+++ b/src/w32menu.c
@@ -72,10 +72,16 @@ typedef BOOL (WINAPI * SetMenuItemInfoA_Proc) (
IN UINT,
IN BOOL,
IN LPCMENUITEMINFOA);
+typedef int (WINAPI * MessageBoxW_Proc) (
+ IN HWND window,
+ IN WCHAR *text,
+ IN WCHAR *caption,
+ IN UINT type);
GetMenuItemInfoA_Proc get_menu_item_info = NULL;
SetMenuItemInfoA_Proc set_menu_item_info = NULL;
AppendMenuW_Proc unicode_append_menu = NULL;
+MessageBoxW_Proc unicode_message_box = NULL;
Lisp_Object Qdebug_on_next_call;
@@ -99,6 +105,8 @@ static int is_simple_dialog (Lisp_Object);
static Lisp_Object simple_dialog_show (FRAME_PTR, Lisp_Object, Lisp_Object);
#endif
+static void utf8to16 (unsigned char *, int, WCHAR *);
+
void w32_free_menu_strings (HWND);
@@ -1220,30 +1228,73 @@ simple_dialog_show (FRAME_PTR f, Lisp_Object contents, Lisp_Object header)
{
int answer;
UINT type;
- char *text, *title;
Lisp_Object lispy_answer = Qnil, temp = XCAR (contents);
- if (STRINGP (temp))
- text = SDATA (temp);
- else
- text = "";
+ type = MB_YESNO;
+
+ /* Since we only handle Yes/No dialogs, and we already checked
+ is_simple_dialog, we don't need to worry about checking contents
+ to see what type of dialog to use. */
- if (NILP (header))
+ /* Use unicode if possible, so any language can be displayed. */
+ if (unicode_message_box)
{
- title = "Question";
- type = MB_ICONQUESTION;
+ WCHAR *text, *title;
+
+ if (STRINGP (temp))
+ {
+ char *utf8_text = SDATA (ENCODE_UTF_8 (temp));
+ /* Be pessimistic about the number of characters needed.
+ Remember characters outside the BMP will take more than
+ one utf16 word, so we cannot simply use the character
+ length of temp. */
+ int utf8_len = strlen (utf8_text);
+ text = alloca ((utf8_len + 1) * sizeof (WCHAR));
+ utf8to16 (utf8_text, utf8_len, text);
+ }
+ else
+ {
+ text = L"";
+ }
+
+ if (NILP (header))
+ {
+ title = L"Question";
+ type |= MB_ICONQUESTION;
+ }
+ else
+ {
+ title = L"Information";
+ type |= MB_ICONINFORMATION;
+ }
+
+ answer = unicode_message_box (FRAME_W32_WINDOW (f), text, title, type);
}
else
{
- title = "Information";
- type = MB_ICONINFORMATION;
- }
- type |= MB_YESNO;
+ char *text, *title;
- /* Since we only handle Yes/No dialogs, and we already checked
- is_simple_dialog, we don't need to worry about checking contents
- to see what type of dialog to use. */
- answer = MessageBox (FRAME_W32_WINDOW (f), text, title, type);
+ /* Fall back on ANSI message box, but at least use system
+ encoding so questions representable by the system codepage
+ are encoded properly. */
+ if (STRINGP (temp))
+ text = SDATA (ENCODE_SYSTEM (temp));
+ else
+ text = "";
+
+ if (NILP (header))
+ {
+ title = "Question";
+ type |= MB_ICONQUESTION;
+ }
+ else
+ {
+ title = "Information";
+ type |= MB_ICONINFORMATION;
+ }
+
+ answer = MessageBox (FRAME_W32_WINDOW (f), text, title, type);
+ }
if (answer == IDYES)
lispy_answer = build_string ("Yes");
@@ -1697,6 +1748,7 @@ globals_of_w32menu (void)
get_menu_item_info = (GetMenuItemInfoA_Proc) GetProcAddress (user32, "GetMenuItemInfoA");
set_menu_item_info = (SetMenuItemInfoA_Proc) GetProcAddress (user32, "SetMenuItemInfoA");
unicode_append_menu = (AppendMenuW_Proc) GetProcAddress (user32, "AppendMenuW");
+ unicode_message_box = (MessageBoxW_Proc) GetProcAddress (user32, "MessageBoxW");
}
/* arch-tag: 0eaed431-bb4e-4aac-a527-95a1b4f1fed0