(x_window) [USE_X_TOOLKIT]: New args window_prompting and minibuffer_only.
[bpt/emacs.git] / src / xfns.c
index 940826f..5eaf114 100644 (file)
@@ -74,6 +74,7 @@ XtAppContext Xt_app_con;
    application.  */
 Widget Xt_app_shell;
 
+extern void free_frame_menubar ();
 extern void free_frame_menubar ();
 #endif /* USE_X_TOOLKIT */
 
@@ -234,7 +235,7 @@ extern Lisp_Object Vwindow_system_version;
 
 \f
 /* Error if we are not connected to X.  */
-static void
+void
 check_x ()
 {
   if (x_current_display == 0)
@@ -263,8 +264,8 @@ x_window_to_frame (wdesc)
 #ifdef USE_X_TOOLKIT
       if (f->display.nothing == 1) 
        return 0;
-      if (f->display.x->edit_widget 
-         && XtWindow (f->display.x->edit_widget) == wdesc
+      if ((f->display.x->edit_widget 
+          && XtWindow (f->display.x->edit_widget) == wdesc)
           || f->display.x->icon_desc == wdesc)
         return f;
 #else /* not USE_X_TOOLKIT */
@@ -459,9 +460,10 @@ x_set_frame_parameters (f, alist)
        left = val;
       else
        {
-         register Lisp_Object param_index = Fget (prop, Qx_frame_parameter);
-         register Lisp_Object old_value = get_frame_param (f, prop);
+         register Lisp_Object param_index, old_value;
 
+         param_index = Fget (prop, Qx_frame_parameter);
+         old_value = get_frame_param (f, prop);
          store_frame_param (f, prop, val);
          if (XTYPE (param_index) == Lisp_Int
              && XINT (param_index) >= 0
@@ -528,6 +530,7 @@ x_report_frame_params (f, alistptr)
   sprintf (buf, "%d", FRAME_X_WINDOW (f));
   store_in_alist (alistptr, Qwindow_id,
                   build_string (buf));
+  FRAME_SAMPLE_VISIBILITY (f);
   store_in_alist (alistptr, Qvisibility,
                  (FRAME_VISIBLE_P (f) ? Qt
                   : FRAME_ICONIFIED_P (f) ? Qicon : Qnil));
@@ -1431,12 +1434,13 @@ x_get_arg (alist, param, attribute, class, type)
              /* As a special case, we map the values `true' and `on'
                 to Qt, and `false' and `off' to Qnil.  */
              {
-               Lisp_Object lower = Fdowncase (tem);
-               if (!strcmp (XSTRING (tem)->data, "on")
-                   || !strcmp (XSTRING (tem)->data, "true"))
+               Lisp_Object lower;
+               lower = Fdowncase (tem);
+               if (!strcmp (XSTRING (lower)->data, "on")
+                   || !strcmp (XSTRING (lower)->data, "true"))
                  return Qt;
-               else if (!strcmp (XSTRING (tem)->data, "off")
-                     || !strcmp (XSTRING (tem)->data, "false"))
+               else if (!strcmp (XSTRING (lower)->data, "off")
+                     || !strcmp (XSTRING (lower)->data, "false"))
                  return Qnil;
                else
                  return Fintern (tem, Qnil);
@@ -1695,10 +1699,19 @@ hack_wm_protocols (widget)
 /* Create and set up the X window or 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;
@@ -1718,12 +1731,11 @@ x_window (f)
   ac = 0;
   XtSetArg (al[ac], XtNallowShellResize, 1); ac++;
   XtSetArg (al[ac], XtNinput, 1); ac++;
-  XtSetArg (al[ac], XtNx, f->display.x->left_pos); ac++;
-  XtSetArg (al[ac], XtNy, f->display.x->top_pos); ac++;
   shell_widget = XtCreatePopupShell ("shell",
                                     topLevelShellWidgetClass,
                                     Xt_app_shell, al, ac);
 
+  f->display.x->widget = shell_widget;
   /* maybe_set_screen_title_format (shell_widget); */
 
 
@@ -1733,6 +1745,11 @@ x_window (f)
                                panedWidgetClass,
                                shell_widget, al, ac);
 
+  f->display.x->column_widget = pane_widget;
+
+  if (!minibuffer_only) 
+    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.
    */
@@ -1748,10 +1765,36 @@ x_window (f)
                                  pane_widget, al, ac);
  
   f->display.x->edit_widget = screen_widget;
-  f->display.x->widget = shell_widget;
-  f->display.x->column_widget = pane_widget;
  
+  if (f->display.x->menubar_widget)
+    XtManageChild (f->display.x->menubar_widget);
   XtManageChild (screen_widget); 
+
+  /* Do some needed geometry management.  */
+  {
+    int len;
+    char *tem, shell_position[32];
+    Arg al[2];
+    int ac = 0;
+
+    if (window_prompting & USPosition)
+      sprintf (shell_position, "=%dx%d%c%d%c%d", PIXEL_WIDTH (f), 
+              PIXEL_HEIGHT (f) + f->display.x->menubar_widget->core.height
+              + f->display.x->menubar_widget->core.border_width,
+              '+', f->display.x->left_pos,
+              '+', f->display.x->top_pos);
+    else
+      sprintf (shell_position, "=%dx%d", PIXEL_WIDTH (f), 
+              PIXEL_HEIGHT (f) + f->display.x->menubar_widget->core.height
+              + f->display.x->menubar_widget->core.border_width);
+    len = strlen (shell_position) + 1;
+    tem = (char *) xmalloc (len);
+    strncpy (tem, shell_position, len);
+    XtSetArg (al[ac], XtNgeometry, tem); ac++;
+    XtSetValues (shell_widget, al, ac);
+  }
+
   XtManageChild (pane_widget);
   XtRealizeWidget (shell_widget);
 
@@ -1772,13 +1815,16 @@ x_window (f)
                   Xatom_wm_protocols, XA_ATOM, 32, PropModeAppend,
                   (unsigned char*) NULL, 0);
 
+ /* Make all the standard events reach the Emacs frame.  */
+  attributes.event_mask = STANDARD_EVENT_SET;
+  attribute_mask = CWEventMask;
+  XChangeWindowAttributes (XtDisplay (shell_widget), XtWindow (shell_widget),
+                          attribute_mask, &attributes);
+
   XtMapWidget (screen_widget);
 
 #else /* not USE_X_TOOLKIT */
 
-  XSetWindowAttributes attributes;
-  unsigned long attribute_mask;
-
 
   attributes.background_pixel = f->display.x->background_pixel;
   attributes.border_pixel = f->display.x->border_pixel;
@@ -1827,11 +1873,12 @@ x_window (f)
      place where that assumption isn't correct; f->name is set, but
      the X server hasn't been told.  */
   {
-    Lisp_Object name = f->name;
+    Lisp_Object name;
     int explicit = f->explicit_name;
 
-    f->name = Qnil;
     f->explicit_name = 0;
+    name = f->name;
+    f->name = Qnil;
     x_set_name (f, name, explicit);
   }
 
@@ -2087,7 +2134,11 @@ be shared by the new frame.")
   f->display.x->parent_desc = ROOT_WINDOW;
   window_prompting = x_figure_window_size (f, parms);
 
+#ifdef USE_X_TOOLKIT
+  x_window (f, window_prompting, minibuffer_only);
+#else
   x_window (f);
+#endif
   x_icon (f, parms);
   x_make_gc (f);
   init_frame_faces (f);
@@ -2115,11 +2166,14 @@ be shared by the new frame.")
   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));
   UNBLOCK_INPUT;
+#endif /* USE_X_TOOLKIT */
 
   tem = x_get_arg (parms, Qunsplittable, 0, 0, boolean);
   f->no_split = minibuffer_only || EQ (tem, Qt);
@@ -2133,8 +2187,9 @@ be shared by the new frame.")
   /* Make the window appear on the frame and enable display,
      unless the caller says not to.  */
   {
-    Lisp_Object visibility = x_get_arg (parms, Qvisibility, 0, 0, symbol);
+    Lisp_Object visibility;
 
+    visibility = x_get_arg (parms, Qvisibility, 0, 0, symbol);
     if (EQ (visibility, Qunbound))
       visibility = Qt;
 
@@ -2373,8 +2428,9 @@ be shared by the new frame.")
 
   /* Make the window appear on the frame and enable display.  */
   {
-    Lisp_Object visibility = x_get_arg (parms, Qvisibility, 0, 0, symbol);
+    Lisp_Object visibility;
 
+    visibility = x_get_arg (parms, Qvisibility, 0, 0, symbol);
     if (EQ (visibility, Qunbound))
       visibility = Qt;
 
@@ -2390,6 +2446,17 @@ be shared by the new frame.")
 #endif /* X10 */
 }
 
+Lisp_Object
+x_get_focus_frame ()
+{
+  Lisp_Object xfocus;
+  if (! x_focus_frame)
+    return Qnil;
+
+  XSET (xfocus, Lisp_Frame, x_focus_frame);
+  return xfocus;
+}
+
 DEFUN ("focus-frame", Ffocus_frame, Sfocus_frame, 1, 1, 0,
   "Set the focus on FRAME.")
   (frame)
@@ -2525,6 +2592,7 @@ fonts), even if they match PATTERN and FACE.")
   XFontStruct *size_ref;
   Lisp_Object list;
 
+  check_x ();
   CHECK_STRING (pattern, 0);
   if (!NILP (face))
     CHECK_SYMBOL (face, 1);
@@ -2576,15 +2644,17 @@ fonts), even if they match PATTERN and FACE.")
       tail = &list;
       for (i = 0; i < num_fonts; i++)
         {
+         XFontStruct *thisinfo;
+
 #ifdef BROKEN_XLISTFONTSWITHINFO
           BLOCK_INPUT;
-          info = XLoadQueryFont (x_current_display, names[i]);
+          thisinfo = XLoadQueryFont (x_current_display, names[i]);
           UNBLOCK_INPUT;
 #else
-         info = &info[i];
+         thisinfo = &info[i];
 #endif
-          if (info && (! size_ref
-                      || same_size_fonts (info, size_ref)))
+          if (thisinfo && (! size_ref
+                          || same_size_fonts (thisinfo, size_ref)))
            {
              *tail = Fcons (build_string (names[i]), Qnil);
              tail = &XCONS (*tail)->cdr;
@@ -3923,6 +3993,12 @@ DEFUN ("x-close-current-connection", Fx_close_current_connection,
        0, 0, 0, "Close the connection to the current X server.")
   ()
 {
+  /* Note: If we're going to call check_x here, then the fatal error
+     can't happen.  For the moment, this check is just for safety,
+     so a user won't try out the function and get a crash.  If it's
+     really intended only to be called when killing emacs, then there's
+     no reason for it to have a lisp interface at all.  */
+  check_x();
 #ifdef HAVE_X11
   /* This is ONLY used when killing emacs;  For switching displays
      we'll have to take care of setting CloseDownMode elsewhere. */