(x_new_font): Don't change a tooltip's size.
[bpt/emacs.git] / src / xterm.c
index 01b8c5b..f5c0a5d 100644 (file)
@@ -1,5 +1,5 @@
 /* X Communication module for terminals which understand the X protocol.
 /* X Communication module for terminals which understand the X protocol.
-   Copyright (C) 1989, 93, 94, 95, 96, 1997, 1998, 1999, 2000
+   Copyright (C) 1989, 93, 94, 95, 96, 1997, 1998, 1999, 2000, 2001
    Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
    Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
@@ -230,9 +230,9 @@ static unsigned char ov_bits[] = {
 extern Lisp_Object Qhelp_echo;
 
 \f
 extern Lisp_Object Qhelp_echo;
 
 \f
-/* Non-zero means Emacs uses toolkit scroll bars.  */
+/* Non-nil means Emacs uses toolkit scroll bars.  */
 
 
-int x_toolkit_scroll_bars_p;
+Lisp_Object Vx_toolkit_scroll_bars;
 
 /* If a string, XTread_socket generates an event to display that string.
    (The display is done in read_char.)  */
 
 /* If a string, XTread_socket generates an event to display that string.
    (The display is done in read_char.)  */
@@ -396,6 +396,7 @@ enum draw_glyphs_face
   DRAW_IMAGE_SUNKEN
 };
 
   DRAW_IMAGE_SUNKEN
 };
 
+static void x_set_window_size_1 P_ ((struct frame *, int, int, int));
 static const XColor *x_color_cells P_ ((struct frame *, int *));
 static void x_update_window_end P_ ((struct window *, int, int));
 static void frame_to_window_pixel_xy P_ ((struct window *, int *, int *));
 static const XColor *x_color_cells P_ ((struct frame *, int *));
 static void x_update_window_end P_ ((struct window *, int, int));
 static void frame_to_window_pixel_xy P_ ((struct window *, int *, int *));
@@ -1139,19 +1140,6 @@ static void x_produce_glyphs P_ ((struct it *));
 static void x_produce_image_glyph P_ ((struct it *it));
 
 
 static void x_produce_image_glyph P_ ((struct it *it));
 
 
-/* Return a pointer to per-char metric information in FONT of a
-   character pointed by B which is a pointer to an XChar2b.  */
-
-#define PER_CHAR_METRIC(font, b)                                          \
-  ((font)->per_char                                                       \
-   ? ((font)->per_char + (b)->byte2 - (font)->min_char_or_byte2                   \
-      + (((font)->min_byte1 || (font)->max_byte1)                         \
-        ? (((b)->byte1 - (font)->min_byte1)                               \
-           * ((font)->max_char_or_byte2 - (font)->min_char_or_byte2 + 1)) \
-        : 0))                                                             \
-   : &((font)->max_bounds))
-
-
 /* Get metrics of character CHAR2B in FONT.  Value is null if CHAR2B
    is not contained in the font.  */
 
 /* Get metrics of character CHAR2B in FONT.  Value is null if CHAR2B
    is not contained in the font.  */
 
@@ -1517,8 +1505,8 @@ x_produce_image_glyph (it)
   prepare_image_for_display (it->f, img);
 
   it->ascent = it->phys_ascent = image_ascent (img, face);
   prepare_image_for_display (it->f, img);
 
   it->ascent = it->phys_ascent = image_ascent (img, face);
-  it->descent = it->phys_descent = img->height + 2 * img->margin - it->ascent;
-  it->pixel_width = img->width + 2 * img->margin;
+  it->descent = it->phys_descent = img->height + 2 * img->vmargin - it->ascent;
+  it->pixel_width = img->width + 2 * img->hmargin;
 
   it->nglyphs = 1;
   
 
   it->nglyphs = 1;
   
@@ -2108,8 +2096,8 @@ x_produce_glyphs (it)
          cmp->font = (void *) font;
 
          /* Initialize the bounding box.  */
          cmp->font = (void *) font;
 
          /* Initialize the bounding box.  */
-         pcm = x_per_char_metric (font, &char2b);
-         if (pcm)
+         if (font_info
+             && (pcm = x_per_char_metric (font, &char2b)))
            {
              width = pcm->width;
              ascent = pcm->ascent;
            {
              width = pcm->width;
              ascent = pcm->ascent;
@@ -2166,8 +2154,8 @@ x_produce_glyphs (it)
                    boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
                }
 
                    boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
                }
 
-             pcm = x_per_char_metric (font, &char2b);
-             if (pcm)
+             if (font_info
+                 && (pcm = x_per_char_metric (font, &char2b)))
                {
                  width = pcm->width;
                  ascent = pcm->ascent;
                {
                  width = pcm->width;
                  ascent = pcm->ascent;
@@ -2176,8 +2164,8 @@ x_produce_glyphs (it)
              else
                {
                  width = FONT_WIDTH (font);
              else
                {
                  width = FONT_WIDTH (font);
-                 ascent = font->ascent;
-                 descent = font->descent;
+                 ascent = 1;
+                 descent = 0;
                }
 
              if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
                }
 
              if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
@@ -2326,7 +2314,7 @@ x_estimate_mode_line_height (f, face_id)
      struct frame *f;
      enum face_id face_id;
 {
      struct frame *f;
      enum face_id face_id;
 {
-  int height = 1;
+  int height = FONT_HEIGHT (FRAME_FONT (f));
 
   /* This function is called so early when Emacs starts that the face
      cache and mode line face are not yet initialized.  */
 
   /* This function is called so early when Emacs starts that the face
      cache and mode line face are not yet initialized.  */
@@ -2334,7 +2322,11 @@ x_estimate_mode_line_height (f, face_id)
       {
        struct face *face = FACE_FROM_ID (f, face_id);
        if (face)
       {
        struct face *face = FACE_FROM_ID (f, face_id);
        if (face)
-         height = FONT_HEIGHT (face->font) + 2 * face->box_line_width;
+         {
+           if (face->font)
+             height = FONT_HEIGHT (face->font);
+           height += 2 * face->box_line_width;
+         }
       }
   
   return height;
       }
   
   return height;
@@ -2670,9 +2662,12 @@ x_set_mouse_face_gc (s)
   int face_id;
   struct face *face;
 
   int face_id;
   struct face *face;
 
-  /* What face has to be used for the mouse face?  */
+  /* What face has to be used last for the mouse face?  */
   face_id = FRAME_X_DISPLAY_INFO (s->f)->mouse_face_face_id;
   face = FACE_FROM_ID (s->f, face_id);
   face_id = FRAME_X_DISPLAY_INFO (s->f)->mouse_face_face_id;
   face = FACE_FROM_ID (s->f, face_id);
+  if (face == NULL)
+    face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
+  
   if (s->first_glyph->type == CHAR_GLYPH)
     face_id = FACE_FOR_CHAR (s->f, face, s->first_glyph->u.ch);
   else
   if (s->first_glyph->type == CHAR_GLYPH)
     face_id = FACE_FOR_CHAR (s->f, face, s->first_glyph->u.ch);
   else
@@ -3853,11 +3848,8 @@ x_draw_image_foreground (s)
 
   /* If there is a margin around the image, adjust x- and y-position
      by that margin.  */
 
   /* If there is a margin around the image, adjust x- and y-position
      by that margin.  */
-  if (s->img->margin)
-    {
-      x += s->img->margin;
-      y += s->img->margin;
-    }
+  x += s->img->hmargin;
+  y += s->img->vmargin;
 
   if (s->img->pixmap)
     {
 
   if (s->img->pixmap)
     {
@@ -3942,11 +3934,8 @@ x_draw_image_relief (s)
   
   /* If there is a margin around the image, adjust x- and y-position
      by that margin.  */
   
   /* If there is a margin around the image, adjust x- and y-position
      by that margin.  */
-  if (s->img->margin)
-    {
-      x += s->img->margin;
-      y += s->img->margin;
-    }
+  x += s->img->hmargin;
+  y += s->img->vmargin;
   
   if (s->hl == DRAW_IMAGE_SUNKEN
       || s->hl == DRAW_IMAGE_RAISED)
   
   if (s->hl == DRAW_IMAGE_SUNKEN
       || s->hl == DRAW_IMAGE_RAISED)
@@ -3991,11 +3980,8 @@ x_draw_image_foreground_1 (s, pixmap)
 
   /* If there is a margin around the image, adjust x- and y-position
      by that margin.  */
 
   /* If there is a margin around the image, adjust x- and y-position
      by that margin.  */
-  if (s->img->margin)
-    {
-      x += s->img->margin;
-      y += s->img->margin;
-    }
+  x += s->img->hmargin;
+  y += s->img->vmargin;
 
   if (s->img->pixmap)
     {
 
   if (s->img->pixmap)
     {
@@ -4083,7 +4069,6 @@ x_draw_image_glyph_string (s)
 {
   int x, y;
   int box_line_width = s->face->box_line_width;
 {
   int x, y;
   int box_line_width = s->face->box_line_width;
-  int margin = s->img->margin;
   int height;
   Pixmap pixmap = None;
 
   int height;
   Pixmap pixmap = None;
 
@@ -4094,7 +4079,8 @@ x_draw_image_glyph_string (s)
      flickering.  */
   s->stippled_p = s->face->stipple != 0;
   if (height > s->img->height
      flickering.  */
   s->stippled_p = s->face->stipple != 0;
   if (height > s->img->height
-      || margin
+      || s->img->hmargin
+      || s->img->vmargin
       || s->img->mask
       || s->img->pixmap == 0
       || s->width != s->background_width)
       || s->img->mask
       || s->img->pixmap == 0
       || s->width != s->background_width)
@@ -5705,31 +5691,31 @@ expose_area (w, row, r, area)
      XRectangle *r;
      enum glyph_row_area area;
 {
      XRectangle *r;
      enum glyph_row_area area;
 {
-  int x;
   struct glyph *first = row->glyphs[area];
   struct glyph *end = row->glyphs[area] + row->used[area];
   struct glyph *last;
   struct glyph *first = row->glyphs[area];
   struct glyph *end = row->glyphs[area] + row->used[area];
   struct glyph *last;
-  int first_x;
-
-  /* Set x to the window-relative start position for drawing glyphs of
-     AREA.  The first glyph of the text area can be partially visible.
-     The first glyphs of other areas cannot.  */
-  if (area == LEFT_MARGIN_AREA)
-    x = 0;
-  else if (area == TEXT_AREA)
-    x = row->x + window_box_width (w, LEFT_MARGIN_AREA);
-  else
-    x = (window_box_width (w, LEFT_MARGIN_AREA)
-        + window_box_width (w, TEXT_AREA));
+  int first_x, start_x, x;
 
   if (area == TEXT_AREA && row->fill_line_p)
     /* If row extends face to end of line write the whole line.  */
 
   if (area == TEXT_AREA && row->fill_line_p)
     /* If row extends face to end of line write the whole line.  */
-    x_draw_glyphs (w, x, row, area,
+    x_draw_glyphs (w, 0, row, area,
                   0, row->used[area],
                   row->inverse_p ? DRAW_INVERSE_VIDEO : DRAW_NORMAL_TEXT,
                   NULL, NULL, 0);
   else
     {
                   0, row->used[area],
                   row->inverse_p ? DRAW_INVERSE_VIDEO : DRAW_NORMAL_TEXT,
                   NULL, NULL, 0);
   else
     {
+      /* Set START_X to the window-relative start position for drawing glyphs of
+        AREA.  The first glyph of the text area can be partially visible.
+        The first glyphs of other areas cannot.  */
+      if (area == LEFT_MARGIN_AREA)
+       start_x = 0;
+      else if (area == TEXT_AREA)
+       start_x = row->x + window_box_width (w, LEFT_MARGIN_AREA);
+      else
+       start_x = (window_box_width (w, LEFT_MARGIN_AREA)
+                  + window_box_width (w, TEXT_AREA));
+      x = start_x;
+
       /* Find the first glyph that must be redrawn.  */
       while (first < end
             && x + first->pixel_width < r->x)
       /* Find the first glyph that must be redrawn.  */
       while (first < end
             && x + first->pixel_width < r->x)
@@ -5750,7 +5736,7 @@ expose_area (w, row, r, area)
       
       /* Repaint.  */
       if (last > first)
       
       /* Repaint.  */
       if (last > first)
-       x_draw_glyphs (w, first_x, row, area,
+       x_draw_glyphs (w, first_x - start_x, row, area,
                       first - row->glyphs[area],
                       last - row->glyphs[area],
                       row->inverse_p ? DRAW_INVERSE_VIDEO : DRAW_NORMAL_TEXT,
                       first - row->glyphs[area],
                       last - row->glyphs[area],
                       row->inverse_p ? DRAW_INVERSE_VIDEO : DRAW_NORMAL_TEXT,
@@ -5828,7 +5814,7 @@ expose_window (w, r)
      happen when toolkit scroll bars are used and a window is split.
      Reconfiguring the scroll bar will generate an expose for a newly
      created window.  */
      happen when toolkit scroll bars are used and a window is split.
      Reconfiguring the scroll bar will generate an expose for a newly
      created window.  */
-  if (w->current_matrix == NULL)
+  if (w->current_matrix == NULL || w == updated_window)
     return;
 
   TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
     return;
 
   TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
@@ -7299,8 +7285,11 @@ void
 clear_mouse_face (dpyinfo)
      struct x_display_info *dpyinfo;
 {
 clear_mouse_face (dpyinfo)
      struct x_display_info *dpyinfo;
 {
-  if (tip_frame)
+#if 0 /* This prevents redrawing tool bar items when changing from one
+        to another while a tooltip is open, so don't do it.  */
+  if (!NILP (tip_frame))
     return;
     return;
+#endif
   
   if (! NILP (dpyinfo->mouse_face_window))
     show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
   
   if (! NILP (dpyinfo->mouse_face_window))
     show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
@@ -7646,7 +7635,7 @@ x_window_to_scroll_bar (window_id)
                         Toolkit scroll bars
  ************************************************************************/
 
                         Toolkit scroll bars
  ************************************************************************/
 
-#if USE_TOOLKIT_SCROLL_BARS
+#ifdef USE_TOOLKIT_SCROLL_BARS
 
 static void x_scroll_bar_to_input_event P_ ((XEvent *, struct input_event *));
 static void x_send_scroll_bar_event P_ ((Lisp_Object, int, int, int));
 
 static void x_scroll_bar_to_input_event P_ ((XEvent *, struct input_event *));
 static void x_send_scroll_bar_event P_ ((Lisp_Object, int, int, int));
@@ -8322,7 +8311,7 @@ x_scroll_bar_create (w, top, left, width, height)
 
   BLOCK_INPUT;
 
 
   BLOCK_INPUT;
 
-#if USE_TOOLKIT_SCROLL_BARS
+#ifdef USE_TOOLKIT_SCROLL_BARS
   x_create_toolkit_scroll_bar (f, bar);
 #else /* not USE_TOOLKIT_SCROLL_BARS */
   {
   x_create_toolkit_scroll_bar (f, bar);
 #else /* not USE_TOOLKIT_SCROLL_BARS */
   {
@@ -8382,7 +8371,7 @@ x_scroll_bar_create (w, top, left, width, height)
     XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
 
   /* Map the window/widget.  */
     XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
 
   /* Map the window/widget.  */
-#if USE_TOOLKIT_SCROLL_BARS
+#ifdef USE_TOOLKIT_SCROLL_BARS
  {
    Widget scroll_bar = SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar);
    XtConfigureWidget (scroll_bar,
  {
    Widget scroll_bar = SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar);
    XtConfigureWidget (scroll_bar,
@@ -8527,7 +8516,7 @@ x_scroll_bar_remove (bar)
   struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
   BLOCK_INPUT;
 
   struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
   BLOCK_INPUT;
 
-#if USE_TOOLKIT_SCROLL_BARS
+#ifdef USE_TOOLKIT_SCROLL_BARS
   XtDestroyWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar));
 #else
   XDestroyWindow (FRAME_X_DISPLAY (f), SCROLL_BAR_X_WINDOW (bar));
   XtDestroyWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar));
 #else
   XDestroyWindow (FRAME_X_DISPLAY (f), SCROLL_BAR_X_WINDOW (bar));
@@ -8672,7 +8661,7 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
       UNBLOCK_INPUT;
     }
 
       UNBLOCK_INPUT;
     }
 
-#if USE_TOOLKIT_SCROLL_BARS
+#ifdef USE_TOOLKIT_SCROLL_BARS
   x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole);
 #else /* not USE_TOOLKIT_SCROLL_BARS */
   /* Set the scroll bar's current state, unless we're currently being
   x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole);
 #else /* not USE_TOOLKIT_SCROLL_BARS */
   /* Set the scroll bar's current state, unless we're currently being
@@ -9725,7 +9714,7 @@ XTread_socket (sd, bufp, numchars, expected)
            case KeyPress:
              f = x_any_window_to_frame (dpyinfo, event.xkey.window);
 
            case KeyPress:
              f = x_any_window_to_frame (dpyinfo, event.xkey.window);
 
-#ifdef USE_MOTIF
+#if defined USE_MOTIF && defined USE_TOOLKIT_SCROLL_BARS
              /* I couldn't find a way to prevent LessTif scroll bars
                 from consuming key events.  */
              if (f == 0)
              /* I couldn't find a way to prevent LessTif scroll bars
                 from consuming key events.  */
              if (f == 0)
@@ -9738,7 +9727,7 @@ XTread_socket (sd, bufp, numchars, expected)
                      f = x_any_window_to_frame (dpyinfo, XtWindow (widget));
                    }
                }
                      f = x_any_window_to_frame (dpyinfo, XtWindow (widget));
                    }
                }
-#endif /* USE_MOTIF */
+#endif /* USE_MOTIF and USE_TOOLKIT_SCROLL_BARS */
 
              if (f != 0)
                {
 
              if (f != 0)
                {
@@ -9915,7 +9904,6 @@ XTread_socket (sd, bufp, numchars, expected)
                        {
                          register int i;
                          register int c;
                        {
                          register int i;
                          register int c;
-                         unsigned char *p, *pend;
                          int nchars, len;
 
                          for (i = 0; i < nbytes; i++)
                          int nchars, len;
 
                          for (i = 0; i < nbytes; i++)
@@ -10098,7 +10086,6 @@ XTread_socket (sd, bufp, numchars, expected)
              f = x_top_window_to_frame (dpyinfo, event.xcrossing.window);
              if (f)
                {
              f = x_top_window_to_frame (dpyinfo, event.xcrossing.window);
              if (f)
                {
-                 Lisp_Object frame;
                  int from_menu_bar_p = 0;
                  
                  if (f == dpyinfo->mouse_face_mouse_frame)
                  int from_menu_bar_p = 0;
                  
                  if (f == dpyinfo->mouse_face_mouse_frame)
@@ -10119,6 +10106,7 @@ XTread_socket (sd, bufp, numchars, expected)
                      int n;
 
                      XSETFRAME (frame, f);
                      int n;
 
                      XSETFRAME (frame, f);
+                     help_echo = Qnil;
                      n = gen_help_event (bufp, numchars,
                                          Qnil, frame, Qnil, Qnil, 0);
                      bufp += n, count += n, numchars -= n;
                      n = gen_help_event (bufp, numchars,
                                          Qnil, frame, Qnil, Qnil, 0);
                      bufp += n, count += n, numchars -= n;
@@ -11259,27 +11247,58 @@ x_connection_signal (signalnum)       /* If we don't have an argument, */
   signal (signalnum, x_connection_signal);
 #endif /* USG */
 }
   signal (signalnum, x_connection_signal);
 #endif /* USG */
 }
+
 \f
 \f
-/* Handling X errors.  */
+/************************************************************************
+                         Handling X errors
+ ************************************************************************/
 
 
-/* Handle the loss of connection to display DISPLAY.  */
+/* Handle the loss of connection to display DPY.  ERROR_MESSAGE is
+   the text of an error message that lead to the connection loss.  */
 
 static SIGTYPE
 
 static SIGTYPE
-x_connection_closed (display, error_message)
-     Display *display;
+x_connection_closed (dpy, error_message)
+     Display *dpy;
      char *error_message;
 {
      char *error_message;
 {
-  struct x_display_info *dpyinfo = x_display_info_for_display (display);
+  struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
   Lisp_Object frame, tail;
   Lisp_Object frame, tail;
+  int count;
+  char *msg;
+  
+  msg = (char *) alloca (strlen (error_message) + 1);
+  strcpy (msg, error_message);
+  handling_signal = 0;
+  
+  /* Prevent being called recursively because of an error condition
+     below.  Otherwise, we might end up with printing ``can't find per
+     display information'' in the recursive call instead of printing
+     the original message here.  */
+  count = x_catch_errors (dpy);
+  
+  /* We have to close the display to inform Xt that it doesn't
+     exist anymore.  If we don't, Xt will continue to wait for
+     events from the display.  As a consequence, a sequence of
 
 
-  /* Indicate that this display is dead.  */
+     M-x make-frame-on-display RET :1 RET
+     ...kill the new frame, so that we get an IO error...
+     M-x make-frame-on-display RET :1 RET
+
+     will indefinitely wait in Xt for events for display `:1', opened
+     in the first class to make-frame-on-display.
 
 
-#if 0 /* Closing the display caused a bus error on OpenWindows.  */
+     Closing the display is reported to lead to a bus error on
+     OpenWindows in certain situations.  I suspect that is a bug
+     in OpenWindows.  I don't know how to cicumvent it here.  */
+  
 #ifdef USE_X_TOOLKIT
 #ifdef USE_X_TOOLKIT
-  XtCloseDisplay (display);
-#endif
+  /* If DPYINFO is null, this means we didn't open the display
+     in the first place, so don't try to close it.  */
+  if (dpyinfo)
+    XtCloseDisplay (dpy);
 #endif
 
 #endif
 
+  /* Indicate that this display is dead.  */
   if (dpyinfo)
     dpyinfo->display = 0;
 
   if (dpyinfo)
     dpyinfo->display = 0;
 
@@ -11313,9 +11332,11 @@ x_connection_closed (display, error_message)
   if (dpyinfo)
     x_delete_display (dpyinfo);
 
   if (dpyinfo)
     x_delete_display (dpyinfo);
 
+  x_uncatch_errors (dpy, count);
+  
   if (x_display_list == 0)
     {
   if (x_display_list == 0)
     {
-      fprintf (stderr, "%s\n", error_message);
+      fprintf (stderr, "%s\n", msg);
       shut_down_emacs (0, 0, Qnil);
       exit (70);
     }
       shut_down_emacs (0, 0, Qnil);
       exit (70);
     }
@@ -11328,10 +11349,10 @@ x_connection_closed (display, error_message)
   TOTALLY_UNBLOCK_INPUT;
 
   clear_waiting_for_input ();
   TOTALLY_UNBLOCK_INPUT;
 
   clear_waiting_for_input ();
-  handling_signal = 0;
-  error ("%s", error_message);
+  error ("%s", msg);
 }
 
 }
 
+
 /* This is the usual handler for X protocol errors.
    It kills all frames on the display that we got the error for.
    If that was the only one, it prints an error message and kills Emacs.  */
 /* This is the usual handler for X protocol errors.
    It kills all frames on the display that we got the error for.
    If that was the only one, it prints an error message and kills Emacs.  */
@@ -11352,6 +11373,7 @@ x_error_quitter (display, error)
   x_connection_closed (display, buf1);
 }
 
   x_connection_closed (display, buf1);
 }
 
+
 /* This is the first-level handler for X protocol errors.
    It calls x_error_quitter or x_error_catcher.  */
 
 /* This is the first-level handler for X protocol errors.
    It calls x_error_quitter or x_error_catcher.  */
 
@@ -11427,7 +11449,12 @@ x_new_font (f, fontname)
                f->output_data.x->font->fid);
 
       frame_update_line_height (f);
                f->output_data.x->font->fid);
 
       frame_update_line_height (f);
-      x_set_window_size (f, 0, f->width, f->height);
+
+      /* Don't change the size of a tip frame; there's no point in
+        doing it because it's done in Fx_show_tip, and it leads to
+        problems because the tip frame has no widget.  */
+      if (NILP (tip_frame) || XFRAME (tip_frame) != f)
+       x_set_window_size (f, 0, f->width, f->height);
     }
   else
     /* If we are setting a new frame's font for the first time,
     }
   else
     /* If we are setting a new frame's font for the first time,
@@ -11667,11 +11694,13 @@ xim_close_dpy (dpyinfo)
 {
 #ifdef USE_XIM
 #ifdef HAVE_X11R6_XIM
 {
 #ifdef USE_XIM
 #ifdef HAVE_X11R6_XIM
-  XUnregisterIMInstantiateCallback (dpyinfo->display, dpyinfo->xrdb,
-                                   NULL, EMACS_CLASS,
-                                   xim_instantiate_callback, NULL);
+  if (dpyinfo->display)
+    XUnregisterIMInstantiateCallback (dpyinfo->display, dpyinfo->xrdb,
+                                     NULL, EMACS_CLASS,
+                                     xim_instantiate_callback, NULL);
 #endif /* not HAVE_X11R6_XIM */
 #endif /* not HAVE_X11R6_XIM */
-  XCloseIM (dpyinfo->xim);
+  if (dpyinfo->display)
+    XCloseIM (dpyinfo->xim);
   dpyinfo->xim = NULL;
   XFree (dpyinfo->xim_styles);
 #endif /* USE_XIM */
   dpyinfo->xim = NULL;
   XFree (dpyinfo->xim_styles);
 #endif /* USE_XIM */
@@ -11757,25 +11786,33 @@ x_calc_absolute_position (f)
                                  - PIXEL_WIDTH (f)
                                  + f->output_data.x->left_pos);
 
                                  - PIXEL_WIDTH (f)
                                  + f->output_data.x->left_pos);
 
-  if (flags & YNegative)
-    {
-      int menubar_height = 0;
+  {
+    int height = PIXEL_HEIGHT (f);
 
 
-#ifdef USE_X_TOOLKIT
-      if (f->output_data.x->menubar_widget)
-       menubar_height
-         = (f->output_data.x->menubar_widget->core.height
-            + f->output_data.x->menubar_widget->core.border_width);
+#if defined USE_X_TOOLKIT && defined USE_MOTIF
+    /* Something is fishy here.  When using Motif, starting Emacs with
+       `-g -0-0', the frame appears too low by a few pixels.
+
+       This seems to be so because initially, while Emacs is starting,
+       the column widget's height and the frame's pixel height are
+       different.  The column widget's height is the right one.  In
+       later invocations, when Emacs is up, the frame's pixel height
+       is right, though.
+
+       It's not obvious where the initial small difference comes from.
+       2000-12-01, gerd.  */
+    
+    XtVaGetValues (f->output_data.x->column_widget, XtNheight, &height, NULL);
 #endif
 #endif
-      
-      f->output_data.x->top_pos = (FRAME_X_DISPLAY_INFO (f)->height
-                                  - 2 * f->output_data.x->border_width
-                                  - win_y
-                                  - PIXEL_HEIGHT (f)
-                                  - menubar_height
-                                  + f->output_data.x->top_pos);
-    }
 
 
+  if (flags & YNegative)
+    f->output_data.x->top_pos = (FRAME_X_DISPLAY_INFO (f)->height
+                                - 2 * f->output_data.x->border_width
+                                - win_y
+                                - height
+                                + f->output_data.x->top_pos);
+  }
+  
   /* The left_pos and top_pos
      are now relative to the top and left screen edges,
      so the flags should correspond.  */
   /* The left_pos and top_pos
      are now relative to the top and left screen edges,
      so the flags should correspond.  */
@@ -11835,37 +11872,19 @@ x_set_offset (f, xoff, yoff, change_gravity)
   UNBLOCK_INPUT;
 }
 
   UNBLOCK_INPUT;
 }
 
-/* Call this to change the size of frame F's x-window.
-   If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
-   for this size change and subsequent size changes.
-   Otherwise we leave the window gravity unchanged.  */
 
 
-void
-x_set_window_size (f, change_gravity, cols, rows)
+/* Change the size of frame F's X window to COLS/ROWS in the case F
+   doesn't have a widget.  If CHANGE_GRAVITY is 1, we change to
+   top-left-corner window gravity for this size change and subsequent
+   size changes.  Otherwise we leave the window gravity unchanged.  */
+
+static void
+x_set_window_size_1 (f, change_gravity, cols, rows)
      struct frame *f;
      int change_gravity;
      int cols, rows;
 {
      struct frame *f;
      int change_gravity;
      int cols, rows;
 {
-#ifndef USE_X_TOOLKIT
   int pixelwidth, pixelheight;
   int pixelwidth, pixelheight;
-#endif
-
-  BLOCK_INPUT;
-
-#ifdef USE_X_TOOLKIT
-  {
-    /* The x and y position of the widget is clobbered by the
-       call to XtSetValues within EmacsFrameSetCharSize.
-       This is a real kludge, but I don't understand Xt so I can't
-       figure out a correct fix.  Can anyone else tell me? -- rms.  */
-    int xpos = f->output_data.x->widget->core.x;
-    int ypos = f->output_data.x->widget->core.y;
-    EmacsFrameSetCharSize (f->output_data.x->edit_widget, cols, rows);
-    f->output_data.x->widget->core.x = xpos;
-    f->output_data.x->widget->core.y = ypos;
-  }
-
-#else /* not USE_X_TOOLKIT */
 
   check_frame_size (f, &rows, &cols);
   f->output_data.x->vertical_scroll_bar_extra
 
   check_frame_size (f, &rows, &cols);
   f->output_data.x->vertical_scroll_bar_extra
@@ -11910,7 +11929,43 @@ x_set_window_size (f, change_gravity, cols, rows)
   SET_FRAME_GARBAGED (f);
 
   XFlush (FRAME_X_DISPLAY (f));
   SET_FRAME_GARBAGED (f);
 
   XFlush (FRAME_X_DISPLAY (f));
+}
+
+
+/* Call this to change the size of frame F's x-window.
+   If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
+   for this size change and subsequent size changes.
+   Otherwise we leave the window gravity unchanged.  */
+
+void
+x_set_window_size (f, change_gravity, cols, rows)
+     struct frame *f;
+     int change_gravity;
+     int cols, rows;
+{
+  BLOCK_INPUT;
 
 
+#ifdef USE_X_TOOLKIT
+  
+  if (f->output_data.x->widget != None)
+    {
+      /* The x and y position of the widget is clobbered by the
+        call to XtSetValues within EmacsFrameSetCharSize.
+        This is a real kludge, but I don't understand Xt so I can't
+        figure out a correct fix.  Can anyone else tell me? -- rms.  */
+      int xpos = f->output_data.x->widget->core.x;
+      int ypos = f->output_data.x->widget->core.y;
+      EmacsFrameSetCharSize (f->output_data.x->edit_widget, cols, rows);
+      f->output_data.x->widget->core.x = xpos;
+      f->output_data.x->widget->core.y = ypos;
+    }
+  else
+    x_set_window_size_1 (f, change_gravity, cols, rows);
+  
+#else /* not USE_X_TOOLKIT */
+  
+  x_set_window_size_1 (f, change_gravity, cols, rows);
+  
 #endif /* not USE_X_TOOLKIT */
 
   /* If cursor was outside the new size, mark it as off.  */
 #endif /* not USE_X_TOOLKIT */
 
   /* If cursor was outside the new size, mark it as off.  */
@@ -12393,11 +12448,12 @@ x_iconify_frame (f)
   UNBLOCK_INPUT;
 #endif /* not USE_X_TOOLKIT */
 }
   UNBLOCK_INPUT;
 #endif /* not USE_X_TOOLKIT */
 }
+
 \f
 \f
-/* Destroy the X window of frame F.  */
+/* Free X resources of frame F.  */
 
 void
 
 void
-x_destroy_window (f)
+x_free_frame_resources (f)
      struct frame *f;
 {
   struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
      struct frame *f;
 {
   struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
@@ -12406,15 +12462,19 @@ x_destroy_window (f)
 
   /* If a display connection is dead, don't try sending more
      commands to the X server.  */
 
   /* If a display connection is dead, don't try sending more
      commands to the X server.  */
-  if (dpyinfo->display != 0)
+  if (dpyinfo->display)
     {
     {
-      if (f->output_data.x->icon_desc != 0)
+      if (f->output_data.x->icon_desc)
        XDestroyWindow (FRAME_X_DISPLAY (f), f->output_data.x->icon_desc);
        XDestroyWindow (FRAME_X_DISPLAY (f), f->output_data.x->icon_desc);
+      
 #ifdef HAVE_X_I18N
       if (FRAME_XIC (f))
        free_frame_xic (f);
 #endif
 #ifdef HAVE_X_I18N
       if (FRAME_XIC (f))
        free_frame_xic (f);
 #endif
-      XDestroyWindow (FRAME_X_DISPLAY (f), f->output_data.x->window_desc);
+      
+      if (FRAME_X_WINDOW (f))
+       XDestroyWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
+      
 #ifdef USE_X_TOOLKIT
       if (f->output_data.x->widget)
        XtDestroyWidget (f->output_data.x->widget);
 #ifdef USE_X_TOOLKIT
       if (f->output_data.x->widget)
        XtDestroyWidget (f->output_data.x->widget);
@@ -12427,6 +12487,7 @@ x_destroy_window (f)
       unload_color (f, f->output_data.x->cursor_foreground_pixel);
       unload_color (f, f->output_data.x->border_pixel);
       unload_color (f, f->output_data.x->mouse_pixel);
       unload_color (f, f->output_data.x->cursor_foreground_pixel);
       unload_color (f, f->output_data.x->border_pixel);
       unload_color (f, f->output_data.x->mouse_pixel);
+      
       if (f->output_data.x->scroll_bar_background_pixel != -1)
        unload_color (f, f->output_data.x->scroll_bar_background_pixel);
       if (f->output_data.x->scroll_bar_foreground_pixel != -1)
       if (f->output_data.x->scroll_bar_background_pixel != -1)
        unload_color (f, f->output_data.x->scroll_bar_background_pixel);
       if (f->output_data.x->scroll_bar_foreground_pixel != -1)
@@ -12435,8 +12496,11 @@ x_destroy_window (f)
        unload_color (f, f->output_data.x->white_relief.pixel);
       if (f->output_data.x->black_relief.allocated_p)
        unload_color (f, f->output_data.x->black_relief.pixel);
        unload_color (f, f->output_data.x->white_relief.pixel);
       if (f->output_data.x->black_relief.allocated_p)
        unload_color (f, f->output_data.x->black_relief.pixel);
+
+      if (FRAME_FACE_CACHE (f))
+       free_frame_faces (f);
       
       
-      free_frame_faces (f);
+      x_free_gcs (f);
       XFlush (FRAME_X_DISPLAY (f));
     }
 
       XFlush (FRAME_X_DISPLAY (f));
     }
 
@@ -12444,7 +12508,8 @@ x_destroy_window (f)
     xfree (f->output_data.x->saved_menu_event);
 
   xfree (f->output_data.x);
     xfree (f->output_data.x->saved_menu_event);
 
   xfree (f->output_data.x);
-  f->output_data.x = 0;
+  f->output_data.x = NULL;
+  
   if (f == dpyinfo->x_focus_frame)
     dpyinfo->x_focus_frame = 0;
   if (f == dpyinfo->x_focus_event_frame)
   if (f == dpyinfo->x_focus_frame)
     dpyinfo->x_focus_frame = 0;
   if (f == dpyinfo->x_focus_event_frame)
@@ -12452,8 +12517,6 @@ x_destroy_window (f)
   if (f == dpyinfo->x_highlight_frame)
     dpyinfo->x_highlight_frame = 0;
 
   if (f == dpyinfo->x_highlight_frame)
     dpyinfo->x_highlight_frame = 0;
 
-  dpyinfo->reference_count--;
-
   if (f == dpyinfo->mouse_face_mouse_frame)
     {
       dpyinfo->mouse_face_beg_row
   if (f == dpyinfo->mouse_face_mouse_frame)
     {
       dpyinfo->mouse_face_beg_row
@@ -12467,6 +12530,24 @@ x_destroy_window (f)
 
   UNBLOCK_INPUT;
 }
 
   UNBLOCK_INPUT;
 }
+
+
+/* Destroy the X window of frame F.  */
+
+void
+x_destroy_window (f)
+     struct frame *f;
+{
+  struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+
+  /* If a display connection is dead, don't try sending more
+     commands to the X server.  */
+  if (dpyinfo->display != 0)
+    x_free_frame_resources (f);
+
+  dpyinfo->reference_count--;
+}
+
 \f
 /* Setting window manager hints.  */
 
 \f
 /* Setting window manager hints.  */
 
@@ -12723,24 +12804,38 @@ x_get_font_info (f, font_idx)
 }
 
 
 }
 
 
-/* Return a list of names of available fonts matching PATTERN on frame
-   F.  If SIZE is not 0, it is the size (maximum bound width) of fonts
-   to be listed.  Frame F NULL means we have not yet created any
-   frame on X, and consult the first display in x_display_list.
-   MAXNAMES sets a limit on how many fonts to match.  */
+/* Return a list of names of available fonts matching PATTERN on frame F.
+
+   If SIZE is > 0, it is the size (maximum bounds width) of fonts
+   to be listed.
+
+   SIZE < 0 means include scalable fonts.
+
+   Frame F null means we have not yet created any frame on X, and
+   consult the first display in x_display_list.  MAXNAMES sets a limit
+   on how many fonts to match.  */
 
 Lisp_Object
 x_list_fonts (f, pattern, size, maxnames)
 
 Lisp_Object
 x_list_fonts (f, pattern, size, maxnames)
-     FRAME_PTR f;
+     struct frame *f;
      Lisp_Object pattern;
      int size;
      int maxnames;
 {
   Lisp_Object list = Qnil, patterns, newlist = Qnil, key = Qnil;
   Lisp_Object tem, second_best;
      Lisp_Object pattern;
      int size;
      int maxnames;
 {
   Lisp_Object list = Qnil, patterns, newlist = Qnil, key = Qnil;
   Lisp_Object tem, second_best;
-  Display *dpy = f != NULL ? FRAME_X_DISPLAY (f) : x_display_list->display;
+  struct x_display_info *dpyinfo
+    = f ? FRAME_X_DISPLAY_INFO (f) : x_display_list;
+  Display *dpy = dpyinfo->display;
   int try_XLoadQueryFont = 0;
   int count;
   int try_XLoadQueryFont = 0;
   int count;
+  int allow_scalable_fonts_p = 0;
+
+  if (size < 0)
+    {
+      allow_scalable_fonts_p = 1;
+      size = 0;
+    }
 
   patterns = Fassoc (pattern, Valternate_fontname_alist);
   if (NILP (patterns))
 
   patterns = Fassoc (pattern, Valternate_fontname_alist);
   if (NILP (patterns))
@@ -12758,11 +12853,12 @@ x_list_fonts (f, pattern, size, maxnames)
       pattern = XCAR (patterns);
       /* See if we cached the result for this particular query.
          The cache is an alist of the form:
       pattern = XCAR (patterns);
       /* See if we cached the result for this particular query.
          The cache is an alist of the form:
-          (((PATTERN . MAXNAMES) (FONTNAME . WIDTH) ...) ...)
-      */
-      if (f && (tem = XCDR (FRAME_X_DISPLAY_INFO (f)->name_list_element),
-               key = Fcons (pattern, make_number (maxnames)),
-               !NILP (list = Fassoc (key, tem))))
+        ((((PATTERN . MAXNAMES) . SCALABLE) (FONTNAME . WIDTH) ...) ...)  */
+      tem = XCDR (dpyinfo->name_list_element);
+      key = Fcons (Fcons (pattern, make_number (maxnames)),
+                  allow_scalable_fonts_p ? Qt : Qnil);
+      list = Fassoc (key, tem);
+      if (!NILP (list))
        {
          list = Fcdr_safe (list);
          /* We have a cashed list.  Don't have to get the list again.  */
        {
          list = Fcdr_safe (list);
          /* We have a cashed list.  Don't have to get the list again.  */
@@ -12849,10 +12945,10 @@ x_list_fonts (f, pattern, size, maxnames)
              int average_width = -1, dashes = 0;
              
              /* Count the number of dashes in NAMES[I].  If there are
              int average_width = -1, dashes = 0;
              
              /* Count the number of dashes in NAMES[I].  If there are
-               14 dashes, and the field value following 12th dash
-               (AVERAGE_WIDTH) is 0, this is a auto-scaled font which
-               is usually too ugly to be used for editing.  Let's
-               ignore it.  */
+                14 dashes, and the field value following 12th dash
+                (AVERAGE_WIDTH) is 0, this is a auto-scaled font which
+                is usually too ugly to be used for editing.  Let's
+                ignore it.  */
              while (*p)
                if (*p++ == '-')
                  {
              while (*p)
                if (*p++ == '-')
                  {
@@ -12862,7 +12958,9 @@ x_list_fonts (f, pattern, size, maxnames)
                    else if (dashes == 12) /* AVERAGE_WIDTH field */
                      average_width = atoi (p);
                  }
                    else if (dashes == 12) /* AVERAGE_WIDTH field */
                      average_width = atoi (p);
                  }
-             if (dashes < 14 || average_width != 0)
+             
+             if (allow_scalable_fonts_p
+                 || dashes < 14 || average_width != 0)
                {
                  tem = build_string (names[i]);
                  if (NILP (Fassoc (tem, list)))
                {
                  tem = build_string (names[i]);
                  if (NILP (Fassoc (tem, list)))
@@ -12885,10 +12983,8 @@ x_list_fonts (f, pattern, size, maxnames)
        }
 
       /* Now store the result in the cache.  */
        }
 
       /* Now store the result in the cache.  */
-      if (f != NULL)
-       XCDR (FRAME_X_DISPLAY_INFO (f)->name_list_element)
-         = Fcons (Fcons (key, list),
-                  XCDR (FRAME_X_DISPLAY_INFO (f)->name_list_element));
+      XCDR (dpyinfo->name_list_element)
+        = Fcons (Fcons (key, list), XCDR (dpyinfo->name_list_element));
 
     label_cached:
       if (NILP (list)) continue; /* Try the remaining alternatives.  */
 
     label_cached:
       if (NILP (list)) continue; /* Try the remaining alternatives.  */
@@ -12912,7 +13008,7 @@ x_list_fonts (f, pattern, size, maxnames)
          if (!INTEGERP (XCDR (tem)))
            {
              /* Since we have not yet known the size of this font, we
          if (!INTEGERP (XCDR (tem)))
            {
              /* Since we have not yet known the size of this font, we
-               must try slow function call XLoadQueryFont.  */
+                must try slow function call XLoadQueryFont.  */
              XFontStruct *thisinfo;
 
              BLOCK_INPUT;
              XFontStruct *thisinfo;
 
              BLOCK_INPUT;
@@ -13196,13 +13292,6 @@ x_load_font (f, fontname, size)
 
     fontp->size = font->max_bounds.width;
     fontp->height = FONT_HEIGHT (font);
 
     fontp->size = font->max_bounds.width;
     fontp->height = FONT_HEIGHT (font);
-    {
-      /* For some font, ascent and descent in max_bounds field is
-        larger than the above value.  */
-      int max_height = font->max_bounds.ascent + font->max_bounds.descent;
-      if (max_height > fontp->height)
-       fontp->height = max_height;
-    }
 
     if (NILP (font_names))
       {
 
     if (NILP (font_names))
       {
@@ -13211,20 +13300,26 @@ x_load_font (f, fontname, size)
           the cache for x_list_fonts.  */
        Lisp_Object lispy_name = build_string (fontname);
        Lisp_Object lispy_full_name = build_string (fontp->full_name);
           the cache for x_list_fonts.  */
        Lisp_Object lispy_name = build_string (fontname);
        Lisp_Object lispy_full_name = build_string (fontp->full_name);
+       Lisp_Object key = Fcons (Fcons (lispy_name, make_number (256)),
+                                Qnil);
 
        XCDR (dpyinfo->name_list_element)
 
        XCDR (dpyinfo->name_list_element)
-         = Fcons (Fcons (Fcons (lispy_name, make_number (256)),
+         = Fcons (Fcons (key,
                          Fcons (Fcons (lispy_full_name,
                                        make_number (fontp->size)),
                                 Qnil)),
                   XCDR (dpyinfo->name_list_element));
        if (full_name)
                          Fcons (Fcons (lispy_full_name,
                                        make_number (fontp->size)),
                                 Qnil)),
                   XCDR (dpyinfo->name_list_element));
        if (full_name)
-         XCDR (dpyinfo->name_list_element)
-           = Fcons (Fcons (Fcons (lispy_full_name, make_number (256)),
-                           Fcons (Fcons (lispy_full_name,
-                                         make_number (fontp->size)),
-                                  Qnil)),
-                    XCDR (dpyinfo->name_list_element));
+         {
+           key = Fcons (Fcons (lispy_full_name, make_number (256)),
+                        Qnil);
+           XCDR (dpyinfo->name_list_element)
+             = Fcons (Fcons (key,
+                             Fcons (Fcons (lispy_full_name,
+                                           make_number (fontp->size)),
+                                    Qnil)),
+                      XCDR (dpyinfo->name_list_element));
+         }
       }
 
     /* The slot `encoding' specifies how to map a character
       }
 
     /* The slot `encoding' specifies how to map a character
@@ -13691,7 +13786,7 @@ x_term_init (display_name, xrm_option, resource_name)
 
   {
     extern int gray_bitmap_width, gray_bitmap_height;
 
   {
     extern int gray_bitmap_width, gray_bitmap_height;
-    extern unsigned char *gray_bitmap_bits;
+    extern char *gray_bitmap_bits;
     dpyinfo->gray
       = XCreatePixmapFromBitmapData (dpyinfo->display, dpyinfo->root_window,
                                     gray_bitmap_bits,
     dpyinfo->gray
       = XCreatePixmapFromBitmapData (dpyinfo->display, dpyinfo->root_window,
                                     gray_bitmap_bits,
@@ -13882,7 +13977,7 @@ x_initialize ()
   estimate_mode_line_height_hook = x_estimate_mode_line_height;
 
   scroll_region_ok = 1;                /* we'll scroll partial frames */
   estimate_mode_line_height_hook = x_estimate_mode_line_height;
 
   scroll_region_ok = 1;                /* we'll scroll partial frames */
-  char_ins_del_ok = 0;         /* just as fast to write the line */
+  char_ins_del_ok = 1;
   line_ins_del_ok = 1;         /* we'll just blt 'em */
   fast_clear_end_of_line = 1;  /* X does this well */
   memory_below_frame = 0;      /* we don't remember what scrolls
   line_ins_del_ok = 1;         /* we'll just blt 'em */
   fast_clear_end_of_line = 1;  /* X does this well */
   memory_below_frame = 0;      /* we don't remember what scrolls
@@ -13913,7 +14008,7 @@ x_initialize ()
   }
 #endif
   
   }
 #endif
   
-#if USE_TOOLKIT_SCROLL_BARS
+#ifdef USE_TOOLKIT_SCROLL_BARS
   xaw3d_arrow_scroll = False;
   xaw3d_pick_top = True;
 #endif
   xaw3d_arrow_scroll = False;
   xaw3d_pick_top = True;
 #endif
@@ -13966,12 +14061,20 @@ For example, if a block cursor is over a tab, it will be drawn as\n\
 wide as that tab on the display.");
   x_stretch_cursor_p = 0;
 
 wide as that tab on the display.");
   x_stretch_cursor_p = 0;
 
-  DEFVAR_BOOL ("x-toolkit-scroll-bars-p", &x_toolkit_scroll_bars_p,
-    "If not nil, Emacs uses toolkit scroll bars.");
-#if USE_TOOLKIT_SCROLL_BARS
-  x_toolkit_scroll_bars_p = 1;
+  DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars,
+    "What X toolkit scroll bars Emacs uses.\n\
+A value of nil means Emacs doesn't use X toolkit scroll bars.\n\
+Otherwise, value is a symbol describing the X toolkit.");
+#ifdef USE_TOOLKIT_SCROLL_BARS
+#ifdef USE_MOTIF
+  Vx_toolkit_scroll_bars = intern ("motif");
+#elif defined HAVE_XAW3D
+  Vx_toolkit_scroll_bars = intern ("xaw3d");
+#else
+  Vx_toolkit_scroll_bars = intern ("xaw");
+#endif
 #else
 #else
-  x_toolkit_scroll_bars_p = 0;
+  Vx_toolkit_scroll_bars = Qnil;
 #endif
 
   staticpro (&last_mouse_motion_frame);
 #endif
 
   staticpro (&last_mouse_motion_frame);