Change defvar_int def and vars to use EMACS_INT instead of just int.
[bpt/emacs.git] / src / xterm.c
index 1d46b26..58a60b5 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: `<-'.  */
 
@@ -245,6 +253,10 @@ static Lisp_Object previous_help_echo;
 
 static int any_help_event_p;
 
+/* Non-zero means autoselect window with the mouse cursor.  */
+
+int x_autoselect_window_p;
+
 /* Non-zero means draw block and hollow cursor as wide as the glyph
    under it.  For example, if a block cursor is over a tab, it will be
    drawn as wide as that tab on the display.  */
@@ -274,8 +286,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;
@@ -373,7 +383,12 @@ extern int errno;
 
 /* A mask of extra modifier bits to put into every keyboard char.  */
 
-extern int extra_keyboard_modifiers;
+extern EMACS_INT extra_keyboard_modifiers;
+
+/* The keysyms to use for the various modifiers.  */
+
+Lisp_Object Vx_alt_keysym, Vx_hyper_keysym, Vx_meta_keysym, Vx_super_keysym;
+static Lisp_Object Qalt, Qhyper, Qmeta, Qsuper, Qmodifier_value;
 
 static Lisp_Object Qvendor_specific_keysyms;
 
@@ -463,14 +478,15 @@ 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 notice_overwritten_cursor P_ ((struct window *, int, int));
+static void x_draw_row_fringe_bitmaps P_ ((struct window *, struct glyph_row *));
+static void notice_overwritten_cursor P_ ((struct window *, enum glyph_row_area,
+                                          int, int, int, int));
 static void x_flush P_ ((struct frame *f));
 static void x_update_begin P_ ((struct frame *));
 static void x_update_window_begin P_ ((struct window *));
@@ -483,6 +499,8 @@ static void x_scroll_bar_report_motion P_ ((struct frame **, Lisp_Object *,
                                            enum scroll_bar_part *,
                                            Lisp_Object *, Lisp_Object *,
                                            unsigned long *));
+static void x_check_fullscreen P_ ((struct frame *));
+static void x_check_fullscreen_move P_ ((struct frame *));
 
 /* Flush display of frame F, or of all frames if F is null.  */
 
@@ -659,7 +677,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 +776,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
@@ -769,53 +787,67 @@ x_after_update_window_line (desired_row)
      struct glyph_row *desired_row;
 {
   struct window *w = updated_window;
+  struct frame *f;
+  int width, height;
   
   xassert (w);
   
   if (!desired_row->mode_line_p && !w->pseudo_window_p)
     {
-      struct frame *f;
-      int width;
-      
       BLOCK_INPUT;
-      x_draw_row_bitmaps (w, desired_row);
-
-      /* When a window has disappeared, make sure that no rest of
-        full-width rows stays visible in the internal border.  */
-      if (windows_or_buffers_changed
-         && (f = XFRAME (w->frame),
-             width = FRAME_INTERNAL_BORDER_WIDTH (f),
-             width != 0))
-       {
-         int height = desired_row->visible_height;
-         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));
-
-         x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                       x, y, width, height, False);
-       }
+      x_draw_row_fringe_bitmaps (w, desired_row);
+      UNBLOCK_INPUT;
+    }
       
+  /* When a window has disappeared, make sure that no rest of
+     full-width rows stays visible in the internal border.  Could
+     check here if updated_window is the leftmost/rightmost window,
+     but I guess it's not worth doing since vertically split windows
+     are almost never used, internal border is rarely set, and the
+     overhead is very small.  */
+  if (windows_or_buffers_changed
+      && desired_row->full_width_p
+      && (f = XFRAME (w->frame),
+         width = FRAME_INTERNAL_BORDER_WIDTH (f),
+         width != 0)
+      && (height = desired_row->visible_height,
+         height > 0))
+    {
+      int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
+
+      /* Internal border is drawn below the tool bar.  */
+      if (WINDOWP (f->tool_bar_window)
+         && w == XWINDOW (f->tool_bar_window))
+       y -= width;
+      
+      BLOCK_INPUT;
+      x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+                   0, y, width, height, False);
+      x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+                   f->output_data.x->pixel_width - width,
+                   y, width, height, False);
       UNBLOCK_INPUT;
     }
 }
 
 
-/* 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;
@@ -825,93 +857,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);
 
@@ -920,103 +1010,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);
-    }
-
-  /* Draw the left bitmap.  */
-  if (bitmap != NO_BITMAP)
-    x_draw_bitmap (w, row, bitmap);
+       bitmap = NO_FRINGE_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
@@ -1595,7 +1619,7 @@ x_append_stretch_glyph (it, object, width, height, ascent)
    4. `:height HEIGHT' specifies that the height of the stretch produced
    should be HEIGHT, measured in canonical character units.
 
-   5. `:relative-height FACTOR' specifies that the height of the the
+   5. `:relative-height FACTOR' specifies that the height of the
    stretch should be FACTOR times the height of the characters having
    the glyph property.
 
@@ -3823,6 +3847,10 @@ x_setup_relief_colors (s)
 
   if (s->face->use_box_color_for_shadows_p)
     color = s->face->box_color;
+  else if (s->first_glyph->type == IMAGE_GLYPH
+          && s->img->pixmap
+          && !IMAGE_BACKGROUND_TRANSPARENT (s->img, s->f, 0))
+    color = IMAGE_BACKGROUND (s->img, s->f, 0);
   else
     {
       XGCValues xgcv;
@@ -3893,7 +3921,7 @@ x_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width,
   for (i = 0; i < width; ++i)
     XDrawLine (dpy, window, gc,
               left_x + i * left_p, bottom_y - i,
-              right_x + 2 - i * right_p, bottom_y - i);
+              right_x + 1 - i * right_p, bottom_y - i);
   
   /* Right.  */
   if (right_p)
@@ -3963,7 +3991,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);
     }
@@ -3990,7 +4018,7 @@ x_draw_glyph_string_box (s)
             || (s->hl == DRAW_MOUSE_FACE
                 && (s->next == NULL
                     || s->next->hl != s->hl)));
-  
+
   x_get_glyph_string_clip_rect (s, &clip_rect);
 
   if (s->face->box == FACE_SIMPLE_BOX)
@@ -4058,8 +4086,6 @@ x_draw_image_foreground (s)
        }
       else
        {
-         unsigned long mask = GCClipXOrigin | GCClipYOrigin | GCFunction;
-         XGCValues xgcv;
          XRectangle clip_rect, image_rect, r;
 
          x_get_glyph_string_clip_rect (s, &clip_rect);
@@ -4116,7 +4142,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 : DEFAULT_TOOL_BAR_BUTTON_RELIEF;
       raised_p = s->hl == DRAW_IMAGE_RAISED;
     }
   else
@@ -4814,7 +4840,9 @@ x_set_glyph_string_background_width (s, start, last_x)
               || s->face->background != default_face->background
               || s->face->stipple != default_face->stipple
               || s->row->mouse_face_p))
-         || s->hl == DRAW_MOUSE_FACE))
+         || s->hl == DRAW_MOUSE_FACE
+         || ((s->hl == DRAW_IMAGE_RAISED || s->hl == DRAW_IMAGE_SUNKEN)
+             && s->row->fill_line_p)))
       s->extends_to_end_of_line_p = 1;
   
   /* If S extends its face to the end of the line, set its
@@ -5049,9 +5077,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;
@@ -5173,7 +5200,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)
+  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;
@@ -5181,14 +5213,15 @@ 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;
          x1 -= left_area_width;
        }
 
-      notice_overwritten_cursor (w, x0, x1);
+      notice_overwritten_cursor (w, area, x0, x1,
+                                row->y, MATRIX_ROW_BOTTOM_Y (row));
     }
 
   /* Value is the x-position up to which drawn, relative to AREA of W.
@@ -5298,7 +5331,7 @@ x_insert_glyphs (start, len)
   int line_height, shift_by_width, shifted_region_width;
   struct glyph_row *row;
   struct glyph *glyph;
-  int frame_x, frame_y, hpos, real_start, real_end;
+  int frame_x, frame_y, hpos;
 
   xassert (updated_window && updated_row);
   BLOCK_INPUT;
@@ -5410,7 +5443,10 @@ x_clear_end_of_line (to_x)
   
   /* Notice if the cursor will be cleared by this operation.  */
   if (!updated_row->full_width_p)
-    notice_overwritten_cursor (w, output_cursor.x, -1);
+    notice_overwritten_cursor (w, updated_area,
+                              output_cursor.x, -1,
+                              updated_row->y,
+                              MATRIX_ROW_BOTTOM_Y (updated_row));
 
   from_x = output_cursor.x;
      
@@ -5717,11 +5753,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);
@@ -5965,7 +6001,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;
@@ -6395,12 +6431,28 @@ x_x_to_emacs_modifiers (dpyinfo, state)
      struct x_display_info *dpyinfo;
      unsigned int state;
 {
+  EMACS_UINT mod_meta = meta_modifier;
+  EMACS_UINT mod_alt  = alt_modifier;
+  EMACS_UINT mod_hyper = hyper_modifier;
+  EMACS_UINT mod_super = super_modifier;
+  Lisp_Object tem;
+  
+  tem = Fget (Vx_alt_keysym, Qmodifier_value);
+  if (! EQ (tem, Qnil)) mod_alt = XUINT (tem);
+  tem = Fget (Vx_meta_keysym, Qmodifier_value);
+  if (! EQ (tem, Qnil)) mod_meta = XUINT (tem);
+  tem = Fget (Vx_hyper_keysym, Qmodifier_value);
+  if (! EQ (tem, Qnil)) mod_hyper = XUINT (tem);
+  tem = Fget (Vx_super_keysym, Qmodifier_value);
+  if (! EQ (tem, Qnil)) mod_super = XUINT (tem);
+  
+
   return (  ((state & (ShiftMask | dpyinfo->shift_lock_mask)) ? shift_modifier : 0)
-         | ((state & ControlMask)             ? ctrl_modifier  : 0)
-         | ((state & dpyinfo->meta_mod_mask)  ? meta_modifier  : 0)
-         | ((state & dpyinfo->alt_mod_mask)   ? alt_modifier  : 0)
-         | ((state & dpyinfo->super_mod_mask) ? super_modifier  : 0)
-         | ((state & dpyinfo->hyper_mod_mask) ? hyper_modifier  : 0));
+            | ((state & ControlMask)                   ? ctrl_modifier : 0)
+            | ((state & dpyinfo->meta_mod_mask)                ? mod_meta      : 0)
+            | ((state & dpyinfo->alt_mod_mask)         ? mod_alt       : 0)
+            | ((state & dpyinfo->super_mod_mask)       ? mod_super     : 0)
+            | ((state & dpyinfo->hyper_mod_mask)       ? mod_hyper     : 0));
 }
 
 static unsigned int
@@ -6408,12 +6460,29 @@ x_emacs_to_x_modifiers (dpyinfo, state)
      struct x_display_info *dpyinfo;
      unsigned int state;
 {
-  return (  ((state & alt_modifier)    ? dpyinfo->alt_mod_mask   : 0)
-         | ((state & super_modifier)   ? dpyinfo->super_mod_mask : 0)
-         | ((state & hyper_modifier)   ? dpyinfo->hyper_mod_mask : 0)
-         | ((state & shift_modifier)   ? ShiftMask        : 0)
-         | ((state & ctrl_modifier)    ? ControlMask      : 0)
-         | ((state & meta_modifier)    ? dpyinfo->meta_mod_mask  : 0));
+  EMACS_UINT mod_meta = meta_modifier;
+  EMACS_UINT mod_alt  = alt_modifier;
+  EMACS_UINT mod_hyper = hyper_modifier;
+  EMACS_UINT mod_super = super_modifier;
+  
+  Lisp_Object tem;
+  
+  tem = Fget (Vx_alt_keysym, Qmodifier_value);
+  if (! EQ (tem, Qnil)) mod_alt = XUINT (tem);
+  tem = Fget (Vx_meta_keysym, Qmodifier_value);
+  if (! EQ (tem, Qnil)) mod_meta = XUINT (tem);
+  tem = Fget (Vx_hyper_keysym, Qmodifier_value);
+  if (! EQ (tem, Qnil)) mod_hyper = XUINT (tem);
+  tem = Fget (Vx_super_keysym, Qmodifier_value);
+  if (! EQ (tem, Qnil)) mod_super = XUINT (tem);
+  
+  
+  return (  ((state & mod_alt)         ? dpyinfo->alt_mod_mask   : 0)
+            | ((state & mod_super)     ? dpyinfo->super_mod_mask : 0)
+            | ((state & mod_hyper)     ? dpyinfo->hyper_mod_mask : 0)
+            | ((state & shift_modifier)        ? ShiftMask        : 0)
+            | ((state & ctrl_modifier) ? ControlMask      : 0)
+            | ((state & mod_meta)      ? dpyinfo->meta_mod_mask  : 0));
 }
 
 /* Convert a keysym to its name.  */
@@ -6578,6 +6647,26 @@ note_mouse_movement (frame, event)
   last_mouse_motion_event = *event;
   XSETFRAME (last_mouse_motion_frame, frame);
 
+  if (x_autoselect_window_p)
+    {
+      int area;
+      Lisp_Object window;
+      static Lisp_Object last_window;
+
+      window = window_from_coordinates (frame, XINT (event->x), XINT (event->y), &area, 0);
+
+      /* Window will be selected only when it is not selected now and
+        last mouse movement event was not in it.  Minubuffer window
+        will be selected iff it is active.  */
+      if (!EQ (window, last_window)
+         && !EQ (window, selected_window)
+         && (!MINI_WINDOW_P (XWINDOW (window))
+             || (EQ (window, minibuf_window) && minibuf_level > 0)))
+       Fselect_window (window);
+
+      last_window=window;
+    }
+
   if (event->window != FRAME_X_WINDOW (frame))
     {
       frame->mouse_moved = 1;
@@ -6597,11 +6686,6 @@ note_mouse_movement (frame, event)
     }
 }
 
-/* This is used for debugging, to turn off note_mouse_highlight.  */
-
- int disable_mouse_highlight;
-
-
 \f
 /************************************************************************
                              Mouse Face
@@ -6721,7 +6805,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
@@ -6749,7 +6833,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)
@@ -6819,7 +6903,7 @@ note_mouse_highlight (f, x, y)
     return;
 #endif
 
-  if (disable_mouse_highlight
+  if (NILP (Vmouse_highlight)
       || !f->glyphs_initialized_p)
     return;
 
@@ -7114,7 +7198,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
@@ -7299,7 +7383,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
@@ -7443,7 +7527,7 @@ note_tool_bar_highlight (f, x, y)
       
  set_help_echo:
   
-  /* Set help_echo to a help string.to display for this tool-bar item.
+  /* Set help_echo to a help string to display for this tool-bar item.
      XTread_socket does the rest.  */
   help_echo_object = help_echo_window = Qnil;
   help_echo_pos = -1;
@@ -7479,7 +7563,7 @@ fast_find_position (w, charpos, hpos, vpos, x, y, stop)
   int i, past_end = 0;
 
   first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
-  row = row_containing_pos (w, charpos, first, NULL);
+  row = row_containing_pos (w, charpos, first, NULL, 0);
   if (row == NULL)
     {
       if (charpos < MATRIX_ROW_START_CHARPOS (first))
@@ -7629,9 +7713,9 @@ fast_find_position (w, pos, hpos, vpos, x, y, stop)
 #endif /* not 0 */
 
 
-/* Find the position of the the glyph for position POS in OBJECT in
-   window W's current matrix, and return in *X/*Y the pixel
-   coordinates, and return in *HPOS/*VPOS the column/row of the glyph.
+/* Find the position of the glyph for position POS in OBJECT in
+   window W's current matrix, and return in *X*Y the pixel
+   coordinates, and return in *HPOS*VPOS the column/row of the glyph.
 
    RIGHT_P non-zero means return the position of the right edge of the
    glyph, RIGHT_P zero means return the left edge position.
@@ -7721,82 +7805,61 @@ show_mouse_face (dpyinfo, draw)
 {
   struct window *w = XWINDOW (dpyinfo->mouse_face_window);
   struct frame *f = XFRAME (WINDOW_FRAME (w));
-  int i;
-  int cursor_off_p = 0;
-  struct cursor_pos saved_cursor;
-
-  saved_cursor = output_cursor;
-  
-  /* If window is in the process of being destroyed, don't bother
-     to do anything.  */
-  if (w->current_matrix == NULL)
-    goto set_x_cursor;
-
-  /* Recognize when we are called to operate on rows that don't exist
-     anymore.  This can happen when a window is split.  */
-  if (dpyinfo->mouse_face_end_row >= w->current_matrix->nrows)
-    goto set_x_cursor;
-
-  set_output_cursor (&w->phys_cursor);
 
-  /* Note that mouse_face_beg_row etc. are window relative.  */
-  for (i = dpyinfo->mouse_face_beg_row;
-       i <= dpyinfo->mouse_face_end_row;
-       i++)
+  if (/* If window is in the process of being destroyed, don't bother
+        to do anything.  */
+      w->current_matrix != NULL
+      /* Don't update mouse highlight if hidden */
+      && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
+      /* Recognize when we are called to operate on rows that don't exist
+        anymore.  This can happen when a window is split.  */
+      && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
     {
-      int start_hpos, end_hpos, start_x;
-      struct glyph_row *row = MATRIX_ROW (w->current_matrix, i);
+      int phys_cursor_on_p = w->phys_cursor_on_p;
+      struct glyph_row *row, *first, *last;
 
-      /* Don't do anything if row doesn't have valid contents.  */
-      if (!row->enabled_p)
-       continue;
-
-      /* For all but the first row, the highlight starts at column 0.  */
-      if (i == dpyinfo->mouse_face_beg_row)
-       {
-         start_hpos = dpyinfo->mouse_face_beg_col;
-         start_x = dpyinfo->mouse_face_beg_x;
-       }
-      else
+      first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
+      last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
+      
+      for (row = first; row <= last && row->enabled_p; ++row)
        {
-         start_hpos = 0;
-         start_x = 0;
-       }
+         int start_hpos, end_hpos, start_x;
 
-      if (i == dpyinfo->mouse_face_end_row)
-       end_hpos = dpyinfo->mouse_face_end_col;
-      else
-       end_hpos = row->used[TEXT_AREA];
+         /* For all but the first row, the highlight starts at column 0.  */
+         if (row == first)
+           {
+             start_hpos = dpyinfo->mouse_face_beg_col;
+             start_x = dpyinfo->mouse_face_beg_x;
+           }
+         else
+           {
+             start_hpos = 0;
+             start_x = 0;
+           }
 
-      /* If the cursor's in the text we are about to rewrite, turn the
-        cursor off.  */
-      if (!w->pseudo_window_p
-         && i == output_cursor.vpos
-         && output_cursor.hpos >= start_hpos - 1
-         && output_cursor.hpos <= end_hpos)
-       {
-         x_update_window_cursor (w, 0);
-         cursor_off_p = 1;
-       }
+         if (row == last)
+           end_hpos = dpyinfo->mouse_face_end_col;
+         else
+           end_hpos = row->used[TEXT_AREA];
 
-      if (end_hpos > start_hpos)
-       {
-         x_draw_glyphs (w, start_x, row, TEXT_AREA, 
-                        start_hpos, end_hpos, draw, 0);
-         row->mouse_face_p = draw == DRAW_MOUSE_FACE || DRAW_IMAGE_RAISED;
-       }
-    }
+         if (end_hpos > start_hpos)
+           {
+             x_draw_glyphs (w, start_x, row, TEXT_AREA, 
+                            start_hpos, end_hpos, draw, 0);
 
-  /* If we turned the cursor off, turn it back on.  */
-  if (cursor_off_p)
-    x_display_cursor (w, 1,
-                     output_cursor.hpos, output_cursor.vpos,
-                     output_cursor.x, output_cursor.y);
+             row->mouse_face_p
+               = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
+           }
+       }
 
-  output_cursor = saved_cursor;
+      /* When we've written over the cursor, arrange for it to
+        be displayed again.  */
+      if (phys_cursor_on_p && !w->phys_cursor_on_p)
+       x_display_cursor (w, 1,
+                         w->phys_cursor.hpos, w->phys_cursor.vpos,
+                         w->phys_cursor.x, w->phys_cursor.y);
+    }
 
- set_x_cursor:
-  
   /* Change the mouse cursor.  */
   if (draw == DRAW_NORMAL_TEXT)
     XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
@@ -7895,7 +7958,6 @@ glyph_rect (f, x, y, rect)
       struct window *w = XWINDOW (window);
       struct glyph_row *r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
       struct glyph_row *end = r + w->current_matrix->nrows - 1;
-      int area;
 
       frame_to_window_pixel_xy (w, &x, &y);
       
@@ -8930,7 +8992,7 @@ x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole)
                                                                         
 /* Create a scroll bar and return the scroll bar vector for it.  W is
    the Emacs window on which to create the scroll bar. TOP, LEFT,
-   WIDTH and HEIGHT are.the pixel coordinates and dimensions of the
+   WIDTH and HEIGHT are the pixel coordinates and dimensions of the
    scroll bar. */
 
 static struct scroll_bar *
@@ -8966,9 +9028,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.  */
@@ -9211,11 +9274,14 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
   /* Does the scroll bar exist yet?  */
   if (NILP (w->vertical_scroll_bar))
     {
-      BLOCK_INPUT;
-      if (width && height)
-       x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                     left, top, width, height, False);
-      UNBLOCK_INPUT;
+      if (width > 0 && height > 0)
+       {
+         BLOCK_INPUT;
+         x_clear_area (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
@@ -9240,7 +9306,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);
 
@@ -9268,16 +9334,22 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
        }
 
       /* Clear areas not covered by the scroll bar because it's not as
-        wide as the area reserved for it .  This makes sure a
+        wide as the area reserved for it.  This makes sure a
         previous mode line display is cleared after C-x 2 C-x 1, for
         example.  */
       {
        int area_width = FRAME_SCROLL_BAR_COLS (f) * CANON_X_UNIT (f);
        int rest = area_width - sb_width;
-       if (rest > 0)
-         x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                       left + area_width -  rest, 0,
-                       rest, max (height, 1), False);
+       if (rest > 0 && height > 0)
+         {
+           if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f))
+             x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+                           left + area_width -  rest, top,
+                           rest, height, False);
+           else
+             x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+                           left, top, rest, height, False);
+         }
       }
       
       /* Move/size the scroll bar window.  */
@@ -9809,11 +9881,13 @@ x_stop_queuing_selection_requests (display)
 \f
 /* The main X event-reading loop - XTread_socket.  */
 
+#if 0
 /* Time stamp of enter window event.  This is only used by XTread_socket,
    but we have to put it out here, since static variables within functions
    sometimes don't work.  */
 
 static Time enter_timestamp;
+#endif
 
 /* This holds the state XLookupString needs to implement dead keys
    and other tricks known as "compose processing".  _X Window System_
@@ -9821,7 +9895,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;
 
@@ -10232,6 +10306,8 @@ XTread_socket (sd, bufp, numchars, expected)
              f = x_window_to_frame (dpyinfo, event.xexpose.window);
              if (f)
                {
+                  x_check_fullscreen (f);
+
                  if (f->async_visible == 0)
                    {
                      f->async_visible = 1;
@@ -10377,6 +10453,12 @@ XTread_socket (sd, bufp, numchars, expected)
            case KeyPress:
              f = x_any_window_to_frame (dpyinfo, event.xkey.window);
 
+             if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight))
+               {
+                 dpyinfo->mouse_face_hidden = 1;
+                 clear_mouse_face (dpyinfo);
+               }
+
 #if defined USE_MOTIF && defined USE_TOOLKIT_SCROLL_BARS
              if (f == 0)
                {
@@ -10404,7 +10486,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;
@@ -10608,8 +10690,12 @@ XTread_socket (sd, bufp, numchars, expected)
                             character events.  */
                          for (i = 0; i < nbytes; i += len)
                            {
-                             c = STRING_CHAR_AND_LENGTH (copy_bufptr + i,
-                                                         nbytes - i, len);
+                             if (nchars == nbytes)
+                               c = copy_bufptr[i], len = 1;
+                             else
+                               c = STRING_CHAR_AND_LENGTH (copy_bufptr + i,
+                                                           nbytes - i, len);
+                             
                              bufp->kind = (SINGLE_BYTE_CHAR_P (c)
                                            ? ascii_keystroke
                                            : multibyte_char_keystroke);
@@ -10665,6 +10751,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.  */
@@ -10678,7 +10765,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)
@@ -10742,6 +10830,7 @@ XTread_socket (sd, bufp, numchars, expected)
                      bufp += n, count += n, numchars -= n;
                    }
 
+#if 0
                  if (event.xcrossing.focus)
                    x_mouse_leave (dpyinfo);
                  else
@@ -10751,6 +10840,7 @@ XTread_socket (sd, bufp, numchars, expected)
                      if (f == dpyinfo->x_focus_frame)
                        x_new_focus_frame (dpyinfo, 0);
                    }
+#endif
                }
              goto OTHER;
 
@@ -10781,6 +10871,12 @@ XTread_socket (sd, bufp, numchars, expected)
                else
                  f = x_window_to_frame (dpyinfo, event.xmotion.window);
 
+               if (dpyinfo->mouse_face_hidden)
+                 {
+                   dpyinfo->mouse_face_hidden = 0;
+                   clear_mouse_face (dpyinfo);
+                 }
+
                if (f)
                  note_mouse_movement (f, &event.xmotion);
                else
@@ -10826,8 +10922,17 @@ XTread_socket (sd, bufp, numchars, expected)
              if (f)
                {
 #ifndef USE_X_TOOLKIT
+                  /* If there is a pending resize for fullscreen, don't
+                     do this one, the right one will come later.
+                    The toolkit version doesn't seem to need this, but we
+                    need to reset it below.  */
+                  int dont_resize =
+                    ((f->output_data.x->want_fullscreen & FULLSCREEN_WAIT)
+                     && FRAME_NEW_WIDTH (f) != 0);
                  int rows = PIXEL_TO_CHAR_HEIGHT (f, event.xconfigure.height);
                  int columns = PIXEL_TO_CHAR_WIDTH (f, event.xconfigure.width);
+                  if (dont_resize)
+                    goto OTHER;
                  
                  /* In the toolkit version, change_frame_size
                     is called by the code that handles resizing
@@ -10855,6 +10960,10 @@ XTread_socket (sd, bufp, numchars, expected)
                  x_real_positions (f, &f->output_data.x->left_pos,
                                    &f->output_data.x->top_pos);
 
+                  x_check_fullscreen_move(f);
+                  if (f->output_data.x->want_fullscreen & FULLSCREEN_WAIT)
+                    f->output_data.x->want_fullscreen &=
+                      ~(FULLSCREEN_WAIT|FULLSCREEN_BOTH);
 #ifdef HAVE_X_I18N
                  if (FRAME_XIC (f) && (FRAME_XIC_STYLE (f) & XIMStatusArea))
                    xic_set_statusarea (f);
@@ -11086,22 +11195,25 @@ XTread_socket (sd, bufp, numchars, expected)
                             Text Cursor
  ***********************************************************************/
 
-/* Notice if the text cursor of window W has been overwritten by a
-   drawing operation that outputs N glyphs starting at START_X and
-   ending at END_X in the line given by output_cursor.vpos.
-   Coordinates are area-relative.  END_X < 0 means means all the rest
-   of the line after START_X has been written.  */
+/* Notice when the text cursor of window W has been completely
+   overwritten by a drawing operation that outputs glyphs in AREA
+   starting at X0 and ending at X1 in the line starting at Y0 and
+   ending at Y1.  X coordinates are area-relative.  X1 < 0 means all
+   the rest of the line after X0 has been written.  Y coordinates
+   are window-relative.  */
 
 static void
-notice_overwritten_cursor (w, start_x, end_x)
+notice_overwritten_cursor (w, area, x0, x1, y0, y1)
      struct window *w;
-     int start_x, end_x;
+     enum glyph_row_area area;
+     int x0, y0, x1, y1;
 {
-  if (updated_area == TEXT_AREA
+  if (area == TEXT_AREA
       && w->phys_cursor_on_p
-      && output_cursor.vpos == w->phys_cursor.vpos
-      && start_x <= w->phys_cursor.x
-      && end_x > w->phys_cursor.x)
+      && y0 <= w->phys_cursor.y
+      && y1 >= w->phys_cursor.y + w->phys_cursor_height
+      && x0 <= w->phys_cursor.x
+      && (x1 < 0 || x1 > w->phys_cursor.x))
     w->phys_cursor_on_p = 0;
 }
 
@@ -11138,8 +11250,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);
@@ -11215,12 +11327,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
@@ -11240,13 +11346,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);
@@ -11258,14 +11374,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);
     }
 }
@@ -11354,6 +11469,12 @@ x_erase_phys_cursor (w)
   if (!cursor_row->enabled_p)
     goto mark_cursor_off;
   
+  /* If row is completely invisible, don't attempt to delete a cursor which
+     isn't there.  This can happen if cursor is at top of a window, and
+     we switch to a buffer with a header line in that window.  */
+  if (cursor_row->visible_height <= 0)
+    goto mark_cursor_off;
+  
   /* This can happen when the new row is shorter than the old one.
      In this case, either x_draw_glyphs or clear_end_of_line
      should have cleared the cursor.  Note that we wouldn't be
@@ -11456,6 +11577,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
@@ -11491,6 +11613,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)
@@ -11498,25 +11623,23 @@ 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
+      else if (cursor_non_selected)
        new_cursor_type = HOLLOW_BOX_CURSOR;
+      else
+       new_cursor_type = NO_CURSOR;
     }
   else
     {
       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
            new_cursor_type = HOLLOW_BOX_CURSOR;
        }
-      else if (w->cursor_off_p)
-       new_cursor_type = NO_CURSOR;
       else
        {
          struct buffer *b = XBUFFER (w->buffer);
@@ -11526,6 +11649,15 @@ x_display_and_set_cursor (w, on, hpos, vpos, x, y)
          else
            new_cursor_type = x_specified_cursor_type (b->cursor_type, 
                                                       &new_cursor_width);
+         if (w->cursor_off_p)
+           {
+             if (new_cursor_type == FILLED_BOX_CURSOR)
+               new_cursor_type = HOLLOW_BOX_CURSOR;
+             else if (new_cursor_type == BAR_CURSOR && new_cursor_width > 1)
+               new_cursor_width = 1;
+             else
+               new_cursor_type = NO_CURSOR;
+           }
        }
     }
 
@@ -11536,7 +11668,9 @@ x_display_and_set_cursor (w, on, hpos, vpos, x, y)
       && (!on
          || w->phys_cursor.x != x
          || w->phys_cursor.y != y
-         || new_cursor_type != w->phys_cursor_type))
+         || new_cursor_type != w->phys_cursor_type
+         || (new_cursor_type == BAR_CURSOR
+             && new_cursor_width != w->phys_cursor_width)))
     x_erase_phys_cursor (w);
 
   /* If the cursor is now invisible and we want it to be visible,
@@ -11553,6 +11687,7 @@ x_display_and_set_cursor (w, on, hpos, vpos, x, y)
       w->phys_cursor.hpos = hpos;
       w->phys_cursor.vpos = vpos;
       w->phys_cursor_type = new_cursor_type;
+      w->phys_cursor_width = new_cursor_width;
       w->phys_cursor_on_p = 1;
 
       switch (new_cursor_type)
@@ -11894,7 +12029,7 @@ x_connection_signal (signalnum) /* If we don't have an argument, */
 
 static char *error_msg;
 
-/* Function installed as fatal_error_signal_hook.in
+/* Function installed as fatal_error_signal_hook in
    x_connection_closed.  Print the X error message, and exit normally,
    instead of dumping core when XtCloseDisplay fails.  */
 
@@ -12081,7 +12216,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)
     {
@@ -12159,6 +12296,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
@@ -12528,6 +12749,114 @@ x_set_offset (f, xoff, yoff, change_gravity)
   UNBLOCK_INPUT;
 }
 
+/* Check if we need to resize the frame due to a fullscreen request.
+   If so needed, resize the frame. */
+static void
+x_check_fullscreen (f)
+     struct frame *f;
+{
+  if (f->output_data.x->want_fullscreen & FULLSCREEN_BOTH)
+    {
+      int width, height, ign;
+                      
+      x_real_positions (f, &f->output_data.x->left_pos,
+                        &f->output_data.x->top_pos);
+
+      x_fullscreen_adjust (f, &width, &height, &ign, &ign);
+                  
+      /* We do not need to move the window, it shall be taken care of
+         when setting WM manager hints.
+         If the frame is visible already, the position is checked by
+         x_check_fullscreen_move. */
+      if (f->width != width || f->height != height)
+        {
+          change_frame_size (f, height, width, 0, 1, 0);
+          SET_FRAME_GARBAGED (f);
+          cancel_mouse_face (f);
+
+          /* Wait for the change of frame size to occur */
+          f->output_data.x->want_fullscreen |= FULLSCREEN_WAIT;
+          
+        }
+    }
+}
+
+/* If frame parameters are set after the frame is mapped, we need to move
+   the window.  This is done in xfns.c.
+   Some window managers moves the window to the right position, some
+   moves the outer window manager window to the specified position.
+   Here we check that we are in the right spot.  If not, make a second
+   move, assuming we are dealing with the second kind of window manager. */
+static void
+x_check_fullscreen_move (f)
+     struct frame *f;
+{
+  if (f->output_data.x->want_fullscreen & FULLSCREEN_MOVE_WAIT)
+  {
+    int expect_top = f->output_data.x->top_pos;
+    int expect_left = f->output_data.x->left_pos;
+
+    if (f->output_data.x->want_fullscreen & FULLSCREEN_HEIGHT)
+      expect_top = 0;
+    if (f->output_data.x->want_fullscreen & FULLSCREEN_WIDTH)
+      expect_left = 0;
+    
+    if (expect_top != f->output_data.x->top_pos
+        || expect_left != f->output_data.x->left_pos)
+      x_set_offset (f, expect_left, expect_top, 1);
+
+    /* Just do this once */
+    f->output_data.x->want_fullscreen &= ~FULLSCREEN_MOVE_WAIT;
+  }
+}
+
+
+/* Calculate fullscreen size.  Return in *TOP_POS and *LEFT_POS the
+   wanted positions of the WM window (not emacs window).
+   Return in *WIDTH and *HEIGHT the wanted width and height of Emacs
+   window (FRAME_X_WINDOW).
+ */
+void
+x_fullscreen_adjust (f, width, height, top_pos, left_pos)
+     struct frame *f;
+     int *width;
+     int *height;
+     int *top_pos;
+     int *left_pos;
+{
+  int newwidth = f->width, newheight = f->height;
+
+  *top_pos = f->output_data.x->top_pos;
+  *left_pos = f->output_data.x->left_pos;
+  
+  if (f->output_data.x->want_fullscreen & FULLSCREEN_HEIGHT)
+    {
+      int ph;
+      
+      ph = FRAME_X_DISPLAY_INFO (f)->height;
+      newheight = PIXEL_TO_CHAR_HEIGHT (f, ph);
+      ph = CHAR_TO_PIXEL_HEIGHT (f, newheight)
+        - f->output_data.x->y_pixels_diff;
+      newheight = PIXEL_TO_CHAR_HEIGHT (f, ph);
+      *top_pos = 0;
+    }
+
+  if (f->output_data.x->want_fullscreen & FULLSCREEN_WIDTH)
+    {
+      int pw;
+      
+      pw = FRAME_X_DISPLAY_INFO (f)->width;
+      newwidth = PIXEL_TO_CHAR_WIDTH (f, pw);
+      pw = CHAR_TO_PIXEL_WIDTH (f, newwidth)
+        - f->output_data.x->x_pixels_diff;
+      newwidth = PIXEL_TO_CHAR_WIDTH (f, pw);
+      *left_pos = 0;
+    }
+
+  *width = newwidth;
+  *height = newheight;
+}
+
 
 /* Change the size of frame F's X window to COLS/ROWS in the case F
    doesn't have a widget.  If CHANGE_GRAVITY is 1, we change to
@@ -12549,8 +12878,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);
 
@@ -13113,6 +13443,8 @@ x_free_frame_resources (f)
      struct frame *f;
 {
   struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+  Lisp_Object bar;
+  struct scroll_bar *b;
 
   BLOCK_INPUT;
 
@@ -13122,23 +13454,40 @@ x_free_frame_resources (f)
     {
       if (f->output_data.x->icon_desc)
        XDestroyWindow (FRAME_X_DISPLAY (f), f->output_data.x->icon_desc);
-      
+
+#ifdef USE_X_TOOLKIT
+      /* Explicitly destroy the scroll bars of the frame.  Without
+        this, we get "BadDrawable" errors from the toolkit later on,
+        presumably from expose events generated for the disappearing
+        toolkit scroll bars.  */
+      for (bar = FRAME_SCROLL_BARS (f); !NILP (bar); bar = b->next)
+       {
+         b = XSCROLL_BAR (bar);
+         x_scroll_bar_remove (b);
+       }
+#endif
+
 #ifdef HAVE_X_I18N
       if (FRAME_XIC (f))
        free_frame_xic (f);
 #endif
-      
-      if (FRAME_X_WINDOW (f))
-       XDestroyWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
-      
+
 #ifdef USE_X_TOOLKIT
       if (f->output_data.x->widget)
        {
          XtDestroyWidget (f->output_data.x->widget);
          f->output_data.x->widget = NULL;
        }
+      /* Tooltips don't have widgets, only a simple X window, even if
+        we are using a toolkit.  */
+      else if (FRAME_X_WINDOW (f))
+       XDestroyWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
+
       free_frame_menubar (f);
-#endif /* USE_X_TOOLKIT */
+#else  /* !USE_X_TOOLKIT */
+      if (FRAME_X_WINDOW (f))
+       XDestroyWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
+#endif /* !USE_X_TOOLKIT */
 
       unload_color (f, f->output_data.x->foreground_pixel);
       unload_color (f, f->output_data.x->background_pixel);
@@ -13146,7 +13495,7 @@ x_free_frame_resources (f)
       unload_color (f, f->output_data.x->cursor_foreground_pixel);
       unload_color (f, f->output_data.x->border_pixel);
       unload_color (f, f->output_data.x->mouse_pixel);
-      
+
       if (f->output_data.x->scroll_bar_background_pixel != -1)
        unload_color (f, f->output_data.x->scroll_bar_background_pixel);
       if (f->output_data.x->scroll_bar_foreground_pixel != -1)
@@ -14038,10 +14387,10 @@ x_load_font (f, fontname, size)
 
     /* Set global flag fonts_changed_p to non-zero if the font loaded
        has a character with a smaller width than any other character
-       before, or if the font loaded has a smalle>r height than any
+       before, or if the font loaded has a smaller height than any
        other font loaded before.  If this happens, it will make a
        glyph matrix reallocation necessary.  */
-    fonts_changed_p = x_compute_min_glyph_bounds (f);
+    fonts_changed_p |= x_compute_min_glyph_bounds (f);
     UNBLOCK_INPUT;
     return fontp;
   }
@@ -14352,6 +14701,7 @@ x_term_init (display_name, xrm_option, resource_name)
   dpyinfo->mouse_face_overlay = Qnil;
   dpyinfo->mouse_face_mouse_x = dpyinfo->mouse_face_mouse_y = 0;
   dpyinfo->mouse_face_defer = 0;
+  dpyinfo->mouse_face_hidden = 0;
   dpyinfo->x_focus_frame = 0;
   dpyinfo->x_focus_event_frame = 0;
   dpyinfo->x_highlight_frame = 0;
@@ -14737,6 +15087,10 @@ syms_of_xterm ()
   staticpro (&previous_help_echo);
   help_echo_pos = -1;
 
+  DEFVAR_BOOL ("x-autoselect-window", &x_autoselect_window_p,
+    doc: /* *Non-nil means autoselect window with mouse pointer.  */);
+  x_autoselect_window_p = 0;
+
   DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
     doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
 For example, if a block cursor is over a tab, it will be drawn as
@@ -14746,7 +15100,7 @@ wide as that tab on the display.  */);
   DEFVAR_BOOL ("x-use-underline-position-properties",
               &x_use_underline_position_properties,
      doc: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
-Nil means ignore them.  If you encounter fonts with bogus
+nil means ignore them.  If you encounter fonts with bogus
 UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
 to 4.1, set this to nil.  */);
   x_use_underline_position_properties = 1;
@@ -14769,6 +15123,45 @@ Otherwise, value is a symbol describing the X toolkit.  */);
 
   staticpro (&last_mouse_motion_frame);
   last_mouse_motion_frame = Qnil;
+  
+  Qmodifier_value = intern ("modifier-value");
+  Qalt = intern ("alt");
+  Fput (Qalt, Qmodifier_value, make_number (alt_modifier));
+  Qhyper = intern ("hyper");
+  Fput (Qhyper, Qmodifier_value, make_number (hyper_modifier));
+  Qmeta = intern ("meta");
+  Fput (Qmeta, Qmodifier_value, make_number (meta_modifier));
+  Qsuper = intern ("super");
+  Fput (Qsuper, Qmodifier_value, make_number (super_modifier));
+  
+  DEFVAR_LISP ("x-alt-keysym", &Vx_alt_keysym,
+    doc: /* Which keys Emacs uses for the alt modifier.
+This should be one of the symbols `alt', `hyper', `meta', `super'.
+For example, `alt' means use the Alt_L and Alt_R keysyms.  The default
+is nil, which is the same as `alt'.  */);
+  Vx_alt_keysym = Qnil;
+  
+  DEFVAR_LISP ("x-hyper-keysym", &Vx_hyper_keysym,
+    doc: /* Which keys Emacs uses for the hyper modifier.
+This should be one of the symbols `alt', `hyper', `meta', `super'.
+For example, `hyper' means use the Hyper_L and Hyper_R keysyms.  The
+default is nil, which is the same as `hyper'.  */);
+  Vx_hyper_keysym = Qnil;
+  
+  DEFVAR_LISP ("x-meta-keysym", &Vx_meta_keysym,
+    doc: /* Which keys Emacs uses for the meta modifier.
+This should be one of the symbols `alt', `hyper', `meta', `super'.
+For example, `meta' means use the Meta_L and Meta_R keysyms.  The
+default is nil, which is the same as `meta'.  */);
+  Vx_meta_keysym = Qnil;
+  
+  DEFVAR_LISP ("x-super-keysym", &Vx_super_keysym,
+    doc: /* Which keys Emacs uses for the super modifier.
+This should be one of the symbols `alt', `hyper', `meta', `super'.
+For example, `super' means use the Super_L and Super_R keysyms.  The
+default is nil, which is the same as `super'.  */);
+  Vx_super_keysym = Qnil;
+
 }
 
 #endif /* HAVE_X_WINDOWS */