]> code.delx.au - gnu-emacs/blobdiff - src/xterm.c
(XTread_socket): Check Lisp types for Vx_keysym_table
[gnu-emacs] / src / xterm.c
index 6a3b6ac3a1184f5f8ef2928b5f92ec3b6b6d16c1..b6c63aacfa10f499cc3048ba246d0ea3c356c427 100644 (file)
@@ -1,5 +1,5 @@
 /* X Communication module for terminals which understand the X protocol.
-   Copyright (C) 1989, 93, 94, 95, 96, 1997, 1998, 1999, 2000, 2001
+   Copyright (C) 1989, 93, 94, 95, 96, 1997, 1998, 1999, 2000, 01, 02
    Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
@@ -68,6 +68,7 @@ Boston, MA 02111-1307, USA.  */
 /* #include <sys/param.h>  */
 
 #include "charset.h"
+#include "character.h"
 #include "coding.h"
 #include "ccl.h"
 #include "frame.h"
@@ -84,6 +85,7 @@ Boston, MA 02111-1307, USA.  */
 #include "intervals.h"
 #include "process.h"
 #include "atimer.h"
+#include "keymap.h"
 
 #ifdef USE_X_TOOLKIT
 #include <X11/Shell.h>
@@ -96,6 +98,11 @@ Boston, MA 02111-1307, USA.  */
 #include <unistd.h>
 #endif
 
+#ifdef USE_LUCID
+extern int xlwmenu_window_p P_ ((Widget w, Window window));
+extern void xlwmenu_redisplay P_ ((Widget));
+#endif
+
 #ifdef USE_X_TOOLKIT
 
 extern void free_frame_menubar P_ ((struct frame *));
@@ -144,11 +151,9 @@ extern void _XEditResCheckMessages ();
 #endif
 #endif
 
-#ifndef min
-#define min(a,b) ((a) < (b) ? (a) : (b))
-#endif
-#ifndef max
-#define max(a,b) ((a) > (b) ? (a) : (b))
+#ifdef HAVE_X11R6
+/* This isn't prototyped in OSF 5.0 or or XFree 4.1.  */
+extern char * XSetIMValues P_ ((XIM, ...));
 #endif
 
 #define abs(x) ((x) < 0 ? -(x) : (x))
@@ -156,11 +161,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,
@@ -173,9 +178,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: `<-'.  */
 
@@ -224,6 +237,8 @@ static unsigned char ov_bits[] = {
 
 extern Lisp_Object Qhelp_echo;
 
+/* Default to using XIM if available.  */
+int use_xim = 1;
 \f
 /* Non-nil means Emacs uses toolkit scroll bars.  */
 
@@ -246,6 +261,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.  */
@@ -275,8 +294,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;
@@ -368,7 +385,7 @@ extern Lisp_Object Vcommand_line_args, Vsystem_name;
 
 extern Lisp_Object Vx_no_window_manager;
 
-extern Lisp_Object Qface, Qmouse_face;
+extern Lisp_Object Qface, Qmouse_face, Qeql;
 
 extern int errno;
 
@@ -376,6 +393,12 @@ extern int errno;
 
 extern 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;
+Lisp_Object Vx_keysym_table;
+static Lisp_Object Qalt, Qhyper, Qmeta, Qsuper, Qmodifier_value;
+
 static Lisp_Object Qvendor_specific_keysyms;
 
 extern XrmDatabase x_load_resources P_ ((Display *, char *, char *, char *));
@@ -437,8 +460,6 @@ static void x_draw_phys_cursor_glyph P_ ((struct window *,
                                          enum draw_glyphs_face));
 static void x_update_end P_ ((struct frame *));
 static void XTframe_up_to_date P_ ((struct frame *));
-static void XTreassert_line_highlight P_ ((int, int));
-static void x_change_line_highlight P_ ((int, int, int, int));
 static void XTset_terminal_modes P_ ((void));
 static void XTreset_terminal_modes P_ ((void));
 static void XTcursor_to P_ ((int, int, int, int));
@@ -466,14 +487,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 note_overwritten_text_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 *));
@@ -486,6 +508,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.  */
 
@@ -662,7 +686,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), 
@@ -761,7 +785,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
@@ -772,53 +796,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;
@@ -828,227 +866,193 @@ 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);
-  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);
-  XSetClipMask (display, gc, None);
-}
+  /* 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 flags bitmaps for glyph row ROW on window W.  Call this
-   function with input blocked.  */
-
-static void
-x_draw_row_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;
-
-  xassert (interrupt_input_blocked);
-
-  /* If row is completely invisible, because of vscrolling, we
-     don't have to draw anything.  */
-  if (row->visible_height <= 0)
-    return;
-
-  face = FACE_FROM_ID (f, BITMAP_AREA_FACE_ID);
+  face = FACE_FROM_ID (f, FRINGE_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;
+  /* 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
-    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);
+    {
+      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 bitmap areas and
+      /* 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 (FRAME_X_DISPLAY (f), face->gc, FillOpaqueStippled);
+       XSetFillStyle (display, face->gc, FillOpaqueStippled);
       else
-       XSetForeground (FRAME_X_DISPLAY (f), face->gc, face->background);
+       XSetForeground (display, face->gc, face->background);
       
-      XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                     face->gc,
-                     (left
-                      - FRAME_X_LEFT_FLAGS_AREA_WIDTH (f)
-                      + border),
+      XFillRectangle (display, window, face->gc,
+                     b1,
                      WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height,
                                                       row->y)),
-                     FRAME_X_LEFT_FLAGS_AREA_WIDTH (f) - border,
+                     b2,
                      row->visible_height);
       if (!face->stipple)
-       XSetForeground (FRAME_X_DISPLAY (f), face->gc, face->foreground);
+       XSetForeground (display, face->gc, face->foreground);
     }
 
-  /* 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;
-
-  /* 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 (which != NO_FRINGE_BITMAP)
     {
-      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);
-      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);
+      /* 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);
     }
-
-  /* Draw the right bitmap.  */
-  if (bitmap != NO_BITMAP)
-    x_draw_bitmap (w, row, bitmap);
+  
+  XSetClipMask (display, gc, None);
 }
 
-\f
-/***********************************************************************
-                         Line Highlighting
- ***********************************************************************/
 
-/* External interface to control of standout mode.  Not used for X
-   frames.  Aborts when called.  */
+/* Draw fringe bitmaps for glyph row ROW on window W.  Call this
+   function with input blocked.  */
 
 static void
-XTreassert_line_highlight (new, vpos)
-     int new, vpos;
+x_draw_row_fringe_bitmaps (w, row)
+     struct window *w;
+     struct glyph_row *row;
 {
-  abort ();
-}
+  struct frame *f = XFRAME (w->frame);
+  enum fringe_bitmap_type bitmap;
 
+  xassert (interrupt_input_blocked);
 
-/* Call this when about to modify line at position VPOS and change
-   whether it is highlighted.  Not used for X frames.  Aborts when
-   called.  */
+  /* If row is completely invisible, because of vscrolling, we
+     don't have to draw anything.  */
+  if (row->visible_height <= 0)
+    return;
 
-static void
-x_change_line_highlight (new_highlight, vpos, y, first_unused_hpos)
-     int new_highlight, vpos, y, first_unused_hpos;
-{
-  abort ();
+  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
+       bitmap = NO_FRINGE_BITMAP;
+
+      x_draw_fringe_bitmap (w, row, bitmap, 1);
+    }
+
+  if (FRAME_X_RIGHT_FRINGE_WIDTH (f) != 0)
+    {
+      /* 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
+       bitmap = NO_FRINGE_BITMAP;
+
+      x_draw_fringe_bitmap (w, row, bitmap, 0);
+    }
 }
 
+\f
 
 /* This is called when starting Emacs and when restarting after
    suspend.  When starting Emacs, no X window is mapped.  And nothing
@@ -1142,7 +1146,8 @@ static struct face *x_get_glyph_face_and_encoding P_ ((struct frame *,
 static struct face *x_get_char_face_and_encoding P_ ((struct frame *, int,
                                                      int, XChar2b *, int));
 static XCharStruct *x_per_char_metric P_ ((XFontStruct *, XChar2b *));
-static void x_encode_char P_ ((int, XChar2b *, struct font_info *));
+static void x_encode_char P_ ((int, XChar2b *, struct font_info *,
+                              struct charset *));
 static void x_append_glyph P_ ((struct it *));
 static void x_append_composite_glyph P_ ((struct it *));
 static void x_append_stretch_glyph P_ ((struct it *it, Lisp_Object,
@@ -1226,12 +1231,12 @@ x_per_char_metric (font, char2b)
    the two-byte form of C.  Encoding is returned in *CHAR2B.  */
 
 static INLINE void
-x_encode_char (c, char2b, font_info)
+x_encode_char (c, char2b, font_info, charset)
      int c;
      XChar2b *char2b;
      struct font_info *font_info;
+     struct charset *charset;
 {
-  int charset = CHAR_CHARSET (c);
   XFontStruct *font = font_info->font;
 
   /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
@@ -1244,17 +1249,17 @@ x_encode_char (c, char2b, font_info)
 
       if (CHARSET_DIMENSION (charset) == 1)
        {
-         ccl->reg[0] = charset;
+         ccl->reg[0] = CHARSET_ID (charset);
          ccl->reg[1] = char2b->byte2;
        }
       else
        {
-         ccl->reg[0] = charset;
+         ccl->reg[0] = CHARSET_ID (charset);
          ccl->reg[1] = char2b->byte1;
          ccl->reg[2] = char2b->byte2;
        }
       
-      ccl_driver (ccl, NULL, NULL, 0, 0, NULL);
+      ccl_driver (ccl, NULL, NULL, 0, 0, Qnil);
       
       /* We assume that MSBs are appropriately set/reset by CCL
         program.  */
@@ -1263,11 +1268,11 @@ x_encode_char (c, char2b, font_info)
       else
        char2b->byte1 = ccl->reg[1], char2b->byte2 = ccl->reg[2];
     }
-  else if (font_info->encoding[charset])
+  else if (font_info->encoding_type)
     {
       /* Fixed encoding scheme.  See fontset.h for the meaning of the
         encoding numbers.  */
-      int enc = font_info->encoding[charset];
+      unsigned char enc = font_info->encoding_type;
       
       if ((enc == 1 || enc == 2)
          && CHARSET_DIMENSION (charset) == 2)
@@ -1308,26 +1313,20 @@ x_get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p)
       char2b->byte1 = 0;
       char2b->byte2 = c;
     }
-  else
+  else if (face->font != NULL)
     {
-      int c1, c2, charset;
+      struct font_info *font_info
+       = FONT_INFO_FROM_ID (f, face->font_info_id);
+      struct charset *charset = CHARSET_FROM_ID (font_info->charset);
+      unsigned code = ENCODE_CHAR (charset, c);
       
-      /* Split characters into bytes.  If c2 is -1 afterwards, C is
-        really a one-byte character so that byte1 is zero.  */
-      SPLIT_CHAR (c, charset, c1, c2);
-      if (c2 > 0)
-       char2b->byte1 = c1, char2b->byte2 = c2;
+      if (CHARSET_DIMENSION (charset) == 1)
+       char2b->byte1 = 0, char2b->byte2 = code;
       else
-       char2b->byte1 = 0, char2b->byte2 = c1;
+       char2b->byte1 = code >> 8, char2b->byte2 = code & 0xFF;
 
       /* Maybe encode the character in *CHAR2B.  */
-      if (face->font != NULL)
-       {
-         struct font_info *font_info
-           = FONT_INFO_FROM_ID (f, face->font_info_id);
-         if (font_info)
-           x_encode_char (c, char2b, font_info);
-       }
+      x_encode_char (c, char2b, font_info, charset);
     }
 
   /* Make sure X resources of the face are allocated.  */
@@ -1373,24 +1372,22 @@ x_get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
     }
   else
     {
-      int c1, c2, charset;
+      struct font_info *font_info
+       = FONT_INFO_FROM_ID (f, face->font_info_id);
+      if (font_info)
+       {
+         struct charset *charset = CHARSET_FROM_ID (font_info->charset);
+         unsigned code = ENCODE_CHAR (charset, glyph->u.ch);
       
-      /* Split characters into bytes.  If c2 is -1 afterwards, C is
-        really a one-byte character so that byte1 is zero.  */
-      SPLIT_CHAR (glyph->u.ch, charset, c1, c2);
-      if (c2 > 0)
-       char2b->byte1 = c1, char2b->byte2 = c2;
-      else
-       char2b->byte1 = 0, char2b->byte2 = c1;
+         if (CHARSET_DIMENSION (charset) == 1)
+           char2b->byte1 = 0, char2b->byte2 = code;
+         else
+           char2b->byte1 = code >> 8, char2b->byte2 = code & 0xFF;
 
-      /* Maybe encode the character in *CHAR2B.  */
-      if (charset != CHARSET_ASCII)
-       {
-         struct font_info *font_info
-           = FONT_INFO_FROM_ID (f, face->font_info_id);
-         if (font_info)
+         /* Maybe encode the character in *CHAR2B.  */
+         if (CHARSET_ID (charset) != charset_ascii)
            {
-             x_encode_char (glyph->u.ch, char2b, font_info);
+             x_encode_char (glyph->u.ch, char2b, font_info, charset);
              if (two_byte_p)
                *two_byte_p
                  = ((XFontStruct *) (font_info->font))->max_byte1 > 0;
@@ -1624,7 +1621,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.
 
@@ -1819,20 +1816,13 @@ x_produce_glyphs (it)
       /* Maybe translate single-byte characters to multibyte, or the
         other way.  */
       it->char_to_display = it->c;
-      if (!ASCII_BYTE_P (it->c))
+      if (! ASCII_CHAR_P (it->c)
+         && ! it->multibyte_p)
        {
-         if (unibyte_display_via_language_environment
-             && SINGLE_BYTE_CHAR_P (it->c)
-             && (it->c >= 0240
-                 || !NILP (Vnonascii_translation_table)))
-           {
-             it->char_to_display = unibyte_char_to_multibyte (it->c);
-             it->multibyte_p = 1;
-             it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
-             face = FACE_FROM_ID (it->f, it->face_id);
-           }
-         else if (!SINGLE_BYTE_CHAR_P (it->c)
-                  && !it->multibyte_p)
+         if (SINGLE_BYTE_CHAR_P (it->c)
+             && unibyte_display_via_language_environment)
+           it->char_to_display = unibyte_char_to_multibyte (it->c);
+         if (! SINGLE_BYTE_CHAR_P (it->c))
            {
              it->multibyte_p = 1;
              it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
@@ -1990,17 +1980,15 @@ x_produce_glyphs (it)
 
          /* If we found a font, this font should give us the right
             metrics.  If we didn't find a font, use the frame's
-            default font and calculate the width of the character
-            from the charset width; this is what old redisplay code
-            did.  */
+            default font and calculate the width of the character by
+            multiplying the width of font by the width of the
+            character.  */
          pcm = x_per_char_metric (font, &char2b);
          if (font_not_found_p || !pcm)
            {
-             int charset = CHAR_CHARSET (it->char_to_display);
-
              it->glyph_not_available_p = 1;
              it->pixel_width = (FONT_WIDTH (FRAME_FONT (it->f))
-                                * CHARSET_WIDTH (charset));
+                                * CHAR_WIDTH (it->char_to_display));
              it->phys_ascent = font->ascent + boff;
              it->phys_descent = font->descent - boff;
            }
@@ -2063,10 +2051,7 @@ x_produce_glyphs (it)
       /* Maybe translate single-byte characters to multibyte.  */
       it->char_to_display = it->c;
       if (unibyte_display_via_language_environment
-         && SINGLE_BYTE_CHAR_P (it->c)
-         && (it->c >= 0240
-             || (it->c >= 0200
-                 && !NILP (Vnonascii_translation_table))))
+         && it->c >= 0200)
        {
          it->char_to_display = unibyte_char_to_multibyte (it->c);
        }
@@ -2535,7 +2520,7 @@ static void x_init_glyph_string P_ ((struct glyph_string *,
                                        enum draw_glyphs_face));
 static int x_draw_glyphs P_ ((struct window *, int , struct glyph_row *,
                              enum glyph_row_area, int, int,
-                             enum draw_glyphs_face, int *, int *, int));
+                             enum draw_glyphs_face, int));
 static void x_set_glyph_string_clipping P_ ((struct glyph_string *));
 static void x_set_glyph_string_gc P_ ((struct glyph_string *));
 static void x_draw_glyph_string_background P_ ((struct glyph_string *,
@@ -3852,6 +3837,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;
@@ -3922,7 +3911,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)
@@ -3992,7 +3981,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);
     }
@@ -4019,7 +4008,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)
@@ -4087,8 +4076,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);
@@ -4145,7 +4132,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
@@ -4446,7 +4433,6 @@ x_draw_glyph_string (s)
 
   /* Set up S->gc, set clipping and draw S.  */
   x_set_glyph_string_gc (s);
-  x_set_glyph_string_clipping (s);
 
   /* Draw relief (if any) in advance for char/composition so that the
      glyph string can be drawn over it.  */
@@ -4456,10 +4442,14 @@ x_draw_glyph_string (s)
          || s->first_glyph->type == COMPOSITE_GLYPH))
 
     {
+      x_set_glyph_string_clipping (s);
       x_draw_glyph_string_background (s, 1);
       x_draw_glyph_string_box (s);
+      x_set_glyph_string_clipping (s);
       relief_drawn_p = 1;
     }
+  else
+    x_set_glyph_string_clipping (s);
 
   switch (s->first_glyph->type)
     {
@@ -4840,7 +4830,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
@@ -5044,27 +5036,19 @@ x_set_glyph_string_background_width (s, start, last_x)
    DRAW_IMAGE_SUNKEN   draw an image with a sunken relief around it
    DRAW_IMAGE_RAISED   draw an image with a raised relief around it
 
-   If REAL_START is non-null, return in *REAL_START the real starting
-   position for display.  This can be different from START in case
-   overlapping glyphs must be displayed.  If REAL_END is non-null,
-   return in *REAL_END the real end position for display.  This can be
-   different from END in case overlapping glyphs must be displayed.
-
    If OVERLAPS_P is non-zero, draw only the foreground of characters
    and clip to the physical height of ROW.
 
    Value is the x-position reached, relative to AREA of W.  */
      
 static int
-x_draw_glyphs (w, x, row, area, start, end, hl, real_start, real_end,
-              overlaps_p)
+x_draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
      struct window *w;
      int x;
      struct glyph_row *row;
      enum glyph_row_area area;
      int start, end;
      enum draw_glyphs_face hl;
-     int *real_start, *real_end;
      int overlaps_p;
 {
   struct glyph_string *head, *tail;
@@ -5077,19 +5061,14 @@ x_draw_glyphs (w, x, row, area, start, end, hl, real_start, real_end,
   end = min (end, row->used[area]);
   start = max (0, start);
   start = min (end, start);
-  if (real_start)
-    *real_start = start;
-  if (real_end)
-    *real_end = end;
 
   /* Translate X to frame coordinates.  Set last_x to the right
      end of the drawing area.  */
   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;
@@ -5152,8 +5131,6 @@ x_draw_glyphs (w, x, row, area, start, end, hl, real_start, real_end,
                               DRAW_NORMAL_TEXT, dummy_x, last_x,
                               overlaps_p);
          start = i;
-         if (real_start)
-           *real_start = start;
          x_compute_overhangs_and_x (t, head->x, 1);
          x_prepend_glyph_string_lists (&head, &tail, h, t);
        }
@@ -5173,8 +5150,6 @@ x_draw_glyphs (w, x, row, area, start, end, hl, real_start, real_end,
                               overlaps_p);
          for (s = h; s; s = s->next)
            s->background_filled_p = 1;
-         if (real_start)
-           *real_start = i;
          x_compute_overhangs_and_x (t, head->x, 1);
          x_prepend_glyph_string_lists (&head, &tail, h, t);
        }
@@ -5191,8 +5166,6 @@ x_draw_glyphs (w, x, row, area, start, end, hl, real_start, real_end,
                               overlaps_p);
          x_compute_overhangs_and_x (h, tail->x + tail->width, 0);
          x_append_glyph_string_lists (&head, &tail, h, t);
-         if (real_end)
-           *real_end = i;
        }
 
       /* Append glyph strings for glyphs following the last glyph
@@ -5210,8 +5183,6 @@ x_draw_glyphs (w, x, row, area, start, end, hl, real_start, real_end,
            s->background_filled_p = 1;
          x_compute_overhangs_and_x (h, tail->x + tail->width, 0);
          x_append_glyph_string_lists (&head, &tail, h, t);
-         if (real_end)
-           *real_end = i;
        }
     }
 
@@ -5219,12 +5190,36 @@ x_draw_glyphs (w, x, row, area, start, end, hl, real_start, real_end,
   for (s = head; s; s = s->next)
     x_draw_glyph_string (s);
 
+  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;
+      
+      x0 = FRAME_TO_WINDOW_PIXEL_X (w, x0);
+      x1 = FRAME_TO_WINDOW_PIXEL_X (w, x1);
+      
+      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, area, x0, x1,
+                                row->y, MATRIX_ROW_BOTTOM_Y (row));
+    }
+
   /* Value is the x-position up to which drawn, relative to AREA of W.
      This doesn't include parts drawn because of overhangs.  */
   x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
   if (!row->full_width_p)
     {
-      if (area > LEFT_MARGIN_AREA)
+      if (area > LEFT_MARGIN_AREA && XFASTINT (w->left_margin_width) != 0)
        x_reached -= window_box_width (w, LEFT_MARGIN_AREA);
       if (area > TEXT_AREA)
        x_reached -= window_box_width (w, TEXT_AREA);
@@ -5269,9 +5264,7 @@ x_fix_overlapping_area (w, row, area)
                 && row->glyphs[area][i].overlaps_vertically_p);
 
          x_draw_glyphs (w, start_x, row, area, start, i,
-                        (row->inverse_p
-                         ? DRAW_INVERSE_VIDEO : DRAW_NORMAL_TEXT),
-                        NULL, NULL, 1);
+                        DRAW_NORMAL_TEXT, 1);
        }
       else
        {
@@ -5295,7 +5288,7 @@ x_write_glyphs (start, len)
      struct glyph *start;
      int len;
 {
-  int x, hpos, real_start, real_end;
+  int x, hpos;
 
   xassert (updated_window && updated_row);
   BLOCK_INPUT;
@@ -5306,13 +5299,7 @@ x_write_glyphs (start, len)
   x = x_draw_glyphs (updated_window, output_cursor.x,
                     updated_row, updated_area,
                     hpos, hpos + len,
-                    (updated_row->inverse_p
-                     ? DRAW_INVERSE_VIDEO : DRAW_NORMAL_TEXT),
-                    &real_start, &real_end, 0);
-
-  /* If we drew over the cursor, note that it is not visible any more.  */
-  note_overwritten_text_cursor (updated_window, real_start,
-                               real_end - real_start);
+                    DRAW_NORMAL_TEXT, 0);
 
   UNBLOCK_INPUT;
   
@@ -5334,7 +5321,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;
@@ -5367,8 +5354,7 @@ x_insert_glyphs (start, len)
   /* Write the glyphs.  */
   hpos = start - row->glyphs[updated_area];
   x_draw_glyphs (w, output_cursor.x, row, updated_area, hpos, hpos + len,
-                DRAW_NORMAL_TEXT, &real_start, &real_end, 0);
-  note_overwritten_text_cursor (w, real_start, real_end - real_start);
+                DRAW_NORMAL_TEXT, 0);
   
   /* Advance the output cursor.  */
   output_cursor.hpos += len;
@@ -5447,7 +5433,10 @@ x_clear_end_of_line (to_x)
   
   /* Notice if the cursor will be cleared by this operation.  */
   if (!updated_row->full_width_p)
-    note_overwritten_text_cursor (w, output_cursor.hpos, -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;
      
@@ -5754,11 +5743,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);
@@ -5935,10 +5924,8 @@ expose_area (w, row, r, area)
 
   if (area == TEXT_AREA && row->fill_line_p)
     /* If row extends face to end of line write the whole line.  */
-    x_draw_glyphs (w, 0, row, area,
-                  0, row->used[area],
-                  row->inverse_p ? DRAW_INVERSE_VIDEO : DRAW_NORMAL_TEXT,
-                  NULL, NULL, 0);
+    x_draw_glyphs (w, 0, row, area, 0, row->used[area],
+                  DRAW_NORMAL_TEXT, 0);
   else
     {
       /* Set START_X to the window-relative start position for drawing glyphs of
@@ -5976,8 +5963,7 @@ expose_area (w, row, r, area)
        x_draw_glyphs (w, first_x - start_x, row, area,
                       first - row->glyphs[area],
                       last - row->glyphs[area],
-                      row->inverse_p ? DRAW_INVERSE_VIDEO : DRAW_NORMAL_TEXT,
-                      NULL, NULL, 0);
+                      DRAW_NORMAL_TEXT, 0);
     }
 }
       
@@ -5996,8 +5982,7 @@ expose_line (w, row, r)
   
   if (row->mode_line_p || w->pseudo_window_p)
     x_draw_glyphs (w, 0, row, TEXT_AREA, 0, row->used[TEXT_AREA],
-                  row->inverse_p ? DRAW_INVERSE_VIDEO : DRAW_NORMAL_TEXT,
-                  NULL, NULL, 0);
+                  DRAW_NORMAL_TEXT, 0);
   else
     {
       if (row->used[LEFT_MARGIN_AREA])
@@ -6006,7 +5991,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;
@@ -6436,12 +6421,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
@@ -6449,12 +6450,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.  */
@@ -6619,6 +6637,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, event->x, 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;
@@ -6638,11 +6676,6 @@ note_mouse_movement (frame, event)
     }
 }
 
-/* This is used for debugging, to turn off note_mouse_highlight.  */
-
- int disable_mouse_highlight;
-
-
 \f
 /************************************************************************
                              Mouse Face
@@ -6762,7 +6795,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
@@ -6790,7 +6823,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)
@@ -6860,7 +6893,7 @@ note_mouse_highlight (f, x, y)
     return;
 #endif
 
-  if (disable_mouse_highlight
+  if (NILP (Vmouse_highlight)
       || !f->glyphs_initialized_p)
     return;
 
@@ -7155,7 +7188,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
@@ -7340,7 +7373,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
@@ -7484,7 +7517,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;
@@ -7520,7 +7553,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))
@@ -7670,9 +7703,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.
@@ -7762,82 +7795,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, NULL, NULL, 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),
@@ -7936,7 +7948,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);
       
@@ -8252,7 +8263,7 @@ x_window_to_scroll_bar (window_id)
 }
 
 
-#if defined USE_X_TOOLKIT && defined USE_LUCID
+#if defined USE_LUCID
 
 /* Return the Lucid menu bar WINDOW is part of.  Return null
    if WINDOW is not part of a menu bar.  */
@@ -8277,7 +8288,7 @@ x_window_to_menu_bar (window)
   return NULL;
 }
 
-#endif /* USE_X_TOOLKIT && USE_LUCID */
+#endif /* USE_LUCID */
 
 \f
 /************************************************************************
@@ -8484,7 +8495,6 @@ xm_scroll_callback (widget, client_data, call_data)
 {
   struct scroll_bar *bar = (struct scroll_bar *) client_data;
   XmScrollBarCallbackStruct *cs = (XmScrollBarCallbackStruct *) call_data;
-  double percent;
   int part = -1, whole = 0, portion = 0;
 
   switch (cs->reason)
@@ -8619,7 +8629,7 @@ xaw_jump_callback (widget, client_data, call_data)
    i.e. line or page up or down.  WIDGET is the Xaw scroll bar
    widget.  CLIENT_DATA is a pointer to the scroll_bar structure for
    the scroll bar.  CALL_DATA is an integer specifying the action that
-   has taken place.  It's magnitude is in the range 0..height of the
+   has taken place.  Its magnitude is in the range 0..height of the
    scroll bar.  Negative values mean scroll towards buffer start.
    Values < height of scroll bar mean line-wise movement.  */
 
@@ -8629,7 +8639,8 @@ xaw_scroll_callback (widget, client_data, call_data)
      XtPointer client_data, call_data;
 {
   struct scroll_bar *bar = (struct scroll_bar *) client_data;
-  int position = (int) call_data;
+  /* The position really is stored cast to a pointer.  */
+  int position = (long) call_data;
   Dimension height;
   int part;
 
@@ -8736,7 +8747,6 @@ x_create_toolkit_scroll_bar (f, bar)
   XtSetArg (av[ac], XtNorientation, XtorientVertical); ++ac;
   /* For smoother scrolling with Xaw3d   -sm */
   /* XtSetArg (av[ac], XtNpickTop, True); ++ac; */
-  /* XtSetArg (av[ac], XtNbeNiceToColormap, True); ++ac; */
   
   pixel = f->output_data.x->scroll_bar_foreground_pixel;
   if (pixel != -1)
@@ -8751,7 +8761,61 @@ x_create_toolkit_scroll_bar (f, bar)
       XtSetArg (av[ac], XtNbackground, pixel);
       ++ac;
     }
-  
+
+  /* Top/bottom shadow colors.  */
+
+  /* Allocate them, if necessary.  */
+  if (f->output_data.x->scroll_bar_top_shadow_pixel == -1)
+    {
+      pixel = f->output_data.x->scroll_bar_background_pixel;
+      if (!x_alloc_lighter_color (f, FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f),
+                                 &pixel, 1.2, 0x8000))
+       pixel = -1;
+      f->output_data.x->scroll_bar_top_shadow_pixel = pixel;
+    }
+  if (f->output_data.x->scroll_bar_bottom_shadow_pixel == -1)
+    {
+      pixel = f->output_data.x->scroll_bar_background_pixel;
+      if (!x_alloc_lighter_color (f, FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f),
+                                 &pixel, 0.6, 0x4000))
+       pixel = -1;
+      f->output_data.x->scroll_bar_bottom_shadow_pixel = pixel;
+    }
+
+  /* Tell the toolkit about them.  */
+  if (f->output_data.x->scroll_bar_top_shadow_pixel == -1
+      || f->output_data.x->scroll_bar_bottom_shadow_pixel == -1)
+    /* We tried to allocate a color for the top/bottom shadow, and
+       failed, so tell Xaw3d to use dithering instead.   */
+    {
+      XtSetArg (av[ac], XtNbeNiceToColormap, True);
+      ++ac;
+    }
+  else
+    /* Tell what colors Xaw3d should use for the top/bottom shadow, to
+       be more consistent with other emacs 3d colors, and since Xaw3d is
+       not good at dealing with allocation failure.  */
+    {
+      /* This tells Xaw3d to use real colors instead of dithering for
+        the shadows.  */
+      XtSetArg (av[ac], XtNbeNiceToColormap, False);
+      ++ac;
+
+      /* Specify the colors.  */
+      pixel = f->output_data.x->scroll_bar_top_shadow_pixel;
+      if (pixel != -1)
+       {
+         XtSetArg (av[ac], "topShadowPixel", pixel);
+         ++ac;
+       }
+      pixel = f->output_data.x->scroll_bar_bottom_shadow_pixel;
+      if (pixel != -1)
+       {
+         XtSetArg (av[ac], "bottomShadowPixel", pixel);
+         ++ac;
+       }
+    }
+
   widget = XtCreateWidget (scroll_bar_name, scrollbarWidgetClass,
                           f->output_data.x->edit_widget, av, ac);
 
@@ -8817,7 +8881,6 @@ x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole)
 #ifdef USE_MOTIF
   {
     int size, value;
-    XmScrollBarWidget sb;
 
     /* Slider size.  Must be in the range [1 .. MAX - MIN] where MAX
        is the scroll bar's maximum and MIN is the scroll bar's minimum
@@ -8956,9 +9019,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.  */
@@ -9201,11 +9265,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
@@ -9230,7 +9297,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);
 
@@ -9264,10 +9331,16 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
       {
        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.  */
@@ -9799,11 +9872,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_
@@ -9811,7 +9886,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;
 
@@ -9908,7 +9983,7 @@ XTread_socket (sd, bufp, numchars, expected)
   /* The input is converted to events, thus we can't handle
      composition.  Anyway, there's no XIM that gives us composition
      information.  */
-  coding.composing = COMPOSITION_DISABLED;
+  coding.common_flags &= ~CODING_ANNOTATION_MASK;
 
   /* Find the display we are supposed to read input for.
      It's the one communicating on descriptor SD.  */
@@ -10222,6 +10297,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;
@@ -10240,7 +10317,7 @@ XTread_socket (sd, bufp, numchars, expected)
 #ifndef USE_TOOLKIT_SCROLL_BARS
                  struct scroll_bar *bar;
 #endif
-#if defined USE_X_TOOLKIT && defined USE_LUCID
+#if defined USE_LUCID
                  /* Submenus of the Lucid menu bar aren't widgets
                     themselves, so there's no way to dispatch events
                     to them.  Recognize this case separately.  */
@@ -10250,8 +10327,8 @@ XTread_socket (sd, bufp, numchars, expected)
                    if (widget)
                      xlwmenu_redisplay (widget);
                  }
-#endif /* USE_X_TOOLKIT && USE_LUCID */
-                 
+#endif /* USE_LUCID */
+
 #ifdef USE_TOOLKIT_SCROLL_BARS
                  /* Dispatch event to the widget.  */
                  goto OTHER;
@@ -10269,8 +10346,8 @@ XTread_socket (sd, bufp, numchars, expected)
              break;
 
            case GraphicsExpose:        /* This occurs when an XCopyArea's
-                                     source area was obscured or not
-                                     available.*/
+                                          source area was obscured or not
+                                          available.  */
              f = x_window_to_frame (dpyinfo, event.xgraphicsexpose.drawable);
              if (f)
                {
@@ -10287,7 +10364,7 @@ XTread_socket (sd, bufp, numchars, expected)
 
            case NoExpose:              /* This occurs when an XCopyArea's
                                           source area was completely
-                                          available */
+                                          available */
              break;
 
            case UnmapNotify:
@@ -10300,7 +10377,7 @@ XTread_socket (sd, bufp, numchars, expected)
              
              f = x_top_window_to_frame (dpyinfo, event.xunmap.window);
              if (f)            /* F may no longer exist if
-                                      the frame was deleted.  */
+                                  the frame was deleted.  */
                {
                  /* While a frame is unmapped, display generation is
                     disabled; you don't want to spend time updating a
@@ -10367,6 +10444,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)
                {
@@ -10394,7 +10477,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;
@@ -10468,80 +10551,150 @@ XTread_socket (sd, bufp, numchars, expected)
 
                  if (numchars > 1)
                    {
-                     if (((keysym >= XK_BackSpace && keysym <= XK_Escape)
-                          || keysym == XK_Delete
+                     Lisp_Object c;
+
+                     /* First deal with keysyms which have defined
+                        translations to characters.  */
+                     if (keysym >= 32 && keysym < 128)
+                       /* Avoid explicitly decoding each ASCII character.  */
+                       {
+                         bufp->kind = ascii_keystroke;
+                         bufp->code = keysym;                        
+                         XSETFRAME (bufp->frame_or_window, f);
+                         bufp->arg = Qnil;
+                         bufp->modifiers
+                           = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f),
+                                                     modifiers);
+                         bufp->timestamp = event.xkey.time;
+                         bufp++;
+                         count++;
+                         numchars--;
+                       }
+                     /* Now non-ASCII.  */
+                     else if (HASH_TABLE_P (Vx_keysym_table)
+                              && (CHARACTERP (c = Fgethash (make_number (keysym),
+                                                            Vx_keysym_table,
+                                                            Qnil))))
+                       {
+                         bufp->kind = (ASCII_CHAR_P (XFASTINT (c))
+                                       ? ascii_keystroke
+                                       : multibyte_char_keystroke);
+                         bufp->code = XFASTINT (c);
+                         XSETFRAME (bufp->frame_or_window, f);
+                         bufp->arg = Qnil;
+                         bufp->modifiers
+                           = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f),
+                                                     modifiers);
+                         bufp->timestamp = event.xkey.time;
+                         bufp++;
+                         count++;
+                         numchars--;
+                       }
+                     else if (((keysym >= XK_BackSpace && keysym <= XK_Escape)
+                               || keysym == XK_Delete
 #ifdef XK_ISO_Left_Tab
-                          || (keysym >= XK_ISO_Left_Tab && keysym <= XK_ISO_Enter)
+                               || (keysym >= XK_ISO_Left_Tab && keysym <= XK_ISO_Enter)
 #endif
-                          || (keysym >= XK_Kanji && keysym <= XK_Eisu_toggle)
-                          || IsCursorKey (keysym) /* 0xff50 <= x < 0xff60 */
-                          || IsMiscFunctionKey (keysym) /* 0xff60 <= x < VARIES */
+                               || (keysym >= XK_Kanji && keysym <= XK_Eisu_toggle)
+                               || IsCursorKey (keysym) /* 0xff50 <= x < 0xff60 */
+                               || IsMiscFunctionKey (keysym) /* 0xff60 <= x < VARIES */
 #ifdef HPUX
-                          /* This recognizes the "extended function keys".
-                             It seems there's no cleaner way.
-                             Test IsModifierKey to avoid handling mode_switch
-                             incorrectly.  */
-                          || ((unsigned) (keysym) >= XK_Select
-                              && (unsigned)(keysym) < XK_KP_Space)
+                               /* This recognizes the "extended function
+                                  keys".  It seems there's no cleaner way.
+                                  Test IsModifierKey to avoid handling
+                                  mode_switch incorrectly.  */
+                               || ((unsigned) (keysym) >= XK_Select
+                                   && (unsigned)(keysym) < XK_KP_Space)
 #endif
 #ifdef XK_dead_circumflex
-                          || orig_keysym == XK_dead_circumflex
+                               || orig_keysym == XK_dead_circumflex
 #endif
 #ifdef XK_dead_grave
-                          || orig_keysym == XK_dead_grave
+                               || orig_keysym == XK_dead_grave
 #endif
 #ifdef XK_dead_tilde
-                          || orig_keysym == XK_dead_tilde
+                               || orig_keysym == XK_dead_tilde
 #endif
 #ifdef XK_dead_diaeresis
-                          || orig_keysym == XK_dead_diaeresis
+                               || orig_keysym == XK_dead_diaeresis
 #endif
 #ifdef XK_dead_macron
-                          || orig_keysym == XK_dead_macron
+                               || orig_keysym == XK_dead_macron
 #endif
 #ifdef XK_dead_degree
-                          || orig_keysym == XK_dead_degree
+                               || orig_keysym == XK_dead_degree
 #endif
 #ifdef XK_dead_acute
-                          || orig_keysym == XK_dead_acute
+                               || orig_keysym == XK_dead_acute
 #endif
 #ifdef XK_dead_cedilla
-                          || orig_keysym == XK_dead_cedilla
+                               || orig_keysym == XK_dead_cedilla
 #endif
 #ifdef XK_dead_breve
-                          || orig_keysym == XK_dead_breve
+                               || orig_keysym == XK_dead_breve
 #endif
 #ifdef XK_dead_ogonek
-                          || orig_keysym == XK_dead_ogonek
+                               || orig_keysym == XK_dead_ogonek
 #endif
 #ifdef XK_dead_caron
-                          || orig_keysym == XK_dead_caron
+                               || orig_keysym == XK_dead_caron
 #endif
 #ifdef XK_dead_doubleacute
-                          || orig_keysym == XK_dead_doubleacute
+                               || orig_keysym == XK_dead_doubleacute
 #endif
 #ifdef XK_dead_abovedot
-                          || orig_keysym == XK_dead_abovedot
+                               || orig_keysym == XK_dead_abovedot
 #endif
-                          || IsKeypadKey (keysym) /* 0xff80 <= x < 0xffbe */
-                          || IsFunctionKey (keysym) /* 0xffbe <= x < 0xffe1 */
-                          /* Any "vendor-specific" key is ok.  */
-                          || (orig_keysym & (1 << 28))
-                          || (keysym != NoSymbol && nbytes == 0))
-                         && ! (IsModifierKey (orig_keysym)
+#ifdef XK_dead_abovering
+                               || orig_keysym == XK_dead_abovering
+#endif
+#ifdef XK_dead_iota
+                               || orig_keysym == XK_dead_iota
+#endif
+#ifdef XK_dead_belowdot
+                               || orig_keysym == XK_dead_belowdot
+#endif
+#ifdef XK_dead_voiced_sound
+                               || orig_keysym == XK_dead_voiced_sound
+#endif
+#ifdef XK_dead_semivoiced_sound
+                               || orig_keysym == XK_dead_semivoiced_sound
+#endif
+#ifdef XK_dead_hook
+                               || orig_keysym == XK_dead_hook
+#endif
+#ifdef XK_dead_horn
+                               || orig_keysym == XK_dead_horn
+#endif
+                               || IsKeypadKey (keysym) /* 0xff80 <= x < 0xffbe */
+                               || IsFunctionKey (keysym) /* 0xffbe <= x < 0xffe1 */
+                               /* Any "vendor-specific" key is ok.  */
+                               || (orig_keysym & (1 << 28))
+                               || (keysym != NoSymbol && nbytes == 0))
+                              && ! (IsModifierKey (orig_keysym)
 #ifndef HAVE_X11R5
 #ifdef XK_Mode_switch
-                               || ((unsigned)(orig_keysym) == XK_Mode_switch)
+                                    || ((unsigned)(orig_keysym) == XK_Mode_switch)
 #endif
 #ifdef XK_Num_Lock
-                               || ((unsigned)(orig_keysym) == XK_Num_Lock)
+                                    || ((unsigned)(orig_keysym) == XK_Num_Lock)
 #endif
 #endif /* not HAVE_X11R5 */
-                               ))
+                                    /* The symbols from XK_ISO_Lock to
+                                       XK_ISO_Last_Group_Lock doesn't have
+                                       real modifiers but should be treated
+                                       similarly to Mode_switch by Emacs. */
+#if defined XK_ISO_Lock && defined XK_ISO_Last_Group_Lock
+                                    || ((unsigned)(orig_keysym) >=  XK_ISO_Lock
+                                        && (unsigned)(orig_keysym) <= XK_ISO_Last_Group_Lock)
+#endif
+                                    ))
                        {
                          if (temp_index == sizeof temp_buffer / sizeof (short))
                            temp_index = 0;
                          temp_buffer[temp_index++] = keysym;
+                         /* make_lispy_event will convert this to a symbolic
+                            key.  */
                          bufp->kind = non_ascii_keystroke;
                          bufp->code = keysym;
                          XSETFRAME (bufp->frame_or_window, f);
@@ -10555,7 +10708,7 @@ XTread_socket (sd, bufp, numchars, expected)
                          numchars--;
                        }
                      else if (numchars > nbytes)
-                       {
+                       {       /* Raw characters, not keysym.  */
                          register int i;
                          register int c;
                          int nchars, len;
@@ -10568,39 +10721,38 @@ XTread_socket (sd, bufp, numchars, expected)
                              temp_buffer[temp_index++] = copy_bufptr[i];
                            }
 
-                         if (/* If the event is not from XIM, */
-                             event.xkey.keycode != 0
-                             /* or the current locale doesn't request
-                                decoding of the intup data, ... */
-                             || coding.type == coding_type_raw_text
-                             || coding.type == coding_type_no_conversion)
-                           {
-                             /* ... we can use the input data as is.  */
-                             nchars = nbytes;
-                           }
-                         else
-                           { 
-                             /* We have to decode the input data.  */
-                             int require;
-                             unsigned char *p;
-
-                             require = decoding_buffer_size (&coding, nbytes);
-                             p = (unsigned char *) alloca (require);
-                             coding.mode |= CODING_MODE_LAST_BLOCK;
-                             decode_coding (&coding, copy_bufptr, p,
-                                            nbytes, require);
-                             nbytes = coding.produced;
-                             nchars = coding.produced_char;
-                             copy_bufptr = p;
-                           }
+                         {
+                           /* Decode the input data.  */
+                           coding.destination
+                             = (unsigned char *) malloc (nbytes);
+                           if (! coding.destination)
+                             break;
+                           coding.dst_bytes = nbytes;
+                           coding.mode |= CODING_MODE_LAST_BLOCK;
+                           decode_coding_c_string (&coding, copy_bufptr,
+                                                   nbytes, Qnil);
+                           nbytes = coding.produced;
+                           nchars = coding.produced_char;
+                           if (copy_bufsiz < nbytes)
+                             {
+                               copy_bufsiz = nbytes;
+                               copy_bufptr = (char *) alloca (nbytes);
+                             }
+                           bcopy (coding.destination, copy_bufptr, nbytes);
+                           free (coding.destination);
+                         }
 
                          /* Convert the input data to a sequence of
                             character events.  */
                          for (i = 0; i < nbytes; i += len)
                            {
-                             c = STRING_CHAR_AND_LENGTH (copy_bufptr + i,
-                                                         nbytes - i, len);
-                             bufp->kind = (SINGLE_BYTE_CHAR_P (c)
+                             if (nchars == nbytes)
+                               c = copy_bufptr[i], len = 1;
+                             else
+                               c = STRING_CHAR_AND_LENGTH (copy_bufptr + i,
+                                                           nbytes - i, len);
+                             
+                             bufp->kind = (ASCII_CHAR_P (c)
                                            ? ascii_keystroke
                                            : multibyte_char_keystroke);
                              bufp->code = c;
@@ -10655,6 +10807,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.  */
@@ -10668,7 +10821,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)
@@ -10732,6 +10886,7 @@ XTread_socket (sd, bufp, numchars, expected)
                      bufp += n, count += n, numchars -= n;
                    }
 
+#if 0
                  if (event.xcrossing.focus)
                    x_mouse_leave (dpyinfo);
                  else
@@ -10741,6 +10896,7 @@ XTread_socket (sd, bufp, numchars, expected)
                      if (f == dpyinfo->x_focus_frame)
                        x_new_focus_frame (dpyinfo, 0);
                    }
+#endif
                }
              goto OTHER;
 
@@ -10771,6 +10927,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
@@ -10816,8 +10978,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
@@ -10845,6 +11016,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);
@@ -11076,21 +11251,25 @@ XTread_socket (sd, bufp, numchars, expected)
                             Text Cursor
  ***********************************************************************/
 
-/* Note if the text cursor of window W has been overwritten by a
-   drawing operation that outputs N glyphs starting at HPOS in the
-   line given by output_cursor.vpos.  N < 0 means all the rest of the
-   line after HPOS 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
-note_overwritten_text_cursor (w, hpos, n)
+notice_overwritten_cursor (w, area, x0, x1, y0, y1)
      struct window *w;
-     int hpos, n;
-{
-  if (updated_area == TEXT_AREA
-      && output_cursor.vpos == w->phys_cursor.vpos
-      && hpos <= w->phys_cursor.hpos
-      && (n < 0
-         || hpos + n > w->phys_cursor.hpos))
+     enum glyph_row_area area;
+     int x0, y0, x1, y1;
+{
+  if (area == TEXT_AREA
+      && w->phys_cursor_on_p
+      && 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;
 }
 
@@ -11127,8 +11306,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);
@@ -11204,12 +11383,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
@@ -11229,13 +11402,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);
@@ -11247,14 +11430,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);
     }
 }
@@ -11287,9 +11469,12 @@ x_draw_phys_cursor_glyph (w, row, hl)
      glyphs and mini-buffer.  */
   if (w->phys_cursor.hpos < row->used[TEXT_AREA])
     {
+      int on_p = w->phys_cursor_on_p;
+      
       x_draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
                     w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
-                    hl, 0, 0, 0);
+                    hl, 0);
+      w->phys_cursor_on_p = on_p;
 
       /* When we erase the cursor, and ROW is overlapped by other
         rows, make sure that these overlapping parts of other rows
@@ -11340,6 +11525,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
@@ -11388,8 +11579,6 @@ x_erase_phys_cursor (w)
   /* Erase the cursor by redrawing the character underneath it.  */
   if (mouse_face_here_p)
     hl = DRAW_MOUSE_FACE;
-  else if (cursor_row->inverse_p)
-    hl = DRAW_INVERSE_VIDEO;
   else
     hl = DRAW_NORMAL_TEXT;
   x_draw_phys_cursor_glyph (w, cursor_row, hl);
@@ -11444,6 +11633,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
@@ -11479,6 +11669,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)
@@ -11486,18 +11679,18 @@ 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
@@ -11882,7 +12075,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.  */
 
@@ -12061,15 +12254,22 @@ x_new_font (f, fontname)
      register char *fontname;
 {
   struct font_info *fontp
-    = FS_LOAD_FONT (f, 0, fontname, -1);
+    = FS_LOAD_FONT (f, fontname);
 
   if (!fontp)
     return Qnil;
 
+  if (f->output_data.x->font == (XFontStruct *) (fontp->font))
+    /* This font is already set in frame F.  There's nothing more to
+       do.  */
+    return build_string (fontp->full_name);
+
   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)
     {
@@ -12108,33 +12308,45 @@ x_new_font (f, fontname)
   return build_string (fontp->full_name);
 }
 
-/* Give frame F the fontset named FONTSETNAME as its default font, and
-   return the full name of that fontset.  FONTSETNAME may be a wildcard
-   pattern; in that case, we choose some fontset that fits the pattern.
-   The return value shows which fontset we chose.  */
+/* Give frame F the fontset named FONTSETNAME as its default fontset,
+   and return the full name of that fontset.  FONTSETNAME may be a
+   wildcard pattern; in that case, we choose some fontset that fits
+   the pattern.  FONTSETNAME may be a font name for ASCII characters;
+   in that case, we create a fontset from that font name.
+
+   The return value shows which fontset we chose.  
+   If FONTSETNAME specifies the default fontset, return Qt.
+   If an ASCII font in the specified fontset can't be loaded, return
+   Qnil.  */
 
 Lisp_Object
 x_new_fontset (f, fontsetname)
      struct frame *f;
-     char *fontsetname;
+     Lisp_Object fontsetname;
 {
-  int fontset = fs_query_fontset (build_string (fontsetname), 0);
+  int fontset = fs_query_fontset (fontsetname, 0);
   Lisp_Object result;
 
-  if (fontset < 0)
-    return Qnil;
-
-  if (f->output_data.x->fontset == fontset)
+  if (fontset > 0 && f->output_data.x->fontset == fontset)
     /* This fontset is already set in frame F.  There's nothing more
        to do.  */
     return fontset_name (fontset);
+  else if (fontset == 0)
+    /* The default fontset can't be the default font.   */
+    return Qt;
 
-  result = x_new_font (f, (XSTRING (fontset_ascii (fontset))->data));
+  if (fontset >= 0)
+    result = x_new_font (f, (XSTRING (fontset_ascii (fontset))->data));
+  else
+    result = x_new_font (f, XSTRING (fontsetname)->data);
 
   if (!STRINGP (result))
     /* Can't load ASCII font.  */
     return Qnil;
 
+  if (fontset < 0)
+    fontset = new_fontset_from_font_name (result);
+
   /* Since x_new_font doesn't update any fontset information, do it now.  */
   f->output_data.x->fontset = fontset;
 
@@ -12144,9 +12356,93 @@ x_new_fontset (f, fontsetname)
     xic_set_xfontset (f, XSTRING (fontset_ascii (fontset))->data);
 #endif
   
-  return build_string (fontsetname);
+  return fontset_name (fontset);
 }
 
+/* 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
@@ -12202,32 +12498,32 @@ xim_open_dpy (dpyinfo, resource_name)
      struct x_display_info *dpyinfo;
      char *resource_name;
 {
-#ifdef USE_XIM
   XIM xim;
 
-  xim = XOpenIM (dpyinfo->display, dpyinfo->xrdb, resource_name, EMACS_CLASS);
-  dpyinfo->xim = xim;
-
-  if (xim)
+  if (use_xim)
     {
+      xim = XOpenIM (dpyinfo->display, dpyinfo->xrdb, resource_name,
+                    EMACS_CLASS);
+      dpyinfo->xim = xim;
+
+      if (xim)
+       {
 #ifdef HAVE_X11R6
-      XIMCallback destroy;
+         XIMCallback destroy;
 #endif
       
-      /* Get supported styles and XIM values.  */
-      XGetIMValues (xim, XNQueryInputStyle, &dpyinfo->xim_styles, NULL);
+         /* Get supported styles and XIM values.  */
+         XGetIMValues (xim, XNQueryInputStyle, &dpyinfo->xim_styles, NULL);
       
 #ifdef HAVE_X11R6
-      destroy.callback = xim_destroy_callback;
-      destroy.client_data = (XPointer)dpyinfo;
-      /* This isn't prototyped in OSF 5.0.  */
-      XSetIMValues (xim, XNDestroyCallback, &destroy, NULL);
+         destroy.callback = xim_destroy_callback;
+         destroy.client_data = (XPointer)dpyinfo;
+         XSetIMValues (xim, XNDestroyCallback, &destroy, NULL);
 #endif
+       }
     }
-  
-#else /* not USE_XIM */
-  dpyinfo->xim = NULL;
-#endif /* not USE_XIM */
+  else
+    dpyinfo->xim = NULL;
 }
 
 
@@ -12301,32 +12597,32 @@ xim_initialize (dpyinfo, resource_name)
      struct x_display_info *dpyinfo;
      char *resource_name;
 {
-#ifdef USE_XIM
+  if (use_xim)
+    {
 #ifdef HAVE_X11R6_XIM
-  struct xim_inst_t *xim_inst;
-  int len;
-  
-  dpyinfo->xim = NULL;
-  xim_inst = (struct xim_inst_t *) xmalloc (sizeof (struct xim_inst_t));
-  xim_inst->dpyinfo = dpyinfo;
-  len = strlen (resource_name);
-  xim_inst->resource_name = (char *) xmalloc (len + 1);
-  bcopy (resource_name, xim_inst->resource_name, len + 1);
-  XRegisterIMInstantiateCallback (dpyinfo->display, dpyinfo->xrdb,
-                                 resource_name, EMACS_CLASS,
-                                 xim_instantiate_callback,
-                                 /* Fixme: This is XPointer in
-                                    XFree86 but (XPointer *) on
-                                    Tru64, at least.  */
-                                 (XPointer) xim_inst);
+      struct xim_inst_t *xim_inst;
+      int len;
+  
+      dpyinfo->xim = NULL;
+      xim_inst = (struct xim_inst_t *) xmalloc (sizeof (struct xim_inst_t));
+      xim_inst->dpyinfo = dpyinfo;
+      len = strlen (resource_name);
+      xim_inst->resource_name = (char *) xmalloc (len + 1);
+      bcopy (resource_name, xim_inst->resource_name, len + 1);
+      XRegisterIMInstantiateCallback (dpyinfo->display, dpyinfo->xrdb,
+                                     resource_name, EMACS_CLASS,
+                                     xim_instantiate_callback,
+                                     /* Fixme: This is XPointer in
+                                        XFree86 but (XPointer *) on
+                                        Tru64, at least.  */
+                                     (XPointer) xim_inst);
 #else /* not HAVE_X11R6_XIM */
-  dpyinfo->xim = NULL;
-  xim_open_dpy (dpyinfo, resource_name);
+      dpyinfo->xim = NULL;
+      xim_open_dpy (dpyinfo, resource_name);
 #endif /* not HAVE_X11R6_XIM */
-  
-#else /* not USE_XIM */
-  dpyinfo->xim = NULL;
-#endif /* not USE_XIM */
+    }
+  else
+    dpyinfo->xim = NULL;
 }
 
 
@@ -12336,18 +12632,19 @@ static void
 xim_close_dpy (dpyinfo)
      struct x_display_info *dpyinfo;
 {
-#ifdef USE_XIM
+  if (use_xim)
+    {
 #ifdef HAVE_X11R6_XIM
-  if (dpyinfo->display)
-    XUnregisterIMInstantiateCallback (dpyinfo->display, dpyinfo->xrdb,
-                                     NULL, EMACS_CLASS,
-                                     xim_instantiate_callback, NULL);
+      if (dpyinfo->display)
+       XUnregisterIMInstantiateCallback (dpyinfo->display, dpyinfo->xrdb,
+                                         NULL, EMACS_CLASS,
+                                         xim_instantiate_callback, NULL);
 #endif /* not HAVE_X11R6_XIM */
-  if (dpyinfo->display)
-    XCloseIM (dpyinfo->xim);
-  dpyinfo->xim = NULL;
-  XFree (dpyinfo->xim_styles);
-#endif /* USE_XIM */
+      if (dpyinfo->display)
+       XCloseIM (dpyinfo->xim);
+      dpyinfo->xim = NULL;
+      XFree (dpyinfo->xim_styles);
+    }
 }
 
 #endif /* not HAVE_X11R6_XIM */
@@ -12516,6 +12813,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
@@ -12537,8 +12942,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);
 
@@ -13101,6 +13507,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;
 
@@ -13110,23 +13518,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);
@@ -13134,11 +13559,18 @@ 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)
        unload_color (f, f->output_data.x->scroll_bar_foreground_pixel);
+#ifdef USE_TOOLKIT_SCROLL_BARS
+      /* Scrollbar shadow colors.  */
+      if (f->output_data.x->scroll_bar_top_shadow_pixel != -1)
+       unload_color (f, f->output_data.x->scroll_bar_top_shadow_pixel);
+      if (f->output_data.x->scroll_bar_bottom_shadow_pixel != -1)
+       unload_color (f, f->output_data.x->scroll_bar_bottom_shadow_pixel);
+#endif /* USE_TOOLKIT_SCROLL_BARS */
       if (f->output_data.x->white_relief.allocated_p)
        unload_color (f, f->output_data.x->white_relief.pixel);
       if (f->output_data.x->black_relief.allocated_p)
@@ -13635,8 +14067,8 @@ x_list_fonts (f, pattern, size, maxnames)
        }
 
       /* Now store the result in the cache.  */
-      XCDR (dpyinfo->name_list_element)
-        = Fcons (Fcons (key, list), XCDR (dpyinfo->name_list_element));
+      XSETCDR (dpyinfo->name_list_element,
+              Fcons (Fcons (key, list), XCDR (dpyinfo->name_list_element)));
 
     label_cached:
       if (NILP (list)) continue; /* Try the remaining alternatives.  */
@@ -13679,10 +14111,10 @@ x_list_fonts (f, pattern, size, maxnames)
 
              if (thisinfo)
                {
-                 XCDR (tem)
-                   = (thisinfo->min_bounds.width == 0
-                      ? make_number (0)
-                      : make_number (thisinfo->max_bounds.width));
+                 XSETCDR (tem,
+                          (thisinfo->min_bounds.width == 0
+                           ? make_number (0)
+                           : make_number (thisinfo->max_bounds.width)));
                  BLOCK_INPUT;
                  XFreeFont (dpy, thisinfo);
                  UNBLOCK_INPUT;
@@ -13691,7 +14123,7 @@ x_list_fonts (f, pattern, size, maxnames)
                /* For unknown reason, the previous call of XListFont had
                  returned a font which can't be opened.  Record the size
                  as 0 not to try to open it again.  */
-               XCDR (tem) = make_number (0);
+               XSETCDR (tem, make_number (0));
            }
 
          found_size = XINT (XCDR (tem));
@@ -13907,6 +14339,7 @@ x_load_font (f, fontname, size)
     BLOCK_INPUT;
     fontp->font = font;
     fontp->font_idx = i;
+    fontp->charset = -1;       /* fs_load_font sets it.  */
     fontp->name = (char *) xmalloc (strlen (fontname) + 1);
     bcopy (fontname, fontp->name, strlen (fontname) + 1);
 
@@ -13957,22 +14390,22 @@ x_load_font (f, fontname, size)
        Lisp_Object key = Fcons (Fcons (lispy_name, make_number (256)),
                                 Qnil);
 
-       XCDR (dpyinfo->name_list_element)
-         = Fcons (Fcons (key,
-                         Fcons (Fcons (lispy_full_name,
-                                       make_number (fontp->size)),
-                                Qnil)),
-                  XCDR (dpyinfo->name_list_element));
+       XSETCDR (dpyinfo->name_list_element,
+                Fcons (Fcons (key,
+                              Fcons (Fcons (lispy_full_name,
+                                            make_number (fontp->size)),
+                                     Qnil)),
+                       XCDR (dpyinfo->name_list_element)));
        if (full_name)
          {
            key = Fcons (Fcons (lispy_full_name, make_number (256)),
                         Qnil);
-           XCDR (dpyinfo->name_list_element)
-             = Fcons (Fcons (key,
-                             Fcons (Fcons (lispy_full_name,
-                                           make_number (fontp->size)),
-                                    Qnil)),
-                      XCDR (dpyinfo->name_list_element));
+           XSETCDR (dpyinfo->name_list_element,
+                    Fcons (Fcons (key,
+                                  Fcons (Fcons (lispy_full_name,
+                                                make_number (fontp->size)),
+                                         Qnil)),
+                           XCDR (dpyinfo->name_list_element)));
          }
       }
 
@@ -13984,7 +14417,7 @@ x_load_font (f, fontname, size)
        uses this font.  So, we set information in fontp->encoding[1]
        which is never used by any charset.  If mapping can't be
        decided, set FONT_ENCODING_NOT_DECIDED.  */
-    fontp->encoding[1]
+    fontp->encoding_type
       = (font->max_byte1 == 0
         /* 1-byte font */
         ? (font->min_char_or_byte2 < 0x80
@@ -14019,10 +14452,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;
   }
@@ -14084,6 +14517,100 @@ x_find_ccl_program (fontp)
 }
 
 
+/* Return a char-table whose elements are t if the font FONT_INFO
+   contains a glyph for the corresponding character, and nil if not.
+
+   Fixme: For the moment, this function works only for fonts whose
+   glyph encoding is the same as Unicode (e.g. ISO10646-1 fonts).  */
+
+Lisp_Object
+x_get_font_repertory (f, font_info)
+     FRAME_PTR f;
+     struct font_info *font_info;
+{
+  XFontStruct *font = (XFontStruct *) font_info->font;
+  Lisp_Object table;
+  int min_byte1, max_byte1, min_byte2, max_byte2;
+
+  table = Fmake_char_table (Qnil, Qnil);
+
+  min_byte1 = font->min_byte1;
+  max_byte1 = font->max_byte1;
+  min_byte2 = font->min_char_or_byte2;
+  max_byte2 = font->max_char_or_byte2;
+  if (min_byte1 == 0 && max_byte1 == 0)
+    {
+      if (! font->per_char || font->all_chars_exist == True)
+       char_table_set_range (table, min_byte2, max_byte2, Qt);
+      else
+       {
+         XCharStruct *pcm = font->per_char;
+         int from = -1;
+         int i;
+
+         for (i = min_byte2; i <= max_byte2; i++, pcm++)
+           {
+             if (pcm->width == 0 && pcm->rbearing == pcm->lbearing)
+               {
+                 if (from >= 0)
+                   {
+                     char_table_set_range (table, from, i - 1, Qt);
+                     from = -1;
+                   }
+               }
+             else if (from < 0)
+               from = i;
+           }
+         if (from >= 0)
+           char_table_set_range (table, from, i - 1, Qt);
+       }
+    }
+  else
+    {
+      if (! font->per_char || font->all_chars_exist == True)
+       {
+         int i;
+
+         for (i = min_byte1; i <= max_byte1; i++)
+           char_table_set_range (table,
+                                 (i << 8) | min_byte2, (i << 8) | max_byte2,
+                                 Qt);
+       }
+      else
+       {
+         XCharStruct *pcm = font->per_char;
+         int i;
+
+         for (i = min_byte1; i <= max_byte1; i++)
+           {
+             int from = -1;
+             int j;
+
+             for (j = min_byte2; j <= max_byte2; j++, pcm++)
+               {
+                 if (pcm->width == 0 && pcm->rbearing == pcm->lbearing)
+                   {
+                     if (from >= 0)
+                       {
+                         char_table_set_range (table, (i << 8) | from,
+                                               (i << 8) | (j - 1), Qt);
+                         from = -1;
+                       }
+                   }
+                 else if (from < 0)
+                   from = j;
+               }
+             if (from >= 0)
+               char_table_set_range (table, (i << 8) | from,
+                                     (i << 8) | (j - 1), Qt);
+           }
+       }
+    }
+
+  return table;
+}
+
+
 \f
 /***********************************************************************
                            Initialization
@@ -14333,6 +14860,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;
@@ -14515,6 +15043,18 @@ x_term_init (display_name, xrm_option, resource_name)
       XSynchronize (dpyinfo->display, True);
   }
   
+  {
+    Lisp_Object value;
+    value = display_x_get_resource (dpyinfo,
+                                   build_string ("useXIM"),
+                                   build_string ("UseXIM"),
+                                   Qnil, Qnil);
+    if (STRINGP (value)
+       && (!strcmp (XSTRING (value)->data, "false")
+           || !strcmp (XSTRING (value)->data, "off")))
+      use_xim = 0;
+  }
+  
   UNBLOCK_INPUT;
 
   return dpyinfo;
@@ -14543,7 +15083,7 @@ x_delete_display (dpyinfo)
        {
          if (EQ (XCAR (XCDR (tail)), dpyinfo->name_list_element))
            {
-             XCDR (tail) = XCDR (XCDR (tail));
+             XSETCDR (tail, XCDR (XCDR (tail)));
              break;
            }
          tail = XCDR (tail);
@@ -14611,7 +15151,6 @@ x_initialize ()
 
   clear_frame_hook = x_clear_frame;
   ins_del_lines_hook = x_ins_del_lines;
-  change_line_highlight_hook = x_change_line_highlight;
   delete_glyphs_hook = x_delete_glyphs;
   ring_bell_hook = XTring_bell;
   reset_terminal_modes_hook = XTreset_terminal_modes;
@@ -14621,7 +15160,6 @@ x_initialize ()
   set_terminal_window_hook = XTset_terminal_window;
   read_socket_hook = XTread_socket;
   frame_up_to_date_hook = XTframe_up_to_date;
-  reassert_line_highlight_hook = XTreassert_line_highlight;
   mouse_position_hook = XTmouse_position;
   frame_rehighlight_hook = XTframe_rehighlight;
   frame_raise_lower_hook = XTframe_raise_lower;
@@ -14720,24 +15258,28 @@ 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,
-    "*Non-nil means draw block cursor as wide as the glyph under it.\n\
-For example, if a block cursor is over a tab, it will be drawn as\n\
-wide as that tab on the display.");
+    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
+wide as that tab on the display.  */);
   x_stretch_cursor_p = 0;
 
   DEFVAR_BOOL ("x-use-underline-position-properties",
               &x_use_underline_position_properties,
-     "*Non-nil means make use of UNDERLINE_POSITION font properties.\n\
-Nil means ignore them.  If you encounter fonts with bogus\n\
-UNDERLINE_POSITION font properties, for example 7x13 on XFree prior\n\
-to 4.1, set this to nil.");
+     doc: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
+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;
 
   DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars,
-    "What X toolkit scroll bars Emacs uses.\n\
-A value of nil means Emacs doesn't use X toolkit scroll bars.\n\
-Otherwise, value is a symbol describing the X toolkit.");
+    doc: /* What X toolkit scroll bars Emacs uses.
+A value of nil means Emacs doesn't use X toolkit scroll bars.
+Otherwise, value is a symbol describing the X toolkit.  */);
 #ifdef USE_TOOLKIT_SCROLL_BARS
 #ifdef USE_MOTIF
   Vx_toolkit_scroll_bars = intern ("motif");
@@ -14752,6 +15294,51 @@ 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;
+
+  DEFVAR_LISP ("x-keysym-table", &Vx_keysym_table,
+    doc: /* Hash table of character codes indexed by X keysym codes.  */);
+  Vx_keysym_table = make_hash_table (Qeql, make_number (900),
+                                    make_float (DEFAULT_REHASH_SIZE),
+                                    make_float (DEFAULT_REHASH_THRESHOLD),
+                                    Qnil, Qnil, Qnil);
 }
 
 #endif /* HAVE_X_WINDOWS */