(VALBITS, GCTYPEBITS): Deleted; default is better.
[bpt/emacs.git] / src / xfns.c
index 8fea14d..37e418e 100644 (file)
@@ -78,13 +78,8 @@ extern void _XEditResCheckMessages ();
    Library.  */
 extern LWLIB_ID widget_id_tick;
 
-/* The one and only application context associated with the connection
-   to the one and only X display that Emacs uses.  */
-XtAppContext Xt_app_con;
-
-/* The one and only application shell.  Emacs screens are popup shells of this
-   application.  */
-Widget Xt_app_shell;
+/* This is part of a kludge--see lwlib/xlwmenu.c.  */
+XFontStruct *xlwmenu_default_font;
 
 extern void free_frame_menubar ();
 #endif /* USE_X_TOOLKIT */
@@ -265,7 +260,7 @@ check_x_display_info (frame)
 /* Return the Emacs frame-object corresponding to an X window.
    It could be the frame's main window or an icon window.  */
 
-/* This function can be called during GC, so use XGCTYPE.  */
+/* This function can be called during GC, so use GC_xxx type test macros.  */
 
 struct frame *
 x_window_to_frame (wdesc)
@@ -274,11 +269,10 @@ x_window_to_frame (wdesc)
   Lisp_Object tail, frame;
   struct frame *f;
 
-  for (tail = Vframe_list; XGCTYPE (tail) == Lisp_Cons;
-       tail = XCONS (tail)->cdr)
+  for (tail = Vframe_list; GC_CONSP (tail); tail = XCONS (tail)->cdr)
     {
       frame = XCONS (tail)->car;
-      if (XGCTYPE (frame) != Lisp_Frame)
+      if (!GC_FRAMEP (frame))
         continue;
       f = XFRAME (frame);
 #ifdef USE_X_TOOLKIT
@@ -309,11 +303,10 @@ x_any_window_to_frame (wdesc)
   struct frame *f;
   struct x_display *x;
 
-  for (tail = Vframe_list; XGCTYPE (tail) == Lisp_Cons;
-       tail = XCONS (tail)->cdr)
+  for (tail = Vframe_list; GC_CONSP (tail); tail = XCONS (tail)->cdr)
     {
       frame = XCONS (tail)->car;
-      if (XGCTYPE (frame) != Lisp_Frame)
+      if (!GC_FRAMEP (frame))
         continue;
       f = XFRAME (frame);
       if (f->display.nothing == 1) 
@@ -342,11 +335,10 @@ x_top_window_to_frame (wdesc)
   struct frame *f;
   struct x_display *x;
 
-  for (tail = Vframe_list; XGCTYPE (tail) == Lisp_Cons;
-       tail = XCONS (tail)->cdr)
+  for (tail = Vframe_list; GC_CONSP (tail); tail = XCONS (tail)->cdr)
     {
       frame = XCONS (tail)->car;
-      if (XGCTYPE (frame) != Lisp_Frame)
+      if (!GC_FRAMEP (frame))
         continue;
       f = XFRAME (frame);
       if (f->display.nothing == 1) 
@@ -674,11 +666,15 @@ x_set_frame_parameters (f, alist)
   /* Same here.  */
   Lisp_Object left, top;
 
+  /* Same with these.  */
+  Lisp_Object icon_left, icon_top;
+
   /* Record in these vectors all the parms specified.  */
   Lisp_Object *parms;
   Lisp_Object *values;
   int i;
   int left_no_change = 0, top_no_change = 0;
+  int icon_left_no_change = 0, icon_top_no_change = 0;
 
   i = 0;
   for (tail = alist; CONSP (tail); tail = Fcdr (tail))
@@ -701,6 +697,7 @@ x_set_frame_parameters (f, alist)
     }
 
   width = height = top = left = Qunbound;
+  icon_left = icon_top = Qunbound;
 
   /* Now process them in reverse of specified order.  */
   for (i--; i >= 0; i--)
@@ -718,6 +715,10 @@ x_set_frame_parameters (f, alist)
        top = val;
       else if (EQ (prop, Qleft))
        left = val;
+      else if (EQ (prop, Qicon_top))
+       icon_top = val;
+      else if (EQ (prop, Qicon_left))
+       icon_left = val;
       else
        {
          register Lisp_Object param_index, old_value;
@@ -725,9 +726,8 @@ x_set_frame_parameters (f, alist)
          param_index = Fget (prop, Qx_frame_parameter);
          old_value = get_frame_param (f, prop);
          store_frame_param (f, prop, val);
-         if (INTEGERP (param_index)
-             && XINT (param_index) >= 0
-             && (XINT (param_index)
+         if (NATNUMP (param_index)
+             && (XFASTINT (param_index)
                  < sizeof (x_frame_parms)/sizeof (x_frame_parms[0])))
            (*x_frame_parms[XINT (param_index)].setter)(f, val, old_value);
        }
@@ -751,6 +751,22 @@ x_set_frame_parameters (f, alist)
        XSETINT (top, f->display.x->top_pos);
     }
 
+  /* If one of the icon positions was not set, preserve or default it.  */
+  if (EQ (icon_left, Qunbound) || ! INTEGERP (icon_left))
+    {
+      icon_left_no_change = 1;
+      icon_left = Fcdr (Fassq (Qicon_left, f->param_alist));
+      if (NILP (icon_left))
+       XSETINT (icon_left, 0);
+    }
+  if (EQ (icon_top, Qunbound) || ! INTEGERP (icon_top))
+    {
+      icon_top_no_change = 1;
+      icon_top = Fcdr (Fassq (Qicon_top, f->param_alist));
+      if (NILP (icon_top))
+       XSETINT (icon_top, 0);
+    }
+
   /* Don't die if just one of these was set.  */
   if (EQ (width, Qunbound))
     XSETINT (width, FRAME_WIDTH (f));
@@ -840,6 +856,10 @@ x_set_frame_parameters (f, alist)
        /* Actually set that position, and convert to absolute.  */
        x_set_offset (f, leftpos, toppos, 0);
       }
+
+    if ((!NILP (icon_left) || !NILP (icon_top))
+       && ! (icon_left_no_change && icon_top_no_change))
+      x_wm_set_icon_position (f, XINT (icon_left), XINT (icon_top));
   }
 }
 
@@ -1828,7 +1848,7 @@ enum resource_types
 
    If no default is specified, return Qunbound.  If you call
    x_get_arg, make sure you deal with Qunbound in a reasonable way,
-   and don't let it get stored in any lisp-visible variables!  */
+   and don't let it get stored in any Lisp-visible variables!  */
 
 static Lisp_Object
 x_get_arg (alist, param, attribute, class, type)
@@ -2099,7 +2119,7 @@ x_figure_window_size (f, parms)
            window_prompting |= XNegative;
        }
 
-      if (!NILP (tem2))
+      if (!NILP (tem2) && ! EQ (tem2, Qunbound))
        window_prompting |= USPosition;
       else
        window_prompting |= PPosition;
@@ -2218,9 +2238,9 @@ x_window (f, window_prompting, minibuffer_only)
   ac = 0;
   XtSetArg (al[ac], XtNallowShellResize, 1); ac++;
   XtSetArg (al[ac], XtNinput, 1); ac++;
-  shell_widget = XtCreatePopupShell ("shell",
-                                    topLevelShellWidgetClass,
-                                    Xt_app_shell, al, ac);
+  shell_widget = XtAppCreateShell (name, EMACS_CLASS,
+                                  topLevelShellWidgetClass,
+                                  FRAME_X_DISPLAY (f), al, ac);
 
   f->display.x->widget = shell_widget;
   /* maybe_set_screen_title_format (shell_widget); */
@@ -2271,7 +2291,7 @@ x_window (f, window_prompting, minibuffer_only)
 
     if (FRAME_EXTERNAL_MENU_BAR (f))
       {
-        Dimension ibw;
+        Dimension ibw = 0;
         XtVaGetValues (pane_widget, XtNinternalBorderWidth, &ibw, NULL);
         menubar_size += ibw;
       }
@@ -2391,7 +2411,7 @@ x_window (f)
   BLOCK_INPUT;
   FRAME_X_WINDOW (f)
     = XCreateWindow (FRAME_X_DISPLAY (f),
-                    FRAME_X_DISPLAY_INFO (f)->root_window,
+                    f->display.x->parent_desc,
                     f->display.x->left_pos,
                     f->display.x->top_pos,
                     PIXEL_WIDTH (f), PIXEL_HEIGHT (f),
@@ -2584,6 +2604,7 @@ This function is an internal primitive--use `make-frame' instead.")
   struct gcpro gcpro1;
   Lisp_Object display;
   struct x_display_info *dpyinfo;
+  Lisp_Object parent;
 
   check_x ();
 
@@ -2598,6 +2619,13 @@ This function is an internal primitive--use `make-frame' instead.")
       && ! NILP (name))
     error ("Invalid frame name--not a string or nil");
 
+  /* See if parent window is specified.  */
+  parent = x_get_arg (parms, Qparent_id, NULL, NULL, number);
+  if (EQ (parent, Qunbound))
+    parent = Qnil;
+  if (! NILP (parent))
+    CHECK_NUMBER (parent, 0);
+
   tem = x_get_arg (parms, Qminibuffer, 0, 0, symbol);
   if (EQ (tem, Qnone) || NILP (tem))
     f = make_frame_without_minibuffer (Qnil);
@@ -2624,6 +2652,19 @@ This function is an internal primitive--use `make-frame' instead.")
 
   FRAME_X_DISPLAY_INFO (f) = dpyinfo;
 
+  /* Specify the parent under which to make this X window.  */
+
+  if (!NILP (parent))
+    {
+      f->display.x->parent_desc = parent;
+      f->display.x->explicit_parent = 1;
+    }
+  else
+    {
+      f->display.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
+      f->display.x->explicit_parent = 0;
+    }
+
   /* Note that the frame has no physical cursor right now.  */
   f->phys_cursor_x = -1;
 
@@ -2672,6 +2713,12 @@ This function is an internal primitive--use `make-frame' instead.")
                         "font", "Font", string);
   }
 
+#ifdef USE_X_TOOLKIT
+  /* Prevent lwlib/xlwmenu.c from crashing because of a bug
+     whereby it fails to get any font.  */
+  xlwmenu_default_font = f->display.x->font;
+#endif
+
   x_default_parameter (f, parms, Qborder_width, make_number (2),
                       "borderwidth", "BorderWidth", number);
   /* This defaults to 2 in order to match xterm.  We recognize either
@@ -2781,22 +2828,24 @@ This function is an internal primitive--use `make-frame' instead.")
   FRAME_X_DISPLAY_INFO (f)->reference_count++;
 
   /* Make the window appear on the frame and enable display,
-     unless the caller says not to.  */
-  {
-    Lisp_Object visibility;
+     unless the caller says not to.  However, with explicit parent,
+     Emacs cannot control visibility, so don't try.  */
+  if (! f->display.x->explicit_parent)
+    {
+      Lisp_Object visibility;
 
-    visibility = x_get_arg (parms, Qvisibility, 0, 0, symbol);
-    if (EQ (visibility, Qunbound))
-      visibility = Qt;
+      visibility = x_get_arg (parms, Qvisibility, 0, 0, symbol);
+      if (EQ (visibility, Qunbound))
+       visibility = Qt;
 
-    if (EQ (visibility, Qicon))
-      x_iconify_frame (f);
-    else if (! NILP (visibility))
-      x_make_frame_visible (f);
-    else
-      /* Must have been Qnil.  */
-      ;
-  }
+      if (EQ (visibility, Qicon))
+       x_iconify_frame (f);
+      else if (! NILP (visibility))
+       x_make_frame_visible (f);
+      else
+       /* Must have been Qnil.  */
+       ;
+    }
 
   return unbind_to (count, frame);
 }
@@ -2865,7 +2914,9 @@ even if they match PATTERN and FACE.")
 {
   int num_fonts;
   char **names;
+#ifndef BROKEN_XLISTFONTSWITHINFO
   XFontStruct *info;
+#endif
   XFontStruct *size_ref;
   Lisp_Object list;
   FRAME_PTR f;
@@ -2942,18 +2993,20 @@ even if they match PATTERN and FACE.")
   BLOCK_INPUT;
 
   /* Solaris 2.3 has a bug in XListFontsWithInfo.  */
-#ifdef BROKEN_XLISTFONTSWITHINFO
-  names = XListFonts (FRAME_X_DISPLAY (f),
-                      XSTRING (pattern)->data,
-                      2000, /* maxnames */
-                      &num_fonts); /* count_return */
-#else
-  names = XListFontsWithInfo (FRAME_X_DISPLAY (f),
-                             XSTRING (pattern)->data,
-                             2000, /* maxnames */
-                             &num_fonts, /* count_return */
-                             &info); /* info_return */
+#ifndef BROKEN_XLISTFONTSWITHINFO
+  if (size_ref)
+    names = XListFontsWithInfo (FRAME_X_DISPLAY (f),
+                               XSTRING (pattern)->data,
+                               2000, /* maxnames */
+                               &num_fonts, /* count_return */
+                               &info); /* info_return */
+  else
 #endif
+    names = XListFonts (FRAME_X_DISPLAY (f),
+                       XSTRING (pattern)->data,
+                       2000, /* maxnames */
+                       &num_fonts); /* count_return */
+
   UNBLOCK_INPUT;
 
   list = Qnil;
@@ -2976,27 +3029,36 @@ even if they match PATTERN and FACE.")
       list = Qnil;
       for (i = 0; i < num_fonts; i++)
         {
-         XFontStruct *thisinfo;
+         int keeper;
 
+         if (!size_ref)
+           keeper = 1;
+         else
+           {
 #ifdef BROKEN_XLISTFONTSWITHINFO
-          BLOCK_INPUT;
-          thisinfo = XLoadQueryFont (FRAME_X_DISPLAY (f), names[i]);
-          UNBLOCK_INPUT;
+             XFontStruct *thisinfo;
+
+             BLOCK_INPUT;
+             thisinfo = XLoadQueryFont (FRAME_X_DISPLAY (f), names[i]);
+             UNBLOCK_INPUT;
+
+             keeper = thisinfo && same_size_fonts (thisinfo, size_ref);
 #else
-         thisinfo = &info[i];
+             keeper = same_size_fonts (&info[i], size_ref);
 #endif
-          if (thisinfo && (! size_ref
-                          || same_size_fonts (thisinfo, size_ref)))
+           }
+          if (keeper)
            list = Fcons (build_string (names[i]), list);
         }
       list = Fnreverse (list);
 
       BLOCK_INPUT;
-#ifdef BROKEN_XLISTFONTSWITHINFO
-      XFreeFontNames (names);
-#else
-      XFreeFontInfo (names, info, num_fonts);
+#ifndef BROKEN_XLISTFONTSWITHINFO
+      if (size_ref)
+       XFreeFontInfo (names, info, num_fonts);
+      else
 #endif
+       XFreeFontNames (names);
       UNBLOCK_INPUT;
     }
 
@@ -3024,7 +3086,8 @@ If FRAME is omitted or nil, use the selected frame.")
 DEFUN ("x-color-values", Fx_color_values, Sx_color_values, 1, 2, 0,
   "Return a description of the color named COLOR on frame FRAME.\n\
 The value is a list of integer RGB values--(RED GREEN BLUE).\n\
-These values appear to range from 0 to 65280; white is (65280 65280 65280).\n\
+These values appear to range from 0 to 65280 or 65535, depending\n\
+on the system; white is (65280 65280 65280) or (65535 65535 65535).\n\
 If FRAME is omitted or nil, use the selected frame.")
   (color, frame)
      Lisp_Object color, frame;
@@ -4417,7 +4480,12 @@ If DISPLAY is nil, that stands for the selected frame's display.")
     }
   x_destroy_all_bitmaps (dpyinfo);
   XSetCloseDownMode (dpyinfo->display, DestroyAll);
+
+#ifdef USE_X_TOOLKIT
+  XtCloseDisplay (dpyinfo->display);
+#else
   XCloseDisplay (dpyinfo->display);
+#endif
 
   x_delete_display (dpyinfo);
   UNBLOCK_INPUT;
@@ -4443,7 +4511,7 @@ DEFUN ("x-synchronize", Fx_synchronize, Sx_synchronize, 1, 2, 0,
 If ON is nil, allow buffering of requests.\n\
 Turning on synchronization prohibits the Xlib routines from buffering\n\
 requests and seriously degrades performance, but makes debugging much\n\
-easier.
+easier.\n\
 The optional second argument DISPLAY specifies which display to act on.\n\
 DISPLAY should be either a frame or a display name (a string).\n\
 If DISPLAY is omitted or nil, that stands for the selected frame's display.")