(Faref): Delete codes for a composite character..
[bpt/emacs.git] / src / xterm.c
index 8e4ed04..270bc76 100644 (file)
@@ -22,17 +22,13 @@ Boston, MA 02111-1307, USA.  */
 /* New display code by Gerd Moellmann <gerd@gnu.org>.  */
 /* Xt features made by Fred Pierresteguy.  */
 
+#include <config.h>
+
 /* On 4.3 these lose if they come after xterm.h.  */
-/* On HP-UX 8.0 signal.h loses if it comes after config.h.  */
 /* Putting these at the beginning seems to be standard for other .c files.  */
 #include <signal.h>
 
-#include <config.h>
-
 #include <stdio.h>
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#endif
 
 #ifdef HAVE_X_WINDOWS
 
@@ -122,13 +118,21 @@ extern void _XEditResCheckMessages ();
 #include <Xm/Xm.h>             /* for LESSTIF_VERSION */
 #include <Xm/ScrollBar.h>
 #include <Xm/ScrollBarP.h>
-#elif defined HAVE_XAW3D
+#else /* !USE_MOTIF i.e. use Xaw */
+
+#ifdef HAVE_XAW3D
 #include <X11/Xaw3d/Simple.h>
-#include <X11/Xaw3d/ThreeD.h>
 #include <X11/Xaw3d/Scrollbar.h>
 #define ARROW_SCROLLBAR
 #include <X11/Xaw3d/ScrollbarP.h>
-#endif /* HAVE_XAW3D */
+#else /* !HAVE_XAW3D */
+#include <X11/Xaw/Simple.h>
+#include <X11/Xaw/Scrollbar.h>
+#endif /* !HAVE_XAW3D */
+#ifndef XtNpickTop
+#define XtNpickTop "pickTop"
+#endif /* !XtNpickTop */
+#endif /* !USE_MOTIF */
 #endif /* USE_TOOLKIT_SCROLL_BARS */
 
 #endif /* USE_X_TOOLKIT */
@@ -145,11 +149,6 @@ extern void _XEditResCheckMessages ();
 #endif
 #endif
 
-#ifdef HAVE_SETLOCALE
-/* So we can do setlocale.  */
-#include <locale.h>
-#endif
-
 #ifdef SOLARIS2
 /* memmove will be defined as a macro in Xfuncs.h unless
    <string.h> is included beforehand.  The declaration for memmove in
@@ -197,43 +196,42 @@ static unsigned char zv_bits[] = {
 static unsigned char left_bits[] = {
    0x18, 0x0c, 0x06, 0x3f, 0x3f, 0x06, 0x0c, 0x18};
 
+/* Right truncation arrow bitmap `->'.  */
+
+#define right_width 8
+#define right_height 8
+static unsigned char right_bits[] = {
+   0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18};
+
 /* Marker for continued lines.  */
 
 #define continued_width 8
 #define continued_height 8
 static unsigned char continued_bits[] = {
-   0x30, 0x30, 0x30, 0x30, 0xb4, 0xfc, 0x78, 0x30};
+   0x3c, 0x7c, 0xc0, 0xe4, 0xfc, 0x7c, 0x3c, 0x7c};
+
+/* Marker for continuation lines.  */
 
 #define continuation_width 8
 #define continuation_height 8
 static unsigned char continuation_bits[] = {
-   0x0c, 0x1e, 0x3f, 0x2d, 0x0c, 0x0c, 0x0c, 0x0c};
+   0x3c, 0x3e, 0x03, 0x27, 0x3f, 0x3e, 0x3c, 0x3e};
 
-/* Right truncation arrow bitmap `->'.  */
+/* Overlay arrow bitmap.  */
 
-#define right_width 8
-#define right_height 8
-static unsigned char right_bits[] = {
-   0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18};
-
-/* Overlay arrow bitmap; a filled `<>'.  */
-
-#if 1
+#if 0
+/* A bomb.  */
 #define ov_width 8
 #define ov_height 8
 static unsigned char ov_bits[] = {
    0x30, 0x08, 0x3c, 0x7e, 0x7a, 0x7a, 0x62, 0x3c};
-
-#elif 0
-#define ov_width 8
-#define ov_height 8
-static unsigned char ov_bits[] = {
-   0x18, 0x04, 0x08, 0x1c, 0x3e, 0x3a, 0x32, 0x1c};
 #else
+/* A triangular arrow.  */
 #define ov_width 8
 #define ov_height 8
 static unsigned char ov_bits[] = {
-   0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x3c, 0x18};
+   0x03, 0x0f, 0x1f, 0x3f, 0x3f, 0x1f, 0x0f, 0x03};
+
 #endif
 
 extern Lisp_Object Qhelp_echo;
@@ -412,8 +410,8 @@ static struct glyph *x_y_to_hpos_vpos P_ ((struct window *, int, int,
 static void note_mode_line_highlight P_ ((struct window *, int, int));
 static void x_check_font P_ ((struct frame *, XFontStruct *));
 static void note_mouse_highlight P_ ((struct frame *, int, int));
-static void note_toolbar_highlight P_ ((struct frame *f, int, int));
-static void x_handle_toolbar_click P_ ((struct frame *, XButtonEvent *));
+static void note_tool_bar_highlight P_ ((struct frame *f, int, int));
+static void x_handle_tool_bar_click P_ ((struct frame *, XButtonEvent *));
 static void show_mouse_face P_ ((struct x_display_info *,
                                 enum draw_glyphs_face));
 static int x_io_error_quitter P_ ((Display *));
@@ -642,7 +640,7 @@ x_draw_vertical_border (w)
       int x0, x1, y0, y1;
 
       window_box_edges (w, -1, &x0, &y0, &x1, &y1);
-      x1 += FRAME_X_FLAGS_AREA_WIDTH (f);
+      x1 += FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f);
       y1 -= 1;
       
       XDrawLine (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 
@@ -746,7 +744,8 @@ x_after_update_window_line (desired_row)
          struct frame *f = XFRAME (w->frame);
          int width = FRAME_INTERNAL_BORDER_WIDTH (f);
          int height = desired_row->visible_height;
-         int x = window_box_right (w, -1) + FRAME_X_FLAGS_AREA_WIDTH (f);
+         int x = (window_box_right (w, -1)
+                  + FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f));
          int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
 
          XClearArea (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
@@ -790,7 +789,7 @@ x_draw_bitmap (w, row, which)
       bits = left_bits;
       x = (WINDOW_TO_FRAME_PIXEL_X (w, 0)
           - wd
-          - (FRAME_X_FLAGS_AREA_WIDTH (f) - wd) / 2);
+          - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f) - wd) / 2);
       break;
       
     case OVERLAY_ARROW_BITMAP:
@@ -799,7 +798,7 @@ x_draw_bitmap (w, row, which)
       bits = ov_bits;
       x = (WINDOW_TO_FRAME_PIXEL_X (w, 0)
           - wd
-          - (FRAME_X_FLAGS_AREA_WIDTH (f) - wd) / 2);
+          - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f) - wd) / 2);
       break;
       
     case RIGHT_TRUNCATION_BITMAP:
@@ -807,7 +806,7 @@ x_draw_bitmap (w, row, which)
       h = right_height;
       bits = right_bits;
       x = window_box_right (w, -1);
-      x += (FRAME_X_FLAGS_AREA_WIDTH (f) - wd) / 2;
+      x += (FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f) - wd) / 2;
       break;
 
     case CONTINUED_LINE_BITMAP:
@@ -815,7 +814,7 @@ x_draw_bitmap (w, row, which)
       h = right_height;
       bits = continued_bits;
       x = window_box_right (w, -1);
-      x += (FRAME_X_FLAGS_AREA_WIDTH (f) - wd) / 2;
+      x += (FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f) - wd) / 2;
       break;
       
     case CONTINUATION_LINE_BITMAP:
@@ -824,7 +823,7 @@ x_draw_bitmap (w, row, which)
       bits = continuation_bits;
       x = (WINDOW_TO_FRAME_PIXEL_X (w, 0)
           - wd
-          - (FRAME_X_FLAGS_AREA_WIDTH (f) - wd) / 2);
+          - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f) - wd) / 2);
       break;
 
     case ZV_LINE_BITMAP:
@@ -833,7 +832,7 @@ x_draw_bitmap (w, row, which)
       bits = zv_bits;
       x = (WINDOW_TO_FRAME_PIXEL_X (w, 0)
           - wd
-          - (FRAME_X_FLAGS_AREA_WIDTH (f) - wd) / 2);
+          - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f) - wd) / 2);
       break;
 
     default:
@@ -868,7 +867,7 @@ x_draw_row_bitmaps (w, row)
   struct frame *f = XFRAME (w->frame);
   enum bitmap_type bitmap;
   struct face *face;
-  int top_line_height = -1;
+  int header_line_height = -1;
 
   xassert (interrupt_input_blocked);
 
@@ -895,7 +894,7 @@ x_draw_row_bitmaps (w, row)
   /* Clear flags area if no bitmap to draw or if bitmap doesn't fill
      the flags area.  */
   if (bitmap == NO_BITMAP
-      || FRAME_FLAGS_BITMAP_WIDTH (f) < FRAME_X_FLAGS_AREA_WIDTH (f)
+      || FRAME_FLAGS_BITMAP_WIDTH (f) < FRAME_X_LEFT_FLAGS_AREA_WIDTH (f)
       || row->height > FRAME_FLAGS_BITMAP_HEIGHT (f))
     {
       /* If W has a vertical border to its left, don't draw over it.  */
@@ -904,19 +903,29 @@ x_draw_row_bitmaps (w, row)
                    ? 1 : 0);
       int left = window_box_left (w, -1);
 
-      if (top_line_height < 0)
-       top_line_height = WINDOW_DISPLAY_TOP_LINE_HEIGHT (w);
-      XSetForeground (FRAME_X_DISPLAY (f), face->gc, face->background);
+      if (header_line_height < 0)
+       header_line_height = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
+      
+      /* In case the same realized face is used for bitmap areas and
+        for something displayed in the text (e.g. face `region' on
+        mono-displays, the fill style may have been changed to
+        FillSolid in x_draw_glyph_string_background.  */
+      if (face->stipple)
+       XSetFillStyle (FRAME_X_DISPLAY (f), face->gc, FillOpaqueStippled);
+      else
+       XSetForeground (FRAME_X_DISPLAY (f), face->gc, face->background);
+      
       XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
                      face->gc,
                      (left
-                      - FRAME_X_FLAGS_AREA_WIDTH (f)
+                      - FRAME_X_LEFT_FLAGS_AREA_WIDTH (f)
                       + border),
-                     WINDOW_TO_FRAME_PIXEL_Y (w, max (top_line_height,
+                     WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height,
                                                       row->y)),
-                     FRAME_X_FLAGS_AREA_WIDTH (f) - border,
+                     FRAME_X_LEFT_FLAGS_AREA_WIDTH (f) - border,
                      row->visible_height);
-      XSetForeground (FRAME_X_DISPLAY (f), face->gc, face->foreground);
+      if (!face->stipple)
+       XSetForeground (FRAME_X_DISPLAY (f), face->gc, face->foreground);
     }
 
   /* Draw the left bitmap.  */
@@ -934,22 +943,31 @@ x_draw_row_bitmaps (w, row)
   /* Clear flags area if no bitmap to draw of if bitmap doesn't fill
      the flags area.  */
   if (bitmap == NO_BITMAP
-      || FRAME_FLAGS_BITMAP_WIDTH (f) < FRAME_X_FLAGS_AREA_WIDTH (f)
+      || FRAME_FLAGS_BITMAP_WIDTH (f) < FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f)
       || row->height > FRAME_FLAGS_BITMAP_HEIGHT (f))
     {
       int right = window_box_right (w, -1);
 
-      if (top_line_height < 0)
-       top_line_height = WINDOW_DISPLAY_TOP_LINE_HEIGHT (w);
-      XSetForeground (FRAME_X_DISPLAY (f), face->gc, face->background);
+      if (header_line_height < 0)
+       header_line_height = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
+
+      /* In case the same realized face is used for bitmap areas and
+        for something displayed in the text (e.g. face `region' on
+        mono-displays, the fill style may have been changed to
+        FillSolid in x_draw_glyph_string_background.  */
+      if (face->stipple)
+       XSetFillStyle (FRAME_X_DISPLAY (f), face->gc, FillOpaqueStippled);
+      else
+       XSetForeground (FRAME_X_DISPLAY (f), face->gc, face->background);
       XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
                      face->gc,
                      right,
-                     WINDOW_TO_FRAME_PIXEL_Y (w, max (top_line_height,
+                     WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height,
                                                       row->y)),
-                     FRAME_X_FLAGS_AREA_WIDTH (f),
+                     FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f),
                      row->visible_height);
-      XSetForeground (FRAME_X_DISPLAY (f), face->gc, face->foreground);
+      if (!face->stipple)
+       XSetForeground (FRAME_X_DISPLAY (f), face->gc, face->foreground);
     }
 
   /* Draw the right bitmap.  */
@@ -1057,7 +1075,7 @@ XTcursor_to (vpos, hpos, y, x)
     {
       BLOCK_INPUT;
       x_display_cursor (w, 1, hpos, vpos, x, y);
-      XFlush (FRAME_X_DISPLAY (selected_frame));
+      XFlush (FRAME_X_DISPLAY (SELECTED_FRAME ()));
       UNBLOCK_INPUT;
     }
 }
@@ -1081,7 +1099,6 @@ static void x_append_glyph P_ ((struct it *));
 static void x_append_stretch_glyph P_ ((struct it *it, Lisp_Object,
                                        int, int, double));
 static void x_produce_glyphs P_ ((struct it *));
-static void x_produce_special_glyphs P_ ((struct it *, enum display_element_type));
 static void x_produce_image_glyph P_ ((struct it *it));
      
 
@@ -1421,6 +1438,8 @@ x_append_glyph (it)
       glyph->right_box_line_p = it->end_of_box_run_p;
       glyph->voffset = it->voffset;
       glyph->multibyte_p = it->multibyte_p;
+      glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
+                                     || it->phys_descent > it->descent);
       ++it->glyph_row->used[area];
     }
 }
@@ -1468,8 +1487,8 @@ x_produce_image_glyph (it)
   PREPARE_FACE_FOR_DISPLAY (it->f, face);
   prepare_image_for_display (it->f, img);
 
-  it->ascent = IMAGE_ASCENT (img);
-  it->descent = img->height + 2 * img->margin - it->ascent;
+  it->ascent = it->phys_ascent = IMAGE_ASCENT (img);
+  it->descent = it->phys_descent = img->height + 2 * img->margin - it->ascent;
   it->pixel_width = img->width + 2 * img->margin;
 
   it->nglyphs = 1;
@@ -1672,8 +1691,8 @@ x_produce_stretch_glyph (it)
     }
 
   it->pixel_width = width;
-  it->ascent = height * ascent;
-  it->descent = height - it->ascent;
+  it->ascent = it->phys_ascent = height * ascent;
+  it->descent = it->phys_descent = height - it->ascent;
   it->nglyphs = 1;
 
   if (face->box != FACE_NO_BOX)
@@ -1705,9 +1724,7 @@ x_produce_glyphs (it)
       XFontStruct *font;
       struct face *face;
       XCharStruct *pcm;
-      struct it ci;
       int font_not_found_p;
-      int c;
 
       /* Maybe translate single-byte characters to multibyte.  */
       it->char_to_display = it->c;
@@ -1739,10 +1756,12 @@ x_produce_glyphs (it)
          int stretched_p;
 
          it->nglyphs = 1;
-         it->ascent = font->ascent;
-         it->descent = font->descent;
 
          pcm = x_per_char_metric (font, &char2b);
+         it->ascent = font->ascent;
+         it->descent = font->descent;
+         it->phys_ascent = pcm->ascent;
+         it->phys_descent = pcm->descent;
          it->pixel_width = pcm->width;
 
          /* If this is a space inside a region of text with
@@ -1801,8 +1820,8 @@ x_produce_glyphs (it)
          /* A newline has no width but we need the height of the line.  */
          it->pixel_width = 0;
          it->nglyphs = 0;
-         it->ascent = font->ascent;
-         it->descent = font->descent;
+         it->ascent = it->phys_ascent = font->ascent;
+         it->descent = it->phys_descent = font->descent;
       
          if (face->box != FACE_NO_BOX)
            {
@@ -1821,8 +1840,8 @@ x_produce_glyphs (it)
       
          it->pixel_width = next_tab_x - x;
          it->nglyphs = 1;
-         it->ascent = font->ascent;
-         it->descent = font->descent;
+         it->ascent = it->phys_ascent = font->ascent;
+         it->descent = it->phys_descent = font->descent;
          
          if (it->glyph_row)
            {
@@ -1860,6 +1879,8 @@ x_produce_glyphs (it)
                 information in cmpcharp to do the correct setting.  */
              it->ascent = font->ascent;
              it->descent = font->descent;
+             it->phys_ascent = font->max_bounds.ascent;
+             it->phys_descent = font->max_bounds.descent;
            }
          else
            {
@@ -1875,6 +1896,8 @@ x_produce_glyphs (it)
              it->nglyphs = 1;
              it->ascent = font->ascent;
              it->descent = font->descent;
+             it->phys_ascent = pcm->ascent;
+             it->phys_descent = pcm->descent;
              if (it->glyph_row
                  && (pcm->lbearing < 0
                      || pcm->rbearing > pcm->width))
@@ -1913,8 +1936,11 @@ x_produce_glyphs (it)
   xassert (it->ascent >= 0 && it->descent > 0);
   if (it->area == TEXT_AREA)
     it->current_x += it->pixel_width;
+  
   it->max_ascent = max (it->max_ascent, it->ascent);
   it->max_descent = max (it->max_descent, it->descent);
+  it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
+  it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
 }
 
 
@@ -2046,6 +2072,11 @@ struct glyph_string
      stipple pattern.  */
   unsigned stippled_p : 1;
 
+  /* 1 means only the foreground of this glyph string must be drawn,
+     and we should use the physical height of the line this glyph
+     string appears in as clip rect.  */
+  unsigned for_overlaps_p : 1;
+
   /* The GC to use for drawing this glyph string.  */
   GC gc;
 
@@ -2061,7 +2092,7 @@ struct glyph_string
 };
 
 
-#if GLYPH_DEBUG
+#if 0
 
 static void
 x_dump_glyph_string (s)
@@ -2100,7 +2131,8 @@ static int x_left_overwritten P_ ((struct glyph_string *));
 static int x_left_overwriting P_ ((struct glyph_string *));
 static int x_right_overwritten P_ ((struct glyph_string *));
 static int x_right_overwriting P_ ((struct glyph_string *));
-static int x_fill_glyph_string P_ ((struct glyph_string *, int, int, int));
+static int x_fill_glyph_string P_ ((struct glyph_string *, int, int, int,
+                                   int));
 static void x_init_glyph_string P_ ((struct glyph_string *,
                                        XChar2b *, struct window *,
                                        struct glyph_row *,
@@ -2108,13 +2140,12 @@ static void x_init_glyph_string P_ ((struct glyph_string *,
                                        enum draw_glyphs_face));
 static int x_draw_glyphs P_ ((struct window *, int , struct glyph_row *,
                              enum glyph_row_area, int, int,
-                             enum draw_glyphs_face, int *, int *));
+                             enum draw_glyphs_face, int *, int *, int));
 static void x_set_glyph_string_clipping P_ ((struct glyph_string *));
 static void x_set_glyph_string_gc P_ ((struct glyph_string *));
 static void x_draw_glyph_string_background P_ ((struct glyph_string *,
                                                int));
 static void x_draw_glyph_string_foreground P_ ((struct glyph_string *));
-static void x_draw_glyph_string_underline P_ ((struct glyph_string *));
 static void x_draw_glyph_string_box P_ ((struct glyph_string *));
 static void x_draw_glyph_string  P_ ((struct glyph_string *));
 static void x_compute_glyph_string_overhangs P_ ((struct glyph_string *));
@@ -2125,9 +2156,9 @@ static void x_get_glyph_overhangs P_ ((struct glyph *, struct frame *,
                                       int *, int *));
 static void x_compute_overhangs_and_x P_ ((struct glyph_string *, int, int));
 static int x_alloc_lighter_color P_ ((struct frame *, Display *, Colormap,
-                                     unsigned long *, float, int));
+                                     unsigned long *, double, int));
 static void x_setup_relief_color P_ ((struct frame *, struct relief *,
-                                     float, int, unsigned long));
+                                     double, int, unsigned long));
 static void x_setup_relief_colors P_ ((struct glyph_string *));
 static void x_draw_image_glyph_string P_ ((struct glyph_string *));
 static void x_draw_image_relief P_ ((struct glyph_string *));
@@ -2140,9 +2171,10 @@ static void x_draw_relief_rect P_ ((struct frame *, int, int, int, int,
                                    int, int, int, int, XRectangle *));
 static void x_draw_box_rect P_ ((struct glyph_string *, int, int, int, int,
                                 int, int, int, XRectangle *));
+static void x_fix_overlapping_area P_ ((struct window *, struct glyph_row *,
+                                       enum glyph_row_area));
 
 
-     
 /* Append the list of glyph strings with head H and tail T to the list
    with head *HEAD and tail *TAIL.  Set *HEAD and *TAIL to the result.  */
 
@@ -2376,9 +2408,7 @@ x_get_glyph_string_clip_rect (s, r)
            r->x -= width;
        }
       
-      /* If row should not extend over internal borders, adjust x.  */
-      if (!s->row->internal_border_p)
-       r->x += FRAME_INTERNAL_BORDER_WIDTH (s->f);
+      r->x += FRAME_INTERNAL_BORDER_WIDTH (s->f);
       
       /* Unless displaying a mode or menu bar line, which are always
         fully visible, clip to the visible part of the row.  */
@@ -2400,15 +2430,25 @@ x_get_glyph_string_clip_rect (s, r)
      partially visible lines at the top of a window.  */
   if (!s->row->full_width_p
       && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
-    r->y = WINDOW_DISPLAY_TOP_LINE_HEIGHT (s->w);
+    r->y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s->w);
   else
     r->y = max (0, s->row->y);
-  r->y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r->y);
 
-  /* If drawing a toolbar window, draw it over the internal border
+  /* If drawing a tool-bar window, draw it over the internal border
      at the top of the window.  */
-  if (s->w == XWINDOW (s->f->toolbar_window))
+  if (s->w == XWINDOW (s->f->tool_bar_window))
     r->y -= s->f->output_data.x->internal_border_width;
+
+  /* If S draws overlapping rows, it's sufficient to use the top and
+     bottom of the window for clipping because this glyph string
+     intentionally draws over other lines.  */
+  if (s->for_overlaps_p)
+    {
+      r->y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s->w);
+      r->height = window_text_bottom_y (s->w) - r->y;
+    }
+      
+  r->y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r->y);
 }
 
 
@@ -2737,7 +2777,8 @@ x_draw_glyph_string_foreground (s)
             Always use XDrawImageString when drawing the cursor so
             that there is no chance that characters under a box
             cursor are invisible.  */
-         if (s->background_filled_p && s->hl != DRAW_CURSOR)
+         if (s->for_overlaps_p
+             || (s->background_filled_p && s->hl != DRAW_CURSOR))
            {
              /* Draw characters with 16-bit or 8-bit functions.  */
              if (s->two_byte_p)
@@ -2896,19 +2937,65 @@ x_draw_glyph_string_foreground (s)
 }
 
 
+#ifdef USE_X_TOOLKIT
+
+/* Allocate the color COLOR->pixel on the screen and display of
+   widget WIDGET in colormap CMAP.  If an exact match cannot be
+   allocated, try the nearest color available.  Value is non-zero
+   if successful.  This is called from lwlib.  */
+
+int
+x_alloc_nearest_color_for_widget (widget, cmap, color)
+     Widget widget;
+     Colormap cmap;
+     XColor *color;
+{
+  struct frame *f;
+  struct x_display_info *dpyinfo;
+  Lisp_Object tail;
+
+  dpyinfo = x_display_info_for_display (XtDisplay (widget));
+  
+  /* Find the top-level shell of the widget.  Note that this function
+     can be called when the widget is not yet realized, so XtWindow
+     (widget) == 0.  That's the reason we can't simply use
+     x_any_window_to_frame.  */
+  while (!XtIsTopLevelShell (widget))
+    widget = XtParent (widget);
+
+  /* Look for a frame with that top-level widget.  Allocate the color
+     on that frame to get the right gamma correction value.  */
+  for (tail = Vframe_list; GC_CONSP (tail); tail = XCDR (tail))
+    if (GC_FRAMEP (XCAR (tail))
+       && (f = XFRAME (XCAR (tail)),
+           (f->output_data.nothing != 1
+            && FRAME_X_DISPLAY_INFO (f) == dpyinfo))
+       && f->output_data.x->widget == widget)
+      return x_alloc_nearest_color (f, cmap, color);
+
+  abort ();
+}
+
+#endif /* USE_X_TOOLKIT */
+
+
 /* Allocate the color COLOR->pixel on SCREEN of DISPLAY, colormap
    CMAP.  If an exact match can't be allocated, try the nearest color
    available.  Value is non-zero if successful.  Set *COLOR to the
    color allocated.  */
 
 int
-x_alloc_nearest_color (display, screen, cmap, color)
-     Display *display;
-     Screen *screen;
+x_alloc_nearest_color (f, cmap, color)
+     struct frame *f;
      Colormap cmap;
      XColor *color;
 {
-  int rc = XAllocColor (display, cmap, color);
+  Display *display = FRAME_X_DISPLAY (f);
+  Screen *screen = FRAME_X_SCREEN (f);
+  int rc;
+
+  gamma_correct (f, color);
+  rc = XAllocColor (display, cmap, color);
   if (rc == 0)
     {
       /* If we got to this point, the colormap is full, so we're going
@@ -2961,7 +3048,7 @@ x_alloc_lighter_color (f, display, cmap, pixel, factor, delta)
      Display *display;
      Colormap cmap;
      unsigned long *pixel;
-     float factor;
+     double factor;
      int delta;
 {
   XColor color, new;
@@ -2978,7 +3065,7 @@ x_alloc_lighter_color (f, display, cmap, pixel, factor, delta)
   new.blue = min (0xffff, factor * color.blue);
 
   /* Try to allocate the color.  */
-  success_p = x_alloc_nearest_color (display, FRAME_X_SCREEN (f), cmap, &new);
+  success_p = x_alloc_nearest_color (f, cmap, &new);
   if (success_p)
     {
       if (new.pixel == *pixel)
@@ -2998,8 +3085,7 @@ x_alloc_lighter_color (f, display, cmap, pixel, factor, delta)
          new.red = min (0xffff, delta + color.red);
          new.green = min (0xffff, delta + color.green);
          new.blue = min (0xffff, delta + color.blue);
-         success_p = x_alloc_nearest_color (display, FRAME_X_SCREEN (f),
-                                            cmap, &new);
+         success_p = x_alloc_nearest_color (f, cmap, &new);
        }
       else
        success_p = 1;
@@ -3021,7 +3107,7 @@ static void
 x_setup_relief_color (f, relief, factor, delta, default_pixel)
      struct frame *f;
      struct relief *relief;
-     float factor;
+     double factor;
      int delta;
      unsigned long default_pixel;
 {
@@ -3031,6 +3117,8 @@ x_setup_relief_color (f, relief, factor, delta, default_pixel)
   unsigned long pixel;
   unsigned long background = di->relief_background;
   Colormap cmap = DefaultColormapOfScreen (FRAME_X_SCREEN (f));
+  struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+  Display *dpy = FRAME_X_DISPLAY (f);
 
   xgcv.graphics_exposures = False;
   xgcv.line_width = 1;
@@ -3043,19 +3131,19 @@ x_setup_relief_color (f, relief, factor, delta, default_pixel)
     {
       /* If display has an immutable color map, freeing colors is not
         necessary and some servers don't allow it.  So don't do it.  */
-      int class = FRAME_X_DISPLAY_INFO (f)->visual->class;
+      int class = dpyinfo->visual->class;
       if (class != StaticColor
          && class != StaticGray
          && class != TrueColor)
-       XFreeColors (FRAME_X_DISPLAY (f), cmap, &relief->pixel, 1, 0);
+       XFreeColors (dpy, cmap, &relief->pixel, 1, 0);
       relief->allocated_p = 0;
     }
 
   /* Allocate new color.  */
   xgcv.foreground = default_pixel;
   pixel = background;
-  if (x_alloc_lighter_color (f, FRAME_X_DISPLAY (f), cmap, &pixel,
-                            factor, delta))
+  if (dpyinfo->n_planes != 1
+      && x_alloc_lighter_color (f, dpy, cmap, &pixel, factor, delta))
     {
       relief->allocated_p = 1;
       xgcv.foreground = relief->pixel = pixel;
@@ -3063,13 +3151,12 @@ x_setup_relief_color (f, relief, factor, delta, default_pixel)
   
   if (relief->gc == 0)
     {
-      xgcv.stipple = FRAME_X_DISPLAY_INFO (f)->gray;
+      xgcv.stipple = dpyinfo->gray;
       mask |= GCStipple;
-      relief->gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                             mask, &xgcv);
+      relief->gc = XCreateGC (dpy, FRAME_X_WINDOW (f), mask, &xgcv);
     }
   else
-    XChangeGC (FRAME_X_DISPLAY (f), relief->gc, mask, &xgcv);
+    XChangeGC (dpy, relief->gc, mask, &xgcv);
 }
 
 
@@ -3222,7 +3309,7 @@ x_draw_glyph_string_box (s)
   if (s->row->full_width_p
       && !s->w->pseudo_window_p)
     {
-      last_x += FRAME_X_FLAGS_AREA_WIDTH (s->f);
+      last_x += FRAME_X_RIGHT_FLAGS_AREA_WIDTH (s->f);
       if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (s->f))
        last_x += FRAME_SCROLL_BAR_WIDTH (s->f) * CANON_X_UNIT (s->f);
     }
@@ -3237,7 +3324,7 @@ x_draw_glyph_string_box (s)
   left_x = s->x;
   right_x = ((s->row->full_width_p
              ? last_x - 1
-             : min (last_x, s->x + s->width) - 1));
+             : min (last_x, s->x + s->background_width) - 1));
   top_y = s->y;
   bottom_y = top_y + s->height - 1;
 
@@ -3371,7 +3458,7 @@ x_draw_image_relief (s)
   if (s->hl == DRAW_IMAGE_SUNKEN
       || s->hl == DRAW_IMAGE_RAISED)
     {
-      thick = toolbar_button_relief > 0 ? toolbar_button_relief : 3;
+      thick = tool_bar_button_relief > 0 ? tool_bar_button_relief : 3;
       raised_p = s->hl == DRAW_IMAGE_RAISED;
     }
   else
@@ -3657,7 +3744,7 @@ x_draw_glyph_string (s)
   /* If S draws into the background of its successor, draw the
      background of the successor first so that S can draw into it.
      This makes S->next use XDrawString instead of XDrawImageString.  */
-  if (s->next && s->right_overhang)
+  if (s->next && s->right_overhang && !s->for_overlaps_p)
     {
       xassert (s->next->img == NULL);
       x_set_glyph_string_gc (s->next);
@@ -3680,7 +3767,10 @@ x_draw_glyph_string (s)
       break;
 
     case CHAR_GLYPH:
-      x_draw_glyph_string_background (s, 0);
+      if (s->for_overlaps_p)
+       s->background_filled_p = 1;
+      else
+       x_draw_glyph_string_background (s, 0);
       x_draw_glyph_string_foreground (s);
       break;
 
@@ -3688,72 +3778,75 @@ x_draw_glyph_string (s)
       abort ();
     }
 
-  /* Draw underline.  */
-  if (s->face->underline_p)
+  if (!s->for_overlaps_p)
     {
-      unsigned long dy, h;
+      /* Draw underline.  */
+      if (s->face->underline_p)
+       {
+         unsigned long dy, h;
 
-      if (!XGetFontProperty (s->font, XA_UNDERLINE_THICKNESS, &h))
-       h = 1;
-      if (!XGetFontProperty (s->font, XA_UNDERLINE_POSITION, &dy))
-       dy = s->height - h;
+         if (!XGetFontProperty (s->font, XA_UNDERLINE_THICKNESS, &h))
+           h = 1;
+         if (!XGetFontProperty (s->font, XA_UNDERLINE_POSITION, &dy))
+           dy = s->height - h;
       
-      if (s->face->underline_defaulted_p)
-       XFillRectangle (s->display, s->window, s->gc, s->x, s->y + dy,
-                       s->width, h);
-      else
-       {
-         XGCValues xgcv;
-         XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
-         XSetForeground (s->display, s->gc, s->face->underline_color);
-         XFillRectangle (s->display, s->window, s->gc, s->x, s->y + dy,
-                         s->width, h);
-         XSetForeground (s->display, s->gc, xgcv.foreground);
+         if (s->face->underline_defaulted_p)
+           XFillRectangle (s->display, s->window, s->gc, s->x, s->y + dy,
+                           s->width, h);
+         else
+           {
+             XGCValues xgcv;
+             XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
+             XSetForeground (s->display, s->gc, s->face->underline_color);
+             XFillRectangle (s->display, s->window, s->gc, s->x, s->y + dy,
+                             s->width, h);
+             XSetForeground (s->display, s->gc, xgcv.foreground);
+           }
        }
-    }
-
-  /* Draw overline.  */
-  if (s->face->overline_p)
-    {
-      unsigned long dy = 0, h = 1;
 
-      if (s->face->overline_color_defaulted_p)
-       XFillRectangle (s->display, s->window, s->gc, s->x, s->y + dy,
-                       s->width, h);
-      else
+      /* Draw overline.  */
+      if (s->face->overline_p)
        {
-         XGCValues xgcv;
-         XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
-         XSetForeground (s->display, s->gc, s->face->overline_color);
-         XFillRectangle (s->display, s->window, s->gc, s->x, s->y + dy,
-                         s->width, h);
-         XSetForeground (s->display, s->gc, xgcv.foreground);
+         unsigned long dy = 0, h = 1;
+
+         if (s->face->overline_color_defaulted_p)
+           XFillRectangle (s->display, s->window, s->gc, s->x, s->y + dy,
+                           s->width, h);
+         else
+           {
+             XGCValues xgcv;
+             XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
+             XSetForeground (s->display, s->gc, s->face->overline_color);
+             XFillRectangle (s->display, s->window, s->gc, s->x, s->y + dy,
+                             s->width, h);
+             XSetForeground (s->display, s->gc, xgcv.foreground);
+           }
        }
-    }
   
-  /* Draw strike-through.  */
-  if (s->face->strike_through_p)
-    {
-      unsigned long h = 1;
-      unsigned long dy = (s->height - h) / 2;
-
-      if (s->face->strike_through_color_defaulted_p)
-       XFillRectangle (s->display, s->window, s->gc, s->x, s->y + dy,
-                       s->width, h);
-      else
+      /* Draw strike-through.  */
+      if (s->face->strike_through_p)
        {
-         XGCValues xgcv;
-         XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
-         XSetForeground (s->display, s->gc, s->face->strike_through_color);
-         XFillRectangle (s->display, s->window, s->gc, s->x, s->y + dy,
-                         s->width, h);
-         XSetForeground (s->display, s->gc, xgcv.foreground);
+         unsigned long h = 1;
+         unsigned long dy = (s->height - h) / 2;
+
+         if (s->face->strike_through_color_defaulted_p)
+           XFillRectangle (s->display, s->window, s->gc, s->x, s->y + dy,
+                           s->width, h);
+         else
+           {
+             XGCValues xgcv;
+             XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
+             XSetForeground (s->display, s->gc, s->face->strike_through_color);
+             XFillRectangle (s->display, s->window, s->gc, s->x, s->y + dy,
+                             s->width, h);
+             XSetForeground (s->display, s->gc, xgcv.foreground);
+           }
        }
-    }
   
-  /* Draw relief.  */
-  if (s->face->box != FACE_NO_BOX)
-    x_draw_glyph_string_box (s);
+      /* Draw relief.  */
+      if (s->face->box != FACE_NO_BOX)
+       x_draw_glyph_string_box (s);
+    }
   
   /* Reset clipping.  */
   XSetClipMask (s->display, s->gc, None);
@@ -3779,26 +3872,31 @@ struct work
 
 static void x_fill_composite_glyph_string P_ ((struct glyph_string *,
                                               int, struct work **,
-                                              struct work **));
+                                              struct work **, int));
 
 
 /* Load glyph string S with information from the top of *STACK for a
    composite character.  FACE_ID is the id of the face in which S is
    drawn.  *NEW is a pointer to a struct work not on the stack, that
    can be used if this function needs to push a new structure on the
-   stack.  If it uses it, *NEW is set to null.  */
+   stack.  If it uses it, *NEW is set to null.  OVERLAPS_P non-zero
+   means S should draw the foreground only, and use its lines physical
+   height for clipping.  */
 
 static void
-x_fill_composite_glyph_string (s, face_id, stack, new)
+x_fill_composite_glyph_string (s, face_id, stack, new, overlaps_p)
      struct glyph_string *s;
      int face_id;
      struct work **stack, **new;
+     int overlaps_p;
 {
   int i, c;
   struct work *work;
 
   xassert (s && *new && *stack);
 
+  s->for_overlaps_p = 1;
+  
   /* Pop the work stack.  */
   work = *stack;
   *stack = work->next;
@@ -3867,14 +3965,17 @@ x_fill_composite_glyph_string (s, face_id, stack, new)
 
 /* Load glyph string S with a sequence of non-composite characters.
    FACE_ID is the face id of the string.  START is the index of the
-   first glyph to consider, END is the index of the last + 1.  Value
-   is the index of the first glyph not in S.  */
+   first glyph to consider, END is the index of the last + 1.
+   OVERLAPS_P non-zero means S should draw the foreground only, and
+   use its lines physical height for clipping.
+
+   Value is the index of the first glyph not in S.  */
 
 static int
-x_fill_glyph_string (s, face_id, start, end)
+x_fill_glyph_string (s, face_id, start, end, overlaps_p)
      struct glyph_string *s;
      int face_id;
-     int start, end;
+     int start, end, overlaps_p;
 {
   struct glyph *glyph, *last;
   int voffset;
@@ -3884,6 +3985,7 @@ x_fill_glyph_string (s, face_id, start, end)
   xassert (s->nchars == 0);
   xassert (start >= 0 && end > start);
 
+  s->for_overlaps_p = overlaps_p,
   glyph = s->row->glyphs[s->area] + start;
   last = s->row->glyphs[s->area] + end;
   voffset = glyph->voffset;
@@ -3920,7 +4022,7 @@ x_fill_glyph_string (s, face_id, start, end)
 
   /* Adjust base line for subscript/superscript text.  */
   s->ybase += voffset;
-  
+
   xassert (s->face && s->face->gc);
   return glyph - s->row->glyphs[s->area];
 }
@@ -3991,8 +4093,8 @@ x_init_glyph_string (s, char2b, w, row, area, start, hl)
   s->height = row->height;
   s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
 
-  /* Display the internal border below the toolbar window.  */
-  if (s->w == XWINDOW (s->f->toolbar_window))
+  /* Display the internal border below the tool-bar window.  */
+  if (s->w == XWINDOW (s->f->tool_bar_window))
     s->y -= s->f->output_data.x->internal_border_width;
   
   s->ybase = s->y + row->ascent;
@@ -4038,8 +4140,9 @@ x_set_glyph_string_background_width (s, start, last_x)
    glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn.  LAST_X
    is the right-most x-position of the drawing area.  */
 
-#define BUILD_STRETCH_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL,    \
-                                HL, X, LAST_X)                             \
+/* SunOS 4 bundled cc, barfed on continuations in the arg lists here
+   and below -- keep them on one line.  */
+#define BUILD_STRETCH_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
      do                                                                            \
        {                                                                   \
         s = (struct glyph_string *) alloca (sizeof *s);                    \
@@ -4060,8 +4163,7 @@ x_set_glyph_string_background_width (s, start, last_x)
    glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn.  LAST_X
    is the right-most x-position of the drawing area.  */
 
-#define BUILD_IMAGE_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, \
-                                HL, X, LAST_X)                         \
+#define BUILD_IMAGE_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
      do                                                                        \
        {                                                               \
         s = (struct glyph_string *) alloca (sizeof *s);                \
@@ -4083,8 +4185,7 @@ x_set_glyph_string_background_width (s, start, last_x)
    is DRAW_CURSOR if a cursor has to be drawn.  LAST_X is the
    right-most x-position of the drawing area.  */
 
-#define BUILD_CHAR_GLYPH_STRINGS(W, ROW, AREA, START, END, HEAD, TAIL, HL, \
-                                X, LAST_X)                                \
+#define BUILD_CHAR_GLYPH_STRINGS(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
      do                                                                           \
        {                                                                  \
         int c, charset, face_id;                                          \
@@ -4134,7 +4235,7 @@ x_set_glyph_string_background_width (s, start, last_x)
                 if (new == NULL)                                          \
                   new = (struct work *) alloca (sizeof *new);             \
                 x_fill_composite_glyph_string (s, face_id, &stack,        \
-                                               &new);                     \
+                                               &new, OVERLAPS_P);         \
               }                                                           \
                                                                           \
             ++START;                                                      \
@@ -4148,7 +4249,8 @@ x_set_glyph_string_background_width (s, start, last_x)
             x_append_glyph_string (&HEAD, &TAIL, s);                      \
             s->charset = charset;                                         \
             s->x = (X);                                                   \
-            START = x_fill_glyph_string (s, face_id, START, END);         \
+            START = x_fill_glyph_string (s, face_id, START, END,          \
+                                          OVERLAPS_P);                    \
           }                                                               \
        }                                                                  \
      while (0)
@@ -4164,8 +4266,7 @@ x_set_glyph_string_background_width (s, start, last_x)
    to allocate glyph strings (because x_draw_glyphs can be called
    asynchronously).  */
 
-#define BUILD_GLYPH_STRINGS(W, ROW, AREA, START, END, HEAD, TAIL, HL,     \
-                           X, LAST_X)                                     \
+#define BUILD_GLYPH_STRINGS(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
      do                                                                           \
        {                                                                  \
         HEAD = TAIL = NULL;                                               \
@@ -4176,7 +4277,8 @@ x_set_glyph_string_background_width (s, start, last_x)
               {                                                           \
               case CHAR_GLYPH:                                            \
                  BUILD_CHAR_GLYPH_STRINGS (W, ROW, AREA, START, END, HEAD, \
-                                          TAIL, HL, X, LAST_X);           \
+                                          TAIL, HL, X, LAST_X,            \
+                                           OVERLAPS_P);                           \
                 break;                                                    \
                                                                           \
               case STRETCH_GLYPH:                                         \
@@ -4217,10 +4319,14 @@ x_set_glyph_string_background_width (s, start, last_x)
    return in *REAL_END the real end position for display.  This can be
    different from END in case overlapping glyphs must be displayed.
 
+   If OVERLAPS_P is non-zero, draw only the foreground of characters
+   and clip to the physical height of ROW.
+
    Value is the x-position reached, relative to AREA of W.  */
      
 static int
-x_draw_glyphs (w, x, row, area, start, end, hl, real_start, real_end)
+x_draw_glyphs (w, x, row, area, start, end, hl, real_start, real_end,
+              overlaps_p)
      struct window *w;
      int x;
      struct glyph_row *row;
@@ -4228,6 +4334,7 @@ x_draw_glyphs (w, x, row, area, start, end, hl, real_start, real_end)
      int start, end;
      enum draw_glyphs_face hl;
      int *real_start, *real_end;
+     int overlaps_p;
 {
   struct glyph_string *head, *tail;
   struct glyph_string *s;
@@ -4250,7 +4357,7 @@ x_draw_glyphs (w, x, row, area, start, end, hl, real_start, real_end)
       /* X is relative to the left edge of W, without scroll bars
         or flag areas.  */
       struct frame *f = XFRAME (w->frame);
-      int width = FRAME_FLAGS_AREA_WIDTH (f);
+      /* int width = FRAME_FLAGS_AREA_WIDTH (f);  */
       int window_left_x = WINDOW_LEFT_MARGIN (w) * CANON_X_UNIT (f);
 
       x += window_left_x;
@@ -4259,20 +4366,15 @@ x_draw_glyphs (w, x, row, area, start, end, hl, real_start, real_end)
 
       if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
        {
-         width = FRAME_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f);
+         int width = FRAME_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f);
          if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f))
            last_x += width;
          else
            x -= width;
        }
 
-      /* If row should extend over internal borders, adjust x and
-         width accordingly.  */
-      if (!row->internal_border_p)
-       {
-         x += FRAME_INTERNAL_BORDER_WIDTH (f);
-         last_x -= FRAME_INTERNAL_BORDER_WIDTH (f);
-       }
+      x += FRAME_INTERNAL_BORDER_WIDTH (f);
+      last_x -= FRAME_INTERNAL_BORDER_WIDTH (f);
     }
   else
     {
@@ -4286,7 +4388,8 @@ x_draw_glyphs (w, x, row, area, start, end, hl, real_start, real_end)
      BUILD_GLYPH_STRINGS will modify its start parameter.  That's
      the reason we use a separate variable `i'.  */
   i = start;
-  BUILD_GLYPH_STRINGS (w, row, area, i, end, head, tail, hl, x, last_x);
+  BUILD_GLYPH_STRINGS (w, row, area, i, end, head, tail, hl, x, last_x,
+                      overlaps_p);
   if (tail)
     x_reached = tail->x + tail->background_width;
   else
@@ -4295,7 +4398,7 @@ x_draw_glyphs (w, x, row, area, start, end, hl, real_start, real_end)
   /* If there are any glyphs with lbearing < 0 or rbearing > width in
      the row, redraw some glyphs in front or following the glyph
      strings built above.  */
-  if (row->contains_overlapping_glyphs_p)
+  if (!overlaps_p && row->contains_overlapping_glyphs_p)
     {
       int dummy_x = 0;
       struct glyph_string *h, *t;
@@ -4314,7 +4417,8 @@ x_draw_glyphs (w, x, row, area, start, end, hl, real_start, real_end)
        {
          j = i;
          BUILD_GLYPH_STRINGS (w, row, area, j, start, h, t,
-                              DRAW_NORMAL_TEXT, dummy_x, last_x);
+                              DRAW_NORMAL_TEXT, dummy_x, last_x,
+                              overlaps_p);
          start = i;
          if (real_start)
            *real_start = start;
@@ -4333,7 +4437,8 @@ x_draw_glyphs (w, x, row, area, start, end, hl, real_start, real_end)
       if (i >= 0)
        {
          BUILD_GLYPH_STRINGS (w, row, area, i, start, h, t,
-                              DRAW_NORMAL_TEXT, dummy_x, last_x);
+                              DRAW_NORMAL_TEXT, dummy_x, last_x,
+                              overlaps_p);
          for (s = h; s; s = s->next)
            s->background_filled_p = 1;
          if (real_start)
@@ -4350,7 +4455,8 @@ x_draw_glyphs (w, x, row, area, start, end, hl, real_start, real_end)
       if (i >= 0)
        {
          BUILD_GLYPH_STRINGS (w, row, area, end, i, h, t,
-                              DRAW_NORMAL_TEXT, x, last_x);
+                              DRAW_NORMAL_TEXT, x, last_x,
+                              overlaps_p);
          x_compute_overhangs_and_x (h, tail->x + tail->width, 0);
          x_append_glyph_string_lists (&head, &tail, h, t);
          if (real_end)
@@ -4366,7 +4472,8 @@ x_draw_glyphs (w, x, row, area, start, end, hl, real_start, real_end)
       if (i >= 0)
        {
          BUILD_GLYPH_STRINGS (w, row, area, end, i, h, t,
-                              DRAW_NORMAL_TEXT, x, last_x);
+                              DRAW_NORMAL_TEXT, x, last_x,
+                              overlaps_p);
          for (s = h; s; s = s->next)
            s->background_filled_p = 1;
          x_compute_overhangs_and_x (h, tail->x + tail->width, 0);
@@ -4394,6 +4501,56 @@ x_draw_glyphs (w, x, row, area, start, end, hl, real_start, real_end)
 }
 
 
+/* Fix the display of area AREA of overlapping row ROW in window W.  */
+
+static void
+x_fix_overlapping_area (w, row, area)
+     struct window *w;
+     struct glyph_row *row;
+     enum glyph_row_area area;
+{
+  int i, x;
+  
+  BLOCK_INPUT;
+  
+  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));
+
+  for (i = 0; i < row->used[area];)
+    {
+      if (row->glyphs[area][i].overlaps_vertically_p)
+       {
+         int start = i, start_x = x;
+
+         do
+           {
+             x += row->glyphs[area][i].pixel_width;
+             ++i;
+           }
+         while (i < row->used[area]
+                && row->glyphs[area][i].overlaps_vertically_p);
+
+         x_draw_glyphs (w, start_x, row, area, start, i,
+                        (row->inverse_p
+                         ? DRAW_INVERSE_VIDEO : DRAW_NORMAL_TEXT),
+                        NULL, NULL, 1);
+       }
+      else
+       {
+         x += row->glyphs[area][i].pixel_width;
+         ++i;
+       }
+    }
+  
+  UNBLOCK_INPUT;
+}
+
+
 /* Output LEN glyphs starting at START at the nominal cursor position.
    Advance the nominal cursor over the text.  The global variable
    updated_window contains the window being updated, updated_row is
@@ -4418,7 +4575,7 @@ x_write_glyphs (start, len)
                     hpos, hpos + len,
                     (updated_row->inverse_p
                      ? DRAW_INVERSE_VIDEO : DRAW_NORMAL_TEXT),
-                    &real_start, &real_end);
+                    &real_start, &real_end, 0);
 
   /* If we drew over the cursor, note that it is not visible any more.  */
   note_overwritten_text_cursor (updated_window, real_start,
@@ -4477,7 +4634,7 @@ x_insert_glyphs (start, len)
   /* Write the glyphs.  */
   hpos = start - row->glyphs[updated_area];
   x_draw_glyphs (w, output_cursor.x, row, updated_area, hpos, hpos + len,
-                DRAW_NORMAL_TEXT, &real_start, &real_end);
+                DRAW_NORMAL_TEXT, &real_start, &real_end, 0);
   note_overwritten_text_cursor (w, real_start, real_end - real_start);
   
   /* Advance the output cursor.  */
@@ -4557,7 +4714,7 @@ x_clear_end_of_line (to_x)
       to_x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, updated_area, to_x);
     }
   
-  min_y = WINDOW_DISPLAY_TOP_LINE_HEIGHT (w);
+  min_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
   from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
   to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
   
@@ -4574,7 +4731,7 @@ x_clear_end_of_line (to_x)
 
 
 /* Clear entire frame.  If updating_frame is non-null, clear that
-   frame.  Otherwise clear selected_frame.  */
+   frame.  Otherwise clear the selected frame.  */
 
 static void
 x_clear_frame ()
@@ -4584,7 +4741,7 @@ x_clear_frame ()
   if (updating_frame)
     f = updating_frame;
   else
-    f = selected_frame;
+    f = SELECTED_FRAME ();
 
   /* Clearing the frame will erase any cursor, so mark them all as no
      longer visible.  */
@@ -4705,7 +4862,7 @@ XTflash (f)
          XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
                          flash_left,
                          (FRAME_INTERNAL_BORDER_WIDTH (f)
-                          + FRAME_TOOLBAR_LINES (f) * CANON_Y_UNIT (f)),
+                          + FRAME_TOOL_BAR_LINES (f) * CANON_Y_UNIT (f)),
                          width, flash_height);
          XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
                          flash_left,
@@ -4754,7 +4911,7 @@ XTflash (f)
          XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
                          flash_left,
                          (FRAME_INTERNAL_BORDER_WIDTH (f)
-                          + FRAME_TOOLBAR_LINES (f) * CANON_Y_UNIT (f)),
+                          + FRAME_TOOL_BAR_LINES (f) * CANON_Y_UNIT (f)),
                          width, flash_height);
          XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
                          flash_left,
@@ -4781,24 +4938,24 @@ XTflash (f)
 
 /* Make audible bell.  */
 
-#define XRINGBELL XBell (FRAME_X_DISPLAY (selected_frame), 0)
-
 void
 XTring_bell ()
 {
-  if (FRAME_X_DISPLAY (selected_frame) == 0)
-    return;
-
+  struct frame *f = SELECTED_FRAME ();
+  
+  if (FRAME_X_DISPLAY (f))
+    {
 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
-  if (visible_bell)
-    XTflash (selected_frame);
-  else
+      if (visible_bell)
+       XTflash (f);
+      else
 #endif
-    {
-      BLOCK_INPUT;
-      XRINGBELL;
-      XFlush (FRAME_X_DISPLAY (selected_frame));
-      UNBLOCK_INPUT;
+       {
+         BLOCK_INPUT;
+         XBell (FRAME_X_DISPLAY (f), 0);
+         XFlush (FRAME_X_DISPLAY (f));
+         UNBLOCK_INPUT;
+       }
     }
 }
 
@@ -4846,8 +5003,8 @@ x_scroll_run (w, run)
      without mode lines.  Include in this box the flags areas to the
      left and right of W.  */
   window_box (w, -1, &x, &y, &width, &height);
-  width += 2 * FRAME_X_FLAGS_AREA_WIDTH (f);
-  x -= FRAME_X_FLAGS_AREA_WIDTH (f);
+  width += FRAME_X_FLAGS_AREA_WIDTH (f);
+  x -= FRAME_X_LEFT_FLAGS_AREA_WIDTH (f);
 
   from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y);
   to_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->desired_y);
@@ -4942,9 +5099,9 @@ expose_frame (f, x, y, w, h)
   TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
   expose_window_tree (XWINDOW (f->root_window), &r);
 
-  if (WINDOWP (f->toolbar_window))
+  if (WINDOWP (f->tool_bar_window))
     {
-      struct window *w = XWINDOW (f->toolbar_window);
+      struct window *w = XWINDOW (f->tool_bar_window);
       XRectangle window_rect;
       XRectangle intersection_rect;
       int window_x, window_y, window_width, window_height;
@@ -5008,12 +5165,12 @@ expose_window_tree (w, r)
                      &window_height);
          window_rect.x
            = (window_x
-              - FRAME_X_FLAGS_AREA_WIDTH (f)
-              - FRAME_LEFT_SCROLL_BAR_WIDTH (f) * CANON_Y_UNIT (f));
+              - FRAME_X_LEFT_FLAGS_AREA_WIDTH (f)
+              - FRAME_LEFT_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f));
          window_rect.y = window_y;
          window_rect.width
            = (window_width
-              + 2 * FRAME_X_FLAGS_AREA_WIDTH (f)
+              + FRAME_X_FLAGS_AREA_WIDTH (f)
               + FRAME_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f));
          window_rect.height
            = window_height + CURRENT_MODE_LINE_HEIGHT (w);
@@ -5054,31 +5211,40 @@ expose_area (w, row, r, area)
     x = (window_box_width (w, LEFT_MARGIN_AREA)
         + window_box_width (w, TEXT_AREA));
 
-  /* Find the first glyph that must be redrawn.  */
-  while (first < end
-        && x + first->pixel_width < r->x)
-    {
-      x += first->pixel_width;
-      ++first;
-    }
-  
-  /* Find the last one.  */
-  last = first;
-  first_x = x;
-  while (last < end
-        && x < r->x + r->width)
+  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,
+                  0, row->used[area],
+                  row->inverse_p ? DRAW_INVERSE_VIDEO : DRAW_NORMAL_TEXT,
+                  NULL, NULL, 0);
+  else
     {
-      x += last->pixel_width;
-      ++last;
-    }
+      /* Find the first glyph that must be redrawn.  */
+      while (first < end
+            && x + first->pixel_width < r->x)
+       {
+         x += first->pixel_width;
+         ++first;
+       }
       
-  /* Repaint.  */
-  if (last > first)
-    x_draw_glyphs (w, first_x, row, area,
-                  first - row->glyphs[area],
-                  last - row->glyphs[area],
-                  row->inverse_p ? DRAW_INVERSE_VIDEO : DRAW_NORMAL_TEXT,
-                  NULL, NULL);
+      /* Find the last one.  */
+      last = first;
+      first_x = x;
+      while (last < end
+            && x < r->x + r->width)
+       {
+         x += last->pixel_width;
+         ++last;
+       }
+      
+      /* Repaint.  */
+      if (last > first)
+       x_draw_glyphs (w, first_x, row, area,
+                      first - row->glyphs[area],
+                      last - row->glyphs[area],
+                      row->inverse_p ? DRAW_INVERSE_VIDEO : DRAW_NORMAL_TEXT,
+                      NULL, NULL, 0);
+    }
 }
       
 
@@ -5096,7 +5262,7 @@ expose_line (w, row, r)
   if (row->mode_line_p || w->pseudo_window_p)
     x_draw_glyphs (w, 0, row, TEXT_AREA, 0, row->used[TEXT_AREA],
                   row->inverse_p ? DRAW_INVERSE_VIDEO : DRAW_NORMAL_TEXT,
-                  NULL, NULL);
+                  NULL, NULL, 0);
   else
     {
       if (row->used[LEFT_MARGIN_AREA])
@@ -5147,6 +5313,13 @@ expose_window (w, r)
   int yb = window_text_bottom_y (w);
   int cursor_cleared_p;
 
+  /* If window is not yet fully initialized, do nothing.  This can
+     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)
+    return;
+
   TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
          r->x, r->y, r->width, r->height));
 
@@ -5866,7 +6039,7 @@ note_mode_line_highlight (w, x, mode_line_p)
   if (mode_line_p)
     row = MATRIX_MODE_LINE_ROW (w->current_matrix);
   else
-    row = MATRIX_TOP_LINE_ROW (w->current_matrix);
+    row = MATRIX_HEADER_LINE_ROW (w->current_matrix);
   
   if (row->enabled_p)
     {
@@ -5878,7 +6051,7 @@ note_mode_line_highlight (w, x, mode_line_p)
       glyph = row->glyphs[TEXT_AREA];
       end = glyph + row->used[TEXT_AREA];
       x0 = - (FRAME_LEFT_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f)
-             + FRAME_X_FLAGS_AREA_WIDTH (f));
+             + FRAME_X_LEFT_FLAGS_AREA_WIDTH (f));
       while (glyph < end
             && x >= x0 + glyph->pixel_width)
        {
@@ -5964,11 +6137,11 @@ note_mouse_highlight (f, x, y)
   w = XWINDOW (window);
   frame_to_window_pixel_xy (w, &x, &y);
 
-  /* Handle toolbar window differently since it doesn't display a
+  /* Handle tool-bar window differently since it doesn't display a
      buffer.  */
-  if (EQ (window, f->toolbar_window))
+  if (EQ (window, f->tool_bar_window))
     {
-      note_toolbar_highlight (f, x, y);
+      note_tool_bar_highlight (f, x, y);
       return;
     }
 
@@ -6191,37 +6364,37 @@ redo_mouse_highlight ()
 
 \f
 /***********************************************************************
-                              Toolbars
+                              Tool-bars
  ***********************************************************************/
 
-static int x_toolbar_item P_ ((struct frame *, int, int,
-                              struct glyph **, int *, int *, int *));
+static int x_tool_bar_item P_ ((struct frame *, int, int,
+                               struct glyph **, int *, int *, int *));
 
-/* Toolbar item index of the item on which a mouse button was pressed
+/* Tool-bar item index of the item on which a mouse button was pressed
    or -1.  */
 
-static int last_toolbar_item;
+static int last_tool_bar_item;
 
 
-/* Get information about the toolbar item at position X/Y on frame F.
-   Return in *GLYPH a pointer to the glyph of the toolbar item in
-   the current matrix of the toolbar window of F, or NULL if not
-   on a toolbar item.  Return in *PROP_IDX the index of the toolbar
-   item in F->current_toolbar_items.  Value is
+/* Get information about the tool-bar item at position X/Y on frame F.
+   Return in *GLYPH a pointer to the glyph of the tool-bar item in
+   the current matrix of the tool-bar window of F, or NULL if not
+   on a tool-bar item.  Return in *PROP_IDX the index of the tool-bar
+   item in F->current_tool_bar_items.  Value is
 
-   -1  if X/Y is not on a toolbar item
+   -1  if X/Y is not on a tool-bar item
    0   if X/Y is on the same item that was highlighted before.
    1   otherwise.  */
 
 static int
-x_toolbar_item (f, x, y, glyph, hpos, vpos, prop_idx)
+x_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
      struct frame *f;
      int x, y;
      struct glyph **glyph;
      int *hpos, *vpos, *prop_idx;
 {
   struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
-  struct window *w = XWINDOW (f->toolbar_window);
+  struct window *w = XWINDOW (f->tool_bar_window);
   int area;
 
   /* Find the glyph under X/Y.  */
@@ -6229,13 +6402,13 @@ x_toolbar_item (f, x, y, glyph, hpos, vpos, prop_idx)
   if (*glyph == NULL)
     return -1;
 
-  /* Get the start of this toolbar item's properties in
-     f->current_toolbar_items.  */
-  if (!toolbar_item_info (f, *glyph, prop_idx))
+  /* Get the start of this tool-bar item's properties in
+     f->current_tool_bar_items.  */
+  if (!tool_bar_item_info (f, *glyph, prop_idx))
     return -1;
 
   /* Is mouse on the highlighted item?  */
-  if (EQ (f->toolbar_window, dpyinfo->mouse_face_window)
+  if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
       && *vpos >= dpyinfo->mouse_face_beg_row
       && *vpos <= dpyinfo->mouse_face_end_row
       && (*vpos > dpyinfo->mouse_face_beg_row
@@ -6249,31 +6422,31 @@ x_toolbar_item (f, x, y, glyph, hpos, vpos, prop_idx)
 }
 
 
-/* Handle mouse button event on the toolbar of frame F, at
+/* Handle mouse button event on the tool-bar of frame F, at
    frame-relative coordinates X/Y.  EVENT_TYPE is either ButtionPress
    or ButtonRelase.  */
 
 static void
-x_handle_toolbar_click (f, button_event)
+x_handle_tool_bar_click (f, button_event)
      struct frame *f;
      XButtonEvent *button_event;
 {
   struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
-  struct window *w = XWINDOW (f->toolbar_window);
+  struct window *w = XWINDOW (f->tool_bar_window);
   int hpos, vpos, prop_idx;
   struct glyph *glyph;
   Lisp_Object enabled_p;
   int x = button_event->x;
   int y = button_event->y;
   
-  /* If not on the highlighted toolbar item, return.  */
+  /* If not on the highlighted tool-bar item, return.  */
   frame_to_window_pixel_xy (w, &x, &y);
-  if (x_toolbar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
+  if (x_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
     return;
 
   /* If item is disabled, do nothing.  */
-  enabled_p = (XVECTOR (f->current_toolbar_items)
-              ->contents[prop_idx + TOOLBAR_ITEM_ENABLED_P]);
+  enabled_p = (XVECTOR (f->current_tool_bar_items)
+              ->contents[prop_idx + TOOL_BAR_ITEM_ENABLED_P]);
   if (NILP (enabled_p))
     return;
   
@@ -6282,7 +6455,7 @@ x_handle_toolbar_click (f, button_event)
       /* Show item in pressed state.  */
       show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
       dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
-      last_toolbar_item = prop_idx;
+      last_tool_bar_item = prop_idx;
     }
   else
     {
@@ -6293,44 +6466,44 @@ x_handle_toolbar_click (f, button_event)
       show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
       dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
 
-      key = (XVECTOR (f->current_toolbar_items)
-            ->contents[prop_idx + TOOLBAR_ITEM_KEY]);
+      key = (XVECTOR (f->current_tool_bar_items)
+            ->contents[prop_idx + TOOL_BAR_ITEM_KEY]);
 
       XSETFRAME (frame, f);
-      event.kind = TOOLBAR_EVENT;
-      event.frame_or_window = Fcons (frame, Fcons (Qtoolbar, Qnil));
+      event.kind = TOOL_BAR_EVENT;
+      event.frame_or_window = Fcons (frame, Fcons (Qtool_bar, Qnil));
       kbd_buffer_store_event (&event);
 
-      event.kind = TOOLBAR_EVENT;
+      event.kind = TOOL_BAR_EVENT;
       event.frame_or_window = Fcons (frame, key);
       event.modifiers = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f),
                                                button_event->state);
       kbd_buffer_store_event (&event);
-      last_toolbar_item = -1;
+      last_tool_bar_item = -1;
     }
 }
 
 
-/* Possibly highlight a toolbar item on frame F when mouse moves to
-   toolbar window-relative coordinates X/Y.  Called from
+/* Possibly highlight a tool-bar item on frame F when mouse moves to
+   tool-bar window-relative coordinates X/Y.  Called from
    note_mouse_highlight.  */
 
 static void
-note_toolbar_highlight (f, x, y)
+note_tool_bar_highlight (f, x, y)
      struct frame *f;
      int x, y;
 {
-  Lisp_Object window = f->toolbar_window;
+  Lisp_Object window = f->tool_bar_window;
   struct window *w = XWINDOW (window);
   struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
   int hpos, vpos;
   struct glyph *glyph;
   struct glyph_row *row;
-  int i, j, area;
+  int i;
   Lisp_Object enabled_p;
   int prop_idx;
   enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
-  int on_highlight_p, mouse_down_p, rc;
+  int mouse_down_p, rc;
 
   /* Function note_mouse_highlight is called with negative x(y
      values when mouse moves outside of the frame.  */
@@ -6340,33 +6513,33 @@ note_toolbar_highlight (f, x, y)
       return;
     }
 
-  rc = x_toolbar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
+  rc = x_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
   if (rc < 0)
     {
-      /* Not on toolbar item.  */
+      /* Not on tool-bar item.  */
       clear_mouse_face (dpyinfo);
       return;
     }
   else if (rc == 0)
-    /* On same toolbar item as before.  */
+    /* On same tool-bar item as before.  */
     goto set_help_echo;
 
   clear_mouse_face (dpyinfo);
   
-  /* Mouse is down, but on different toolbar item?  */
+  /* Mouse is down, but on different tool-bar item?  */
   mouse_down_p = (dpyinfo->grabbed
                  && f == last_mouse_frame
                  && FRAME_LIVE_P (f));
   if (mouse_down_p
-      && last_toolbar_item != prop_idx)
+      && last_tool_bar_item != prop_idx)
     return;
 
   dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
   draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
   
-  /* If toolbar item is not enabled, don't highlight it.  */
-  enabled_p = (XVECTOR (f->current_toolbar_items)
-              ->contents[prop_idx + TOOLBAR_ITEM_ENABLED_P]);
+  /* If tool-bar item is not enabled, don't highlight it.  */
+  enabled_p = (XVECTOR (f->current_tool_bar_items)
+              ->contents[prop_idx + TOOL_BAR_ITEM_ENABLED_P]);
   if (!NILP (enabled_p))
     {
       /* Compute the x-position of the glyph.  In front and past the
@@ -6387,7 +6560,7 @@ note_toolbar_highlight (f, x, y)
       dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
       dpyinfo->mouse_face_end_y = row->y;
       dpyinfo->mouse_face_window = window;
-      dpyinfo->mouse_face_face_id = TOOLBAR_FACE_ID;
+      dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
       
       /* Display it as active.  */
       show_mouse_face (dpyinfo, draw);
@@ -6396,13 +6569,13 @@ note_toolbar_highlight (f, x, y)
       
  set_help_echo:
   
-  /* Set help_echo to a help string.to display for this toolbar item.
+  /* Set help_echo to a help string.to display for this tool-bar item.
      XTread_socket does the rest.  */
-  help_echo = (XVECTOR (f->current_toolbar_items)
-              ->contents[prop_idx + TOOLBAR_ITEM_HELP]);
+  help_echo = (XVECTOR (f->current_tool_bar_items)
+              ->contents[prop_idx + TOOL_BAR_ITEM_HELP]);
   if (!STRINGP (help_echo))
-    help_echo = (XVECTOR (f->current_toolbar_items)
-                ->contents[prop_idx + TOOLBAR_ITEM_CAPTION]);
+    help_echo = (XVECTOR (f->current_tool_bar_items)
+                ->contents[prop_idx + TOOL_BAR_ITEM_CAPTION]);
 }
 
 
@@ -6569,8 +6742,8 @@ show_mouse_face (dpyinfo, draw)
        }
 
       if (end_hpos > start_hpos)
-       x_draw_glyphs (w, start_x, row, updated_area
-                      start_hpos, end_hpos, draw, NULL, NULL);
+       x_draw_glyphs (w, start_x, row, TEXT_AREA
+                      start_hpos, end_hpos, draw, NULL, NULL, 0);
     }
 
   /* If we turned the cursor off, turn it back on.  */
@@ -6798,7 +6971,7 @@ XTmouse_position (fp, insist, bar_window, part, x, y, time)
          }
 
        if (f1 == 0 && insist > 0)
-         f1 = selected_frame;
+         f1 = SELECTED_FRAME ();
 
        if (f1)
          {
@@ -6881,11 +7054,11 @@ x_window_to_scroll_bar (window_id)
 
   for (tail = Vframe_list;
        XGCTYPE (tail) == Lisp_Cons;
-       tail = XCONS (tail)->cdr)
+       tail = XCDR (tail))
     {
       Lisp_Object frame, bar, condemned;
 
-      frame = XCONS (tail)->car;
+      frame = XCAR (tail);
       /* All elements of Vframe_list should be frames.  */
       if (! GC_FRAMEP (frame))
        abort ();
@@ -6936,9 +7109,20 @@ static Lisp_Object window_being_scrolled;
 
 static int last_scroll_bar_part;
 
+/* Whether this is an Xaw with arrow-scrollbars.  This should imply
+   that movements of 1/20 of the screen size are mapped to up/down.  */
+
+static Boolean xaw3d_arrow_scroll;
+
+/* Whether the drag scrolling maintains the mouse at the top of the
+   thumb.  If not, resizing the thumb needs to be done more carefully
+   to avoid jerkyness.  */
+
+static Boolean xaw3d_pick_top;
+
 
 /* Action hook installed via XtAppAddActionHook when toolkit scroll
-   bars are used..  The hoos is responsible for detecting when
+   bars are used..  The hook is responsible for detecting when
    the user ends an interaction with the scroll bar, and generates
    a `end-scroll' scroll_bar_click' event if so.  */
 
@@ -6958,12 +7142,10 @@ xt_action_hook (widget, client_data, action_name, event, params,
 #ifdef USE_MOTIF
   scroll_bar_p = XmIsScrollBar (widget);
   end_action = "Release";
-#elif defined HAVE_XAW3D
+#else /* !USE_MOTIF i.e. use Xaw */
   scroll_bar_p = XtIsSubclass (widget, scrollbarWidgetClass);
   end_action = "EndScroll";
-#else
-#error unknown scroll bar toolkit
-#endif /* HAVE_XAW3D */
+#endif /* USE_MOTIF */
 
   /* Although LessTif uses XtTimeouts like Xaw3d, the timer hack to
      let Xt timeouts be processed doesn't work.  */
@@ -7148,40 +7330,39 @@ xm_scroll_callback (widget, client_data, call_data)
 }
 
 
-#else /* not USE_MOTIF, i.e. XAW3D.  */
+#else /* !USE_MOTIF, i.e. Xaw.  */
 
 
-/* Xaw3d scroll bar callback.  Invoked when the thumb is dragged.
+/* Xaw scroll bar callback.  Invoked when the thumb is dragged.
    WIDGET is the scroll bar widget.  CLIENT_DATA is a pointer to the
    scroll bar struct.  CALL_DATA is a pointer to a float saying where
    the thumb is.  */
 
 static void
-xaw3d_jump_callback (widget, client_data, call_data)
+xaw_jump_callback (widget, client_data, call_data)
      Widget widget;
      XtPointer client_data, call_data;
 {
   struct scroll_bar *bar = (struct scroll_bar *) client_data;
   float top = *(float *) call_data;
   float shown;
-  int whole, portion;
-  int dragging_down_p, part;
-  double epsilon = 0.01;
+  int whole, portion, height;
+  int part;
 
   /* Get the size of the thumb, a value between 0 and 1.  */
   BLOCK_INPUT;
-  XtVaGetValues (widget, XtNshown, &shown, NULL);
+  XtVaGetValues (widget, XtNshown, &shown, XtNheight, &height, NULL);
   UNBLOCK_INPUT;
 
   whole = 10000000;
   portion = shown < 1 ? top * whole : 0;
-  dragging_down_p = (INTEGERP (bar->dragging)
-                    && XINT (bar->dragging) < portion);
 
-  if (shown < 1
-      && (abs (top + shown - 1) < epsilon
-         || (dragging_down_p
-             && last_scroll_bar_part == scroll_bar_down_arrow)))
+  if (shown < 1 && (abs (top + shown - 1) < 1.0/height))
+    /* Some derivatives of Xaw refuse to shrink the thumb when you reach
+       the bottom, so we force the scrolling whenever we see that we're
+       too close to the bottom (in x_set_toolkit_scroll_bar_thumb
+       we try to ensure that we always stay two pixels away from the
+       bottom).  */
     part = scroll_bar_down_arrow;
   else
     part = scroll_bar_handle;
@@ -7193,8 +7374,8 @@ xaw3d_jump_callback (widget, client_data, call_data)
 }
 
 
-/* Xaw3d scroll bar callback.  Invoked for incremental scrolling.,
-   i.e. line or page up or down.  WIDGET is the Xaw3d scroll bar
+/* Xaw scroll bar callback.  Invoked for incremental scrolling.,
+   i.e. line or page up or down.  WIDGET is the Xaw scroll bar
    widget.  CLIENT_DATA is a pointer to the scroll_bar structure for
    the scroll bar.  CALL_DATA is an integer specifying the action that
    has taken place.  It's magnitude is in the range 0..height of the
@@ -7202,7 +7383,7 @@ xaw3d_jump_callback (widget, client_data, call_data)
    Values < height of scroll bar mean line-wise movement.  */
 
 static void
-xaw3d_scroll_callback (widget, client_data, call_data)
+xaw_scroll_callback (widget, client_data, call_data)
      Widget widget;
      XtPointer client_data, call_data;
 {
@@ -7216,25 +7397,20 @@ xaw3d_scroll_callback (widget, client_data, call_data)
   XtVaGetValues (widget, XtNheight, &height, NULL);
   UNBLOCK_INPUT;
 
-  if (position < 0)
-    {
-      if (abs (position) < height)
-       part = scroll_bar_up_arrow;
-      else
-       part = scroll_bar_above_handle;
-    }
+  if (abs (position) >= height)
+    part = (position < 0) ? scroll_bar_above_handle : scroll_bar_below_handle;
+
+  /* If Xaw3d was compiled with ARROW_SCROLLBAR,
+     it maps line-movement to call_data = max(5, height/20).  */
+  else if (xaw3d_arrow_scroll && abs (position) <= max (5, height / 20))
+    part = (position < 0) ? scroll_bar_up_arrow : scroll_bar_down_arrow;
   else
-    {
-      if (abs (position) < height)
-       part = scroll_bar_down_arrow;
-      else
-       part = scroll_bar_below_handle;
-    }
+    part = scroll_bar_move_ratio;
 
   window_being_scrolled = bar->window;
   bar->dragging = Qnil;
   last_scroll_bar_part = part;
-  x_send_scroll_bar_event (bar->window, part, 0, 0);
+  x_send_scroll_bar_event (bar->window, part, position, height);
 }
 
 
@@ -7317,7 +7493,7 @@ x_create_toolkit_scroll_bar (f, bar)
   XDefineCursor (XtDisplay (widget), XtWindow (widget),
                 f->output_data.x->nontext_cursor);
   
-#elif defined HAVE_XAW3D
+#else /* !USE_MOTIF i.e. use Xaw */
   
   /* Set resources.  Create the widget.  The background of the
      Xaw3d scroll bar widget is a little bit light for my taste.
@@ -7325,8 +7501,9 @@ x_create_toolkit_scroll_bar (f, bar)
      to their taste with `emacs*verticalScrollBar.background: xxx'.  */
   XtSetArg (av[ac], XtNmappedWhenManaged, False); ++ac;
   XtSetArg (av[ac], XtNorientation, XtorientVertical); ++ac;
-  XtSetArg (av[ac], XtNcursorName, "left_ptr"); ++ac;
-  XtSetArg (av[ac], XtNbeNiceToColormap, True); ++ac;
+  /* For smoother scrolling with Xaw3d   -sm */
+  /* XtSetArg (av[ac], XtNpickTop, True); ++ac; */
+  /* XtSetArg (av[ac], XtNbeNiceToColormap, True); ++ac; */
   
   pixel = f->output_data.x->scroll_bar_foreground_pixel;
   if (pixel != -1)
@@ -7344,16 +7521,29 @@ x_create_toolkit_scroll_bar (f, bar)
   
   widget = XtCreateWidget (scroll_bar_name, scrollbarWidgetClass,
                           f->output_data.x->edit_widget, av, ac);
+
+  {
+    char *initial = "";
+    char *val = initial;
+    XtVaGetValues (widget, XtNscrollVCursor, (XtPointer) &val,
+                  XtNpickTop, (XtPointer) &xaw3d_pick_top, NULL);
+    if (val == initial)
+      {        /* ARROW_SCROLL */
+       xaw3d_arrow_scroll = True;
+       /* Isn't that just a personal preference ?   -sm */
+       XtVaSetValues (widget, XtNcursorName, "top_left_arrow", NULL);
+      }
+  }
   
   /* Define callbacks.  */
-  XtAddCallback (widget, XtNjumpProc, xaw3d_jump_callback, (XtPointer) bar);
-  XtAddCallback (widget, XtNscrollProc, xaw3d_scroll_callback,
+  XtAddCallback (widget, XtNjumpProc, xaw_jump_callback, (XtPointer) bar);
+  XtAddCallback (widget, XtNscrollProc, xaw_scroll_callback,
                 (XtPointer) bar);
   
   /* Realize the widget.  Only after that is the X window created.  */
   XtRealizeWidget (widget);
   
-#endif /* HAVE_XAW3D */
+#endif /* !USE_MOTIF */
 
   /* Install an action hook that let's us detect when the user
      finishes interacting with a scroll bar.  */
@@ -7378,7 +7568,6 @@ x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole)
      int portion, position, whole;
 {
   float top, shown;
-  Arg av[2];
   Widget widget = SCROLL_BAR_X_WIDGET (bar);
 
   if (whole == 0)
@@ -7398,7 +7587,7 @@ x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole)
     unsigned char flags;
     XmScrollBarWidget sb;
 
-    /* Slider size.  Must be in the range [1 .. MAX - MIN] where NAX
+    /* Slider size.  Must be in the range [1 .. MAX - MIN] where MAX
        is the scroll bar's maximum and MIN is the scroll bar's minimum
        value.  */
     size = shown * XM_SB_RANGE;
@@ -7426,7 +7615,7 @@ x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole)
       XmScrollBarSetValues (widget, value, size, 0, 0, False);
     else if (last_scroll_bar_part == scroll_bar_down_arrow)
       /* This has the negative side effect that the slider value is
-        not would it would be if we scrolled here using line-wise or
+        not what it would be if we scrolled here using line-wise or
         page-wise movement.  */
       XmScrollBarSetValues (widget, value, XM_SB_RANGE - value, 0, 0, False);
     else
@@ -7446,37 +7635,61 @@ x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole)
     sb->scrollBar.arrow2_selected = arrow2_selected;
     sb->scrollBar.flags = flags;
   }
-#elif defined HAVE_XAW3D
+#else /* !USE_MOTIF i.e. use Xaw */
   {
-    /* Restrict to [0 1].  */
-    top = max (0, min (1, top));
-    shown = max (0, min (1, shown));
+    float old_top, old_shown;
+    Dimension height;
+    XtVaGetValues (widget,
+                  XtNtopOfThumb, &old_top,
+                  XtNshown, &old_shown,
+                  XtNheight, &height,
+                  NULL);
+
+    /* Massage the top+shown values.  */
+    if (NILP (bar->dragging) || last_scroll_bar_part == scroll_bar_down_arrow)
+      top = max (0, min (1, top));
+    else
+      top = old_top;
+    /* Keep two pixels available for moving the thumb down.  */
+    shown = max (0, min (1 - top - (2.0 / height), shown));
 
     /* If the call to XawScrollbarSetThumb below doesn't seem to work,
        check that your system's configuration file contains a define
        for `NARROWPROTO'.  See s/freebsd.h for an example.  */
-    if (NILP (bar->dragging))
-      XawScrollbarSetThumb (widget, top, shown);
-    else
+    if (top != old_top || shown != old_shown)
       {
-       ScrollbarWidget sb = (ScrollbarWidget) widget;
-       int scroll_mode = sb->scrollbar.scroll_mode;
-
-       sb->scrollbar.scroll_mode = 0;
-       
-       if (last_scroll_bar_part == scroll_bar_down_arrow)
-         XawScrollbarSetThumb (widget, top, 1 - top);
+       if (NILP (bar->dragging))
+         XawScrollbarSetThumb (widget, top, shown);
        else
          {
-           float old_top;
-           XtVaGetValues (widget, XtNtopOfThumb, &old_top, NULL);
-           XawScrollbarSetThumb (widget, old_top, min (shown, 1 - old_top));
+#ifdef HAVE_XAW3D
+           ScrollbarWidget sb = (ScrollbarWidget) widget;
+           int scroll_mode;
+           
+           /* `scroll_mode' only exists with Xaw3d + ARROW_SCROLLBAR.  */
+           if (xaw3d_arrow_scroll)
+             {
+               /* Xaw3d stupidly ignores resize requests while dragging
+                  so we have to make it believe it's not in dragging mode.  */
+               scroll_mode = sb->scrollbar.scroll_mode;
+               if (scroll_mode == 2)
+                 sb->scrollbar.scroll_mode = 0;
+             }
+#endif
+           /* Try to make the scrolling a tad smoother.  */
+           if (!xaw3d_pick_top)
+             shown = min (shown, old_shown);
+           
+           XawScrollbarSetThumb (widget, top, shown);
+           
+#ifdef HAVE_XAW3D
+           if (xaw3d_arrow_scroll && scroll_mode == 2)
+             sb->scrollbar.scroll_mode = scroll_mode;
+#endif
          }
-       
-       sb->scrollbar.scroll_mode = scroll_mode;
       }
   }
-#endif /* HAVE_XAW3D */
+#endif /* !USE_MOTIF */
 
   UNBLOCK_INPUT;
 }
@@ -7500,11 +7713,6 @@ x_scroll_bar_create (w, top, left, width, height)
      int top, left, width, height;
 {
   struct frame *f = XFRAME (w->frame);
-#ifdef USE_X_TOOLKIT
-  Arg av[10];
-#endif
-  int ac = 0;
-  Window window;
   struct scroll_bar *bar
     = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE), Qnil));
 
@@ -7516,6 +7724,7 @@ x_scroll_bar_create (w, top, left, width, height)
   {
     XSetWindowAttributes a;
     unsigned long mask;
+    Window window;
 
     a.background_pixel = f->output_data.x->scroll_bar_background_pixel;
     if (a.background_pixel == -1)
@@ -7598,13 +7807,14 @@ x_scroll_bar_create (w, top, left, width, height)
    the bar's top is as far down as it goes; otherwise, there's no way
    to move to the very end of the buffer.  */
 
+#ifndef USE_TOOLKIT_SCROLL_BARS
+
 static void
 x_scroll_bar_set_handle (bar, start, end, rebuild)
      struct scroll_bar *bar;
      int start, end;
      int rebuild;
 {
-#ifndef USE_TOOLKIT_SCROLL_BARS
   int dragging = ! NILP (bar->dragging);
   Window w = SCROLL_BAR_X_WINDOW (bar);
   FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
@@ -7696,9 +7906,9 @@ x_scroll_bar_set_handle (bar, start, end, rebuild)
   }
 
   UNBLOCK_INPUT;
-#endif /* not USE_TOOLKIT_SCROLL_BARS */
 }
 
+#endif /* !USE_TOOLKIT_SCROLL_BARS */
 
 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
    nil.  */
@@ -7707,14 +7917,15 @@ static void
 x_scroll_bar_remove (bar)
      struct scroll_bar *bar;
 {
-  FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
-
   BLOCK_INPUT;
 
 #if USE_TOOLKIT_SCROLL_BARS
   XtDestroyWidget (SCROLL_BAR_X_WIDGET (bar));
 #else /* not USE_TOOLKIT_SCROLL_BARS */
-  XDestroyWindow (FRAME_X_DISPLAY (f), SCROLL_BAR_X_WINDOW (bar));
+  {
+    FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
+    XDestroyWindow (FRAME_X_DISPLAY (f), SCROLL_BAR_X_WINDOW (bar));
+  }
 #endif /* not USE_TOOLKIT_SCROLL_BARS */
   
   /* Disassociate this scroll bar from its window.  */
@@ -7736,41 +7947,52 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
 {
   struct frame *f = XFRAME (w->frame);
   struct scroll_bar *bar;
-  int pixel_top, pixel_left, pixel_width, pixel_height;
+  int top, height, left, sb_left, width, sb_width;
   int window_x, window_y, window_width, window_height;
-  int scroll_bar_area_width;
 
+  /* Get window dimensions.  */
   window_box (w, -1, &window_x, &window_y, &window_width, &window_height);
-  
-  /* Where should this scroll bar be, pixel-wise?  */
-  pixel_top = window_y;
-  pixel_height = window_height;
-
-  /* The width of the scroll bar itself.  */
-  pixel_width = (FRAME_SCROLL_BAR_PIXEL_WIDTH (f) > 0
-                ? FRAME_SCROLL_BAR_PIXEL_WIDTH (f)
-                : (FRAME_SCROLL_BAR_COLS (f)
-                   * FONT_WIDTH (FRAME_FONT (f))));
-
-  /* The width on the screen reserved for the scroll bar plus maybe
-     some empty room at both sides of the scroll bar.  */
-  scroll_bar_area_width = FRAME_SCROLL_BAR_COLS (f) * CANON_X_UNIT (f);
+  top = window_y;
+  width = FRAME_SCROLL_BAR_COLS (f) * CANON_X_UNIT (f);
+  height = window_height;
 
+  /* Compute the left edge of the scroll bar area.  */
   if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f))
-    pixel_left = (window_x
-                 + window_width
-                 + FRAME_FLAGS_AREA_WIDTH (f)
-                 + scroll_bar_area_width
-                 - pixel_width + 1);
+    left = XINT (w->left) + XINT (w->width) - FRAME_SCROLL_BAR_COLS (f);
+  else
+    left = XFASTINT (w->left);
+  left *= CANON_X_UNIT (f);
+  left += FRAME_INTERNAL_BORDER_WIDTH (f);
+
+  /* Compute the width of the scroll bar which might be less than
+     the width of the area reserved for the scroll bar.  */
+  if (FRAME_SCROLL_BAR_PIXEL_WIDTH (f) > 0)
+    sb_width = FRAME_SCROLL_BAR_PIXEL_WIDTH (f);
   else
-    pixel_left = (window_x
-                 - FRAME_FLAGS_AREA_WIDTH (f)
-                 - scroll_bar_area_width);
+    sb_width = width;
 
+  /* Compute the left edge of the scroll bar.  */
+#ifdef USE_TOOLKIT_SCROLL_BARS
+  if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f))
+    sb_left = left + width - sb_width - (width - sb_width) / 2; 
+  else
+    sb_left = left + (width - sb_width) / 2;
+#else
+  if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f))
+    sb_left = left + width - sb_width; 
+  else
+    sb_left = left;
+#endif
+  
   /* Does the scroll bar exist yet?  */
   if (NILP (w->vertical_scroll_bar))
-    bar = x_scroll_bar_create (w, pixel_top, pixel_left, pixel_width,
-                              pixel_height);
+    {
+      BLOCK_INPUT;
+      XClearArea (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+                 left, top, width, height, False);
+      UNBLOCK_INPUT;
+      bar = x_scroll_bar_create (w, top, sb_left, sb_width, height);
+    }
   else
     {
       /* It may just need to be moved and resized.  */
@@ -7780,84 +8002,56 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
 
       BLOCK_INPUT;
 
-      if (pixel_left != XINT (bar->left))
+      if (sb_left != XINT (bar->left))
        mask |= CWX;
-      if (pixel_top != XINT (bar->top))
+      if (top != XINT (bar->top))
        mask |= CWY;
-      if (pixel_width != XINT (bar->width))
+      if (sb_width != XINT (bar->width))
        mask |= CWWidth;
-      if (pixel_height != XINT (bar->height))  
+      if (height != XINT (bar->height))        
        mask |= CWHeight;
       
 #ifdef USE_TOOLKIT_SCROLL_BARS
-      
-      if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f))
-       {
-         XClearArea (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                     pixel_left + pixel_width - scroll_bar_area_width,
-                     pixel_top,
-                     (scroll_bar_area_width
-                      - pixel_width
-                      + VERTICAL_SCROLL_BAR_WIDTH_TRIM),
-                     pixel_height, False);
-         XClearArea (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                     (pixel_left
-                      + pixel_width
-                      - VERTICAL_SCROLL_BAR_WIDTH_TRIM),
-                     pixel_top,
-                     VERTICAL_SCROLL_BAR_WIDTH_TRIM,
-                     pixel_height, False);
-       }
-      else
-       {
-         XClearArea (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                     pixel_left, pixel_top,
-                     VERTICAL_SCROLL_BAR_WIDTH_TRIM, pixel_height, False);
-         XClearArea (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                     (pixel_left
-                      + pixel_width
-                      - VERTICAL_SCROLL_BAR_WIDTH_TRIM),
-                     pixel_top,
-                     (scroll_bar_area_width
-                      - pixel_width
-                      + VERTICAL_SCROLL_BAR_WIDTH_TRIM),
-                     pixel_height, False);
-       }
+
+      /* Since toolkit scroll bars are smaller than the space reserved
+        for them on the frame, we have to clear "under" them.  */
+      XClearArea (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+                 left, top, width, height, False);
 
       /* Move/size the scroll bar widget.  */
       if (mask)
        XtConfigureWidget (SCROLL_BAR_X_WIDGET (bar),
-                          pixel_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
-                          pixel_top,
-                          pixel_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
-                          pixel_height, 0);
+                          sb_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
+                          top,
+                          sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
+                          height, 0);
 
 #else /* not USE_TOOLKIT_SCROLL_BARS */
   
-      /* Clear areas not covered by the scroll bar.  This makes sure a
-        previous mode line display is cleared after C-x 2 C-x 1, for
-        example.  Non-toolkit scroll bars are as wide as the area
-        reserved for scroll bars - trim at both sides.  */
-      XClearArea (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                 pixel_left, pixel_top, VERTICAL_SCROLL_BAR_WIDTH_TRIM,
-                 pixel_height, False);
-      XClearArea (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                 (pixel_left
-                  + pixel_width
-                  - VERTICAL_SCROLL_BAR_WIDTH_TRIM),
-                 pixel_top,
-                 VERTICAL_SCROLL_BAR_WIDTH_TRIM,
-                 pixel_height, False);
+      if (VERTICAL_SCROLL_BAR_WIDTH_TRIM)
+       {
+         /* Clear areas not covered by the scroll bar.  This makes sure a
+            previous mode line display is cleared after C-x 2 C-x 1, for
+            example.  Non-toolkit scroll bars are as wide as the area
+            reserved for scroll bars - trim at both sides.  */
+         XClearArea (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+                     left, top, VERTICAL_SCROLL_BAR_WIDTH_TRIM,
+                     height, False);
+         XClearArea (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+                     left + width - VERTICAL_SCROLL_BAR_WIDTH_TRIM,
+                     top, VERTICAL_SCROLL_BAR_WIDTH_TRIM,
+                     height, False);
+       }
       
       /* Move/size the scroll bar window.  */
       if (mask)
        {
          XWindowChanges wc;
          
-         wc.x = pixel_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM;
-         wc.y = pixel_top;
-         wc.width = pixel_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2;
-         wc.height = pixel_height;
+         wc.x = sb_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM;
+         wc.y = top;
+         wc.width = sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2;
+         wc.height = height;
          XConfigureWindow (FRAME_X_DISPLAY (f), SCROLL_BAR_X_WINDOW (bar),
                            mask, &wc);
        }
@@ -7865,10 +8059,10 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
 #endif /* not USE_TOOLKIT_SCROLL_BARS */
 
       /* Remember new settings.  */
-      XSETINT (bar->left, pixel_left);
-      XSETINT (bar->top, pixel_top);
-      XSETINT (bar->width, pixel_width);
-      XSETINT (bar->height, pixel_height);
+      XSETINT (bar->left, sb_left);
+      XSETINT (bar->top, top);
+      XSETINT (bar->width, sb_width);
+      XSETINT (bar->height, height);
       
       UNBLOCK_INPUT;
     }
@@ -7880,7 +8074,7 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
      dragged.  */
   if (NILP (bar->dragging))
     {
-      int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, pixel_height);
+      int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, height);
 
       if (whole == 0)
        x_scroll_bar_set_handle (bar, 0, top_range, 0);
@@ -8045,6 +8239,8 @@ x_scroll_bar_expose (bar, event)
    This may be called from a signal handler, so we have to ignore GC
    mark bits.  */
 
+#ifndef USE_TOOLKIT_SCROLL_BARS
+
 static void
 x_scroll_bar_handle_click (bar, event, emacs_event)
      struct scroll_bar *bar;
@@ -8155,6 +8351,8 @@ x_scroll_bar_note_movement (bar, event)
     }
 }
 
+#endif /* !USE_TOOLKIT_SCROLL_BARS */
+
 /* Return information to the user about the current position of the mouse
    on the scroll bar.  */
 
@@ -8559,6 +8757,19 @@ XTread_socket (sd, bufp, numchars, expected)
                        if (f && FRAME_XIC (f))
                          XSetICFocus (FRAME_XIC (f));
 #endif
+#if 0 /* Emacs sets WM hints whose `input' field is `true'.  This
+        instructs the WM to set the input focus automatically for
+        Emacs with a call to XSetInputFocus.  Setting WM_TAKE_FOCUS
+        tells the WM to send us a ClientMessage WM_TAKE_FOCUS after
+        it has set the focus.  So, XSetInputFocus below is not
+        needed.
+
+        The call to XSetInputFocus below has also caused trouble.  In
+        cases where the XSetInputFocus done by the WM and the one
+        below are temporally close (on a fast machine), the call
+        below can generate additional FocusIn events which confuse
+        Emacs.  */
+                       
                        /* Since we set WM_TAKE_FOCUS, we must call
                           XSetInputFocus explicitly.  But not if f is null,
                           since that might be an event for a deleted frame.  */
@@ -8569,7 +8780,9 @@ XTread_socket (sd, bufp, numchars, expected)
                               iconified by a window manager such as GWM.  */
                            int count = x_catch_errors (d);
                            XSetInputFocus (d, event.xclient.window,
-                                           RevertToPointerRoot,
+                                           /* The ICCCM says this is
+                                              the only valid choice.  */
+                                           RevertToParent,
                                            event.xclient.data.l[1]);
                            /* This is needed to detect the error
                               if there is an error.  */
@@ -8577,6 +8790,7 @@ XTread_socket (sd, bufp, numchars, expected)
                            x_uncatch_errors (d, count);
                          }  
                        /* Not certain about handling scroll bars here */
+#endif /* 0 */
                      }
                    else if (event.xclient.data.l[0]
                             == dpyinfo->Xatom_wm_save_yourself)
@@ -8593,7 +8807,7 @@ XTread_socket (sd, bufp, numchars, expected)
 
                            /* This is just so we only give real data once
                               for a single Emacs process.  */
-                           if (f == selected_frame)
+                           if (f == SELECTED_FRAME ())
                              XSetCommand (FRAME_X_DISPLAY (f),
                                           event.xclient.window,
                                           initial_argv, initial_argc);
@@ -8663,7 +8877,6 @@ XTread_socket (sd, bufp, numchars, expected)
                       reply with "Next" if we received "Page", but we
                       currently never do because we are interested in
                       images, only, which should have 1 page.  */
-                   Window gs_window = (Window) event.xclient.data.l[0];
                    Pixmap pixmap = (Pixmap) event.xclient.data.l[1];
                    struct frame *f
                      = x_window_to_frame (dpyinfo, event.xclient.window);
@@ -8676,6 +8889,8 @@ XTread_socket (sd, bufp, numchars, expected)
                else if (event.xclient.message_type
                         == dpyinfo->Xatom_Scrollbar)
                  {
+                   if (display_busy_cursor_p)
+                     inhibit_busy_cursor = 2;
                    x_scroll_bar_to_input_event (&event, bufp);
                    ++bufp, ++count, --numchars;
                    goto out;
@@ -8889,7 +9104,7 @@ XTread_socket (sd, bufp, numchars, expected)
                      numchars--;
                    }
                  else if (! NILP (Vframe_list)
-                          && ! NILP (XCONS (Vframe_list)->cdr))
+                          && ! NILP (XCDR (Vframe_list)))
                    /* Force a redisplay sooner or later
                       to update the frame titles
                       in case this is the second frame.  */
@@ -9259,13 +9474,13 @@ XTread_socket (sd, bufp, numchars, expected)
                  note_mouse_movement (f, &event.xmotion);
                else
                  {
-#ifndef USE_X_TOOLKIT
+#ifndef USE_TOOLKIT_SCROLL_BARS
                    struct scroll_bar *bar
                      = x_window_to_scroll_bar (event.xmotion.window);
 
                    if (bar)
                      x_scroll_bar_note_movement (bar, &event);
-#endif /* USE_X_TOOLKIT */
+#endif /* USE_TOOLKIT_SCROLL_BARS */
 
                    /* If we move outside the frame, then we're
                       certainly no longer on any text in the frame.  */
@@ -9297,10 +9512,10 @@ XTread_socket (sd, bufp, numchars, expected)
              f = x_top_window_to_frame (dpyinfo, event.xconfigure.window);
              if (f)
                {
+#ifndef USE_X_TOOLKIT
                  int rows = PIXEL_TO_CHAR_HEIGHT (f, event.xconfigure.height);
                  int columns = PIXEL_TO_CHAR_WIDTH (f, event.xconfigure.width);
-
-#ifndef USE_X_TOOLKIT
+                 
                  /* In the toolkit version, change_frame_size
                     is called by the code that handles resizing
                     of the EmacsFrame widget.  */
@@ -9313,7 +9528,7 @@ XTread_socket (sd, bufp, numchars, expected)
                      || event.xconfigure.width != f->output_data.x->pixel_width
                      || event.xconfigure.height != f->output_data.x->pixel_height)
                    {
-                     change_frame_size (f, rows, columns, 0, 1);
+                     change_frame_size (f, rows, columns, 0, 1, 0);
                      SET_FRAME_GARBAGED (f);
                      cancel_mouse_face (f);
                    }
@@ -9353,7 +9568,7 @@ XTread_socket (sd, bufp, numchars, expected)
                /* If we decide we want to generate an event to be seen
                   by the rest of Emacs, we put it here.  */
                struct input_event emacs_event;
-               int toolbar_p = 0;
+               int tool_bar_p = 0;
                
                emacs_event.kind = no_event;
                bzero (&compose_status, sizeof (compose_status));
@@ -9367,9 +9582,9 @@ XTread_socket (sd, bufp, numchars, expected)
 
                if (f)
                  {
-                   /* Is this in the toolbar?  */
-                   if (WINDOWP (f->toolbar_window)
-                       && XFASTINT (XWINDOW (f->toolbar_window)->height))
+                   /* Is this in the tool-bar?  */
+                   if (WINDOWP (f->tool_bar_window)
+                       && XFASTINT (XWINDOW (f->tool_bar_window)->height))
                      {
                        Lisp_Object window;
                        int p, x, y;
@@ -9379,14 +9594,14 @@ XTread_socket (sd, bufp, numchars, expected)
 
                        /* Set x and y.  */
                        window = window_from_coordinates (f, x, y, &p, 1);
-                       if (EQ (window, f->toolbar_window))
+                       if (EQ (window, f->tool_bar_window))
                          {
-                           x_handle_toolbar_click (f, &event.xbutton);
-                           toolbar_p = 1;
+                           x_handle_tool_bar_click (f, &event.xbutton);
+                           tool_bar_p = 1;
                          }
                      }
 
-                   if (!toolbar_p)
+                   if (!tool_bar_p)
                      if (!dpyinfo->x_focus_frame
                          || f == dpyinfo->x_focus_frame)
                        construct_mouse_click (&emacs_event, &event, f);
@@ -9413,8 +9628,8 @@ XTread_socket (sd, bufp, numchars, expected)
                    if (f != 0)
                      f->mouse_moved = 0;
                    
-                   if (!toolbar_p)
-                     last_toolbar_item = -1;
+                   if (!tool_bar_p)
+                     last_tool_bar_item = -1;
                    if (display_busy_cursor_p)
                      inhibit_busy_cursor = 2;
                  }
@@ -9605,8 +9820,8 @@ x_clip_to_row (w, row, gc, whole_line_p)
      the rectangle to the left and increase its width.  */
   if (whole_line_p)
     {
-      clip_rect.x -= FRAME_X_FLAGS_AREA_WIDTH (f);
-      clip_rect.width += 2 * FRAME_X_FLAGS_AREA_WIDTH (f);
+      clip_rect.x -= FRAME_X_LEFT_FLAGS_AREA_WIDTH (f);
+      clip_rect.width += FRAME_X_FLAGS_AREA_WIDTH (f);
     }
 
   XSetClipRectangles (FRAME_X_DISPLAY (f), gc, 0, 0, &clip_rect, 1, Unsorted);
@@ -9752,8 +9967,25 @@ x_draw_phys_cursor_glyph (w, row, hl)
      happen in mini-buffer windows when switching between echo area
      glyphs and mini-buffer.  */
   if (w->phys_cursor.hpos < row->used[TEXT_AREA])
-    x_draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
-                  w->phys_cursor.hpos, w->phys_cursor.hpos + 1, hl, 0, 0);
+    {
+      x_draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
+                    w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
+                    hl, 0, 0, 0);
+
+      /* When we erase the cursor, and ROW is overlapped by other
+        rows, make sure that these overlapping parts of other rows
+        are redrawn.  */
+      if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
+       {
+         if (row > w->current_matrix->rows
+             && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
+           x_fix_overlapping_area (w, row - 1, TEXT_AREA);
+
+         if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
+             && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
+           x_fix_overlapping_area (w, row + 1, TEXT_AREA);
+       }
+    }
 }
 
 
@@ -9816,7 +10048,7 @@ x_erase_phys_cursor (w)
   if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
     {
       int x;
-      int top_line_height = WINDOW_DISPLAY_TOP_LINE_HEIGHT (w);
+      int header_line_height = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
 
       cursor_glyph = get_phys_cursor_glyph (w);
       if (cursor_glyph == NULL)
@@ -9826,7 +10058,7 @@ x_erase_phys_cursor (w)
       
       XClearArea (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
                  x,
-                 WINDOW_TO_FRAME_PIXEL_Y (w, max (top_line_height,
+                 WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height,
                                                   cursor_row->y)),
                  cursor_glyph->pixel_width,
                  cursor_row->visible_height,
@@ -9897,18 +10129,30 @@ x_display_and_set_cursor (w, on, hpos, vpos, x, y)
      the cursor type given by the frame parameter.  If explicitly
      marked off, draw no cursor.  In all other cases, we want a hollow
      box cursor.  */
-  if (w != XWINDOW (selected_window)
-      || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame)
+  if (cursor_in_echo_area
+      && FRAME_HAS_MINIBUF_P (f)
+      && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
     {
-      if (MINI_WINDOW_P (w))
-       new_cursor_type = NO_CURSOR;
+      if (w == XWINDOW (echo_area_window))
+       new_cursor_type = FRAME_DESIRED_CURSOR (f);
       else
        new_cursor_type = HOLLOW_BOX_CURSOR;
     }
-  else if (w->cursor_off_p)
-    new_cursor_type = NO_CURSOR;
   else
-    new_cursor_type = FRAME_DESIRED_CURSOR (f);
+    {
+      if (w != XWINDOW (selected_window)
+         || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame)
+       {
+         if (MINI_WINDOW_P (w))
+           new_cursor_type = NO_CURSOR;
+         else
+           new_cursor_type = HOLLOW_BOX_CURSOR;
+       }
+      else if (w->cursor_off_p)
+       new_cursor_type = NO_CURSOR;
+      else
+       new_cursor_type = FRAME_DESIRED_CURSOR (f);
+    }
 
   /* If cursor is currently being shown and we don't want it to be or
      it is in the wrong place, or the cursor type is not what we want,
@@ -10675,7 +10919,7 @@ x_set_window_size (f, change_gravity, cols, rows)
        ? FRAME_SCROLL_BAR_PIXEL_WIDTH (f)
        : (FRAME_SCROLL_BAR_COLS (f) * FONT_WIDTH (f->output_data.x->font)));
   f->output_data.x->flags_areas_extra
-    = 2 * FRAME_FLAGS_AREA_WIDTH (f);
+    = FRAME_FLAGS_AREA_WIDTH (f);
   pixelwidth = CHAR_TO_PIXEL_WIDTH (f, cols);
   pixelheight = CHAR_TO_PIXEL_HEIGHT (f, rows);
 
@@ -10693,10 +10937,13 @@ x_set_window_size (f, change_gravity, cols, rows)
 
      We could just not bother storing any of this information here,
      and let the ConfigureNotify event set everything up, but that
-     might be kind of confusing to the lisp code, since size changes
+     might be kind of confusing to the Lisp code, since size changes
      wouldn't be reported in the frame parameters until some random
-     point in the future when the ConfigureNotify event arrives.  */
-  change_frame_size (f, rows, cols, 0, 0);
+     point in the future when the ConfigureNotify event arrives.
+
+     We pass 1 for DELAY since we can't run Lisp code inside of
+     a BLOCK_INPUT.  */
+  change_frame_size (f, rows, cols, 0, 1, 0);
   PIXEL_WIDTH (f) = pixelwidth;
   PIXEL_HEIGHT (f) = pixelheight;
 
@@ -11524,17 +11771,17 @@ x_list_fonts (f, pattern, size, maxnames)
     /* We can return any single font matching PATTERN.  */
     try_XLoadQueryFont = 1;
 
-  for (; CONSP (patterns); patterns = XCONS (patterns)->cdr)
+  for (; CONSP (patterns); patterns = XCDR (patterns))
     {
       int num_fonts;
       char **names;
 
-      pattern = XCONS (patterns)->car;
+      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 = XCONS (FRAME_X_DISPLAY_INFO (f)->name_list_element)->cdr,
+      if (f && (tem = XCDR (FRAME_X_DISPLAY_INFO (f)->name_list_element),
                key = Fcons (pattern, make_number (maxnames)),
                !NILP (list = Fassoc (key, tem))))
        {
@@ -11660,30 +11907,30 @@ x_list_fonts (f, pattern, size, maxnames)
 
       /* Now store the result in the cache.  */
       if (f != NULL)
-       XCONS (FRAME_X_DISPLAY_INFO (f)->name_list_element)->cdr
+       XCDR (FRAME_X_DISPLAY_INFO (f)->name_list_element)
          = Fcons (Fcons (key, list),
-                  XCONS (FRAME_X_DISPLAY_INFO (f)->name_list_element)->cdr);
+                  XCDR (FRAME_X_DISPLAY_INFO (f)->name_list_element));
 
     label_cached:
       if (NILP (list)) continue; /* Try the remaining alternatives.  */
 
       newlist = second_best = Qnil;
       /* Make a list of the fonts that have the right width.  */
-      for (; CONSP (list); list = XCONS (list)->cdr)
+      for (; CONSP (list); list = XCDR (list))
        {
          int found_size;
 
-         tem = XCONS (list)->car;
+         tem = XCAR (list);
 
-         if (!CONSP (tem) || NILP (XCONS (tem)->car))
+         if (!CONSP (tem) || NILP (XCAR (tem)))
            continue;
          if (!size)
            {
-             newlist = Fcons (XCONS (tem)->car, newlist);
+             newlist = Fcons (XCAR (tem), newlist);
              continue;
            }
 
-         if (!INTEGERP (XCONS (tem)->cdr))
+         if (!INTEGERP (XCDR (tem)))
            {
              /* Since we have not yet known the size of this font, we
                must try slow function call XLoadQueryFont.  */
@@ -11692,7 +11939,7 @@ x_list_fonts (f, pattern, size, maxnames)
              BLOCK_INPUT;
              count = x_catch_errors (dpy);
              thisinfo = XLoadQueryFont (dpy,
-                                        XSTRING (XCONS (tem)->car)->data);
+                                        XSTRING (XCAR (tem))->data);
              if (x_had_errors_p (dpy))
                {
                  /* This error is perhaps due to insufficient memory on X
@@ -11705,7 +11952,7 @@ x_list_fonts (f, pattern, size, maxnames)
 
              if (thisinfo)
                {
-                 XCONS (tem)->cdr
+                 XCDR (tem)
                    = (thisinfo->min_bounds.width == 0
                       ? make_number (0)
                       : make_number (thisinfo->max_bounds.width));
@@ -11715,26 +11962,26 @@ x_list_fonts (f, pattern, size, maxnames)
                /* For unknown reason, the previous call of XListFont had
                  returned a font which can't be opened.  Record the size
                  as 0 not to try to open it again.  */
-               XCONS (tem)->cdr = make_number (0);
+               XCDR (tem) = make_number (0);
            }
 
-         found_size = XINT (XCONS (tem)->cdr);
+         found_size = XINT (XCDR (tem));
          if (found_size == size)
-           newlist = Fcons (XCONS (tem)->car, newlist);
+           newlist = Fcons (XCAR (tem), newlist);
          else if (found_size > 0)
            {
              if (NILP (second_best))
                second_best = tem;
              else if (found_size < size)
                {
-                 if (XINT (XCONS (second_best)->cdr) > size
-                     || XINT (XCONS (second_best)->cdr) < found_size)
+                 if (XINT (XCDR (second_best)) > size
+                     || XINT (XCDR (second_best)) < found_size)
                    second_best = tem;
                }
              else
                {
-                 if (XINT (XCONS (second_best)->cdr) > size
-                     && XINT (XCONS (second_best)->cdr) > found_size)
+                 if (XINT (XCDR (second_best)) > size
+                     && XINT (XCDR (second_best)) > found_size)
                    second_best = tem;
                }
            }
@@ -11743,7 +11990,7 @@ x_list_fonts (f, pattern, size, maxnames)
        break;
       else if (!NILP (second_best))
        {
-         newlist = Fcons (XCONS (second_best)->car, Qnil);
+         newlist = Fcons (XCAR (second_best), Qnil);
          break;
        }
     }
@@ -11867,12 +12114,12 @@ x_load_font (f, fontname, size)
       int i;
 
       for (i = 0; i < dpyinfo->n_fonts; i++)
-       for (tail = font_names; CONSP (tail); tail = XCONS (tail)->cdr)
+       for (tail = font_names; CONSP (tail); tail = XCDR (tail))
          if (dpyinfo->font_table[i].name
              && (!strcmp (dpyinfo->font_table[i].name,
-                          XSTRING (XCONS (tail)->car)->data)
+                          XSTRING (XCAR (tail))->data)
                  || !strcmp (dpyinfo->font_table[i].full_name,
-                             XSTRING (XCONS (tail)->car)->data)))
+                             XSTRING (XCAR (tail))->data)))
            return (dpyinfo->font_table + i);
     }
 
@@ -11890,7 +12137,7 @@ x_load_font (f, fontname, size)
        a bug of not finding a font even if the font surely exists and
        is loadable by XLoadQueryFont.  */
     if (size > 0 && !NILP (font_names))
-      fontname = (char *) XSTRING (XCONS (font_names)->car)->data;
+      fontname = (char *) XSTRING (XCAR (font_names))->data;
 
     BLOCK_INPUT;
     count = x_catch_errors (FRAME_X_DISPLAY (f));
@@ -11986,19 +12233,19 @@ x_load_font (f, fontname, size)
        Lisp_Object lispy_name = build_string (fontname);
        Lisp_Object lispy_full_name = build_string (fontp->full_name);
 
-       XCONS (dpyinfo->name_list_element)->cdr
+       XCDR (dpyinfo->name_list_element)
          = Fcons (Fcons (Fcons (lispy_name, make_number (256)),
                          Fcons (Fcons (lispy_full_name,
                                        make_number (fontp->size)),
                                 Qnil)),
-                  XCONS (dpyinfo->name_list_element)->cdr);
+                  XCDR (dpyinfo->name_list_element));
        if (full_name)
-         XCONS (dpyinfo->name_list_element)->cdr
+         XCDR (dpyinfo->name_list_element)
            = Fcons (Fcons (Fcons (lispy_full_name, make_number (256)),
                            Fcons (Fcons (lispy_full_name,
                                          make_number (fontp->size)),
                                   Qnil)),
-                    XCONS (dpyinfo->name_list_element)->cdr);
+                    XCDR (dpyinfo->name_list_element));
       }
 
     /* The slot `encoding' specifies how to map a character
@@ -12084,20 +12331,21 @@ x_find_ccl_program (fontp)
 {
   Lisp_Object list, elt;
 
-  for (list = Vfont_ccl_encoder_alist; CONSP (list); list = XCONS (list)->cdr)
+  for (list = Vfont_ccl_encoder_alist; CONSP (list); list = XCDR (list))
     {
-      elt = XCONS (list)->car;
+      elt = XCAR (list);
       if (CONSP (elt)
-         && STRINGP (XCONS (elt)->car)
-         && (fast_c_string_match_ignore_case (XCONS (elt)->car, fontp->name)
+         && STRINGP (XCAR (elt))
+         && (fast_c_string_match_ignore_case (XCAR (elt), fontp->name)
              >= 0))
        break;
     }
   if (! NILP (list))
     {
-      struct ccl_program *ccl = xmalloc (sizeof (struct ccl_program));
+      struct ccl_program *ccl
+       = (struct ccl_program *) xmalloc (sizeof (struct ccl_program));
 
-      if (setup_ccl_program (ccl, XCONS (elt)->cdr) < 0)
+      if (setup_ccl_program (ccl, XCDR (elt)) < 0)
        xfree (ccl);
       else
        fontp->font_encoder = ccl;
@@ -12180,28 +12428,6 @@ same_x_server (name1, name2)
 }
 #endif
 
-#if defined (HAVE_X_I18N) || (defined (USE_X_TOOLKIT) && defined (HAVE_X11XTR6))
-/* Recover from setlocale (LC_ALL, "").  */
-static void
-fixup_locale ()
-{
-  /* Currently we require strerror to use the "C" locale,
-     since we don't yet support decoding its string result.  */
-#ifdef LC_MESSAGES
-  setlocale (LC_MESSAGES, "C");
-#endif
-
-  /* The Emacs Lisp reader needs LC_NUMERIC to be "C",
-     so that numbers are read and printed properly for Emacs Lisp.  */
-  setlocale (LC_NUMERIC, "C");
-
-  /* Currently we require strftime to use the "C" locale,
-     since we don't yet support encoding its format argument,
-     or decoding its string result.  */
-  setlocale (LC_TIME, "C");
-}
-#endif
-
 struct x_display_info *
 x_term_init (display_name, xrm_option, resource_name)
      Lisp_Object display_name;
@@ -12221,11 +12447,6 @@ x_term_init (display_name, xrm_option, resource_name)
       x_initialized = 1;
     }
 
-#ifdef HAVE_X_I18N
-  setlocale (LC_ALL, "");
-  fixup_locale ();
-#endif
-
 #ifdef USE_X_TOOLKIT
   /* weiner@footloose.sps.mot.com reports that this causes
      errors with X11R5:
@@ -12282,8 +12503,8 @@ x_term_init (display_name, xrm_option, resource_name)
     Lisp_Object tail;
 
     for (share = x_display_list, tail = x_display_name_list; share;
-        share = share->next, tail = XCONS (tail)->cdr)
-      if (same_x_server (XSTRING (XCONS (XCONS (tail)->car)->car)->data,
+        share = share->next, tail = XCDR (tail))
+      if (same_x_server (XSTRING (XCAR (XCAR (tail)))->data,
                         XSTRING (display_name)->data))
        break;
     if (share)
@@ -12319,7 +12540,7 @@ x_term_init (display_name, xrm_option, resource_name)
   /* Put it on x_display_name_list as well, to keep them parallel.  */ 
   x_display_name_list = Fcons (Fcons (display_name, Qnil),
                               x_display_name_list);
-  dpyinfo->name_list_element = XCONS (x_display_name_list)->car;
+  dpyinfo->name_list_element = XCAR (x_display_name_list);
 
   dpyinfo->display = dpy;
 
@@ -12538,22 +12759,22 @@ x_delete_display (dpyinfo)
   /* Discard this display from x_display_name_list and x_display_list.
      We can't use Fdelq because that can quit.  */
   if (! NILP (x_display_name_list)
-      && EQ (XCONS (x_display_name_list)->car, dpyinfo->name_list_element))
-    x_display_name_list = XCONS (x_display_name_list)->cdr;
+      && EQ (XCAR (x_display_name_list), dpyinfo->name_list_element))
+    x_display_name_list = XCDR (x_display_name_list);
   else
     {
       Lisp_Object tail;
 
       tail = x_display_name_list;
-      while (CONSP (tail) && CONSP (XCONS (tail)->cdr))
+      while (CONSP (tail) && CONSP (XCDR (tail)))
        {
-         if (EQ (XCONS (XCONS (tail)->cdr)->car,
+         if (EQ (XCAR (XCDR (tail)),
                  dpyinfo->name_list_element))
            {
-             XCONS (tail)->cdr = XCONS (XCONS (tail)->cdr)->cdr;
+             XCDR (tail) = XCDR (XCDR (tail));
              break;
            }
-         tail = XCONS (tail)->cdr;
+         tail = XCDR (tail);
        }
     }
 
@@ -12596,7 +12817,8 @@ static struct redisplay_interface x_redisplay_interface =
   x_update_window_end,
   XTcursor_to,
   x_flush,
-  x_get_glyph_overhangs
+  x_get_glyph_overhangs,
+  x_fix_overlapping_area
 };
 
 void
@@ -12635,7 +12857,7 @@ x_initialize ()
   baud_rate = 19200;
 
   x_noop_count = 0;
-  last_toolbar_item = -1;
+  last_tool_bar_item = -1;
   any_help_event_p = 0;
   
   /* Try to use interrupt input; if we can't, then start polling.  */
@@ -12646,6 +12868,10 @@ x_initialize ()
   Xt_app_con = XtCreateApplicationContext ();
   XtAppSetFallbackResources (Xt_app_con, Xt_default_resources);
 #endif
+#if USE_TOOLKIT_SCROLL_BARS
+  xaw3d_arrow_scroll = False;
+  xaw3d_pick_top = True;
+#endif
 
   /* Note that there is no real way portable across R3/R4 to get the
      original error handler.  */