(x_window) [USE_X_TOOLKIT]: Call XSetWMHints.
[bpt/emacs.git] / src / xfns.c
index 86dcfda..a56a302 100644 (file)
@@ -147,6 +147,9 @@ extern Atom Xatom_wm_delete_window;
 extern Atom Xatom_wm_configure_denied; /* When our config request is denied */
 extern Atom Xatom_wm_window_moved;     /* When the WM moves us. */
 
+/* EditRes protocol */
+extern Atom Xatom_editres_name;
+
 #else  /* X10 */
 
 /* Default size of an Emacs window.  */
@@ -312,6 +315,38 @@ x_any_window_to_frame (wdesc)
     }
   return 0;
 }
+
+/* Return the frame whose principal (outermost) window is WDESC.
+   If WDESC is some other (smaller) window, we return 0.  */
+
+struct frame *
+x_top_window_to_frame (wdesc)
+     int wdesc;
+{
+  Lisp_Object tail, frame;
+  struct frame *f;
+  struct x_display *x;
+
+  for (tail = Vframe_list; XGCTYPE (tail) == Lisp_Cons;
+       tail = XCONS (tail)->cdr)
+    {
+      frame = XCONS (tail)->car;
+      if (XGCTYPE (frame) != Lisp_Frame)
+        continue;
+      f = XFRAME (frame);
+      if (f->display.nothing == 1) 
+       return 0;
+      x = f->display.x;
+      /* This frame matches if the window is its topmost widget.  */
+      if (wdesc == XtWindow (x->widget))
+       return f;
+      /* Match if the window is this frame's menubar.  */
+      if (x->menubar_widget 
+         && wdesc == XtWindow (x->menubar_widget))
+       return f;
+    }
+  return 0;
+}
 #endif /* USE_X_TOOLKIT */
 
 \f
@@ -1555,7 +1590,9 @@ Returns an alist of the form ((top . TOP), (left . LEFT) ... ).")
 
 #ifdef HAVE_X11
 /* Calculate the desired size and position of this window,
-   or set rubber-band prompting if none. */
+   and return the attributes saying which aspects were specified.
+
+   This function does not make the coordinates positive.  */
 
 #define DEFAULT_ROWS 40
 #define DEFAULT_COLS 80
@@ -1608,7 +1645,10 @@ x_figure_window_size (f, parms)
       CHECK_NUMBER (tem1, 0);
       f->display.x->top_pos = XINT (tem0);
       f->display.x->left_pos = XINT (tem1);
-      x_calc_absolute_position (f);
+      if (f->display.x->top_pos < 0)
+       window_prompting |= YNegative;
+      if (f->display.x->left_pos < 0)
+       window_prompting |= YNegative;
       window_prompting |= USPosition;
     }
   else if (! EQ (tem0, Qunbound) || ! EQ (tem1, Qunbound))
@@ -1713,24 +1753,20 @@ hack_wm_protocols (widget)
 }
 #endif
 \f
-/* Create and set up the X window or widget for frame F.  */
+#ifdef USE_X_TOOLKIT
+
+/* Create and set up the X widget for frame F.  */
 
 static void
-#ifdef USE_X_TOOLKIT
 x_window (f, window_prompting, minibuffer_only)
      struct frame *f;
      long window_prompting;
      int minibuffer_only;
-#else /* not USE_X_TOOLKIT */
-x_window (f)
-     struct frame *f;
-#endif /* not USE_X_TOOLKIT */
 {
   XClassHint class_hints;
   XSetWindowAttributes attributes;
   unsigned long attribute_mask;
 
-#ifdef USE_X_TOOLKIT
   Widget shell_widget;
   Widget pane_widget;
   Widget screen_widget;
@@ -1764,12 +1800,11 @@ x_window (f)
 
   f->display.x->column_widget = pane_widget;
 
-  if (!minibuffer_only
+  if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f))
     initialize_frame_menubar (f);
 
   /* mappedWhenManaged to false tells to the paned window to not map/unmap 
-   * the emacs screen when changing menubar.  This reduces flickering a lot.
-   */
+     the emacs screen when changing menubar.  This reduces flickering.  */
 
   ac = 0;
   XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++;
@@ -1793,17 +1828,27 @@ x_window (f)
     char *tem, shell_position[32];
     Arg al[2];
     int ac = 0;
-    int menubar_size 
-      (f->display.x->menubar_widget
-       ? (f->display.x->menubar_widget->core.height
-         + f->display.x->menubar_widget->core.border_width)
-       : 0);
+    int menubar_size 
+      (f->display.x->menubar_widget
+        ? (f->display.x->menubar_widget->core.height
+           + f->display.x->menubar_widget->core.border_width)
+        : 0);
 
     if (window_prompting & USPosition)
-      sprintf (shell_position, "=%dx%d%c%d%c%d", PIXEL_WIDTH (f), 
-              PIXEL_HEIGHT (f) + menubar_size,
-              '+', f->display.x->left_pos,
-              '+', f->display.x->top_pos);
+      {
+       int left = f->display.x->left_pos;
+       int xneg = left < 0;
+       int top = f->display.x->top_pos;
+       int yneg = top < 0;
+       if (left < 0)
+         left = -left;
+       if (top < 0)
+         top = -top;
+       sprintf (shell_position, "=%dx%d%c%d%c%d", PIXEL_WIDTH (f), 
+                PIXEL_HEIGHT (f) + menubar_size,
+                (xneg ? '-' : '+'), left,
+                (yneg ? '-' : '+'), top);
+      }
     else
       sprintf (shell_position, "=%dx%d", PIXEL_WIDTH (f), 
               PIXEL_HEIGHT (f) + menubar_size);
@@ -1814,7 +1859,8 @@ x_window (f)
     XtSetValues (shell_widget, al, ac);
   }
 
+  x_calc_absolute_position (f);
+
   XtManageChild (pane_widget);
   XtRealizeWidget (shell_widget);
 
@@ -1825,6 +1871,10 @@ x_window (f)
   class_hints.res_class = EMACS_CLASS;
   XSetClassHint (x_current_display, XtWindow (shell_widget), &class_hints);
 
+  f->display.x->wm_hints.input = True;
+  f->display.x->wm_hints.flags |= InputHint;
+  XSetWMHints (x_current_display, FRAME_X_WINDOW (f), &f->display.x->wm_hints);
+
   hack_wm_protocols (shell_widget);
 
   /* Do a stupid property change to force the server to generate a
@@ -1843,8 +1893,40 @@ x_window (f)
 
   XtMapWidget (screen_widget);
 
+  /* x_set_name normally ignores requests to set the name if the
+     requested name is the same as the current name.  This is the one
+     place where that assumption isn't correct; f->name is set, but
+     the X server hasn't been told.  */
+  {
+    Lisp_Object name;
+    int explicit = f->explicit_name;
+
+    f->explicit_name = 0;
+    name = f->name;
+    f->name = Qnil;
+    x_set_name (f, name, explicit);
+  }
+
+  XDefineCursor (XDISPLAY FRAME_X_WINDOW (f),
+                f->display.x->text_cursor);
+
+  UNBLOCK_INPUT;
+
+  if (FRAME_X_WINDOW (f) == 0)
+    error ("Unable to create window");
+}
+
 #else /* not USE_X_TOOLKIT */
 
+/* Create and set up the X window for frame F.  */
+
+x_window (f)
+     struct frame *f;
+
+{
+  XClassHint class_hints;
+  XSetWindowAttributes attributes;
+  unsigned long attribute_mask;
 
   attributes.background_pixel = f->display.x->background_pixel;
   attributes.border_pixel = f->display.x->border_pixel;
@@ -1886,7 +1968,6 @@ x_window (f)
   XSetWMProtocols (x_current_display, FRAME_X_WINDOW (f),
                   &Xatom_wm_delete_window, 1);
 
-#endif /* not USE_X_TOOLKIT */
 
   /* x_set_name normally ignores requests to set the name if the
      requested name is the same as the current name.  This is the one
@@ -1911,6 +1992,8 @@ x_window (f)
     error ("Unable to create window");
 }
 
+#endif /* not USE_X_TOOLKIT */
+
 /* Handle the icon stuff for this window.  Perhaps later we might
    want an x_set_icon_position which can be called interactively as
    well. */
@@ -2035,7 +2118,7 @@ be shared by the new frame.")
 {
 #ifdef HAVE_X11
   struct frame *f;
-  Lisp_Object frame, tem, tem0, tem1;
+  Lisp_Object frame, tem;
   Lisp_Object name;
   int minibuffer_only = 0;
   long window_prompting = 0;
@@ -2151,9 +2234,28 @@ be shared by the new frame.")
   x_default_parameter (f, parms, Qborder_color, build_string ("black"),
                       "borderColor", "BorderColor", string);
 
+  x_default_parameter (f, parms, Qmenu_bar_lines, make_number (0),
+                      "menuBarLines", "MenuBarLines", number);
+
   f->display.x->parent_desc = ROOT_WINDOW;
   window_prompting = x_figure_window_size (f, parms);
 
+  switch (((f->display.x->left_pos < 0) << 1) + (f->display.x->top_pos < 0))
+    {
+    case 0:
+      f->display.x->win_gravity = NorthWestGravity;
+      break;
+    case 1:
+      f->display.x->win_gravity = SouthWestGravity;
+      break;
+    case 2:
+      f->display.x->win_gravity = NorthEastGravity;
+      break;
+    case 3:
+      f->display.x->win_gravity = SouthEastGravity;
+      break;
+    }
+
 #ifdef USE_X_TOOLKIT
   x_window (f, window_prompting, minibuffer_only);
 #else
@@ -2183,15 +2285,10 @@ be shared by the new frame.")
   f->height = f->width = 0;
   change_frame_size (f, height, width, 1, 0);
 
-  x_default_parameter (f, parms, Qmenu_bar_lines, make_number (0),
-                      "menuBarLines", "MenuBarLines", number);
-
 /* With the toolkit, the geometry management is done in x_window.  */
 #ifndef USE_X_TOOLKIT
-  tem0 = x_get_arg (parms, Qleft, 0, 0, number);
-  tem1 = x_get_arg (parms, Qtop, 0, 0, number);
   BLOCK_INPUT;
-  x_wm_set_size_hint (f, window_prompting, 1, XINT (tem0), XINT (tem1));
+  x_wm_set_size_hint (f, window_prompting, 1);
   UNBLOCK_INPUT;
 #endif /* USE_X_TOOLKIT */
 
@@ -2601,8 +2698,8 @@ FACE is a face name - a symbol.\n\
 The return value is a list of strings, suitable as arguments to\n\
 set-face-font.\n\
 \n\
-The list does not include fonts Emacs can't use (i.e.  proportional\n\
-fonts), even if they match PATTERN and FACE.")
+Fonts Emacs can't use (i.e. proportional fonts) may or may not be excluded\n\
+even if they match PATTERN and FACE.")
   (pattern, face, frame)
     Lisp_Object pattern, face, frame;
 {
@@ -2624,7 +2721,13 @@ fonts), even if they match PATTERN and FACE.")
   else
     {
       FRAME_PTR f = NILP (frame) ? selected_frame : XFRAME (frame);
-      int face_id = face_name_id_number (f, face);
+      int face_id;
+
+      /* Don't die if we get called with a terminal frame.  */
+      if (! FRAME_X_P (f))
+       error ("non-X frame used in `x-list-fonts'");
+
+      face_id = face_name_id_number (f, face);
 
       if (face_id < 0 || face_id >= FRAME_N_PARAM_FACES (f)
          || FRAME_PARAM_FACES (f) [face_id] == 0)
@@ -4001,6 +4104,7 @@ Optional second arg XRM_STRING is a string of resources in xrdb format.")
                                            "WM_CONFIGURE_DENIED", False);
   Xatom_wm_window_moved =  XInternAtom (x_current_display, "WM_MOVED",
                                        False);
+  Xatom_editres_name =  XInternAtom (x_current_display, "Editres", False);
   UNBLOCK_INPUT;
 #else /* not HAVE_X11 */
   XFASTINT (Vwindow_system_version) = 10;