* w32fns.c (syms_of_w32fns) <x-max-tooltip-size>: Fix typo in docstring.
[bpt/emacs.git] / src / xfns.c
index 25ace42..1d7d3d0 100644 (file)
@@ -1,6 +1,6 @@
 /* Functions for the X window system.
    Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
 /* Functions for the X window system.
    Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-                 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+                 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
                  Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
                  Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
@@ -21,6 +21,8 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <config.h>
 #include <stdio.h>
 #include <math.h>
 #include <config.h>
 #include <stdio.h>
 #include <math.h>
+#include <setjmp.h>
+#include <ctype.h>
 
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
@@ -62,6 +64,8 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <X11/bitmaps/gray>
 #endif
 
 #include <X11/bitmaps/gray>
 #endif
 
+#include "xsettings.h"
+
 #ifdef USE_GTK
 #include "gtkutil.h"
 #endif
 #ifdef USE_GTK
 #include "gtkutil.h"
 #endif
@@ -97,13 +101,10 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <Xm/FileSB.h>
 #endif
 
 #include <Xm/FileSB.h>
 #endif
 
-/* Do the EDITRES protocol if running X11R5
-   Exception: HP-UX (at least version A.09.05) has X11R5 without EditRes */
-
-#if (XtSpecificationRelease >= 5) && !defined(NO_EDITRES)
+#if !defined(NO_EDITRES)
 #define HACK_EDITRES
 extern void _XEditResCheckMessages ();
 #define HACK_EDITRES
 extern void _XEditResCheckMessages ();
-#endif /* R5 + Athena */
+#endif /* not defined NO_EDITRES */
 
 /* Unique id counter for widgets created by the Lucid Widget Library.  */
 
 
 /* Unique id counter for widgets created by the Lucid Widget Library.  */
 
@@ -196,7 +197,7 @@ Lisp_Object Qnone;
 Lisp_Object Qsuppress_icon;
 Lisp_Object Qundefined_color;
 Lisp_Object Qcompound_text, Qcancel_timer;
 Lisp_Object Qsuppress_icon;
 Lisp_Object Qundefined_color;
 Lisp_Object Qcompound_text, Qcancel_timer;
-static Lisp_Object Qfont_param;
+Lisp_Object Qfont_param;
 
 /* In dispnew.c */
 
 
 /* In dispnew.c */
 
@@ -204,10 +205,15 @@ extern Lisp_Object Vwindow_system_version;
 
 /* The below are defined in frame.c.  */
 
 
 /* The below are defined in frame.c.  */
 
+extern Lisp_Object Qtooltip;
+
 #if GLYPH_DEBUG
 int image_cache_refcount, dpyinfo_refcount;
 #endif
 
 #if GLYPH_DEBUG
 int image_cache_refcount, dpyinfo_refcount;
 #endif
 
+#if defined (USE_GTK) && defined (HAVE_FREETYPE)
+char *x_last_font_name;
+#endif
 
 \f
 /* Error if we are not connected to X.  */
 
 \f
 /* Error if we are not connected to X.  */
@@ -247,7 +253,7 @@ check_x_frame (frame)
 }
 
 /* Let the user specify an X display with a Lisp object.
 }
 
 /* Let the user specify an X display with a Lisp object.
-   OBJECT may be nil, a frame or a terminal id.
+   OBJECT may be nil, a frame or a terminal object.
    nil stands for the selected frame--or, if that is not an X frame,
    the first X display on the list.  */
 
    nil stands for the selected frame--or, if that is not an X frame,
    the first X display on the list.  */
 
@@ -268,7 +274,7 @@ check_x_display_info (object)
       else
        error ("X windows are not in use or not initialized");
     }
       else
        error ("X windows are not in use or not initialized");
     }
-  else if (INTEGERP (object))
+  else if (TERMINALP (object))
     {
       struct terminal *t = get_terminal (object, 1);
 
     {
       struct terminal *t = get_terminal (object, 1);
 
@@ -374,10 +380,7 @@ x_any_window_to_frame (dpyinfo, wdesc)
 #ifdef USE_GTK
               GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
               if (gwdesc != 0
 #ifdef USE_GTK
               GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
               if (gwdesc != 0
-                  && (gwdesc == x->widget
-                      || gwdesc == x->edit_widget
-                      || gwdesc == x->vbox_widget
-                      || gwdesc == x->menubar_widget))
+                  && gtk_widget_get_toplevel (gwdesc) == x->widget)
                 found = f;
 #else
              if (wdesc == XtWindow (x->widget)
                 found = f;
 #else
              if (wdesc == XtWindow (x->widget)
@@ -398,61 +401,14 @@ x_any_window_to_frame (dpyinfo, wdesc)
   return found;
 }
 
   return found;
 }
 
-/* Likewise, but exclude the menu bar widget.  */
-
-struct frame *
-x_non_menubar_window_to_frame (dpyinfo, wdesc)
-     struct x_display_info *dpyinfo;
-     int wdesc;
-{
-  Lisp_Object tail, frame;
-  struct frame *f;
-  struct x_output *x;
-
-  if (wdesc == None) return 0;
-
-  for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
-    {
-      frame = XCAR (tail);
-      if (!FRAMEP (frame))
-        continue;
-      f = XFRAME (frame);
-      if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
-       continue;
-      x = f->output_data.x;
-      /* This frame matches if the window is any of its widgets.  */
-      if (x->hourglass_window == wdesc)
-       return f;
-      else if (x->widget)
-       {
-#ifdef USE_GTK
-          GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
-          if (gwdesc != 0
-              && (gwdesc == x->widget
-                  || gwdesc == x->edit_widget
-                  || gwdesc == x->vbox_widget))
-            return f;
-#else
-         if (wdesc == XtWindow (x->widget)
-             || wdesc == XtWindow (x->column_widget)
-             || wdesc == XtWindow (x->edit_widget))
-           return f;
-#endif
-       }
-      else if (FRAME_X_WINDOW (f) == wdesc)
-       /* A tooltip frame.  */
-       return f;
-    }
-  return 0;
-}
-
 /* Likewise, but consider only the menu bar widget.  */
 
 struct frame *
 /* Likewise, but consider only the menu bar widget.  */
 
 struct frame *
-x_menubar_window_to_frame (dpyinfo, wdesc)
+x_menubar_window_to_frame (dpyinfo, event)
      struct x_display_info *dpyinfo;
      struct x_display_info *dpyinfo;
-     int wdesc;
+     XEvent *event;
 {
 {
+  Window wdesc = event->xany.window;
   Lisp_Object tail, frame;
   struct frame *f;
   struct x_output *x;
   Lisp_Object tail, frame;
   struct frame *f;
   struct x_output *x;
@@ -468,22 +424,11 @@ x_menubar_window_to_frame (dpyinfo, wdesc)
       if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
        continue;
       x = f->output_data.x;
       if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
        continue;
       x = f->output_data.x;
-      /* Match if the window is this frame's menubar.  */
 #ifdef USE_GTK
 #ifdef USE_GTK
-      if (x->menubar_widget)
-        {
-          GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
-          int found = 0;
-
-          BLOCK_INPUT;
-          if (gwdesc != 0
-              && (gwdesc == x->menubar_widget
-                  || gtk_widget_get_parent (gwdesc) == x->menubar_widget))
-            found = 1;
-          UNBLOCK_INPUT;
-          if (found) return f;
-        }
+      if (x->menubar_widget && xg_event_is_for_menubar (f, event))
+        return f;
 #else
 #else
+      /* Match if the window is this frame's menubar.  */
       if (x->menubar_widget
          && lw_window_is_in_menubar (wdesc, x->menubar_widget))
        return f;
       if (x->menubar_widget
          && lw_window_is_in_menubar (wdesc, x->menubar_widget))
        return f;
@@ -941,6 +886,35 @@ x_set_background_color (f, arg, oldval)
     }
 }
 
     }
 }
 
+static Cursor
+make_invisible_cursor (f)
+     struct frame *f;
+{
+  Display *dpy = FRAME_X_DISPLAY (f);
+  static char const no_data[] = { 0 };
+  Pixmap pix;
+  XColor col;
+  Cursor c;
+
+  x_catch_errors (dpy);
+  pix = XCreateBitmapFromData (dpy, FRAME_X_DISPLAY_INFO (f)->root_window,
+                               no_data, 1, 1);
+  if (! x_had_errors_p (dpy) && pix != None)
+    {
+      col.pixel = 0;
+      col.red = col.green = col.blue = 0;
+      col.flags = DoRed | DoGreen | DoBlue;
+      c = XCreatePixmapCursor (dpy, pix, pix, &col, &col, 0, 0);
+      if (x_had_errors_p (dpy) || c == None)
+        c = 0;
+      XFreePixmap (dpy, pix);
+    }
+
+  x_uncatch_errors ();
+
+  return c;
+}
+
 void
 x_set_mouse_color (f, arg, oldval)
      struct frame *f;
 void
 x_set_mouse_color (f, arg, oldval)
      struct frame *f;
@@ -1046,7 +1020,11 @@ x_set_mouse_color (f, arg, oldval)
   }
 
   if (FRAME_X_WINDOW (f) != 0)
   }
 
   if (FRAME_X_WINDOW (f) != 0)
-    XDefineCursor (dpy, FRAME_X_WINDOW (f), cursor);
+    XDefineCursor (dpy, FRAME_X_WINDOW (f),
+                   f->output_data.x->current_cursor = cursor);
+
+  if (FRAME_X_DISPLAY_INFO (f)->invisible_cursor == 0)
+    FRAME_X_DISPLAY_INFO (f)->invisible_cursor = make_invisible_cursor (f);
 
   if (cursor != x->text_cursor
       && x->text_cursor != 0)
 
   if (cursor != x->text_cursor
       && x->text_cursor != 0)
@@ -1332,7 +1310,43 @@ x_set_menu_bar_lines (f, value, oldval)
 #else /* not USE_X_TOOLKIT && not USE_GTK */
   FRAME_MENU_BAR_LINES (f) = nlines;
   change_window_heights (f->root_window, nlines - olines);
 #else /* not USE_X_TOOLKIT && not USE_GTK */
   FRAME_MENU_BAR_LINES (f) = nlines;
   change_window_heights (f->root_window, nlines - olines);
-#endif /* not USE_X_TOOLKIT */
+
+  /* If the menu bar height gets changed, the internal border below
+     the top margin has to be cleared.  Also, if the menu bar gets
+     larger, the area for the added lines has to be cleared except for
+     the first menu bar line that is to be drawn later.  */
+  if (nlines != olines)
+    {
+      int height = FRAME_INTERNAL_BORDER_WIDTH (f);
+      int width = FRAME_PIXEL_WIDTH (f);
+      int y;
+
+      /* height can be zero here. */
+      if (height > 0 && width > 0)
+       {
+         y = FRAME_TOP_MARGIN_HEIGHT (f);
+
+         BLOCK_INPUT;
+         x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+                       0, y, width, height, False);
+         UNBLOCK_INPUT;
+       }
+
+      if (nlines > 1 && nlines > olines)
+       {
+         y = (olines == 0 ? 1 : olines) * FRAME_LINE_HEIGHT (f);
+         height = nlines * FRAME_LINE_HEIGHT (f) - y;
+
+         BLOCK_INPUT;
+         x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+                       0, y, width, height, False);
+         UNBLOCK_INPUT;
+       }
+
+      if (nlines == 0 && WINDOWP (f->menu_bar_window))
+       clear_glyph_matrix (XWINDOW (f->menu_bar_window)->current_matrix);
+    }
+#endif /* not USE_X_TOOLKIT && not USE_GTK */
   adjust_glyphs (f);
 }
 
   adjust_glyphs (f);
 }
 
@@ -1418,7 +1432,7 @@ x_set_tool_bar_lines (f, value, oldval)
     {
       int height = FRAME_INTERNAL_BORDER_WIDTH (f);
       int width = FRAME_PIXEL_WIDTH (f);
     {
       int height = FRAME_INTERNAL_BORDER_WIDTH (f);
       int width = FRAME_PIXEL_WIDTH (f);
-      int y = nlines * FRAME_LINE_HEIGHT (f);
+      int y = (FRAME_MENU_BAR_LINES (f) + nlines) * FRAME_LINE_HEIGHT (f);
 
       /* height can be zero here. */
       if (height > 0 && width > 0)
 
       /* height can be zero here. */
       if (height > 0 && width > 0)
@@ -2671,7 +2685,8 @@ x_window (f, window_prompting, minibuffer_only)
   }
 
   XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
   }
 
   XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                f->output_data.x->text_cursor);
+                f->output_data.x->current_cursor
+                 = f->output_data.x->text_cursor);
 
   UNBLOCK_INPUT;
 
 
   UNBLOCK_INPUT;
 
@@ -2816,7 +2831,8 @@ x_window (f)
   }
 
   XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
   }
 
   XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                f->output_data.x->text_cursor);
+                f->output_data.x->current_cursor
+                 = f->output_data.x->text_cursor);
 
   UNBLOCK_INPUT;
 
 
   UNBLOCK_INPUT;
 
@@ -2901,14 +2917,6 @@ x_icon (f, parms)
    background, border and mouse colors; also create the
    mouse cursor and the gray border tile.  */
 
    background, border and mouse colors; also create the
    mouse cursor and the gray border tile.  */
 
-static char cursor_bits[] =
-  {
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-  };
-
 static void
 x_make_gc (f)
      struct frame *f;
 static void
 x_make_gc (f)
      struct frame *f;
@@ -2942,14 +2950,10 @@ x_make_gc (f)
   gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
   gc_values.background = f->output_data.x->cursor_pixel;
   gc_values.fill_style = FillOpaqueStippled;
   gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
   gc_values.background = f->output_data.x->cursor_pixel;
   gc_values.fill_style = FillOpaqueStippled;
-  gc_values.stipple
-    = XCreateBitmapFromData (FRAME_X_DISPLAY (f),
-                            FRAME_X_DISPLAY_INFO (f)->root_window,
-                            cursor_bits, 16, 16);
   f->output_data.x->cursor_gc
     = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
                 (GCForeground | GCBackground
   f->output_data.x->cursor_gc
     = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
                 (GCForeground | GCBackground
-                 | GCFillStyle /* | GCStipple */ | GCLineWidth),
+                 | GCFillStyle | GCLineWidth),
                 &gc_values);
 
   /* Reliefs.  */
                 &gc_values);
 
   /* Reliefs.  */
@@ -2971,7 +2975,7 @@ x_make_gc (f)
 }
 
 
 }
 
 
-/* Free what was was allocated in x_make_gc.  */
+/* Free what was allocated in x_make_gc.  */
 
 void
 x_free_gcs (f)
 
 void
 x_free_gcs (f)
@@ -3053,10 +3057,22 @@ x_default_font_parameter (f, parms)
 {
   struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
   Lisp_Object font_param = x_get_arg (dpyinfo, parms, Qfont, NULL, NULL,
 {
   struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
   Lisp_Object font_param = x_get_arg (dpyinfo, parms, Qfont, NULL, NULL,
-                               RES_TYPE_STRING);
+                                      RES_TYPE_STRING);
   Lisp_Object font;
   Lisp_Object font;
+  int got_from_gconf = 0;
   if (EQ (font_param, Qunbound))
     font_param = Qnil;
   if (EQ (font_param, Qunbound))
     font_param = Qnil;
+
+  if (NILP (font_param))
+    {
+      /* System font takes precedendce over X resources.  We must suggest this
+         regardless of font-use-system-font because .emacs may not have been
+         read yet.  */
+      const char *system_font = xsettings_get_system_font ();
+      if (system_font) font_param = make_string (system_font,
+                                                 strlen (system_font));
+    }
+
   font = !NILP (font_param) ? font_param
     : x_get_arg (dpyinfo, parms, Qfont, "font", "Font", RES_TYPE_STRING);
 
   font = !NILP (font_param) ? font_param
     : x_get_arg (dpyinfo, parms, Qfont, "font", "Font", RES_TYPE_STRING);
 
@@ -3066,7 +3082,7 @@ x_default_font_parameter (f, parms)
        = {
 #ifdef HAVE_XFT
            /* This will find the normal Xft font.  */
        = {
 #ifdef HAVE_XFT
            /* This will find the normal Xft font.  */
-           "monospace-12",
+           "monospace-10",
 #endif
            "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1",
            "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
 #endif
            "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1",
            "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
@@ -3096,7 +3112,11 @@ x_default_font_parameter (f, parms)
         we've applied the `default' face settings.  */
       x_set_frame_parameters (f, Fcons (Fcons (Qfont_param, font_param), Qnil));
     }
         we've applied the `default' face settings.  */
       x_set_frame_parameters (f, Fcons (Fcons (Qfont_param, font_param), Qnil));
     }
-  x_default_parameter (f, parms, Qfont, font, "font", "Font", RES_TYPE_STRING);
+
+  x_default_parameter (f, parms, Qfont, font,
+                       got_from_gconf ? NULL : "font",
+                       got_from_gconf ? NULL : "Font",
+                       RES_TYPE_STRING);
 }
 
 
 }
 
 
@@ -3296,7 +3316,6 @@ This function is an internal primitive--use `make-frame' instead.  */)
   f->resx = dpyinfo->resx;
   f->resy = dpyinfo->resy;
 
   f->resx = dpyinfo->resx;
   f->resy = dpyinfo->resy;
 
-  register_font_driver (&xfont_driver, f);
 #ifdef HAVE_FREETYPE
 #ifdef HAVE_XFT
   register_font_driver (&xftfont_driver, f);
 #ifdef HAVE_FREETYPE
 #ifdef HAVE_XFT
   register_font_driver (&xftfont_driver, f);
@@ -3304,6 +3323,7 @@ This function is an internal primitive--use `make-frame' instead.  */)
   register_font_driver (&ftxfont_driver, f);
 #endif /* not HAVE_XFT */
 #endif /* HAVE_FREETYPE */
   register_font_driver (&ftxfont_driver, f);
 #endif /* not HAVE_XFT */
 #endif /* HAVE_FREETYPE */
+  register_font_driver (&xfont_driver, f);
 
   x_default_parameter (f, parms, Qfont_backend, Qnil,
                       "fontBackend", "FontBackend", RES_TYPE_STRING);
 
   x_default_parameter (f, parms, Qfont_backend, Qnil,
                       "fontBackend", "FontBackend", RES_TYPE_STRING);
@@ -3311,11 +3331,18 @@ This function is an internal primitive--use `make-frame' instead.  */)
   /* Extract the window parameters from the supplied values
      that are needed to determine window geometry.  */
   x_default_font_parameter (f, parms);
   /* Extract the window parameters from the supplied values
      that are needed to determine window geometry.  */
   x_default_font_parameter (f, parms);
+  if (!FRAME_FONT (f))
+    {
+      delete_frame (frame, Qnoelisp);
+      error ("Invalid frame font");
+    }
 
 #ifdef USE_LUCID
   /* Prevent lwlib/xlwmenu.c from crashing because of a bug
      whereby it fails to get any font.  */
 
 #ifdef USE_LUCID
   /* Prevent lwlib/xlwmenu.c from crashing because of a bug
      whereby it fails to get any font.  */
+  BLOCK_INPUT;
   xlwmenu_default_font = XLoadQueryFont (FRAME_X_DISPLAY (f), "fixed");
   xlwmenu_default_font = XLoadQueryFont (FRAME_X_DISPLAY (f), "fixed");
+  UNBLOCK_INPUT;
 #endif
 
   /* Frame contents get displaced if an embedded X window has a border.  */
 #endif
 
   /* Frame contents get displaced if an embedded X window has a border.  */
@@ -3384,7 +3411,7 @@ This function is an internal primitive--use `make-frame' instead.  */)
   init_frame_faces (f);
 
   x_default_parameter (f, parms, Qmenu_bar_lines, make_number (1),
   init_frame_faces (f);
 
   x_default_parameter (f, parms, Qmenu_bar_lines, make_number (1),
-                      "menuBar", "MenuBar", RES_TYPE_NUMBER);
+                      "menuBar", "MenuBar", RES_TYPE_BOOLEAN_NUMBER);
   x_default_parameter (f, parms, Qtool_bar_lines, make_number (1),
                       "toolBar", "ToolBar", RES_TYPE_NUMBER);
   x_default_parameter (f, parms, Qbuffer_predicate, Qnil,
   x_default_parameter (f, parms, Qtool_bar_lines, make_number (1),
                       "toolBar", "ToolBar", RES_TYPE_NUMBER);
   x_default_parameter (f, parms, Qbuffer_predicate, Qnil,
@@ -3638,7 +3665,7 @@ DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p,
        doc: /* Return t if the X display supports shades of gray.
 Note that color displays do support shades of gray.
 The optional argument TERMINAL specifies which display to ask about.
        doc: /* Return t if the X display supports shades of gray.
 Note that color displays do support shades of gray.
 The optional argument TERMINAL specifies which display to ask about.
-TERMINAL should be a terminal id, a frame or a display name (a string).
+TERMINAL should be a terminal object, a frame or a display name (a string).
 If omitted or nil, that stands for the selected frame's display.  */)
      (terminal)
      Lisp_Object terminal;
 If omitted or nil, that stands for the selected frame's display.  */)
      (terminal)
      Lisp_Object terminal;
@@ -3667,7 +3694,7 @@ DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
        0, 1, 0,
        doc: /* Return the width in pixels of the X display TERMINAL.
 The optional argument TERMINAL specifies which display to ask about.
        0, 1, 0,
        doc: /* Return the width in pixels of the X display TERMINAL.
 The optional argument TERMINAL specifies which display to ask about.
-TERMINAL should be a terminal id, a frame or a display name (a string).
+TERMINAL should be a terminal object, a frame or a display name (a string).
 If omitted or nil, that stands for the selected frame's display.  */)
      (terminal)
      Lisp_Object terminal;
 If omitted or nil, that stands for the selected frame's display.  */)
      (terminal)
      Lisp_Object terminal;
@@ -3681,7 +3708,7 @@ DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
        Sx_display_pixel_height, 0, 1, 0,
        doc: /* Return the height in pixels of the X display TERMINAL.
 The optional argument TERMINAL specifies which display to ask about.
        Sx_display_pixel_height, 0, 1, 0,
        doc: /* Return the height in pixels of the X display TERMINAL.
 The optional argument TERMINAL specifies which display to ask about.
-TERMINAL should be a terminal id, a frame or a display name (a string).
+TERMINAL should be a terminal object, a frame or a display name (a string).
 If omitted or nil, that stands for the selected frame's display.  */)
      (terminal)
      Lisp_Object terminal;
 If omitted or nil, that stands for the selected frame's display.  */)
      (terminal)
      Lisp_Object terminal;
@@ -3695,7 +3722,7 @@ DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
        0, 1, 0,
        doc: /* Return the number of bitplanes of the X display TERMINAL.
 The optional argument TERMINAL specifies which display to ask about.
        0, 1, 0,
        doc: /* Return the number of bitplanes of the X display TERMINAL.
 The optional argument TERMINAL specifies which display to ask about.
-TERMINAL should be a terminal id, a frame or a display name (a string).
+TERMINAL should be a terminal object, a frame or a display name (a string).
 If omitted or nil, that stands for the selected frame's display.  */)
      (terminal)
      Lisp_Object terminal;
 If omitted or nil, that stands for the selected frame's display.  */)
      (terminal)
      Lisp_Object terminal;
@@ -3709,7 +3736,7 @@ DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
        0, 1, 0,
        doc: /* Return the number of color cells of the X display TERMINAL.
 The optional argument TERMINAL specifies which display to ask about.
        0, 1, 0,
        doc: /* Return the number of color cells of the X display TERMINAL.
 The optional argument TERMINAL specifies which display to ask about.
-TERMINAL should be a terminal id, a frame or a display name (a string).
+TERMINAL should be a terminal object, a frame or a display name (a string).
 If omitted or nil, that stands for the selected frame's display.  */)
      (terminal)
      Lisp_Object terminal;
 If omitted or nil, that stands for the selected frame's display.  */)
      (terminal)
      Lisp_Object terminal;
@@ -3734,7 +3761,7 @@ DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
        0, 1, 0,
        doc: /* Return the maximum request size of the X server of display TERMINAL.
 The optional argument TERMINAL specifies which display to ask about.
        0, 1, 0,
        doc: /* Return the maximum request size of the X server of display TERMINAL.
 The optional argument TERMINAL specifies which display to ask about.
-TERMINAL should be a terminal id, a frame or a display name (a string).
+TERMINAL should be a terminal object, a frame or a display name (a string).
 If omitted or nil, that stands for the selected frame's display.  */)
      (terminal)
      Lisp_Object terminal;
 If omitted or nil, that stands for the selected frame's display.  */)
      (terminal)
      Lisp_Object terminal;
@@ -3749,7 +3776,7 @@ DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
 \(Labelling every distributor as a "vendor" embodies the false assumption
 that operating systems cannot be developed and distributed noncommercially.)
 The optional argument TERMINAL specifies which display to ask about.
 \(Labelling every distributor as a "vendor" embodies the false assumption
 that operating systems cannot be developed and distributed noncommercially.)
 The optional argument TERMINAL specifies which display to ask about.
-TERMINAL should be a terminal id, a frame or a display name (a string).
+TERMINAL should be a terminal object, a frame or a display name (a string).
 If omitted or nil, that stands for the selected frame's display.  */)
      (terminal)
      Lisp_Object terminal;
 If omitted or nil, that stands for the selected frame's display.  */)
      (terminal)
      Lisp_Object terminal;
@@ -3768,7 +3795,7 @@ version numbers of the X Protocol in use, and the distributor-specific release
 number.  See also the function `x-server-vendor'.
 
 The optional argument TERMINAL specifies which display to ask about.
 number.  See also the function `x-server-vendor'.
 
 The optional argument TERMINAL specifies which display to ask about.
-TERMINAL should be a terminal id, a frame or a display name (a string).
+TERMINAL should be a terminal object, a frame or a display name (a string).
 If omitted or nil, that stands for the selected frame's display.  */)
      (terminal)
      Lisp_Object terminal;
 If omitted or nil, that stands for the selected frame's display.  */)
      (terminal)
      Lisp_Object terminal;
@@ -3784,7 +3811,7 @@ If omitted or nil, that stands for the selected frame's display.  */)
 DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
        doc: /* Return the number of screens on the X server of display TERMINAL.
 The optional argument TERMINAL specifies which display to ask about.
 DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
        doc: /* Return the number of screens on the X server of display TERMINAL.
 The optional argument TERMINAL specifies which display to ask about.
-TERMINAL should be a terminal id, a frame or a display name (a string).
+TERMINAL should be a terminal object, a frame or a display name (a string).
 If omitted or nil, that stands for the selected frame's display.  */)
      (terminal)
      Lisp_Object terminal;
 If omitted or nil, that stands for the selected frame's display.  */)
      (terminal)
      Lisp_Object terminal;
@@ -3797,7 +3824,7 @@ If omitted or nil, that stands for the selected frame's display.  */)
 DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
        doc: /* Return the height in millimeters of the X display TERMINAL.
 The optional argument TERMINAL specifies which display to ask about.
 DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
        doc: /* Return the height in millimeters of the X display TERMINAL.
 The optional argument TERMINAL specifies which display to ask about.
-TERMINAL should be a terminal id, a frame or a display name (a string).
+TERMINAL should be a terminal object, a frame or a display name (a string).
 If omitted or nil, that stands for the selected frame's display.  */)
      (terminal)
      Lisp_Object terminal;
 If omitted or nil, that stands for the selected frame's display.  */)
      (terminal)
      Lisp_Object terminal;
@@ -3810,7 +3837,7 @@ If omitted or nil, that stands for the selected frame's display.  */)
 DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
        doc: /* Return the width in millimeters of the X display TERMINAL.
 The optional argument TERMINAL specifies which display to ask about.
 DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
        doc: /* Return the width in millimeters of the X display TERMINAL.
 The optional argument TERMINAL specifies which display to ask about.
-TERMINAL should be a terminal id, a frame or a display name (a string).
+TERMINAL should be a terminal object, a frame or a display name (a string).
 If omitted or nil, that stands for the selected frame's display.  */)
      (terminal)
      Lisp_Object terminal;
 If omitted or nil, that stands for the selected frame's display.  */)
      (terminal)
      Lisp_Object terminal;
@@ -3825,7 +3852,7 @@ DEFUN ("x-display-backing-store", Fx_display_backing_store,
        doc: /* Return an indication of whether X display TERMINAL does backing store.
 The value may be `always', `when-mapped', or `not-useful'.
 The optional argument TERMINAL specifies which display to ask about.
        doc: /* Return an indication of whether X display TERMINAL does backing store.
 The value may be `always', `when-mapped', or `not-useful'.
 The optional argument TERMINAL specifies which display to ask about.
-TERMINAL should be a terminal id, a frame or a display name (a string).
+TERMINAL should be a terminal object, a frame or a display name (a string).
 If omitted or nil, that stands for the selected frame's display.  */)
      (terminal)
      Lisp_Object terminal;
 If omitted or nil, that stands for the selected frame's display.  */)
      (terminal)
      Lisp_Object terminal;
@@ -3862,7 +3889,7 @@ The value is one of the symbols `static-gray', `gray-scale',
 `static-color', `pseudo-color', `true-color', or `direct-color'.
 
 The optional argument TERMINAL specifies which display to ask about.
 `static-color', `pseudo-color', `true-color', or `direct-color'.
 
 The optional argument TERMINAL specifies which display to ask about.
-TERMINAL should a terminal id, a frame or a display name (a string).
+TERMINAL should a terminal object, a frame or a display name (a string).
 If omitted or nil, that stands for the selected frame's display.  */)
      (terminal)
      Lisp_Object terminal;
 If omitted or nil, that stands for the selected frame's display.  */)
      (terminal)
      Lisp_Object terminal;
@@ -3902,7 +3929,7 @@ DEFUN ("x-display-save-under", Fx_display_save_under,
        Sx_display_save_under, 0, 1, 0,
        doc: /* Return t if the X display TERMINAL supports the save-under feature.
 The optional argument TERMINAL specifies which display to ask about.
        Sx_display_save_under, 0, 1, 0,
        doc: /* Return t if the X display TERMINAL supports the save-under feature.
 The optional argument TERMINAL specifies which display to ask about.
-TERMINAL should be a terminal id, a frame or a display name (a string).
+TERMINAL should be a terminal object, a frame or a display name (a string).
 If omitted or nil, that stands for the selected frame's display.  */)
      (terminal)
      Lisp_Object terminal;
 If omitted or nil, that stands for the selected frame's display.  */)
      (terminal)
      Lisp_Object terminal;
@@ -4173,7 +4200,7 @@ An insecure way to solve the problem may be to use `xhost'.\n",
 DEFUN ("x-close-connection", Fx_close_connection,
        Sx_close_connection, 1, 1, 0,
        doc: /* Close the connection to TERMINAL's X server.
 DEFUN ("x-close-connection", Fx_close_connection,
        Sx_close_connection, 1, 1, 0,
        doc: /* Close the connection to TERMINAL's X server.
-For TERMINAL, specify a terminal id, a frame or a display name (a
+For TERMINAL, specify a terminal object, a frame or a display name (a
 string).  If TERMINAL is nil, that stands for the selected frame's
 terminal.  */)
      (terminal)
 string).  If TERMINAL is nil, that stands for the selected frame's
 terminal.  */)
      (terminal)
@@ -4209,7 +4236,7 @@ Turning on synchronization prohibits the Xlib routines from buffering
 requests and seriously degrades performance, but makes debugging much
 easier.
 The optional second argument TERMINAL specifies which display to act on.
 requests and seriously degrades performance, but makes debugging much
 easier.
 The optional second argument TERMINAL specifies which display to act on.
-TERMINAL should be a terminal id, a frame or a display name (a string).
+TERMINAL should be a terminal object, a frame or a display name (a string).
 If TERMINAL is omitted or nil, that stands for the selected frame's display.  */)
      (on, terminal)
     Lisp_Object terminal, on;
 If TERMINAL is omitted or nil, that stands for the selected frame's display.  */)
      (on, terminal)
     Lisp_Object terminal, on;
@@ -4829,6 +4856,7 @@ x_create_tip_frame (dpyinfo, parms, text)
   {
     XSetWindowAttributes attrs;
     unsigned long mask;
   {
     XSetWindowAttributes attrs;
     unsigned long mask;
+    Atom type = FRAME_X_DISPLAY_INFO (f)->Xatom_net_window_type_tooltip;
 
     BLOCK_INPUT;
     mask = CWBackPixel | CWOverrideRedirect | CWEventMask;
 
     BLOCK_INPUT;
     mask = CWBackPixel | CWOverrideRedirect | CWEventMask;
@@ -4853,6 +4881,10 @@ x_create_tip_frame (dpyinfo, parms, text)
                       f->border_width,
                       CopyFromParent, InputOutput, CopyFromParent,
                       mask, &attrs);
                       f->border_width,
                       CopyFromParent, InputOutput, CopyFromParent,
                       mask, &attrs);
+    XChangeProperty (FRAME_X_DISPLAY (f), tip_window,
+                     FRAME_X_DISPLAY_INFO (f)->Xatom_net_window_type,
+                     XA_ATOM, 32, PropModeReplace,
+                     (unsigned char *)&type, 1);
     UNBLOCK_INPUT;
   }
 
     UNBLOCK_INPUT;
   }
 
@@ -4875,9 +4907,8 @@ x_create_tip_frame (dpyinfo, parms, text)
   change_frame_size (f, height, width, 1, 0, 0);
 
   /* Add `tooltip' frame parameter's default value. */
   change_frame_size (f, height, width, 1, 0, 0);
 
   /* Add `tooltip' frame parameter's default value. */
-  if (NILP (Fframe_parameter (frame, intern ("tooltip"))))
-    Fmodify_frame_parameters (frame, Fcons (Fcons (intern ("tooltip"), Qt),
-                                           Qnil));
+  if (NILP (Fframe_parameter (frame, Qtooltip)))
+    Fmodify_frame_parameters (frame, Fcons (Fcons (Qtooltip, Qt), Qnil));
 
   /* FIXME - can this be done in a similar way to normal frames?
      http://lists.gnu.org/archive/html/emacs-devel/2007-10/msg00641.html */
 
   /* FIXME - can this be done in a similar way to normal frames?
      http://lists.gnu.org/archive/html/emacs-devel/2007-10/msg00641.html */
@@ -5592,7 +5623,10 @@ If FRAME is omitted or nil, it defaults to the selected frame. */)
 {
   FRAME_PTR f = check_x_frame (frame);
   char *name;
 {
   FRAME_PTR f = check_x_frame (frame);
   char *name;
-  Lisp_Object default_font, font = Qnil;
+  Lisp_Object font;
+  Lisp_Object font_param;
+  char *default_name = NULL;
+  struct gcpro gcpro1, gcpro2;
   int count = SPECPDL_INDEX ();
 
   check_x ();
   int count = SPECPDL_INDEX ();
 
   check_x ();
@@ -5606,21 +5640,43 @@ If FRAME is omitted or nil, it defaults to the selected frame. */)
 
   BLOCK_INPUT;
 
 
   BLOCK_INPUT;
 
-  XSETFONT (default_font, FRAME_FONT (f));
-  if (FONTP (default_font))
+  GCPRO2(font_param, font);
+
+  XSETFONT (font, FRAME_FONT (f));
+  font_param = Ffont_get (font, intern (":name"));
+  if (STRINGP (font_param))
+    default_name = xstrdup (SDATA (font_param));
+  else
     {
     {
-      char *default_name = alloca (256);
-      if (font_unparse_gtkname (default_font, f, default_name, 256) < 0)
-       default_name = NULL;
-      name = xg_get_font_name (f, default_name);
+      font_param = Fframe_parameter (frame, Qfont_param);
+      if (STRINGP (font_param))
+        default_name = xstrdup (SDATA (font_param));
     }
     }
-  else
-    name = xg_get_font_name (f, NULL);
+
+  if (default_name == NULL && x_last_font_name != NULL)
+    default_name = xstrdup (x_last_font_name);
+
+  /* Convert fontconfig names to Gtk names, i.e. remove - before number */
+  if (default_name)
+    {
+      char *p = strrchr (default_name, '-');
+      if (p)
+        {
+          char *ep = p+1;
+          while (isdigit (*ep))
+            ++ep;
+          if (*ep == '\0') *p = ' ';
+        }
+    }
+
+  name = xg_get_font_name (f, default_name);
+  xfree (default_name);
 
   if (name)
     {
       font = build_string (name);
 
   if (name)
     {
       font = build_string (name);
-      xfree (name);
+      g_free (x_last_font_name);
+      x_last_font_name = name;
     }
 
   UNBLOCK_INPUT;
     }
 
   UNBLOCK_INPUT;
@@ -5778,7 +5834,8 @@ frame_parm_handler x_frame_parm_handlers[] =
   x_set_wait_for_wm,
   x_set_fullscreen,
   x_set_font_backend,
   x_set_wait_for_wm,
   x_set_fullscreen,
   x_set_font_backend,
-  x_set_alpha
+  x_set_alpha,
+  x_set_sticky,
 };
 
 void
 };
 
 void
@@ -5790,17 +5847,17 @@ syms_of_xfns ()
   /* The section below is built by the lisp expression at the top of the file,
      just above where these variables are declared.  */
   /*&&& init symbols here &&&*/
   /* The section below is built by the lisp expression at the top of the file,
      just above where these variables are declared.  */
   /*&&& init symbols here &&&*/
-  Qnone = intern ("none");
+  Qnone = intern_c_string ("none");
   staticpro (&Qnone);
   staticpro (&Qnone);
-  Qsuppress_icon = intern ("suppress-icon");
+  Qsuppress_icon = intern_c_string ("suppress-icon");
   staticpro (&Qsuppress_icon);
   staticpro (&Qsuppress_icon);
-  Qundefined_color = intern ("undefined-color");
+  Qundefined_color = intern_c_string ("undefined-color");
   staticpro (&Qundefined_color);
   staticpro (&Qundefined_color);
-  Qcompound_text = intern ("compound-text");
+  Qcompound_text = intern_c_string ("compound-text");
   staticpro (&Qcompound_text);
   staticpro (&Qcompound_text);
-  Qcancel_timer = intern ("cancel-timer");
+  Qcancel_timer = intern_c_string ("cancel-timer");
   staticpro (&Qcancel_timer);
   staticpro (&Qcancel_timer);
-  Qfont_param = intern ("font-parameter");
+  Qfont_param = intern_c_string ("font-parameter");
   staticpro (&Qfont_param);
   /* This is the end of symbol initialization.  */
 
   staticpro (&Qfont_param);
   /* This is the end of symbol initialization.  */
 
@@ -5810,9 +5867,9 @@ syms_of_xfns ()
 
 
   Fput (Qundefined_color, Qerror_conditions,
 
 
   Fput (Qundefined_color, Qerror_conditions,
-       Fcons (Qundefined_color, Fcons (Qerror, Qnil)));
+       pure_cons (Qundefined_color, pure_cons (Qerror, Qnil)));
   Fput (Qundefined_color, Qerror_message,
   Fput (Qundefined_color, Qerror_message,
-       build_string ("Undefined color"));
+       make_pure_c_string ("Undefined color"));
 
   DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape,
     doc: /* The shape of the pointer when over text.
 
   DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape,
     doc: /* The shape of the pointer when over text.
@@ -5861,8 +5918,8 @@ or when you set the mouse color.  */);
   Vx_cursor_fore_pixel = Qnil;
 
   DEFVAR_LISP ("x-max-tooltip-size", &Vx_max_tooltip_size,
   Vx_cursor_fore_pixel = Qnil;
 
   DEFVAR_LISP ("x-max-tooltip-size", &Vx_max_tooltip_size,
-    doc: /* Maximum size for tooltips.  Value is a pair (COLUMNS . ROWS).
-Text larger than this is clipped.  */);
+    doc: /* Maximum size for tooltips.
+Value is a pair (COLUMNS . ROWS).  Text larger than this is clipped.  */);
   Vx_max_tooltip_size = Fcons (make_number (80), make_number (40));
 
   DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager,
   Vx_max_tooltip_size = Fcons (make_number (80), make_number (40));
 
   DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager,
@@ -5909,12 +5966,12 @@ 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;
 
 the tool bar buttons.  */);
   x_gtk_whole_detached_tool_bar = 0;
 
-  Fprovide (intern ("x"), Qnil);
+  Fprovide (intern_c_string ("x"), Qnil);
 
 #ifdef USE_X_TOOLKIT
 
 #ifdef USE_X_TOOLKIT
-  Fprovide (intern ("x-toolkit"), Qnil);
+  Fprovide (intern_c_string ("x-toolkit"), Qnil);
 #ifdef USE_MOTIF
 #ifdef USE_MOTIF
-  Fprovide (intern ("motif"), Qnil);
+  Fprovide (intern_c_string ("motif"), Qnil);
 
   DEFVAR_LISP ("motif-version-string", &Vmotif_version_string,
               doc: /* Version info for LessTif/Motif.  */);
 
   DEFVAR_LISP ("motif-version-string", &Vmotif_version_string,
               doc: /* Version info for LessTif/Motif.  */);
@@ -5927,8 +5984,8 @@ the tool bar buttons.  */);
      is not an X toolkit in that sense (USE_X_TOOLKIT is not defined).
      But for a user it is a toolkit for X, and indeed, configure
      accepts --with-x-toolkit=gtk.  */
      is not an X toolkit in that sense (USE_X_TOOLKIT is not defined).
      But for a user it is a toolkit for X, and indeed, configure
      accepts --with-x-toolkit=gtk.  */
-  Fprovide (intern ("x-toolkit"), Qnil);
-  Fprovide (intern ("gtk"), Qnil);
+  Fprovide (intern_c_string ("x-toolkit"), Qnil);
+  Fprovide (intern_c_string ("gtk"), Qnil);
 
   DEFVAR_LISP ("gtk-version-string", &Vgtk_version_string,
                doc: /* Version info for GTK+.  */);
 
   DEFVAR_LISP ("gtk-version-string", &Vgtk_version_string,
                doc: /* Version info for GTK+.  */);
@@ -5936,7 +5993,7 @@ the tool bar buttons.  */);
     char gtk_version[40];
     g_snprintf (gtk_version, sizeof (gtk_version), "%u.%u.%u",
                 GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION);
     char gtk_version[40];
     g_snprintf (gtk_version, sizeof (gtk_version), "%u.%u.%u",
                 GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION);
-    Vgtk_version_string = build_string (gtk_version);
+    Vgtk_version_string = make_pure_string (gtk_version, strlen (gtk_version), strlen (gtk_version), 0);
   }
 #endif /* USE_GTK */
 
   }
 #endif /* USE_GTK */
 
@@ -5991,6 +6048,7 @@ the tool bar buttons.  */);
 
 #if defined (USE_GTK) && defined (HAVE_FREETYPE)
   defsubr (&Sx_select_font);
 
 #if defined (USE_GTK) && defined (HAVE_FREETYPE)
   defsubr (&Sx_select_font);
+  x_last_font_name = NULL;
 #endif
 }
 
 #endif
 }