]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix for bug#5629: Use unicode message box if available.
authorJason Rumney <jasonr@wanchan>
Fri, 13 Aug 2010 14:54:32 +0000 (22:54 +0800)
committerJason Rumney <jasonr@wanchan>
Fri, 13 Aug 2010 14:54:32 +0000 (22:54 +0800)
* 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.

src/ChangeLog
src/w32menu.c

index 69b1e9866d5a888ff95ba291ec5fe9cc3e321a60..f13e5105368e7bb489caee24376dbde470135dd5 100644 (file)
@@ -1,3 +1,10 @@
+2010-08-13  Jason Rumney  <jasonr@gnu.org>
+
+       * 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. (Bug#5629)
+
 2010-08-13  Jan Djärv  <jan.h.d@swipnet.se>
 
        * frame.h (Qtool_bar_position): Declare.
index 0aaca5e234eefa6d3cfa3a58c523c57e167ab527..1146843bec889e4647180851ea065115edbc5b5f 100644 (file)
@@ -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);
 \f
 
@@ -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