]> code.delx.au - gnu-emacs/blobdiff - src/xterm.c
Fix typos.
[gnu-emacs] / src / xterm.c
index 60b46bc3d129d34b41b92c06ad0bea7a0307faea..13bc4d3a19cf2f9b7973adcf1767153b2da4ce10 100644 (file)
@@ -155,11 +155,11 @@ extern void _XEditResCheckMessages ();
 #define BETWEEN(X, LOWER, UPPER)  ((X) >= (LOWER) && (X) < (UPPER))
 
 \f
-/* Bitmaps for truncated lines.  */
+/* Fringe bitmaps.  */
 
-enum bitmap_type
+enum fringe_bitmap_type
 {
-  NO_BITMAP,
+  NO_FRINGE_BITMAP,
   LEFT_TRUNCATION_BITMAP,
   RIGHT_TRUNCATION_BITMAP,
   OVERLAY_ARROW_BITMAP,
@@ -172,9 +172,17 @@ enum bitmap_type
    `indicate-empty-lines' is non-nil.  */
 
 #define zv_width 8
-#define zv_height 8
+#define zv_height 72
+#define zv_period 3
 static unsigned char zv_bits[] = {
-   0x00, 0x00, 0x1e, 0x1e, 0x1e, 0x1e, 0x00, 0x00};
+  0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
+  0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
+  0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
+  0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
+  0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
+  0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
+  0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
+  0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00};
 
 /* An arrow like this: `<-'.  */
 
@@ -274,8 +282,6 @@ Lisp_Object x_display_name_list;
 
 extern struct frame *updating_frame;
 
-extern int waiting_for_input;
-
 /* This is a frame waiting to be auto-raised, within XTread_socket.  */
 
 struct frame *pending_autoraise_frame;
@@ -463,13 +469,13 @@ static void x_update_cursor_in_window_tree P_ ((struct window *, int));
 static void x_update_window_cursor P_ ((struct window *, int));
 static void x_erase_phys_cursor P_ ((struct window *));
 void x_display_and_set_cursor P_ ((struct window *, int, int, int, int, int));
-static void x_draw_bitmap P_ ((struct window *, struct glyph_row *, 
-                              enum bitmap_type));
+static void x_draw_fringe_bitmap P_ ((struct window *, struct glyph_row *, 
+                                     enum fringe_bitmap_type, int left_p));
 
 static void x_clip_to_row P_ ((struct window *, struct glyph_row *,
                               GC, int));
 static int x_phys_cursor_in_rect_p P_ ((struct window *, XRectangle *));
-static void x_draw_row_bitmaps P_ ((struct window *, struct glyph_row *));
+static void x_draw_row_fringe_bitmaps P_ ((struct window *, struct glyph_row *));
 static void notice_overwritten_cursor P_ ((struct window *, int, int));
 static void x_flush P_ ((struct frame *f));
 static void x_update_begin P_ ((struct frame *));
@@ -659,7 +665,7 @@ x_draw_vertical_border (w)
       int x0, x1, y0, y1;
 
       window_box_edges (w, -1, &x0, &y0, &x1, &y1);
-      x1 += FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f);
+      x1 += FRAME_X_RIGHT_FRINGE_WIDTH (f);
       y1 -= 1;
       
       XDrawLine (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 
@@ -758,7 +764,7 @@ XTframe_up_to_date (f)
 
 
 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
-   arrow bitmaps, or clear the areas where they would be displayed
+   arrow bitmaps, or clear the fringes if no bitmaps are required
    before DESIRED_ROW is made current.  The window being updated is
    found in updated_window.  This function It is called from
    update_window_line only if it is known that there are differences
@@ -770,14 +776,14 @@ x_after_update_window_line (desired_row)
 {
   struct window *w = updated_window;
   struct frame *f;
-  int width;
+  int width, height;
   
   xassert (w);
   
   if (!desired_row->mode_line_p && !w->pseudo_window_p)
     {
       BLOCK_INPUT;
-      x_draw_row_bitmaps (w, desired_row);
+      x_draw_row_fringe_bitmaps (w, desired_row);
       UNBLOCK_INPUT;
     }
       
@@ -791,9 +797,10 @@ x_after_update_window_line (desired_row)
       && desired_row->full_width_p
       && (f = XFRAME (w->frame),
          width = FRAME_INTERNAL_BORDER_WIDTH (f),
-         width != 0))
+         width != 0)
+      && (height = desired_row->visible_height,
+         height > 0))
     {
-      int height = desired_row->visible_height;
       int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
 
       /* Internal border is drawn below the tool bar.  */
@@ -812,21 +819,23 @@ x_after_update_window_line (desired_row)
 }
 
 
-/* Draw the bitmap WHICH in one of the areas to the left or right of
+/* Draw the bitmap WHICH in one of the left or right fringes of
    window W.  ROW is the glyph row for which to display the bitmap; it
    determines the vertical position at which the bitmap has to be
    drawn.  */
 
 static void
-x_draw_bitmap (w, row, which)
+x_draw_fringe_bitmap (w, row, which, left_p)
      struct window *w;
      struct glyph_row *row;
-     enum bitmap_type which;
+     enum fringe_bitmap_type which;
+     int left_p;
 {
   struct frame *f = XFRAME (WINDOW_FRAME (w));
   Display *display = FRAME_X_DISPLAY (f);
   Window window = FRAME_X_WINDOW (f);
   int x, y, wd, h, dy;
+  int b1, b2;
   unsigned char *bits;
   Pixmap pixmap;
   GC gc = f->output_data.x->normal_gc;
@@ -836,93 +845,151 @@ x_draw_bitmap (w, row, which)
   /* Must clip because of partially visible lines.  */
   x_clip_to_row (w, row, gc, 1);
 
+  /* Convert row to frame coordinates.  */
+  y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
+
   switch (which)
     {
+    case NO_FRINGE_BITMAP:
+      wd = 0;
+      h = 0;
+      break;
+
     case LEFT_TRUNCATION_BITMAP:
       wd = left_width;
       h = left_height;
       bits = left_bits;
-      x = (WINDOW_TO_FRAME_PIXEL_X (w, 0)
-          - wd
-          - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f) - wd) / 2);
       break;
       
     case OVERLAY_ARROW_BITMAP:
-      wd = left_width;
-      h = left_height;
+      wd = ov_width;
+      h = ov_height;
       bits = ov_bits;
-      x = (WINDOW_TO_FRAME_PIXEL_X (w, 0)
-          - wd
-          - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f) - wd) / 2);
       break;
       
     case RIGHT_TRUNCATION_BITMAP:
       wd = right_width;
       h = right_height;
       bits = right_bits;
-      x = window_box_right (w, -1);
-      x += (FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f) - wd) / 2;
       break;
 
     case CONTINUED_LINE_BITMAP:
-      wd = right_width;
-      h = right_height;
+      wd = continued_width;
+      h = continued_height;
       bits = continued_bits;
-      x = window_box_right (w, -1);
-      x += (FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f) - wd) / 2;
       break;
       
     case CONTINUATION_LINE_BITMAP:
       wd = continuation_width;
       h = continuation_height;
       bits = continuation_bits;
-      x = (WINDOW_TO_FRAME_PIXEL_X (w, 0)
-          - wd
-          - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f) - wd) / 2);
       break;
 
     case ZV_LINE_BITMAP:
       wd = zv_width;
-      h = zv_height;
-      bits = zv_bits;
-      x = (WINDOW_TO_FRAME_PIXEL_X (w, 0)
-          - wd
-          - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f) - wd) / 2);
+      h = zv_height - (y % zv_period);
+      bits = zv_bits + (y % zv_period);
       break;
 
     default:
       abort ();
     }
 
-  /* Convert to frame coordinates.  Set dy to the offset in the row to
-     start drawing the bitmap.  */
-  y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
+  /* Clip bitmap if too high.  */
+  if (h > row->height)
+    h = row->height;
+
+  /* Set dy to the offset in the row to start drawing the bitmap.  */
   dy = (row->height - h) / 2;
 
-  /* Draw the bitmap.  I believe these small pixmaps can be cached
-     by the server.  */
-  face = FACE_FROM_ID (f, BITMAP_AREA_FACE_ID);
-  pixmap = XCreatePixmapFromBitmapData (display, window, bits, wd, h,
-                                       face->foreground,
-                                       face->background, depth);
-  XCopyArea (display, pixmap, window, gc, 0, 0, wd, h, x, y + dy);
-  XFreePixmap (display, pixmap);
+  face = FACE_FROM_ID (f, FRINGE_FACE_ID);
+  PREPARE_FACE_FOR_DISPLAY (f, face);
+
+  /* Clear left fringe if no bitmap to draw or if bitmap doesn't fill
+     the fringe.  */
+  b1 = b2 = -1;
+  if (left_p)
+    {
+      if (wd > FRAME_X_LEFT_FRINGE_WIDTH (f))
+       wd = FRAME_X_LEFT_FRINGE_WIDTH (f);
+      x = (WINDOW_TO_FRAME_PIXEL_X (w, 0)
+          - wd
+          - (FRAME_X_LEFT_FRINGE_WIDTH (f) - wd) / 2);
+      if (wd < FRAME_X_LEFT_FRINGE_WIDTH (f) || row->height > h)
+       {
+         /* If W has a vertical border to its left, don't draw over it.  */
+         int border = ((XFASTINT (w->left) > 0
+                        && !FRAME_HAS_VERTICAL_SCROLL_BARS (f))
+                       ? 1 : 0);
+         b1 = (window_box_left (w, -1)
+               - FRAME_X_LEFT_FRINGE_WIDTH (f)
+               + border);
+         b2 = (FRAME_X_LEFT_FRINGE_WIDTH (f) - border);
+       }
+    }
+  else
+    {
+      if (wd > FRAME_X_RIGHT_FRINGE_WIDTH (f))
+       wd = FRAME_X_RIGHT_FRINGE_WIDTH (f);
+      x = (window_box_right (w, -1)
+          + (FRAME_X_RIGHT_FRINGE_WIDTH (f) - wd) / 2);
+      /* Clear right fringe if no bitmap to draw of if bitmap doesn't fill
+        the fringe.  */
+      if (wd < FRAME_X_RIGHT_FRINGE_WIDTH (f) || row->height > h)
+       {
+         b1 = window_box_right (w, -1);
+         b2 = FRAME_X_RIGHT_FRINGE_WIDTH (f);
+       }
+    }
+
+  if (b1 >= 0)
+    {
+      int header_line_height = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
+      
+      /* In case the same realized face is used for fringes 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 (display, face->gc, FillOpaqueStippled);
+      else
+       XSetForeground (display, face->gc, face->background);
+      
+      XFillRectangle (display, window, face->gc,
+                     b1,
+                     WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height,
+                                                      row->y)),
+                     b2,
+                     row->visible_height);
+      if (!face->stipple)
+       XSetForeground (display, face->gc, face->foreground);
+    }
+
+  if (which != NO_FRINGE_BITMAP)
+    {
+      /* Draw the bitmap.  I believe these small pixmaps can be cached
+        by the server.  */
+      pixmap = XCreatePixmapFromBitmapData (display, window, bits, wd, h,
+                                           face->foreground,
+                                           face->background, depth);
+      XCopyArea (display, pixmap, window, gc, 0, 0, wd, h, x, y + dy);
+      XFreePixmap (display, pixmap);
+    }
+  
   XSetClipMask (display, gc, None);
 }
 
 
-/* Draw flags bitmaps for glyph row ROW on window W.  Call this
+/* Draw fringe bitmaps for glyph row ROW on window W.  Call this
    function with input blocked.  */
 
 static void
-x_draw_row_bitmaps (w, row)
+x_draw_row_fringe_bitmaps (w, row)
      struct window *w;
      struct glyph_row *row;
 {
   struct frame *f = XFRAME (w->frame);
-  enum bitmap_type bitmap;
-  struct face *face;
-  int header_line_height = -1;
+  enum fringe_bitmap_type bitmap;
 
   xassert (interrupt_input_blocked);
 
@@ -931,103 +998,37 @@ x_draw_row_bitmaps (w, row)
   if (row->visible_height <= 0)
     return;
 
-  face = FACE_FROM_ID (f, BITMAP_AREA_FACE_ID);
-  PREPARE_FACE_FOR_DISPLAY (f, face);
-
-  /* Decide which bitmap to draw at the left side.  */
-  if (row->overlay_arrow_p)
-    bitmap = OVERLAY_ARROW_BITMAP;
-  else if (row->truncated_on_left_p)
-    bitmap = LEFT_TRUNCATION_BITMAP;
-  else if (MATRIX_ROW_CONTINUATION_LINE_P (row))
-    bitmap = CONTINUATION_LINE_BITMAP;
-  else if (row->indicate_empty_line_p)
-    bitmap = ZV_LINE_BITMAP;
-  else
-    bitmap = NO_BITMAP;
-
-  /* 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_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.  */
-      int border = ((XFASTINT (w->left) > 0
-                    && !FRAME_HAS_VERTICAL_SCROLL_BARS (f))
-                   ? 1 : 0);
-      int left = window_box_left (w, -1);
-
-      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);
+  if (FRAME_X_LEFT_FRINGE_WIDTH (f) != 0)
+    {
+      /* Decide which bitmap to draw in the left fringe.  */
+      if (row->overlay_arrow_p)
+       bitmap = OVERLAY_ARROW_BITMAP;
+      else if (row->truncated_on_left_p)
+       bitmap = LEFT_TRUNCATION_BITMAP;
+      else if (MATRIX_ROW_CONTINUATION_LINE_P (row))
+       bitmap = CONTINUATION_LINE_BITMAP;
+      else if (row->indicate_empty_line_p)
+       bitmap = ZV_LINE_BITMAP;
       else
-       XSetForeground (FRAME_X_DISPLAY (f), face->gc, face->background);
-      
-      XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                     face->gc,
-                     (left
-                      - FRAME_X_LEFT_FLAGS_AREA_WIDTH (f)
-                      + border),
-                     WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height,
-                                                      row->y)),
-                     FRAME_X_LEFT_FLAGS_AREA_WIDTH (f) - border,
-                     row->visible_height);
-      if (!face->stipple)
-       XSetForeground (FRAME_X_DISPLAY (f), face->gc, face->foreground);
-    }
+       bitmap = NO_FRINGE_BITMAP;
 
-  /* Draw the left bitmap.  */
-  if (bitmap != NO_BITMAP)
-    x_draw_bitmap (w, row, bitmap);
-
-  /* Decide which bitmap to draw at the right side.  */
-  if (row->truncated_on_right_p)
-    bitmap = RIGHT_TRUNCATION_BITMAP;
-  else if (row->continued_p)
-    bitmap = CONTINUED_LINE_BITMAP;
-  else
-    bitmap = NO_BITMAP;
+      x_draw_fringe_bitmap (w, row, bitmap, 1);
+    }
 
-  /* 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_RIGHT_FLAGS_AREA_WIDTH (f)
-      || row->height > FRAME_FLAGS_BITMAP_HEIGHT (f))
+  if (FRAME_X_RIGHT_FRINGE_WIDTH (f) != 0)
     {
-      int right = window_box_right (w, -1);
-
-      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);
+      /* Decide which bitmap to draw in the right fringe.  */
+      if (row->truncated_on_right_p)
+       bitmap = RIGHT_TRUNCATION_BITMAP;
+      else if (row->continued_p)
+       bitmap = CONTINUED_LINE_BITMAP;
+      else if (row->indicate_empty_line_p && FRAME_X_LEFT_FRINGE_WIDTH (f) == 0)
+       bitmap = ZV_LINE_BITMAP;
       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 (header_line_height,
-                                                      row->y)),
-                     FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f),
-                     row->visible_height);
-      if (!face->stipple)
-       XSetForeground (FRAME_X_DISPLAY (f), face->gc, face->foreground);
-    }
+       bitmap = NO_FRINGE_BITMAP;
 
-  /* Draw the right bitmap.  */
-  if (bitmap != NO_BITMAP)
-    x_draw_bitmap (w, row, bitmap);
+      x_draw_fringe_bitmap (w, row, bitmap, 0);
+    }
 }
 
 \f
@@ -3977,7 +3978,7 @@ x_draw_glyph_string_box (s)
   if (s->row->full_width_p
       && !s->w->pseudo_window_p)
     {
-      last_x += FRAME_X_RIGHT_FLAGS_AREA_WIDTH (s->f);
+      last_x += FRAME_X_RIGHT_FRINGE_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);
     }
@@ -4128,7 +4129,7 @@ x_draw_image_relief (s)
   if (s->hl == DRAW_IMAGE_SUNKEN
       || s->hl == DRAW_IMAGE_RAISED)
     {
-      thick = tool_bar_button_relief > 0 ? tool_bar_button_relief : 3;
+      thick = tool_bar_button_relief >= 0 ? tool_bar_button_relief : 3;
       raised_p = s->hl == DRAW_IMAGE_RAISED;
     }
   else
@@ -5063,9 +5064,8 @@ x_draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
   if (row->full_width_p)
     {
       /* X is relative to the left edge of W, without scroll bars
-        or flag areas.  */
+        or fringes.  */
       struct frame *f = XFRAME (w->frame);
-      /* int width = FRAME_FLAGS_AREA_WIDTH (f);  */
       int window_left_x = WINDOW_LEFT_MARGIN (w) * CANON_X_UNIT (f);
 
       x += window_left_x;
@@ -5187,7 +5187,12 @@ x_draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
   for (s = head; s; s = s->next)
     x_draw_glyph_string (s);
 
-  if (area == TEXT_AREA && !row->full_width_p)
+  if (area == TEXT_AREA
+      && !row->full_width_p
+      /* When drawing overlapping rows, only the glyph strings'
+        foreground is drawn, which doesn't erase a cursor
+        completely. */
+      && !overlaps_p)
     {
       int x0 = head ? head->x : x;
       int x1 = tail ? tail->x + tail->background_width : x;
@@ -5195,7 +5200,7 @@ x_draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
       x0 = FRAME_TO_WINDOW_PIXEL_X (w, x0);
       x1 = FRAME_TO_WINDOW_PIXEL_X (w, x1);
       
-      if (!row->full_width_p && XFASTINT (w->left_margin_width) != 0)
+      if (XFASTINT (w->left_margin_width) != 0)
        {
          int left_area_width = window_box_width (w, LEFT_MARGIN_AREA);
          x0 -= left_area_width;
@@ -5731,11 +5736,11 @@ x_scroll_run (w, run)
   int x, y, width, height, from_y, to_y, bottom_y;
 
   /* Get frame-relative bounding box of the text display area of W,
-     without mode lines.  Include in this box the flags areas to the
-     left and right of W.  */
+     without mode lines.  Include in this box the left and right
+     fringe of W.  */
   window_box (w, -1, &x, &y, &width, &height);
-  width += FRAME_X_FLAGS_AREA_WIDTH (f);
-  x -= FRAME_X_LEFT_FLAGS_AREA_WIDTH (f);
+  width += FRAME_X_FRINGE_WIDTH (f);
+  x -= FRAME_X_LEFT_FRINGE_WIDTH (f);
 
   from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y);
   to_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->desired_y);
@@ -5979,7 +5984,7 @@ expose_line (w, row, r)
        expose_area (w, row, r, TEXT_AREA);
       if (row->used[RIGHT_MARGIN_AREA])
        expose_area (w, row, r, RIGHT_MARGIN_AREA);
-      x_draw_row_bitmaps (w, row);
+      x_draw_row_fringe_bitmaps (w, row);
     }
 
   return row->mouse_face_p;
@@ -6735,7 +6740,7 @@ frame_to_window_pixel_xy (w, x, y)
 /* Take proper action when mouse has moved to the mode or header line of
    window W, x-position X.  MODE_LINE_P non-zero means mouse is on the
    mode line.  X is relative to the start of the text display area of
-   W, so the width of bitmap areas and scroll bars must be subtracted
+   W, so the width of fringes and scroll bars must be subtracted
    to get a position relative to the start of the mode line.  */
 
 static void
@@ -6763,7 +6768,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_LEFT_FLAGS_AREA_WIDTH (f));
+             + FRAME_X_LEFT_FRINGE_WIDTH (f));
       
       while (glyph < end
             && x >= x0 + glyph->pixel_width)
@@ -7128,7 +7133,7 @@ note_mouse_highlight (f, x, y)
                {
                  Lisp_Object before = Foverlay_start (overlay);
                  Lisp_Object after = Foverlay_end (overlay);
-                 Lisp_Object ignore;
+                 int ignore;
 
                  /* Note that we might not be able to find position
                     BEFORE in the glyph matrix if the overlay is
@@ -7313,7 +7318,7 @@ x_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
 
 
 /* Handle mouse button event on the tool-bar of frame F, at
-   frame-relative coordinates X/Y.  EVENT_TYPE is either ButtionPress
+   frame-relative coordinates X/Y.  EVENT_TYPE is either ButtonPress
    or ButtonRelase.  */
 
 static void
@@ -8955,9 +8960,10 @@ x_scroll_bar_create (w, top, left, width, height)
     /* Clear the area of W that will serve as a scroll bar.  This is
        for the case that a window has been split horizontally.  In
        this case, no clear_frame is generated to reduce flickering.  */
-    x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                 left, top, width,
-                 window_box_height (w), False);
+    if (width > 0 && height > 0)
+      x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+                   left, top, width,
+                   window_box_height (w), False);
 
     window = XCreateWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
                            /* Position and size of scroll bar.  */
@@ -9200,7 +9206,7 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
   /* Does the scroll bar exist yet?  */
   if (NILP (w->vertical_scroll_bar))
     {
-      if (width && height)
+      if (width > 0 && height > 0)
        {
          BLOCK_INPUT;
          x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
@@ -9232,7 +9238,7 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
 
       /* Since toolkit scroll bars are smaller than the space reserved
         for them on the frame, we have to clear "under" them.  */
-      if (width && height)
+      if (width > 0 && height > 0)
        x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
                      left, top, width, height, False);
 
@@ -9819,7 +9825,7 @@ static Time enter_timestamp;
    me that letting the compiler initialize it to zeros will work okay.
 
    This must be defined outside of XTread_socket, for the same reasons
-   given for enter_time stamp, above.  */
+   given for enter_timestamp, above.  */
 
 static XComposeStatus compose_status;
 
@@ -10402,7 +10408,7 @@ XTread_socket (sd, bufp, numchars, expected)
                     status_return even if the input is too long to
                     fit in 81 bytes.  So, we must prepare sufficient
                     bytes for copy_buffer.  513 bytes (256 chars for
-                    two-byte character set) seems to be a faily good
+                    two-byte character set) seems to be a fairly good
                     approximation.  -- 2000.8.10 handa@etl.go.jp  */
                  unsigned char copy_buffer[513];
                  unsigned char *copy_bufptr = copy_buffer;
@@ -10667,6 +10673,7 @@ XTread_socket (sd, bufp, numchars, expected)
              {
                f = x_any_window_to_frame (dpyinfo, event.xcrossing.window);
 
+#if 0
                if (event.xcrossing.focus)
                  {
                    /* Avoid nasty pop/raise loops.  */
@@ -10680,7 +10687,8 @@ XTread_socket (sd, bufp, numchars, expected)
                  }
                else if (f == dpyinfo->x_focus_frame)
                  x_new_focus_frame (dpyinfo, 0);
-             
+#endif
+
                /* EnterNotify counts as mouse movement,
                   so update things that depend on mouse position.  */
                if (f && !f->output_data.x->hourglass_p)
@@ -10744,6 +10752,7 @@ XTread_socket (sd, bufp, numchars, expected)
                      bufp += n, count += n, numchars -= n;
                    }
 
+#if 0
                  if (event.xcrossing.focus)
                    x_mouse_leave (dpyinfo);
                  else
@@ -10753,6 +10762,7 @@ XTread_socket (sd, bufp, numchars, expected)
                      if (f == dpyinfo->x_focus_frame)
                        x_new_focus_frame (dpyinfo, 0);
                    }
+#endif
                }
              goto OTHER;
 
@@ -11103,7 +11113,7 @@ notice_overwritten_cursor (w, start_x, end_x)
       && w->phys_cursor_on_p
       && output_cursor.vpos == w->phys_cursor.vpos
       && start_x <= w->phys_cursor.x
-      && end_x > w->phys_cursor.x)
+      && (end_x < 0 || end_x > w->phys_cursor.x))
     w->phys_cursor_on_p = 0;
 }
 
@@ -11140,8 +11150,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_LEFT_FLAGS_AREA_WIDTH (f);
-      clip_rect.width += FRAME_X_FLAGS_AREA_WIDTH (f);
+      clip_rect.x -= FRAME_X_LEFT_FRINGE_WIDTH (f);
+      clip_rect.width += FRAME_X_FRINGE_WIDTH (f);
     }
 
   XSetClipRectangles (FRAME_X_DISPLAY (f), gc, 0, 0, &clip_rect, 1, Unsorted);
@@ -11217,12 +11227,6 @@ x_draw_bar_cursor (w, row, width)
 {
   struct frame *f = XFRAME (w->frame);
   struct glyph *cursor_glyph;
-  GC gc;
-  int x;
-  unsigned long mask;
-  XGCValues xgcv;
-  Display *dpy;
-  Window window;
       
   /* If cursor is out of bounds, don't draw garbage.  This can happen
      in mini-buffer windows when switching between echo area glyphs
@@ -11242,13 +11246,23 @@ x_draw_bar_cursor (w, row, width)
     }
   else
     {
-      xgcv.background = f->output_data.x->cursor_pixel;
-      xgcv.foreground = f->output_data.x->cursor_pixel;
+      Display *dpy = FRAME_X_DISPLAY (f);
+      Window window = FRAME_X_WINDOW (f);
+      GC gc = FRAME_X_DISPLAY_INFO (f)->scratch_cursor_gc;
+      unsigned long mask = GCForeground | GCBackground | GCGraphicsExposures;
+      struct face *face = FACE_FROM_ID (f, cursor_glyph->face_id);
+      XGCValues xgcv;
+
+      /* If the glyph's background equals the color we normally draw
+        the bar cursor in, the bar cursor in its normal color is
+        invisible.  Use the glyph's foreground color instead in this
+        case, on the assumption that the glyph's colors are chosen so
+        that the glyph is legible.  */
+      if (face->background == f->output_data.x->cursor_pixel)
+       xgcv.background = xgcv.foreground = face->foreground;
+      else
+       xgcv.background = xgcv.foreground = f->output_data.x->cursor_pixel;
       xgcv.graphics_exposures = 0;
-      mask = GCForeground | GCBackground | GCGraphicsExposures;
-      dpy = FRAME_X_DISPLAY (f);
-      window = FRAME_X_WINDOW (f);
-      gc = FRAME_X_DISPLAY_INFO (f)->scratch_cursor_gc;
   
       if (gc)
        XChangeGC (dpy, gc, mask, &xgcv);
@@ -11260,14 +11274,13 @@ x_draw_bar_cursor (w, row, width)
   
       if (width < 0)
        width = f->output_data.x->cursor_width;
+      width = min (cursor_glyph->pixel_width, width);
   
-      x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
       x_clip_to_row (w, row, gc, 0);
       XFillRectangle (dpy, window, gc,
-                     x,
+                     WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x),
                      WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
-                     min (cursor_glyph->pixel_width, width),
-                     row->height);
+                     width, row->height);
       XSetClipMask (dpy, gc, None);
     }
 }
@@ -11458,6 +11471,7 @@ x_display_and_set_cursor (w, on, hpos, vpos, x, y)
   struct glyph_matrix *current_glyphs;
   struct glyph_row *glyph_row;
   struct glyph *glyph;
+  int cursor_non_selected;
 
   /* This is pointless on invisible frames, and dangerous on garbaged
      windows and frames; in the latter case, the frame or window may
@@ -11493,6 +11507,9 @@ 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.  */
+  cursor_non_selected 
+    = !NILP (Fbuffer_local_value (Qcursor_in_non_selected_windows,
+                                 w->buffer));
   new_cursor_width = -1;
   if (cursor_in_echo_area
       && FRAME_HAS_MINIBUF_P (f)
@@ -11500,7 +11517,7 @@ x_display_and_set_cursor (w, on, hpos, vpos, x, y)
     {
       if (w == XWINDOW (echo_area_window))
        new_cursor_type = FRAME_DESIRED_CURSOR (f);
-      else if (cursor_in_non_selected_windows)
+      else if (cursor_non_selected)
        new_cursor_type = HOLLOW_BOX_CURSOR;
       else
        new_cursor_type = NO_CURSOR;
@@ -11510,10 +11527,8 @@ x_display_and_set_cursor (w, on, hpos, vpos, x, y)
       if (f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
          || w != XWINDOW (f->selected_window))
        {
-         extern int cursor_in_non_selected_windows;
-         
-         if (MINI_WINDOW_P (w)
-             || !cursor_in_non_selected_windows
+         if ((MINI_WINDOW_P (w) && minibuf_level == 0)
+             || !cursor_non_selected
              || NILP (XBUFFER (w->buffer)->cursor_type))
            new_cursor_type = NO_CURSOR;
          else
@@ -12085,7 +12100,9 @@ x_new_font (f, fontname)
   f->output_data.x->font = (XFontStruct *) (fontp->font);
   f->output_data.x->baseline_offset = fontp->baseline_offset;
   f->output_data.x->fontset = -1;
-  
+
+  x_compute_fringe_widths (f, 1);
+
   /* Compute the scroll bar width in character columns.  */
   if (f->scroll_bar_pixel_width > 0)
     {
@@ -12163,6 +12180,90 @@ x_new_fontset (f, fontsetname)
   return build_string (fontsetname);
 }
 
+/* Compute actual fringe widths */
+
+void
+x_compute_fringe_widths (f, redraw)
+     struct frame *f;
+     int redraw;
+{
+  int o_left = f->output_data.x->left_fringe_width;
+  int o_right = f->output_data.x->right_fringe_width;
+  int o_cols = f->output_data.x->fringe_cols;
+
+  Lisp_Object left_fringe = Fassq (Qleft_fringe, f->param_alist);
+  Lisp_Object right_fringe = Fassq (Qright_fringe, f->param_alist);
+  int left_fringe_width, right_fringe_width;
+
+  if (!NILP (left_fringe))
+    left_fringe = Fcdr (left_fringe);
+  if (!NILP (right_fringe))
+    right_fringe = Fcdr (right_fringe);
+
+  left_fringe_width = ((NILP (left_fringe) || !INTEGERP (left_fringe)) ? 8 :
+                      XINT (left_fringe));
+  right_fringe_width = ((NILP (right_fringe) || !INTEGERP (right_fringe)) ? 8 :
+                       XINT (right_fringe));
+
+  if (left_fringe_width || right_fringe_width)
+    {
+      int left_wid = left_fringe_width >= 0 ? left_fringe_width : -left_fringe_width;
+      int right_wid = right_fringe_width >= 0 ? right_fringe_width : -right_fringe_width;
+      int conf_wid = left_wid + right_wid;
+      int font_wid = FONT_WIDTH (f->output_data.x->font);
+      int cols = (left_wid + right_wid + font_wid-1) / font_wid;
+      int real_wid = cols * font_wid;
+      if (left_wid && right_wid)
+       {
+         if (left_fringe_width < 0)
+           {
+             /* Left fringe width is fixed, adjust right fringe if necessary */
+             f->output_data.x->left_fringe_width = left_wid;
+             f->output_data.x->right_fringe_width = real_wid - left_wid;
+           }
+         else if (right_fringe_width < 0)
+           {
+             /* Right fringe width is fixed, adjust left fringe if necessary */
+             f->output_data.x->left_fringe_width = real_wid - right_wid;
+             f->output_data.x->right_fringe_width = right_wid;
+           }
+         else
+           {
+             /* Adjust both fringes with an equal amount.
+                Note that we are doing integer arithmetic here, so don't
+                lose a pixel if the total width is an odd number.  */
+             int fill = real_wid - conf_wid;
+             f->output_data.x->left_fringe_width = left_wid + fill/2;
+             f->output_data.x->right_fringe_width = right_wid + fill - fill/2;
+           }
+       }
+      else if (left_fringe_width)
+       {
+         f->output_data.x->left_fringe_width = real_wid;
+         f->output_data.x->right_fringe_width = 0;
+       }
+      else
+       {
+         f->output_data.x->left_fringe_width = 0;
+         f->output_data.x->right_fringe_width = real_wid;
+       }
+      f->output_data.x->fringe_cols = cols;
+      f->output_data.x->fringes_extra = real_wid;
+    }
+  else
+    {
+      f->output_data.x->left_fringe_width = 0;
+      f->output_data.x->right_fringe_width = 0;
+      f->output_data.x->fringe_cols = 0;
+      f->output_data.x->fringes_extra = 0;
+    }
+
+  if (redraw && FRAME_VISIBLE_P (f))
+    if (o_left != f->output_data.x->left_fringe_width ||
+       o_right != f->output_data.x->right_fringe_width ||
+       o_cols != f->output_data.x->fringe_cols)
+      redraw_frame (f);
+}
 \f
 /***********************************************************************
                           X Input Methods
@@ -12553,8 +12654,9 @@ x_set_window_size_1 (f, change_gravity, cols, rows)
        : FRAME_SCROLL_BAR_PIXEL_WIDTH (f) > 0
        ? 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
-    = FRAME_FLAGS_AREA_WIDTH (f);
+
+  x_compute_fringe_widths (f, 0);
+
   pixelwidth = CHAR_TO_PIXEL_WIDTH (f, cols);
   pixelheight = CHAR_TO_PIXEL_HEIGHT (f, rows);