Merge from emacs-24; up to 2012-05-07T14:57:18Z!michael.albinus@gmx.de
[bpt/emacs.git] / src / w32fns.c
index bbcda21..be008bb 100644 (file)
@@ -26,7 +26,6 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <limits.h>
 #include <errno.h>
 #include <math.h>
-#include <setjmp.h>
 
 #include "lisp.h"
 #include "w32term.h"
@@ -93,7 +92,6 @@ static HWND hourglass_hwnd = NULL;
 
 static int w32_in_use;
 
-Lisp_Object Qnone;
 Lisp_Object Qsuppress_icon;
 Lisp_Object Qundefined_color;
 Lisp_Object Qcancel_timer;
@@ -189,6 +187,8 @@ static int image_cache_refcount, dpyinfo_refcount;
 
 static HWND w32_visible_system_caret_hwnd;
 
+static int w32_unicode_gui;
+
 /* From w32menu.c  */
 extern HMENU current_popup_menu;
 static int menubar_in_use = 0;
@@ -1489,7 +1489,7 @@ x_set_icon_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
   else if (!NILP (arg) || NILP (oldval))
     return;
 
-  FVAR (f, icon_name) = arg;
+  fset_icon_name (f, arg);
 
 #if 0
   if (f->output_data.w32->icon_bitmap != 0)
@@ -1498,11 +1498,11 @@ x_set_icon_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
   BLOCK_INPUT;
 
   result = x_text_icon (f,
-                       SSDATA ((!NILP (FVAR (f, icon_name))
-                                ? FVAR (f, icon_name)
-                                : !NILP (FVAR (f, title))
-                                ? FVAR (f, title)
-                                : FVAR (f, name))));
+                       SSDATA ((!NILP (f->icon_name)
+                                ? f->icon_name
+                                : !NILP (f->title)
+                                ? f->title
+                                : f->name)));
 
   if (result)
     {
@@ -1631,8 +1631,8 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
       }
       UNBLOCK_INPUT;
 
-      if (WINDOWP (FVAR (f, tool_bar_window)))
-       clear_glyph_matrix (XWINDOW (FVAR (f, tool_bar_window))->current_matrix);
+      if (WINDOWP (f->tool_bar_window))
+       clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
     }
 
   run_window_configuration_change_hook (f);
@@ -1674,7 +1674,7 @@ x_set_name (struct frame *f, Lisp_Object name, int explicit)
       /* Check for no change needed in this very common case
         before we do any consing.  */
       if (!strcmp (FRAME_W32_DISPLAY_INFO (f)->w32_id_name,
-                  SDATA (FVAR (f, name))))
+                  SDATA (f->name)))
        return;
       name = build_string (FRAME_W32_DISPLAY_INFO (f)->w32_id_name);
     }
@@ -1682,15 +1682,15 @@ x_set_name (struct frame *f, Lisp_Object name, int explicit)
     CHECK_STRING (name);
 
   /* Don't change the name if it's already NAME.  */
-  if (! NILP (Fstring_equal (name, FVAR (f, name))))
+  if (! NILP (Fstring_equal (name, f->name)))
     return;
 
-  FVAR (f, name) = name;
+  fset_name (f, name);
 
   /* For setting the frame title, the title parameter should override
      the name parameter.  */
-  if (! NILP (FVAR (f, title)))
-    name = FVAR (f, title);
+  if (! NILP (f->title))
+    name = f->title;
 
   if (FRAME_W32_WINDOW (f))
     {
@@ -1728,15 +1728,15 @@ void
 x_set_title (struct frame *f, Lisp_Object name, Lisp_Object old_name)
 {
   /* Don't change the title if it's already NAME.  */
-  if (EQ (name, FVAR (f, title)))
+  if (EQ (name, f->title))
     return;
 
   update_mode_lines = 1;
 
-  FVAR (f, title) = name;
+  fset_title (f, name);
 
   if (NILP (name))
-    name = FVAR (f, name);
+    name = f->name;
 
   if (FRAME_W32_WINDOW (f))
     {
@@ -1780,23 +1780,37 @@ w32_load_cursor (LPCTSTR name)
 
 static LRESULT CALLBACK w32_wnd_proc (HWND, UINT, WPARAM, LPARAM);
 
+#define INIT_WINDOW_CLASS(WC)                    \
+  (WC).style = CS_HREDRAW | CS_VREDRAW;                  \
+  (WC).lpfnWndProc = (WNDPROC) w32_wnd_proc;      \
+  (WC).cbClsExtra = 0;                            \
+  (WC).cbWndExtra = WND_EXTRA_BYTES;              \
+  (WC).hInstance = hinst;                         \
+  (WC).hIcon = LoadIcon (hinst, EMACS_CLASS);     \
+  (WC).hCursor = w32_load_cursor (IDC_ARROW);     \
+  (WC).hbrBackground = NULL;                      \
+  (WC).lpszMenuName = NULL;                       \
+
 static BOOL
 w32_init_class (HINSTANCE hinst)
 {
-  WNDCLASS wc;
 
-  wc.style = CS_HREDRAW | CS_VREDRAW;
-  wc.lpfnWndProc = (WNDPROC) w32_wnd_proc;
-  wc.cbClsExtra = 0;
-  wc.cbWndExtra = WND_EXTRA_BYTES;
-  wc.hInstance = hinst;
-  wc.hIcon = LoadIcon (hinst, EMACS_CLASS);
-  wc.hCursor = w32_load_cursor (IDC_ARROW);
-  wc.hbrBackground = NULL; /* GetStockObject (WHITE_BRUSH);  */
-  wc.lpszMenuName = NULL;
-  wc.lpszClassName = EMACS_CLASS;
+  if (w32_unicode_gui)
+    {
+      WNDCLASSW  uwc;
+      INIT_WINDOW_CLASS(uwc);
+      uwc.lpszClassName = L"Emacs";
+
+      return RegisterClassW (&uwc);
+    }
+  else
+    {
+      WNDCLASS  wc;
+      INIT_WINDOW_CLASS(wc);
+      wc.lpszClassName = EMACS_CLASS;
 
-  return (RegisterClass (&wc));
+      return RegisterClassA (&wc);
+    }
 }
 
 static HWND
@@ -2246,7 +2260,7 @@ w32_msg_pump (deferred_msg * msg_buf)
 
   msh_mousewheel = RegisterWindowMessage (MSH_MOUSEWHEEL);
 
-  while (GetMessage (&msg, NULL, 0, 0))
+  while ((w32_unicode_gui ? GetMessageW : GetMessageA) (&msg, NULL, 0, 0))
     {
       if (msg.hwnd == NULL)
        {
@@ -2265,7 +2279,7 @@ w32_msg_pump (deferred_msg * msg_buf)
               CoInitialize (NULL);
              w32_createwindow ((struct frame *) msg.wParam);
              if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0))
-               abort ();
+               emacs_abort ();
              break;
            case WM_EMACS_SETLOCALE:
              SetThreadLocale (msg.wParam);
@@ -2275,7 +2289,7 @@ w32_msg_pump (deferred_msg * msg_buf)
              result = (int) ActivateKeyboardLayout ((HKL) msg.wParam, 0);
              if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE,
                                      result, 0))
-               abort ();
+               emacs_abort ();
              break;
            case WM_EMACS_REGISTER_HOT_KEY:
              focus_window = GetFocus ();
@@ -2296,7 +2310,7 @@ w32_msg_pump (deferred_msg * msg_buf)
                  GC.  */
              XSETCAR ((Lisp_Object) ((EMACS_INT) msg.lParam), Qnil);
              if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0))
-               abort ();
+               emacs_abort ();
              break;
            case WM_EMACS_TOGGLE_LOCK_KEY:
              {
@@ -2328,7 +2342,7 @@ w32_msg_pump (deferred_msg * msg_buf)
                  }
                if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE,
                                        cur_state, 0))
-                 abort ();
+                 emacs_abort ();
              }
              break;
 #ifdef MSG_DEBUG
@@ -2341,7 +2355,10 @@ w32_msg_pump (deferred_msg * msg_buf)
        }
       else
        {
-         DispatchMessage (&msg);
+         if (w32_unicode_gui)
+           DispatchMessageW (&msg);
+         else
+           DispatchMessageA (&msg);
        }
 
       /* Exit nested loop when our deferred message has completed.  */
@@ -2380,11 +2397,11 @@ send_deferred_msg (deferred_msg * msg_buf,
 {
   /* Only input thread can send deferred messages.  */
   if (GetCurrentThreadId () != dwWindowsThreadId)
-    abort ();
+    emacs_abort ();
 
   /* It is an error to send a message that is already deferred.  */
   if (find_deferred_msg (hwnd, msg) != NULL)
-    abort ();
+    emacs_abort ();
 
   /* Enforced synchronization is not needed because this is the only
      function that alters deferred_msg_head, and the following critical
@@ -2457,7 +2474,7 @@ w32_msg_worker (void *arg)
   PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE);
 
   if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0))
-    abort ();
+    emacs_abort ();
 
   memset (&dummy_buf, 0, sizeof (dummy_buf));
   dummy_buf.w32msg.msg.hwnd = NULL;
@@ -2918,8 +2935,18 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 
     case WM_SYSCHAR:
     case WM_CHAR:
-      post_character_message (hwnd, msg, wParam, lParam,
-                             w32_get_key_modifiers (wParam, lParam));
+      if (wParam > 255 )
+        {
+          W32Msg wmsg;
+
+          wmsg.dwModifiers = w32_get_key_modifiers (wParam, lParam);
+          signal_user_input ();
+          my_post_msg (&wmsg, hwnd, WM_UNICHAR, wParam, lParam);
+
+        }
+      else
+        post_character_message (hwnd, msg, wParam, lParam,
+                                w32_get_key_modifiers (wParam, lParam));
       break;
 
     case WM_UNICHAR:
@@ -3108,7 +3135,7 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
                msg = WM_MBUTTONUP;
                button_state &= ~MMOUSE;
 
-               if (button_state) abort ();
+               if (button_state) emacs_abort ();
              }
            else
              return 0;
@@ -3339,7 +3366,7 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
        /* Detect if message has already been deferred; in this case
           we cannot return any sensible value to ignore this.  */
        if (find_deferred_msg (hwnd, msg) != NULL)
-         abort ();
+         emacs_abort ();
 
         menubar_in_use = 1;
 
@@ -3801,7 +3828,7 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
        }
 
     dflt:
-      return DefWindowProc (hwnd, msg, wParam, lParam);
+      return (w32_unicode_gui ? DefWindowProcW :  DefWindowProcA) (hwnd, msg, wParam, lParam);
     }
 
   /* The most common default return code for handled messages is 0.  */
@@ -3814,7 +3841,7 @@ my_create_window (struct frame * f)
   MSG msg;
 
   if (!PostThreadMessage (dwWindowsThreadId, WM_EMACS_CREATEWINDOW, (WPARAM)f, 0))
-    abort ();
+    emacs_abort ();
   GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE);
 }
 
@@ -3896,8 +3923,8 @@ w32_window (struct frame *f, long window_prompting, int minibuffer_only)
     int explicit = f->explicit_name;
 
     f->explicit_name = 0;
-    name = FVAR (f, name);
-    FVAR (f, name) = Qnil;
+    name = f->name;
+    fset_name (f, Qnil);
     x_set_name (f, name, explicit);
   }
 
@@ -3944,9 +3971,9 @@ x_icon (struct frame *f, Lisp_Object parms)
         ? IconicState
         : NormalState));
 
-  x_text_icon (f, SSDATA ((!NILP (FVAR (f, icon_name))
-                          ? FVAR (f, icon_name)
-                          : FVAR (f, name))));
+  x_text_icon (f, SSDATA ((!NILP (f->icon_name)
+                          ? f->icon_name
+                          : f->name)));
 #endif
 
   UNBLOCK_INPUT;
@@ -4146,11 +4173,11 @@ This function is an internal primitive--use `make-frame' instead.  */)
   f->output_data.w32 = xzalloc (sizeof (struct w32_output));
   FRAME_FONTSET (f) = -1;
 
-  FVAR (f, icon_name)
-    = x_get_arg (dpyinfo, parameters, Qicon_name, "iconName", "Title",
-                   RES_TYPE_STRING);
-  if (! STRINGP (FVAR (f, icon_name)))
-    FVAR (f, icon_name) = Qnil;
+  fset_icon_name
+    (f, x_get_arg (dpyinfo, parameters, Qicon_name, "iconName", "Title",
+                   RES_TYPE_STRING));
+  if (! STRINGP (f->icon_name))
+    fset_icon_name (f, Qnil);
 
 /*  FRAME_W32_DISPLAY_INFO (f) = dpyinfo; */
 
@@ -4179,12 +4206,12 @@ This function is an internal primitive--use `make-frame' instead.  */)
      be set.  */
   if (EQ (name, Qunbound) || NILP (name))
     {
-      FVAR (f, name) = build_string (dpyinfo->w32_id_name);
+      fset_name (f, build_string (dpyinfo->w32_id_name));
       f->explicit_name = 0;
     }
   else
     {
-      FVAR (f, name) = name;
+      fset_name (f, name);
       f->explicit_name = 1;
       /* use the frame's title when getting resources for this frame.  */
       specbind (Qx_resource_name, name);
@@ -4353,13 +4380,13 @@ This function is an internal primitive--use `make-frame' instead.  */)
   if (FRAME_HAS_MINIBUF_P (f)
       && (!FRAMEP (KVAR (kb, Vdefault_minibuffer_frame))
           || !FRAME_LIVE_P (XFRAME (KVAR (kb, Vdefault_minibuffer_frame)))))
-    KVAR (kb, Vdefault_minibuffer_frame) = frame;
+    kset_default_minibuffer_frame (kb, frame);
 
   /* All remaining specified parameters, which have not been "used"
      by x_get_arg and friends, now go in the misc. alist of the frame.  */
   for (tem = parameters; CONSP (tem); tem = XCDR (tem))
     if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
-      FVAR (f, param_alist) = Fcons (XCAR (tem), FVAR (f, param_alist));
+      fset_param_alist (f, Fcons (XCAR (tem), f->param_alist));
 
   UNGCPRO;
 
@@ -4707,7 +4734,7 @@ x_display_info_for_name (Lisp_Object name)
   CHECK_STRING (name);
 
   for (dpyinfo = &one_w32_display_info, names = w32_display_name_list;
-       dpyinfo;
+       dpyinfo && !NILP (w32_display_name_list);
        dpyinfo = dpyinfo->next, names = XCDR (names))
     {
       Lisp_Object tem;
@@ -5209,10 +5236,12 @@ x_create_tip_frame (struct w32_display_info *dpyinfo,
   XSETFRAME (frame, f);
 
   buffer = Fget_buffer_create (build_string (" *tip*"));
-  Fset_window_buffer (FRAME_ROOT_WINDOW (f), buffer, Qnil);
+  /* Use set_window_buffer instead of Fset_window_buffer (see
+     discussion of bug#11984, bug#12025, bug#12026).  */
+  set_window_buffer (FRAME_ROOT_WINDOW (f), buffer, 0, 0);
   old_buffer = current_buffer;
   set_buffer_internal_1 (XBUFFER (buffer));
-  BVAR (current_buffer, truncate_lines) = Qnil;
+  bset_truncate_lines (current_buffer, Qnil);
   specbind (Qinhibit_read_only, Qt);
   specbind (Qinhibit_modification_hooks, Qt);
   Ferase_buffer ();
@@ -5231,7 +5260,7 @@ x_create_tip_frame (struct w32_display_info *dpyinfo,
   f->output_data.w32 = xzalloc (sizeof (struct w32_output));
 
   FRAME_FONTSET (f)  = -1;
-  FVAR (f, icon_name) = Qnil;
+  fset_icon_name (f, Qnil);
 
 #ifdef GLYPH_DEBUG
   image_cache_refcount =
@@ -5246,12 +5275,12 @@ x_create_tip_frame (struct w32_display_info *dpyinfo,
      be set.  */
   if (EQ (name, Qunbound) || NILP (name))
     {
-      FVAR (f, name) = build_string (dpyinfo->w32_id_name);
+      fset_name (f, build_string (dpyinfo->w32_id_name));
       f->explicit_name = 0;
     }
   else
     {
-      FVAR (f, name) = name;
+      fset_name (f, name);
       f->explicit_name = 1;
       /* use the frame's title when getting resources for this frame.  */
       specbind (Qx_resource_name, name);
@@ -5617,7 +5646,8 @@ Text larger than the specified size is clipped.  */)
 
   /* Set up the frame's root window.  */
   w = XWINDOW (FRAME_ROOT_WINDOW (f));
-  WVAR (w, left_col) = WVAR (w, top_line) = make_number (0);
+  wset_left_col (w, make_number (0));
+  wset_top_line (w, make_number (0));
 
   if (CONSP (Vx_max_tooltip_size)
       && INTEGERP (XCAR (Vx_max_tooltip_size))
@@ -5625,23 +5655,23 @@ Text larger than the specified size is clipped.  */)
       && INTEGERP (XCDR (Vx_max_tooltip_size))
       && XINT (XCDR (Vx_max_tooltip_size)) > 0)
     {
-      WVAR (w, total_cols) = XCAR (Vx_max_tooltip_size);
-      WVAR (w, total_lines) = XCDR (Vx_max_tooltip_size);
+      wset_total_cols (w, XCAR (Vx_max_tooltip_size));
+      wset_total_lines (w, XCDR (Vx_max_tooltip_size));
     }
   else
     {
-      WVAR (w, total_cols) = make_number (80);
-      WVAR (w, total_lines) = make_number (40);
+      wset_total_cols (w, make_number (80));
+      wset_total_lines (w, make_number (40));
     }
 
-  FRAME_TOTAL_COLS (f) = XINT (WVAR (w, total_cols));
+  FRAME_TOTAL_COLS (f) = XINT (w->total_cols);
   adjust_glyphs (f);
   w->pseudo_window_p = 1;
 
   /* Display the tooltip text in a temporary buffer.  */
   old_buffer = current_buffer;
-  set_buffer_internal_1 (XBUFFER (WVAR (XWINDOW (FRAME_ROOT_WINDOW (f)), buffer)));
-  BVAR (current_buffer, truncate_lines) = Qnil;
+  set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f))->buffer));
+  bset_truncate_lines (current_buffer, Qnil);
   clear_glyph_matrix (w->desired_matrix);
   clear_glyph_matrix (w->current_matrix);
   SET_TEXT_POS (pos, BEGV, BEGV_BYTE);
@@ -5702,7 +5732,7 @@ Text larger than the specified size is clipped.  */)
       /* w->total_cols and FRAME_TOTAL_COLS want the width in columns,
         not in pixels.  */
       width /= WINDOW_FRAME_COLUMN_WIDTH (w);
-      WVAR (w, total_cols) = make_number (width);
+      wset_total_cols (w, make_number (width));
       FRAME_TOTAL_COLS (f) = width;
       adjust_glyphs (f);
       w->pseudo_window_p = 1;
@@ -6256,7 +6286,7 @@ w32_parse_hot_key (Lisp_Object key)
       lisp_modifiers = XINT (Fcar (Fcdr (c)));
       c = Fcar (c);
       if (!SYMBOLP (c))
-       abort ();
+       emacs_abort ();
       vk_code = lookup_vk_code (SDATA (SYMBOL_NAME (c)));
     }
   else if (INTEGERP (c))
@@ -6778,7 +6808,6 @@ syms_of_w32fns (void)
 
   w32_visible_system_caret_hwnd = NULL;
 
-  DEFSYM (Qnone, "none");
   DEFSYM (Qsuppress_icon, "suppress-icon");
   DEFSYM (Qundefined_color, "undefined-color");
   DEFSYM (Qcancel_timer, "cancel-timer");
@@ -7153,16 +7182,19 @@ globals_of_w32fns (void)
              doc: /* The ANSI code page used by the system.  */);
   w32_ansi_code_page = GetACP ();
 
+  if (os_subtype == OS_NT)
+    w32_unicode_gui = 1;
+  else
+    w32_unicode_gui = 0;
+
   /* MessageBox does not work without this when linked to comctl32.dll 6.0.  */
   InitCommonControls ();
 
   syms_of_w32uniscribe ();
 }
 
-#undef abort
-
 void
-w32_abort (void)
+emacs_abort (void)
 {
   int button;
   button = MessageBox (NULL,