Fix obvious runtime errors after merge.
[bpt/emacs.git] / src / w32fns.c
index c116c51..f7e2116 100644 (file)
@@ -1683,7 +1683,7 @@ x_set_icon_name (f, arg, oldval)
       if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
        return;
     }
-  else if (!STRINGP (oldval) && EQ (oldval, Qnil) == EQ (arg, Qnil))
+  else if (!NILP (arg) || NILP (oldval))
     return;
 
   f->icon_name = arg;
@@ -2066,6 +2066,8 @@ w32_createwindow (f)
 {
   HWND hwnd;
   RECT rect;
+  Lisp_Object top = Qunbound;
+  Lisp_Object left = Qunbound;
 
   rect.left = rect.top = 0;
   rect.right = FRAME_PIXEL_WIDTH (f);
@@ -2078,15 +2080,53 @@ w32_createwindow (f)
 
   if (!hprevinst)
     {
+      Lisp_Object ifa;
+
       w32_init_class (hinst);
+
+      /* Handle the -geometry command line option and the geometry
+        settings in the registry.  They are decoded and put into
+        initial-frame-alist by w32-win.el:x-handle-geometry.  */
+      ifa = Fsymbol_value (intern ("initial-frame-alist"));
+      if (CONSP (ifa))
+       {
+         Lisp_Object lt = Fassq (Qleft, ifa);
+         Lisp_Object tp = Fassq (Qtop,  ifa);
+
+         if (!NILP (lt))
+           {
+             lt = XCDR (lt);
+             if (INTEGERP (lt))
+               left = lt;
+           }
+         if (!NILP (tp))
+           {
+             tp = XCDR (tp);
+             if (INTEGERP (tp))
+               top = tp;
+           }
+       }
+    }
+
+  if (f->size_hint_flags & USPosition || f->size_hint_flags & PPosition)
+    {
+      XSETINT (left, f->left_pos);
+      XSETINT (top, f->top_pos);
+    }
+  else if (EQ (left, Qunbound) && EQ (top, Qunbound))
+    {
+      /* When called with RES_TYPE_NUMBER, w32_get_arg will return zero
+        for anything that is not a number and is not Qunbound.  */
+      left = w32_get_arg (Qnil, Qleft, "left", "Left", RES_TYPE_NUMBER);
+      top = w32_get_arg (Qnil, Qtop, "top", "Top", RES_TYPE_NUMBER);
     }
 
   FRAME_W32_WINDOW (f) = hwnd
     = CreateWindow (EMACS_CLASS,
                    f->namebuf,
                    f->output_data.w32->dwStyle | WS_CLIPCHILDREN,
-                   f->left_pos,
-                   f->top_pos,
+                   EQ (left, Qunbound) ? CW_USEDEFAULT : XINT (left),
+                   EQ (top, Qunbound) ? CW_USEDEFAULT : XINT (top),
                    rect.right - rect.left,
                    rect.bottom - rect.top,
                    NULL,
@@ -2107,6 +2147,11 @@ w32_createwindow (f)
 
       /* Do this to discard the default setting specified by our parent. */
       ShowWindow (hwnd, SW_HIDE);
+
+      /* Update frame positions. */
+      GetWindowRect (hwnd, &rect);
+      f->left_pos = rect.left;
+      f->top_pos = rect.top;
     }
 }
 
@@ -2694,6 +2739,24 @@ w32_msg_worker (dw)
   return 0;
 }
 
+static void
+signal_user_input ()
+{
+  /* Interrupt any lisp that wants to be interrupted by input.  */
+  if (!NILP (Vthrow_on_input))
+    {
+      Vquit_flag = Vthrow_on_input;
+      /* If we're inside a function that wants immediate quits,
+        do it now.  */
+      if (immediate_quit && NILP (Vinhibit_quit))
+       {
+         immediate_quit = 0;
+         QUIT;
+       }
+    }
+}
+
+
 static void
 post_character_message (hwnd, msg, wParam, lParam, modifiers)
      HWND hwnd;
@@ -2751,6 +2814,8 @@ post_character_message (hwnd, msg, wParam, lParam, modifiers)
           to receive C-g to interrupt the lisp thread.  */
        cancel_all_deferred_msgs ();
       }
+    else
+      signal_user_input ();
   }
 
   my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
@@ -3170,6 +3235,7 @@ w32_wnd_proc (hwnd, msg, wParam, lParam)
              }
            wmsg.dwModifiers = w32_get_modifiers ();
            my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
+           signal_user_input ();
 
            /* Clear message buffer. */
            saved_mouse_button_msg.msg.hwnd = 0;
@@ -3227,6 +3293,7 @@ w32_wnd_proc (hwnd, msg, wParam, lParam)
          }
        wmsg.dwModifiers = w32_get_modifiers ();
        my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
+       signal_user_input ();
 
        /* Always clear message buffer and cancel timer. */
        saved_mouse_button_msg.msg.hwnd = 0;
@@ -3270,12 +3337,21 @@ w32_wnd_proc (hwnd, msg, wParam, lParam)
 
       wmsg.dwModifiers = w32_get_modifiers ();
       my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
+      signal_user_input ();
 
       /* Need to return true for XBUTTON messages, false for others,
          to indicate that we processed the message.  */
       return (msg == WM_XBUTTONDOWN || msg == WM_XBUTTONUP);
 
     case WM_MOUSEMOVE:
+      /* Ignore mouse movements as long as the menu is active.  These
+        movements are processed by the window manager anyway, and
+        it's wrong to handle them as if they happened on the
+        underlying frame.  */
+      f = x_window_to_frame (dpyinfo, hwnd);
+      if (f && f->output_data.w32->menubar_active)
+       return 0;
+
       /* If the mouse has just moved into the frame, start tracking
         it, so we will be notified when it leaves the frame.  Mouse
         tracking only works under W98 and NT4 and later. On earlier
@@ -3324,11 +3400,13 @@ w32_wnd_proc (hwnd, msg, wParam, lParam)
     case WM_MOUSEWHEEL:
       wmsg.dwModifiers = w32_get_modifiers ();
       my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
+      signal_user_input ();
       return 0;
 
     case WM_DROPFILES:
       wmsg.dwModifiers = w32_get_modifiers ();
       my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
+      signal_user_input ();
       return 0;
 
     case WM_TIMER:
@@ -3338,6 +3416,7 @@ w32_wnd_proc (hwnd, msg, wParam, lParam)
          if (saved_mouse_button_msg.msg.hwnd)
            {
              post_msg (&saved_mouse_button_msg);
+             signal_user_input ();
              saved_mouse_button_msg.msg.hwnd = 0;
            }
          KillTimer (hwnd, mouse_button_timer);
@@ -3840,6 +3919,7 @@ w32_wnd_proc (hwnd, msg, wParam, lParam)
        {
          wmsg.dwModifiers = w32_get_modifiers ();
          my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
+         signal_user_input ();
          return 0;
        }
 
@@ -4344,17 +4424,6 @@ This function is an internal primitive--use `make-frame' instead.  */)
   x_wm_set_size_hint (f, window_prompting, 0);
   UNBLOCK_INPUT;
 
-  /* Avoid a bug that causes the new frame to never become visible if
-     an echo area message is displayed during the following call1.  */
-  specbind(Qredisplay_dont_pause, Qt);
-
-  /* Set up faces after all frame parameters are known.  This call
-     also merges in face attributes specified for new frames.  If we
-     don't do this, the `menu' face for instance won't have the right
-     colors, and the menu bar won't appear in the specified colors for
-     new frames.  */
-  call1 (Qface_set_after_frame_default, frame);
-
   /* Make the window appear on the frame and enable display, unless
      the caller says not to.  However, with explicit parent, Emacs
      cannot control visibility, so don't try.  */
@@ -6172,7 +6241,7 @@ w32_query_font (struct frame *f, char *fontname)
 
   for (i = 0; i < one_w32_display_info.n_fonts ;i++, pfi++)
     {
-      if (strcmp(pfi->name, fontname) == 0) return pfi;
+      if (stricmp(pfi->name, fontname) == 0) return pfi;
     }
 
   return NULL;
@@ -6291,17 +6360,12 @@ DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
   CHECK_STRING (color);
 
   if (w32_defined_color (f, SDATA (color), &foo, 0))
-    {
-      Lisp_Object rgb[3];
-
-      rgb[0] = make_number ((GetRValue (foo.pixel) << 8)
-                            | GetRValue (foo.pixel));
-      rgb[1] = make_number ((GetGValue (foo.pixel) << 8)
-                            | GetGValue (foo.pixel));
-      rgb[2] = make_number ((GetBValue (foo.pixel) << 8)
-                            | GetBValue (foo.pixel));
-      return Flist (3, rgb);
-    }
+    return list3 (make_number ((GetRValue (foo.pixel) << 8)
+                              | GetRValue (foo.pixel)),
+                 make_number ((GetGValue (foo.pixel) << 8)
+                              | GetGValue (foo.pixel)),
+                 make_number ((GetBValue (foo.pixel) << 8)
+                              | GetBValue (foo.pixel)));
   else
     return Qnil;
 }
@@ -7654,9 +7718,12 @@ Text larger than the specified size is clipped.  */)
     AdjustWindowRect (&rect, f->output_data.w32->dwStyle,
                      FRAME_EXTERNAL_MENU_BAR (f));
 
-    /* Position and size tooltip, and put it in the topmost group.  */
+    /* Position and size tooltip, and put it in the topmost group.
+       The add-on of 3 to the 5th argument is a kludge: without it,
+       some fonts cause the last character of the tip to be truncated,
+       for some obscure reason.  */
     SetWindowPos (FRAME_W32_WINDOW (f), HWND_TOPMOST,
-                 root_x, root_y, rect.right - rect.left,
+                 root_x, root_y, rect.right - rect.left + 3,
                  rect.bottom - rect.top, SWP_NOACTIVATE);
 
     /* Ensure tooltip is on top of other topmost windows (eg menus).  */
@@ -7923,8 +7990,12 @@ If ONLY-DIR-P is non-nil, the user can only select directories.  */)
  ***********************************************************************/
 
 DEFUN ("w32-select-font", Fw32_select_font, Sw32_select_font, 0, 2, 0,
-       doc: /* Select a font using the W32 font dialog.
-Returns an X font string corresponding to the selection.  */)
+       doc: /* Select a font for the named FRAME using the W32 font dialog.
+Returns an X-style font string corresponding to the selection.
+
+If FRAME is omitted or nil, it defaults to the selected frame.
+If INCLUDE-PROPORTIONAL is non-nil, include proportional fonts
+in the font selection dialog. */)
   (frame, include_proportional)
      Lisp_Object frame, include_proportional;
 {
@@ -8543,14 +8614,15 @@ syms_of_w32fns ()
   Vw32_color_map = Qnil;
 
   DEFVAR_LISP ("w32-pass-alt-to-system", &Vw32_pass_alt_to_system,
-              doc: /* Non-nil if alt key presses are passed on to Windows.
-When non-nil, for example, alt pressed and released and then space will
-open the System menu.  When nil, Emacs silently swallows alt key events.  */);
+              doc: /* Non-nil if Alt key presses are passed on to Windows.
+When non-nil, for example, Alt pressed and released and then space will
+open the System menu.  When nil, Emacs processes the Alt key events, and
+then silently swallows them.  */);
   Vw32_pass_alt_to_system = Qnil;
 
   DEFVAR_LISP ("w32-alt-is-meta", &Vw32_alt_is_meta,
-              doc: /* Non-nil if the alt key is to be considered the same as the meta key.
-When nil, Emacs will translate the alt key to the Alt modifier, and not Meta.  */);
+              doc: /* Non-nil if the Alt key is to be considered the same as the META key.
+When nil, Emacs will translate the Alt key to the ALT modifier, not to META.  */);
   Vw32_alt_is_meta = Qt;
 
   DEFVAR_INT ("w32-quit-key", &w32_quit_key,
@@ -8559,14 +8631,32 @@ When nil, Emacs will translate the alt key to the Alt modifier, and not Meta.  *
 
   DEFVAR_LISP ("w32-pass-lwindow-to-system",
               &Vw32_pass_lwindow_to_system,
-              doc: /* Non-nil if the left \"Windows\" key is passed on to Windows.
-When non-nil, the Start menu is opened by tapping the key.  */);
+              doc: /* If non-nil, the left \"Windows\" key is passed on to Windows.
+
+When non-nil, the Start menu is opened by tapping the key.
+If you set this to nil, the left \"Windows\" key is processed by Emacs
+according to the value of `w32-lwindow-modifier', which see.
+
+Note that some combinations of the left \"Windows\" key with other keys are
+caught by Windows at low level, and so binding them in Emacs will have no
+effect.  For example, <lwindow>-r always pops up the Windows Run dialog,
+<lwindow>-<Pause> pops up the "System Properties" dialog, etc.  However, see
+the doc string of `w32-phantom-key-code'.  */);
   Vw32_pass_lwindow_to_system = Qt;
 
   DEFVAR_LISP ("w32-pass-rwindow-to-system",
               &Vw32_pass_rwindow_to_system,
-              doc: /* Non-nil if the right \"Windows\" key is passed on to Windows.
-When non-nil, the Start menu is opened by tapping the key.  */);
+              doc: /* If non-nil, the right \"Windows\" key is passed on to Windows.
+
+When non-nil, the Start menu is opened by tapping the key.
+If you set this to nil, the right \"Windows\" key is processed by Emacs
+according to the value of `w32-rwindow-modifier', which see.
+
+Note that some combinations of the right \"Windows\" key with other keys are
+caught by Windows at low level, and so binding them in Emacs will have no
+effect.  For example, <rwindow>-r always pops up the Windows Run dialog,
+<rwindow>-<Pause> pops up the "System Properties" dialog, etc.  However, see
+the doc string of `w32-phantom-key-code'.  */);
   Vw32_pass_rwindow_to_system = Qt;
 
   DEFVAR_LISP ("w32-phantom-key-code",
@@ -8583,29 +8673,29 @@ acting on \"Windows\" key events when `w32-pass-lwindow-to-system' or
 
   DEFVAR_LISP ("w32-enable-num-lock",
               &Vw32_enable_num_lock,
-              doc: /* Non-nil if Num Lock should act normally.
-Set to nil to see Num Lock as the key `kp-numlock'.  */);
+              doc: /* If non-nil, the Num Lock key acts normally.
+Set to nil to handle Num Lock as the `kp-numlock' key.  */);
   Vw32_enable_num_lock = Qt;
 
   DEFVAR_LISP ("w32-enable-caps-lock",
               &Vw32_enable_caps_lock,
-              doc: /* Non-nil if Caps Lock should act normally.
-Set to nil to see Caps Lock as the key `capslock'.  */);
+              doc: /* If non-nil, the Caps Lock key acts normally.
+Set to nil to handle Caps Lock as the `capslock' key.  */);
   Vw32_enable_caps_lock = Qt;
 
   DEFVAR_LISP ("w32-scroll-lock-modifier",
               &Vw32_scroll_lock_modifier,
-              doc: /* Modifier to use for the Scroll Lock on state.
+              doc: /* Modifier to use for the Scroll Lock ON state.
 The value can be hyper, super, meta, alt, control or shift for the
-respective modifier, or nil to see Scroll Lock as the key `scroll'.
-Any other value will cause the key to be ignored.  */);
+respective modifier, or nil to handle Scroll Lock as the `scroll' key.
+Any other value will cause the Scroll Lock key to be ignored.  */);
   Vw32_scroll_lock_modifier = Qt;
 
   DEFVAR_LISP ("w32-lwindow-modifier",
               &Vw32_lwindow_modifier,
               doc: /* Modifier to use for the left \"Windows\" key.
 The value can be hyper, super, meta, alt, control or shift for the
-respective modifier, or nil to appear as the key `lwindow'.
+respective modifier, or nil to appear as the `lwindow' key.
 Any other value will cause the key to be ignored.  */);
   Vw32_lwindow_modifier = Qnil;
 
@@ -8613,7 +8703,7 @@ Any other value will cause the key to be ignored.  */);
               &Vw32_rwindow_modifier,
               doc: /* Modifier to use for the right \"Windows\" key.
 The value can be hyper, super, meta, alt, control or shift for the
-respective modifier, or nil to appear as the key `rwindow'.
+respective modifier, or nil to appear as the `rwindow' key.
 Any other value will cause the key to be ignored.  */);
   Vw32_rwindow_modifier = Qnil;
 
@@ -8621,7 +8711,7 @@ Any other value will cause the key to be ignored.  */);
               &Vw32_apps_modifier,
               doc: /* Modifier to use for the \"Apps\" key.
 The value can be hyper, super, meta, alt, control or shift for the
-respective modifier, or nil to appear as the key `apps'.
+respective modifier, or nil to appear as the `apps' key.
 Any other value will cause the key to be ignored.  */);
   Vw32_apps_modifier = Qnil;
 
@@ -8637,7 +8727,7 @@ Any other value will cause the key to be ignored.  */);
              &w32_mouse_button_tolerance,
              doc: /* Analogue of double click interval for faking middle mouse events.
 The value is the minimum time in milliseconds that must elapse between
-left/right button down events before they are considered distinct events.
+left and right button down events before they are considered distinct events.
 If both mouse buttons are depressed within this interval, a middle mouse
 button down event is generated instead.  */);
   w32_mouse_button_tolerance = GetDoubleClickTime () / 2;
@@ -8652,7 +8742,7 @@ reported as lisp events.  */);
 
   DEFVAR_BOOL ("w32-pass-extra-mouse-buttons-to-system",
               &w32_pass_extra_mouse_buttons_to_system,
-              doc: /* Non-nil if the fourth and fifth mouse buttons are passed to Windows.
+              doc: /* If non-nil, the fourth and fifth mouse buttons are passed to Windows.
 Recent versions of Windows support mice with up to five buttons.
 Since most applications don't support these extra buttons, most mouse
 drivers will allow you to map them to functions at the system level.