]> code.delx.au - gnu-emacs/blobdiff - src/xfns.c
(ada-83-string-keywords, ada-95-string-keywords, ada-2005-string-keywords):
[gnu-emacs] / src / xfns.c
index e5db1db2e83c560ed463f114996a9ab002456c44..8f03d90c79670d1472de90c13873003121a8c709 100644 (file)
@@ -1,6 +1,6 @@
 /* Functions for the X window system.
    Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-     2001, 2002, 2003, 2004, 2005  Free Software Foundation.
+                 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -16,11 +16,10 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with GNU Emacs; see the file COPYING.  If not, write to
-the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
 
 #include <config.h>
-#include <signal.h>
 #include <stdio.h>
 #include <math.h>
 
@@ -153,7 +152,19 @@ int display_hourglass_p;
 
 /* Non-zero means prompt with the old GTK file selection dialog.  */
 
-int x_use_old_gtk_file_dialog;
+int x_gtk_use_old_file_dialog;
+
+/* If non-zero, by default show hidden files in the GTK file chooser.  */
+
+int x_gtk_show_hidden_files;
+
+/* If non-zero, don't show additional help text in the GTK file chooser.  */
+
+int x_gtk_file_dialog_help_text;
+
+/* If non-zero, don't collapse to tool bar when it is detached.  */
+
+int x_gtk_whole_detached_tool_bar;
 
 /* The background and shape of the mouse pointer, and shape when not
    over text or in the modeline.  */
@@ -570,11 +581,9 @@ x_real_positions (f, xptr, yptr)
   int had_errors = 0;
   Window win = f->output_data.x->parent_desc;
 
-  int count;
-
   BLOCK_INPUT;
 
-  count = x_catch_errors (FRAME_X_DISPLAY (f));
+  x_catch_errors (FRAME_X_DISPLAY (f));
 
   if (win == FRAME_X_DISPLAY_INFO (f)->root_window)
     win = FRAME_OUTER_WINDOW (f);
@@ -609,7 +618,7 @@ x_real_positions (f, xptr, yptr)
 
   if (! had_errors)
     {
-      int ign;
+      unsigned int ign;
       Window child, rootw;
 
       /* Get the real coordinates for the WM window upper left corner */
@@ -661,7 +670,7 @@ x_real_positions (f, xptr, yptr)
       had_errors = x_had_errors_p (FRAME_X_DISPLAY (f));
     }
 
-  x_uncatch_errors (FRAME_X_DISPLAY (f), count);
+  x_uncatch_errors ();
 
   UNBLOCK_INPUT;
 
@@ -754,9 +763,7 @@ x_decode_color (f, color_name, mono_color)
   if (x_defined_color (f, SDATA (color_name), &cdef, 1))
     return cdef.pixel;
 
-  Fsignal (Qerror, Fcons (build_string ("Undefined color"),
-                         Fcons (color_name, Qnil)));
-  return 0;
+  signal_error ("Undefined color", color_name);
 }
 
 
@@ -783,21 +790,16 @@ xg_set_icon (f, file)
     FRAME_PTR f;
     Lisp_Object file;
 {
-  struct gcpro gcpro1;
   int result = 0;
   Lisp_Object found;
 
-  GCPRO1 (found);
-
   found = x_find_image_file (file);
 
   if (! NILP (found))
     {
       GdkPixbuf *pixbuf;
       GError *err = NULL;
-      char *filename;
-
-      filename = SDATA (found);
+      char *filename = (char *) SDATA (found);
       BLOCK_INPUT;
 
       pixbuf = gdk_pixbuf_new_from_file (filename, &err);
@@ -816,9 +818,24 @@ xg_set_icon (f, file)
       UNBLOCK_INPUT;
     }
 
-  UNGCPRO;
   return result;
 }
+
+int
+xg_set_icon_from_xpm_data (f, data)
+    FRAME_PTR f;
+    char **data;
+{
+  int result = 0;
+  GdkPixbuf *pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **) data);
+
+  if (!pixbuf)
+    return 0;
+
+  gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), pixbuf);
+  g_object_unref (pixbuf);
+  return 1;
+}
 #endif /* USE_GTK */
 
 
@@ -925,7 +942,6 @@ x_set_mouse_color (f, arg, oldval)
   Display *dpy = FRAME_X_DISPLAY (f);
   Cursor cursor, nontext_cursor, mode_cursor, hand_cursor;
   Cursor hourglass_cursor, horizontal_drag_cursor;
-  int count;
   unsigned long pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
   unsigned long mask_color = x->background_pixel;
 
@@ -942,7 +958,7 @@ x_set_mouse_color (f, arg, oldval)
   BLOCK_INPUT;
 
   /* It's not okay to crash if the user selects a screwy cursor.  */
-  count = x_catch_errors (dpy);
+  x_catch_errors (dpy);
 
   if (!NILP (Vx_pointer_shape))
     {
@@ -1003,7 +1019,7 @@ x_set_mouse_color (f, arg, oldval)
 
   /* Check and report errors with the above calls.  */
   x_check_errors (dpy, "can't set cursor shape: %s");
-  x_uncatch_errors (dpy, count);
+  x_uncatch_errors ();
 
   {
     XColor fore_color, back_color;
@@ -1235,7 +1251,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;
@@ -1516,11 +1532,12 @@ x_set_scroll_bar_background (f, value, oldval)
    Otherwise store 0 in *STRINGP, which means that the `encoding' of
    the result should be `COMPOUND_TEXT'.  */
 
-unsigned char *
-x_encode_text (string, coding_system, selectionp, text_bytes, stringp)
+static unsigned char *
+x_encode_text (string, coding_system, selectionp, text_bytes, stringp, freep)
      Lisp_Object string, coding_system;
      int *text_bytes, *stringp;
      int selectionp;
+     int *freep;
 {
   unsigned char *str = SDATA (string);
   int chars = SCHARS (string);
@@ -1537,6 +1554,7 @@ x_encode_text (string, coding_system, selectionp, text_bytes, stringp)
       /* No multibyte character in OBJ.  We need not encode it.  */
       *text_bytes = bytes;
       *stringp = 1;
+      *freep = 0;
       return str;
     }
 
@@ -1564,6 +1582,7 @@ x_encode_text (string, coding_system, selectionp, text_bytes, stringp)
   *stringp = (charset_info == 1
              || (!EQ (coding_system, Qcompound_text)
                  && !EQ (coding_system, Qcompound_text_with_extensions)));
+  *freep = 1;
   return buf;
 }
 
@@ -1602,17 +1621,14 @@ x_set_name_internal (f, name)
           in the future which can encode all Unicode characters.
           But, for the moment, there's no way to know that the
           current window manager supports it or not.  */
-       text.value = x_encode_text (name, coding_system, 0, &bytes, &stringp);
+       text.value = x_encode_text (name, coding_system, 0, &bytes, &stringp,
+                                   &do_free_text_value);
        text.encoding = (stringp ? XA_STRING
                         : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
        text.format = 8;
        text.nitems = bytes;
 
-        /* Check early, because ENCODE_UTF_8 below may GC and name may be
-           relocated.  */
-        do_free_text_value = text.value != SDATA (name);
-
-       if (NILP (f->icon_name))
+       if (!STRINGP (f->icon_name))
          {
            icon = text;
          }
@@ -1620,17 +1636,16 @@ x_set_name_internal (f, name)
          {
            /* See the above comment "Note: Encoding strategy".  */
            icon.value = x_encode_text (f->icon_name, coding_system, 0,
-                                       &bytes, &stringp);
+                                       &bytes, &stringp, &do_free_icon_value);
            icon.encoding = (stringp ? XA_STRING
                             : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
            icon.format = 8;
            icon.nitems = bytes;
-            do_free_icon_value = icon.value != SDATA (f->icon_name);
          }
 
 #ifdef USE_GTK
         gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
-                              SDATA (ENCODE_UTF_8 (name)));
+                              (char *) SDATA (ENCODE_UTF_8 (name)));
 #else /* not USE_GTK */
        XSetWMName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &text);
 #endif /* not USE_GTK */
@@ -1988,7 +2003,7 @@ xic_create_fontsetname (base_fontname, motif)
         - the same but with the family also replaced with -*-*-.  */
       char *p = base_fontname;
       int i;
-      
+
       for (i = 0; *p; p++)
        if (*p == '-') i++;
       if (i != 14)
@@ -2005,12 +2020,15 @@ xic_create_fontsetname (base_fontname, motif)
       else
        {
          int len;
-         char *p1 = NULL;
+         char *p1 = NULL, *p2 = NULL, *p3 = NULL;
          char *font_allcs = NULL;
          char *font_allfamilies = NULL;
+         char *font_all = NULL;
          char *allcs = "*-*-*-*-*-*-*";
          char *allfamilies = "-*-*-";
-         
+         char *all = "*-*-*-*-";
+         char *base;
+
          for (i = 0, p = base_fontname; i < 8; p++)
            {
              if (*p == '-')
@@ -2018,8 +2036,29 @@ xic_create_fontsetname (base_fontname, motif)
                  i++;
                  if (i == 3)
                    p1 = p + 1;
+                 else if (i == 7)
+                   p2 = p + 1;
+                 else if (i == 6)
+                   p3 = p + 1;
                }
            }
+         /* If base_fontname specifies ADSTYLE, make it a
+            wildcard.  */
+         if (*p3 != '*')
+           {
+             int diff = (p2 - p3) - 2;
+
+             base = alloca (strlen (base_fontname) + 1);
+             bcopy (base_fontname, base, p3 - base_fontname);
+             base[p3 - base_fontname] = '*';
+             base[(p3 - base_fontname) + 1] = '-';
+             strcpy (base + (p3 - base_fontname) + 2, p2);
+             p = base + (p - base_fontname) - diff;
+             p1 = base + (p1 - base_fontname);
+             p2 = base + (p2 - base_fontname) - diff;
+             base_fontname = base;
+           }
+
          /* Build the font spec that matches all charsets.  */
          len = p - base_fontname + strlen (allcs) + 1;
          font_allcs = (char *) alloca (len);
@@ -2027,17 +2066,27 @@ xic_create_fontsetname (base_fontname, motif)
          bcopy (base_fontname, font_allcs, p - base_fontname);
          strcat (font_allcs, allcs);
 
-         /* Build the font spec that matches all families.  */
+         /* Build the font spec that matches all families and
+            add-styles.  */
          len = p - p1 + strlen (allcs) + strlen (allfamilies) + 1;
          font_allfamilies = (char *) alloca (len);
          bzero (font_allfamilies, len);
          strcpy (font_allfamilies, allfamilies);
-         bcopy (p1, font_allfamilies + (strlen (allfamilies)), p - p1);
+         bcopy (p1, font_allfamilies + strlen (allfamilies), p - p1);
          strcat (font_allfamilies, allcs);
 
+         /* Build the font spec that matches all.  */
+         len = p - p2 + strlen (allcs) + strlen (all) + strlen (allfamilies) + 1;
+         font_all = (char *) alloca (len);
+         bzero (font_all, len);
+         strcpy (font_all, allfamilies);
+         strcat (font_all, all);
+         bcopy (p2, font_all + strlen (all) + strlen (allfamilies), p - p2);
+         strcat (font_all, allcs);
+
          /* Build the actual font set name.  */
          len = strlen (base_fontname) + strlen (font_allcs)
-           + strlen (font_allfamilies) + 4;
+           + strlen (font_allfamilies) + strlen (font_all) + 5;
          fontsetname = xmalloc (len);
          bzero (fontsetname, len);
          strcpy (fontsetname, base_fontname);
@@ -2045,6 +2094,8 @@ xic_create_fontsetname (base_fontname, motif)
          strcat (fontsetname, font_allcs);
          strcat (fontsetname, sep);
          strcat (fontsetname, font_allfamilies);
+         strcat (fontsetname, sep);
+         strcat (fontsetname, font_all);
        }
     }
   if (motif)
@@ -2086,10 +2137,33 @@ xic_create_xfontset (f, base_fontname)
 
       /* New fontset.  */
       xfs = XCreateFontSet (FRAME_X_DISPLAY (f),
-                            fontsetname, &missing_list,
-                            &missing_count, &def_string);
+                           fontsetname, &missing_list,
+                           &missing_count, &def_string);
       if (missing_list)
-        XFreeStringList (missing_list);
+       XFreeStringList (missing_list);
+      if (! xfs)
+       {
+         /* FONTSETNAME contains a list of font names (specific fonts
+            first, general fonts last), but giving that to
+            XCreateFontSet at once occasionally fails (bug of X?).
+            So, we try to call XCreateFontSet for each fontname.  */
+         char *p0 = fontsetname, *p1;
+
+         while (p0)
+           {
+             p1 = strchr (p0, ',');
+             if (p1)
+               *p1 = '\0';
+             xfs = XCreateFontSet (FRAME_X_DISPLAY (f),
+                                   p0, &missing_list,
+                                   &missing_count, &def_string);
+             if (missing_list)
+               XFreeStringList (missing_list);
+             if (xfs)
+               break;
+             p0 = p1 ? p1 + 1 : NULL;
+           }
+       }
       xfree (fontsetname);
     }
 
@@ -2789,12 +2863,15 @@ x_icon (f, parms)
   if (! EQ (icon_x, Qunbound))
     x_wm_set_icon_position (f, XINT (icon_x), XINT (icon_y));
 
+#if 0 /* x_get_arg removes the visibility parameter as a side effect,
+         but x_create_frame still needs it.  */
   /* Start up iconic or window? */
   x_wm_set_window_state
     (f, (EQ (x_get_arg (dpyinfo, parms, Qvisibility, 0, 0, RES_TYPE_SYMBOL),
             Qicon)
         ? IconicState
         : NormalState));
+#endif
 
   x_text_icon (f, (char *) SDATA ((!NILP (f->icon_name)
                                     ? f->icon_name
@@ -2977,6 +3054,8 @@ This function is an internal primitive--use `make-frame' instead.  */)
 
   check_x ();
 
+  parms = Fcopy_alist (parms);
+
   /* Use this general default value to start with
      until we know if this frame has a specified name.  */
   Vx_resource_name = Vinvocation_name;
@@ -3042,7 +3121,6 @@ This function is an internal primitive--use `make-frame' instead.  */)
   f->output_data.x->scroll_bar_top_shadow_pixel = -1;
   f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
 #endif /* USE_TOOLKIT_SCROLL_BARS */
-  record_unwind_protect (unwind_create_frame, frame);
 
   f->icon_name
     = x_get_arg (dpyinfo, parms, Qicon_name, "iconName", "Title",
@@ -3051,6 +3129,9 @@ This function is an internal primitive--use `make-frame' instead.  */)
     f->icon_name = Qnil;
 
   FRAME_X_DISPLAY_INFO (f) = dpyinfo;
+
+  /* With FRAME_X_DISPLAY_INFO set up, this unwind-protect is safe.  */
+  record_unwind_protect (unwind_create_frame, frame);
 #if GLYPH_DEBUG
   image_cache_refcount = FRAME_X_IMAGE_CACHE (f)->refcount;
   dpyinfo_refcount = dpyinfo->reference_count;
@@ -3156,8 +3237,7 @@ This function is an internal primitive--use `make-frame' instead.  */)
     if (! STRINGP (font))
       font = build_string ("fixed");
 
-    x_default_parameter (f, parms, Qfont, font,
-                        "font", "Font", RES_TYPE_STRING);
+    x_set_frame_parameters (f, Fcons (Fcons (Qfont, font), Qnil));
   }
 
 #ifdef USE_LUCID
@@ -3264,7 +3344,7 @@ This function is an internal primitive--use `make-frame' instead.  */)
 
   /* We need to do this after creating the X window, so that the
      icon-creation functions can say whose icon they're describing.  */
-  x_default_parameter (f, parms, Qicon_type, Qnil,
+  x_default_parameter (f, parms, Qicon_type, Qt,
                       "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL);
 
   x_default_parameter (f, parms, Qauto_raise, Qnil,
@@ -3342,10 +3422,23 @@ This function is an internal primitive--use `make-frame' instead.  */)
                        FRAME_OUTER_WINDOW (f),
                        dpyinfo->Xatom_wm_client_leader,
                        XA_WINDOW, 32, PropModeReplace,
-                       (char *) &dpyinfo->client_leader_window, 1);
+                       (unsigned char *) &dpyinfo->client_leader_window, 1);
       UNBLOCK_INPUT;
     }
 
+  /* Initialize `default-minibuffer-frame' in case this is the first
+     frame on this display device.  */
+  if (FRAME_HAS_MINIBUF_P (f)
+      && (!FRAMEP (kb->Vdefault_minibuffer_frame)
+          || !FRAME_LIVE_P (XFRAME (kb->Vdefault_minibuffer_frame))))
+    kb->Vdefault_minibuffer_frame = 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 = parms; !NILP (tem); tem = XCDR (tem))
+    if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
+      f->param_alist = Fcons (XCAR (tem), f->param_alist);
+
   UNGCPRO;
 
   /* Make sure windows on this frame appear in calls to next-window
@@ -3391,13 +3484,12 @@ FRAME nil means use the selected frame.  */)
 {
   struct frame *f = check_x_frame (frame);
   Display *dpy = FRAME_X_DISPLAY (f);
-  int count;
 
   BLOCK_INPUT;
-  count = x_catch_errors (dpy);
+  x_catch_errors (dpy);
   XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
                  RevertToParent, CurrentTime);
-  x_uncatch_errors (dpy, count);
+  x_uncatch_errors ();
   UNBLOCK_INPUT;
 
   return Qnil;
@@ -3431,14 +3523,9 @@ DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
   CHECK_STRING (color);
 
   if (x_defined_color (f, SDATA (color), &foo, 0))
-    {
-      Lisp_Object rgb[3];
-
-      rgb[0] = make_number (foo.red);
-      rgb[1] = make_number (foo.green);
-      rgb[2] = make_number (foo.blue);
-      return Flist (3, rgb);
-    }
+    return list3 (make_number (foo.red),
+                 make_number (foo.green),
+                 make_number (foo.blue));
   else
     return Qnil;
 }
@@ -4028,11 +4115,15 @@ If DISPLAY is nil, that stands for the selected frame's display.  */)
   x_destroy_all_bitmaps (dpyinfo);
   XSetCloseDownMode (dpyinfo->display, DestroyAll);
 
+#ifdef USE_GTK
+  xg_display_close (dpyinfo->display);
+#else
 #ifdef USE_X_TOOLKIT
   XtCloseDisplay (dpyinfo->display);
 #else
   XCloseDisplay (dpyinfo->display);
 #endif
+#endif /* ! USE_GTK */
 
   x_delete_display (dpyinfo);
   UNBLOCK_INPUT;
@@ -4369,6 +4460,10 @@ start_hourglass ()
   EMACS_TIME delay;
   int secs, usecs = 0;
 
+  /* Don't bother for ttys.  */
+  if (NILP (Vwindow_system))
+    return;
+
   cancel_hourglass ();
 
   if (INTEGERP (Vhourglass_delay)
@@ -4587,9 +4682,7 @@ x_create_tip_frame (dpyinfo, parms, text)
 
   check_x ();
 
-  /* Use this general default value to start with until we know if
-     this frame has a specified name.  */
-  Vx_resource_name = Vinvocation_name;
+  parms = Fcopy_alist (parms);
 
 #ifdef MULTI_KBOARD
   kb = dpyinfo->kboard;
@@ -4603,7 +4696,6 @@ x_create_tip_frame (dpyinfo, parms, text)
       && !EQ (name, Qunbound)
       && !NILP (name))
     error ("Invalid frame name--not a string or nil");
-  Vx_resource_name = name;
 
   frame = Qnil;
   GCPRO3 (parms, name, frame);
@@ -4906,16 +4998,22 @@ compute_tip_xy (f, parms, dx, dy, width, height, root_x, root_y)
 
   if (INTEGERP (top))
     *root_y = XINT (top);
-  else if (*root_y + XINT (dy) - height < 0)
-    *root_y -= XINT (dy);
-  else
-    {
-      *root_y -= height;
+  else if (*root_y + XINT (dy) <= 0)
+    *root_y = 0; /* Can happen for negative dy */
+  else if (*root_y + XINT (dy) + height <= FRAME_X_DISPLAY_INFO (f)->height)
+    /* It fits below the pointer */
       *root_y += XINT (dy);
-    }
+  else if (height + XINT (dy) <= *root_y)
+    /* It fits above the pointer.  */
+    *root_y -= height + XINT (dy);
+  else
+    /* Put it on the top.  */
+    *root_y = 0;
 
   if (INTEGERP (left))
     *root_x = XINT (left);
+  else if (*root_x + XINT (dx) <= 0)
+    *root_x = 0; /* Can happen for negative dx */
   else if (*root_x + XINT (dx) + width <= FRAME_X_DISPLAY_INFO (f)->width)
     /* It fits to the right of the pointer.  */
     *root_x += XINT (dx);
@@ -5072,7 +5170,7 @@ Text larger than the specified size is clipped.  */)
   clear_glyph_matrix (w->desired_matrix);
   clear_glyph_matrix (w->current_matrix);
   SET_TEXT_POS (pos, BEGV, BEGV_BYTE);
-  try_window (FRAME_ROOT_WINDOW (f), pos);
+  try_window (FRAME_ROOT_WINDOW (f), pos, 0);
 
   /* Compute width and height of the tooltip.  */
   width = height = 0;
@@ -5196,8 +5294,27 @@ Value is t if tooltip was open, nil otherwise.  */)
                        File selection dialog
  ***********************************************************************/
 
-#ifdef USE_MOTIF
+DEFUN ("x-uses-old-gtk-dialog", Fx_uses_old_gtk_dialog,
+       Sx_uses_old_gtk_dialog,
+       0, 0, 0,
+       doc: /* Return t if the old Gtk+ file selection dialog is used.  */)
+     ()
+{
+#ifdef USE_GTK
+  extern int use_dialog_box;
+  extern int use_file_dialog;
 
+  if (use_dialog_box
+      && use_file_dialog
+      && have_menus_p ()
+      && xg_uses_old_file_dialog ())
+    return Qt;
+#endif
+  return Qnil;
+}
+
+
+#ifdef USE_MOTIF
 /* Callback for "OK" and "Cancel" on file selection dialog.  */
 
 static void
@@ -5254,6 +5371,7 @@ or directory must exist.  ONLY-DIR-P is ignored."  */)
   int result;
   struct frame *f = SELECTED_FRAME ();
   Lisp_Object file = Qnil;
+  Lisp_Object decoded_file;
   Widget dialog, text, help;
   Arg al[10];
   int ac = 0;
@@ -5262,6 +5380,8 @@ or directory must exist.  ONLY-DIR-P is ignored."  */)
   int count = SPECPDL_INDEX ();
   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
 
+  check_x ();
+
   GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
 
   if (popup_activated ())
@@ -5394,7 +5514,9 @@ or directory must exist.  ONLY-DIR-P is ignored."  */)
   if (NILP (file))
     Fsignal (Qquit, Qnil);
 
-  return unbind_to (count, file);
+  decoded_file = DECODE_FILE (file);
+
+  return unbind_to (count, decoded_file);
 }
 
 #endif /* USE_MOTIF */
@@ -5422,10 +5544,13 @@ directories.  */)
   FRAME_PTR f = SELECTED_FRAME ();
   char *fn;
   Lisp_Object file = Qnil;
+  Lisp_Object decoded_file;
   int count = SPECPDL_INDEX ();
   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
   char *cdef_file;
 
+  check_x ();
+
   GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
 
   if (popup_activated ())
@@ -5462,7 +5587,9 @@ directories.  */)
   if (NILP (file))
     Fsignal (Qquit, Qnil);
 
-  return unbind_to (count, file);
+  decoded_file = DECODE_FILE (file);
+
+  return unbind_to (count, decoded_file);
 }
 
 #endif /* USE_GTK */
@@ -5482,7 +5609,8 @@ DEFUN ("x-backspace-delete-keys-p", Fx_backspace_delete_keys_p,
        doc: /* Check if both Backspace and Delete keys are on the keyboard of FRAME.
 FRAME nil means use the selected frame.
 Value is t if we know that both keys are present, and are mapped to the
-usual X keysyms.  */)
+usual X keysyms.  Value is `lambda' if we cannot determine if both keys are
+present and mapped to the usual X keysyms.  */)
      (frame)
      Lisp_Object frame;
 {
@@ -5501,7 +5629,7 @@ usual X keysyms.  */)
   if (!XkbLibraryVersion (&major, &minor))
     {
       UNBLOCK_INPUT;
-      return Qnil;
+      return Qlambda;
     }
 
   /* Check that the server supports XKB.  */
@@ -5510,7 +5638,7 @@ usual X keysyms.  */)
   if (!XkbQueryExtension (dpy, &op, &event, &error, &major, &minor))
     {
       UNBLOCK_INPUT;
-      return Qnil;
+      return Qlambda;
     }
 
   /* In this code we check that the keyboard has physical keys with names
@@ -5565,7 +5693,7 @@ usual X keysyms.  */)
   UNBLOCK_INPUT;
   return have_keys;
 #else /* not HAVE_XKBGETKEYBOARD */
-  return Qnil;
+  return Qlambda;
 #endif /* not HAVE_XKBGETKEYBOARD */
 }
 
@@ -5721,12 +5849,32 @@ Chinese, Japanese, and Korean.  */);
   Vx_pixel_size_width_font_regexp = Qnil;
 
 /* This is not ifdef:ed, so other builds than GTK can customize it.  */
-  DEFVAR_BOOL ("x-use-old-gtk-file-dialog", &x_use_old_gtk_file_dialog,
+  DEFVAR_BOOL ("x-gtk-use-old-file-dialog", &x_gtk_use_old_file_dialog,
     doc: /* *Non-nil means prompt with the old GTK file selection dialog.
 If nil or if the file selection dialog is not available, the new GTK file
 chooser is used instead.  To turn off all file dialogs set the
 variable `use-file-dialog'.  */);
-  x_use_old_gtk_file_dialog = 0;
+  x_gtk_use_old_file_dialog = 0;
+
+  DEFVAR_BOOL ("x-gtk-show-hidden-files", &x_gtk_show_hidden_files,
+    doc: /* *If non-nil, the GTK file chooser will by default show hidden files.
+Note that this is just the default, there is a toggle button on the file
+chooser to show or not show hidden files on a case by case basis.  */);
+  x_gtk_show_hidden_files = 0;
+
+  DEFVAR_BOOL ("x-gtk-file-dialog-help-text", &x_gtk_file_dialog_help_text,
+    doc: /* *If non-nil, the GTK file chooser will show additional help text.
+If more space for files in the file chooser dialog is wanted, set this to nil
+to turn the additional text off.  */);
+  x_gtk_file_dialog_help_text = 1;
+
+  DEFVAR_BOOL ("x-gtk-whole-detached-tool-bar", &x_gtk_whole_detached_tool_bar,
+    doc: /* *If non-nil, a detached tool bar is shown in full.
+The default is to just show an arrow and pressing on that arrow shows
+the tool bar buttons.  */);
+  x_gtk_whole_detached_tool_bar = 0;
+
+  Fprovide (intern ("x"), Qnil);
 
 #ifdef USE_X_TOOLKIT
   Fprovide (intern ("x-toolkit"), Qnil);
@@ -5814,6 +5962,7 @@ variable `use-file-dialog'.  */);
   last_show_tip_args = Qnil;
   staticpro (&last_show_tip_args);
 
+  defsubr (&Sx_uses_old_gtk_dialog);
 #if defined (USE_MOTIF) || defined (USE_GTK)
   defsubr (&Sx_file_dialog);
 #endif