(x_new_font): Don't change a tooltip's size.
[bpt/emacs.git] / src / xterm.c
index da53834..f5c0a5d 100644 (file)
@@ -1,5 +1,5 @@
 /* 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.
@@ -230,9 +230,9 @@ static unsigned char ov_bits[] = {
 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.)  */
@@ -396,6 +396,7 @@ enum draw_glyphs_face
   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 *));
@@ -1504,8 +1505,8 @@ x_produce_image_glyph (it)
   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;
   
@@ -2661,9 +2662,12 @@ x_set_mouse_face_gc (s)
   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);
+  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
@@ -3844,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 (s->img->margin)
-    {
-      x += s->img->margin;
-      y += s->img->margin;
-    }
+  x += s->img->hmargin;
+  y += s->img->vmargin;
 
   if (s->img->pixmap)
     {
@@ -3933,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 (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)
@@ -3982,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 (s->img->margin)
-    {
-      x += s->img->margin;
-      y += s->img->margin;
-    }
+  x += s->img->hmargin;
+  y += s->img->vmargin;
 
   if (s->img->pixmap)
     {
@@ -4074,7 +4069,6 @@ x_draw_image_glyph_string (s)
 {
   int x, y;
   int box_line_width = s->face->box_line_width;
-  int margin = s->img->margin;
   int height;
   Pixmap pixmap = None;
 
@@ -4085,7 +4079,8 @@ x_draw_image_glyph_string (s)
      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)
@@ -5819,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.  */
-  if (w->current_matrix == NULL)
+  if (w->current_matrix == NULL || w == updated_window)
     return;
 
   TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
@@ -7290,8 +7285,11 @@ void
 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;
+#endif
   
   if (! NILP (dpyinfo->mouse_face_window))
     show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
@@ -9906,7 +9904,6 @@ XTread_socket (sd, bufp, numchars, expected)
                        {
                          register int i;
                          register int c;
-                         unsigned char *p, *pend;
                          int nchars, len;
 
                          for (i = 0; i < nbytes; i++)
@@ -10089,7 +10086,6 @@ XTread_socket (sd, bufp, numchars, expected)
              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)
@@ -10110,6 +10106,7 @@ XTread_socket (sd, bufp, numchars, expected)
                      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;
@@ -11250,19 +11247,35 @@ x_connection_signal (signalnum)       /* If we don't have an argument, */
   signal (signalnum, x_connection_signal);
 #endif /* USG */
 }
+
 \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
-x_connection_closed (display, error_message)
-     Display *display;
+x_connection_closed (dpy, error_message)
+     Display *dpy;
      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;
-
+  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
@@ -11279,7 +11292,10 @@ x_connection_closed (display, error_message)
      in OpenWindows.  I don't know how to cicumvent it here.  */
   
 #ifdef USE_X_TOOLKIT
-  XtCloseDisplay (display);
+  /* 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
 
   /* Indicate that this display is dead.  */
@@ -11316,9 +11332,11 @@ x_connection_closed (display, error_message)
   if (dpyinfo)
     x_delete_display (dpyinfo);
 
+  x_uncatch_errors (dpy, count);
+  
   if (x_display_list == 0)
     {
-      fprintf (stderr, "%s\n", error_message);
+      fprintf (stderr, "%s\n", msg);
       shut_down_emacs (0, 0, Qnil);
       exit (70);
     }
@@ -11331,10 +11349,10 @@ x_connection_closed (display, error_message)
   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.  */
@@ -11355,6 +11373,7 @@ x_error_quitter (display, error)
   x_connection_closed (display, buf1);
 }
 
+
 /* This is the first-level handler for X protocol errors.
    It calls x_error_quitter or x_error_catcher.  */
 
@@ -11430,7 +11449,12 @@ x_new_font (f, fontname)
                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,
@@ -11848,37 +11872,19 @@ x_set_offset (f, xoff, yoff, change_gravity)
   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;
 {
-#ifndef USE_X_TOOLKIT
   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
@@ -11923,7 +11929,43 @@ x_set_window_size (f, change_gravity, cols, rows)
   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.  */
@@ -12406,11 +12448,12 @@ x_iconify_frame (f)
   UNBLOCK_INPUT;
 #endif /* not USE_X_TOOLKIT */
 }
+
 \f
-/* Destroy the X window of frame F.  */
+/* Free X resources of frame F.  */
 
 void
-x_destroy_window (f)
+x_free_frame_resources (f)
      struct frame *f;
 {
   struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
@@ -12419,19 +12462,19 @@ x_destroy_window (f)
 
   /* 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);
+      
 #ifdef HAVE_X_I18N
       if (FRAME_XIC (f))
        free_frame_xic (f);
 #endif
+      
       if (FRAME_X_WINDOW (f))
-       {
-         XDestroyWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
-         FRAME_X_WINDOW (f) = 0;
-       }
+       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);
@@ -12444,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);
+      
       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)
@@ -12452,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);
+
+      if (FRAME_FACE_CACHE (f))
+       free_frame_faces (f);
       
-      free_frame_faces (f);
+      x_free_gcs (f);
       XFlush (FRAME_X_DISPLAY (f));
     }
 
@@ -12461,7 +12508,8 @@ x_destroy_window (f)
     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)
@@ -12469,8 +12517,6 @@ x_destroy_window (f)
   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
@@ -12484,6 +12530,24 @@ x_destroy_window (f)
 
   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.  */
 
@@ -12740,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)
-     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;
-  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 allow_scalable_fonts_p = 0;
+
+  if (size < 0)
+    {
+      allow_scalable_fonts_p = 1;
+      size = 0;
+    }
 
   patterns = Fassoc (pattern, Valternate_fontname_alist);
   if (NILP (patterns))
@@ -12775,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 . 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.  */
@@ -12866,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
-               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++ == '-')
                  {
@@ -12879,7 +12958,9 @@ x_list_fonts (f, pattern, size, maxnames)
                    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)))
@@ -12902,10 +12983,8 @@ x_list_fonts (f, pattern, size, maxnames)
        }
 
       /* 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.  */
@@ -12929,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
-               must try slow function call XLoadQueryFont.  */
+                must try slow function call XLoadQueryFont.  */
              XFontStruct *thisinfo;
 
              BLOCK_INPUT;
@@ -13213,13 +13292,6 @@ x_load_font (f, fontname, size)
 
     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))
       {
@@ -13228,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);
+       Lisp_Object key = Fcons (Fcons (lispy_name, make_number (256)),
+                                Qnil);
 
        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)
-         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
@@ -13708,7 +13786,7 @@ x_term_init (display_name, xrm_option, resource_name)
 
   {
     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,
@@ -13899,7 +13977,7 @@ x_initialize ()
   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
@@ -13983,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;
 
-  DEFVAR_BOOL ("x-toolkit-scroll-bars-p", &x_toolkit_scroll_bars_p,
-    "If not nil, Emacs uses toolkit scroll bars.");
+  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
-  x_toolkit_scroll_bars_p = 1;
+#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
-  x_toolkit_scroll_bars_p = 0;
+  Vx_toolkit_scroll_bars = Qnil;
 #endif
 
   staticpro (&last_mouse_motion_frame);