]> code.delx.au - gnu-emacs/blobdiff - src/xterm.c
(expose_overlaps): New function.
[gnu-emacs] / src / xterm.c
index 73e987531a935afa2761d34d71d48192e18daa86..3fbdd725c43dce44d353cd5d2d3c1e7e0f1e213d 100644 (file)
@@ -98,7 +98,7 @@ Boston, MA 02111-1307, USA.  */
 #endif
 
 #ifdef USE_LUCID
-extern int xlwmenu_window_p (Widget w, Window window);
+extern int xlwmenu_window_p P_ ((Widget w, Window window));
 extern void xlwmenu_redisplay P_ ((Widget));
 #endif
 
@@ -255,9 +255,9 @@ static int any_help_event_p;
 
 /* Non-zero means autoselect window with the mouse cursor.  */
 
-int autoselect_window_p;
+int mouse_autoselect_window;
 
-/* Last window where we saw the mouse.  Used by autoselect-window.  */
+/* Last window where we saw the mouse.  Used by mouse-autoselect-window.  */
 static Lisp_Object last_window;
 
 /* Non-zero means draw block and hollow cursor as wide as the glyph
@@ -394,6 +394,7 @@ Lisp_Object Vx_alt_keysym, Vx_hyper_keysym, Vx_meta_keysym, Vx_super_keysym;
 static Lisp_Object Qalt, Qhyper, Qmeta, Qsuper, Qmodifier_value;
 
 static Lisp_Object Qvendor_specific_keysyms;
+static Lisp_Object Qlatin_1, Qutf_8;
 
 extern XrmDatabase x_load_resources P_ ((Display *, char *, char *, char *));
 extern Lisp_Object x_icon_type P_ ((struct frame *));
@@ -429,7 +430,8 @@ static int fast_find_string_pos P_ ((struct window *, int, Lisp_Object,
 static void set_output_cursor P_ ((struct cursor_pos *));
 static struct glyph *x_y_to_hpos_vpos P_ ((struct window *, int, int,
                                           int *, int *, int *, int));
-static void note_mode_line_highlight P_ ((struct window *, int, int));
+static void note_mode_line_or_margin_highlight P_ ((struct window *, int,
+                                                   int, int));
 static void note_mouse_highlight P_ ((struct frame *, int, int));
 static void note_tool_bar_highlight P_ ((struct frame *f, int, int));
 static void x_handle_tool_bar_click P_ ((struct frame *, XButtonEvent *));
@@ -464,14 +466,27 @@ static void x_clear_cursor P_ ((struct window *));
 static void frame_highlight P_ ((struct frame *));
 static void frame_unhighlight P_ ((struct frame *));
 static void x_new_focus_frame P_ ((struct x_display_info *, struct frame *));
+static int  x_focus_changed P_ ((int,
+                                 int,
+                                 struct x_display_info *,
+                                 struct frame *,
+                                 struct input_event *,
+                                 int));
+static int  x_detect_focus_change P_ ((struct x_display_info *,
+                                       XEvent *,
+                                       struct input_event *,
+                                       int));
 static void XTframe_rehighlight P_ ((struct frame *));
 static void x_frame_rehighlight P_ ((struct x_display_info *));
 static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *));
-static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int));
+static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int,
+                                  enum text_cursor_kinds));
 static int x_intersect_rectangles P_ ((XRectangle *, XRectangle *,
                                       XRectangle *));
 static void expose_frame P_ ((struct frame *, int, int, int, int));
 static int expose_window_tree P_ ((struct window *, XRectangle *));
+static void expose_overlaps P_ ((struct window *, struct glyph_row *,
+                                struct glyph_row *));
 static int expose_window P_ ((struct window *, XRectangle *));
 static void expose_area P_ ((struct window *, struct glyph_row *,
                             XRectangle *, enum glyph_row_area));
@@ -851,7 +866,7 @@ x_draw_fringe_bitmap (w, row, which, left_p)
   Window window = FRAME_X_WINDOW (f);
   int x, y, wd, h, dy;
   int b1, b2;
-  unsigned char *bits;
+  unsigned char *bits = NULL;
   Pixmap pixmap;
   GC gc = f->output_data.x->normal_gc;
   struct face *face;
@@ -4113,8 +4128,12 @@ x_draw_image_foreground (s)
             the image.  I believe it's looking better if we do
             nothing here for mouse-face.  */
          if (s->hl == DRAW_CURSOR)
-           XDrawRectangle (s->display, s->window, s->gc, x, y,
-                           s->img->width - 1, s->img->height - 1);
+           {
+             int r = s->img->relief;
+             if (r < 0) r = -r;
+             XDrawRectangle (s->display, s->window, s->gc, x - r, y - r,
+                             s->img->width + r*2 - 1, s->img->height + r*2 - 1);
+           }
        }
     }
   else
@@ -4229,8 +4248,12 @@ x_draw_image_foreground_1 (s, pixmap)
             the image.  I believe it's looking better if we do
             nothing here for mouse-face.  */
          if (s->hl == DRAW_CURSOR)
-           XDrawRectangle (s->display, pixmap, s->gc, x, y,
-                           s->img->width - 1, s->img->height - 1);
+           {
+             int r = s->img->relief;
+             if (r < 0) r = -r;
+             XDrawRectangle (s->display, s->window, s->gc, x - r, y - r,
+                             s->img->width + r*2 - 1, s->img->height + r*2 - 1);
+           }
        }
     }
   else
@@ -5320,6 +5343,14 @@ x_write_glyphs (start, len)
                     hpos, hpos + len,
                     DRAW_NORMAL_TEXT, 0);
 
+  /* Invalidate old phys cursor if the glyph at its hpos is redrawn.  */
+  if (updated_area == TEXT_AREA
+      && updated_window->phys_cursor_on_p
+      && updated_window->phys_cursor.vpos == output_cursor.vpos
+      && updated_window->phys_cursor.hpos >= hpos
+      && updated_window->phys_cursor.hpos < hpos + len)
+    updated_window->phys_cursor_on_p = 0;
+
   UNBLOCK_INPUT;
   
   /* Advance the output cursor.  */
@@ -6041,6 +6072,39 @@ x_phys_cursor_in_rect_p (w, r)
 }
 
 
+/* Redraw those parts of glyphs rows during expose event handling that
+   overlap other rows.  Redrawing of an exposed line writes over parts
+   of lines overlapping that exposed line; this function fixes that.
+
+   W is the window being exposed.  FIRST_OVERLAPPING_ROW is the first
+   row in W's current matrix that is exposed and overlaps other rows.
+   LAST_OVERLAPPING_ROW is the last such row.  */
+
+static void
+expose_overlaps (w, first_overlapping_row, last_overlapping_row)
+     struct window *w;
+     struct glyph_row *first_overlapping_row;
+     struct glyph_row *last_overlapping_row;
+{
+  struct glyph_row *row;
+  
+  for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
+    if (row->overlapping_p)
+      {
+       xassert (row->enabled_p && !row->mode_line_p);
+         
+       if (row->used[LEFT_MARGIN_AREA])
+         x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
+  
+       if (row->used[TEXT_AREA])
+         x_fix_overlapping_area (w, row, TEXT_AREA);
+  
+       if (row->used[RIGHT_MARGIN_AREA])
+         x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
+      }
+}
+
+
 /* Redraw the part of window W intersection rectangle FR.  Pixel
    coordinates in FR are frame-relative.  Call this function with
    input blocked.  Value is non-zero if the exposure overwrites
@@ -6082,6 +6146,7 @@ expose_window (w, fr)
       int yb = window_text_bottom_y (w);
       struct glyph_row *row;
       int cursor_cleared_p;
+      struct glyph_row *first_overlapping_row, *last_overlapping_row;
   
       TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
              r.x, r.y, r.width, r.height));
@@ -6100,7 +6165,8 @@ expose_window (w, fr)
       else
        cursor_cleared_p = 0;
 
-      /* Find the first row intersecting the rectangle R.  */
+      /* Update lines intersecting rectangle R.  */
+      first_overlapping_row = last_overlapping_row = NULL;
       for (row = w->current_matrix->rows;
           row->enabled_p;
           ++row)
@@ -6113,6 +6179,13 @@ expose_window (w, fr)
              || (r.y >= y0 && r.y < y1)
              || (r.y + r.height > y0 && r.y + r.height < y1))
            {
+             if (row->overlapping_p)
+               {
+                 if (first_overlapping_row == NULL)
+                   first_overlapping_row = row;
+                 last_overlapping_row = row;
+               }
+             
              if (expose_line (w, row, &r))
                mouse_face_overwritten_p = 1;
            }
@@ -6133,6 +6206,10 @@ expose_window (w, fr)
 
       if (!w->pseudo_window_p)
        {
+         /* Fix the display of overlapping rows.  */
+         if (first_overlapping_row)
+           expose_overlaps (w, first_overlapping_row, last_overlapping_row);
+         
          /* Draw border between windows.  */
          x_draw_vertical_border (w);
       
@@ -6272,6 +6349,121 @@ x_new_focus_frame (dpyinfo, frame)
   x_frame_rehighlight (dpyinfo);
 }
 
+/* Handle FocusIn and FocusOut state changes for FRAME.
+   If FRAME has focus and there exists more than one frame, puts
+   an FOCUS_IN_EVENT into BUFP.
+   Returns number of events inserted into BUFP. */
+
+static int
+x_focus_changed (type, state, dpyinfo, frame, bufp, numchars)
+     int type;
+     int state;
+     struct x_display_info *dpyinfo;
+     struct frame *frame;
+     struct input_event *bufp;
+     int numchars;
+{
+  int nr_events = 0;
+
+  if (type == FocusIn)
+    {
+      if (dpyinfo->x_focus_event_frame != frame)
+        {
+          x_new_focus_frame (dpyinfo, frame);
+          dpyinfo->x_focus_event_frame = frame;
+      
+          /* Don't stop displaying the initial startup message
+             for a switch-frame event we don't need.  */
+          if (numchars > 0
+              && GC_NILP (Vterminal_frame)
+              && GC_CONSP (Vframe_list)
+              && !GC_NILP (XCDR (Vframe_list)))
+            {
+              bufp->kind = FOCUS_IN_EVENT;
+              XSETFRAME (bufp->frame_or_window, frame);
+              bufp->arg = Qnil;
+              ++bufp;
+              numchars--;
+              ++nr_events;
+            }
+        }
+
+      frame->output_data.x->focus_state |= state;
+
+#ifdef HAVE_X_I18N
+      if (FRAME_XIC (frame))
+        XSetICFocus (FRAME_XIC (frame));
+#endif
+    }
+  else if (type == FocusOut)
+    {
+      frame->output_data.x->focus_state &= ~state;
+      
+      if (dpyinfo->x_focus_event_frame == frame)
+        {
+          dpyinfo->x_focus_event_frame = 0;
+          x_new_focus_frame (dpyinfo, 0);
+        }
+
+#ifdef HAVE_X_I18N
+      if (FRAME_XIC (frame))
+        XUnsetICFocus (FRAME_XIC (frame));
+#endif
+    }
+
+  return nr_events;
+}
+
+/* The focus may have changed.  Figure out if it is a real focus change,
+   by checking both FocusIn/Out and Enter/LeaveNotify events.
+
+   Returns number of events inserted into BUFP. */
+
+static int
+x_detect_focus_change (dpyinfo, event, bufp, numchars)
+     struct x_display_info *dpyinfo;
+     XEvent *event;
+     struct input_event *bufp;
+     int numchars;
+{
+  struct frame *frame;
+  int nr_events = 0;
+  
+  frame = x_top_window_to_frame (dpyinfo, event->xany.window);
+  if (! frame) return nr_events;
+  
+  switch (event->type)
+    {
+    case EnterNotify:
+    case LeaveNotify:
+      if (event->xcrossing.detail != NotifyInferior
+          && event->xcrossing.focus
+          && ! (frame->output_data.x->focus_state & FOCUS_EXPLICIT))
+        nr_events = x_focus_changed ((event->type == EnterNotify
+                                      ? FocusIn : FocusOut),
+                                     FOCUS_IMPLICIT,
+                                     dpyinfo,
+                                     frame,
+                                     bufp,
+                                     numchars);
+      break;
+
+    case FocusIn:
+    case FocusOut:
+      nr_events = x_focus_changed (event->type,
+                                   (event->xfocus.detail == NotifyPointer
+                                    ? FOCUS_IMPLICIT : FOCUS_EXPLICIT),
+                                   dpyinfo,
+                                   frame,
+                                   bufp,
+                                   numchars);
+      break;
+    }
+
+  return nr_events;
+}
+
+
 /* Handle an event saying the mouse has moved out of an Emacs frame.  */
 
 void
@@ -6617,9 +6809,9 @@ construct_mouse_click (result, event, f)
      XButtonEvent *event;
      struct frame *f;
 {
-  /* Make the event type no_event; we'll change that when we decide
+  /* Make the event type NO_EVENT; we'll change that when we decide
      otherwise.  */
-  result->kind = mouse_click;
+  result->kind = MOUSE_CLICK_EVENT;
   result->code = event->button - Button1;
   result->timestamp = event->time;
   result->modifiers = (x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f),
@@ -6791,80 +6983,54 @@ 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 fringes and scroll bars must be subtracted
-   to get a position relative to the start of the mode line.  */
-
+/* Take proper action when mouse has moved to the mode or header line
+   or marginal area of window W, x-position X and y-position Y.  Area
+   is 1, 3, 6 or 7 for the mode line, header line, left and right
+   marginal area respectively.  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 to get a position relative to the start of the
+   mode line.  */
 static void
-note_mode_line_highlight (w, x, mode_line_p)
+note_mode_line_or_margin_highlight (w, x, y, portion)
      struct window *w;
-     int x, mode_line_p;
+     int x, y, portion;
 {
   struct frame *f = XFRAME (w->frame);
   struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
   Cursor cursor = dpyinfo->vertical_scroll_bar_cursor;
-  struct glyph_row *row;
+  int charpos;
+  Lisp_Object string, help, map, pos;
 
-  if (mode_line_p)
-    row = MATRIX_MODE_LINE_ROW (w->current_matrix);
-  else
-    row = MATRIX_HEADER_LINE_ROW (w->current_matrix);
+  if (portion == 1 || portion == 3)
+    string = mode_line_string (w, x, y, portion == 1, &charpos);
+   else
+     string = marginal_area_string (w, x, y, portion, &charpos);
 
-  if (row->enabled_p)
+  if (STRINGP (string))
     {
-      struct glyph *glyph, *end;
-      Lisp_Object help, map;
-      int x0;
+      pos = make_number (charpos);
       
-      /* Find the glyph under X.  */
-      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_FRINGE_WIDTH (f));
-      
-      while (glyph < end
-            && x >= x0 + glyph->pixel_width)
+      /* If we're on a string with `help-echo' text property, arrange
+        for the help to be displayed.  This is done by setting the
+        global variable help_echo to the help string.  */
+      help = Fget_text_property (pos, Qhelp_echo, string);
+      if (!NILP (help))
        {
-         x0 += glyph->pixel_width;
-         ++glyph;
+         help_echo = help;
+         XSETWINDOW (help_echo_window, w);
+         help_echo_object = string;
+         help_echo_pos = charpos;
        }
 
-      if (glyph < end
-         && STRINGP (glyph->object)
-         && XSTRING (glyph->object)->intervals
-         && glyph->charpos >= 0
-         && glyph->charpos < XSTRING (glyph->object)->size)
-       {
-         /* If we're on a string with `help-echo' text property,
-            arrange for the help to be displayed.  This is done by
-            setting the global variable help_echo to the help string.  */
-         help = Fget_text_property (make_number (glyph->charpos),
-                                    Qhelp_echo, glyph->object);
-         if (!NILP (help))
-           {
-             help_echo = help;
-             XSETWINDOW (help_echo_window, w);
-             help_echo_object = glyph->object;
-             help_echo_pos = glyph->charpos;
-           }
-
-         /* Change the mouse pointer according to what is under X/Y.  */
-         map = Fget_text_property (make_number (glyph->charpos),
-                                   Qlocal_map, glyph->object);
-         if (KEYMAPP (map))
-           cursor = f->output_data.x->nontext_cursor;
-         else
-           {
-             map = Fget_text_property (make_number (glyph->charpos),
-                                       Qkeymap, glyph->object);
-             if (KEYMAPP (map))
-               cursor = f->output_data.x->nontext_cursor;
-           }
-       }
+     /* Change the mouse pointer according to what is under X/Y.  */
+      map = Fget_text_property (pos, Qlocal_map, string);
+      if (!KEYMAPP (map))
+       map = Fget_text_property (pos, Qkeymap, string);
+      if (KEYMAPP (map))
+       cursor = f->output_data.x->nontext_cursor;
     }
-
+  
   XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), cursor);
 }
 
@@ -6932,10 +7098,10 @@ note_mouse_highlight (f, x, y)
       return;
     }
 
-  /* Mouse is on the mode or header line?  */
-  if (portion == 1 || portion == 3)
+  /* Mouse is on the mode, header line or margin?  */
+  if (portion == 1 || portion == 3 || portion == 6 || portion == 7)
     {
-      note_mode_line_highlight (w, x, portion == 1);
+      note_mode_line_or_margin_highlight (w, x, y, portion);
       return;
     }
   
@@ -7151,7 +7317,7 @@ note_mouse_highlight (f, x, y)
              if (NILP (b))
                b = make_number (0);
              if (NILP (e))
-               e = make_number (XSTRING (object)->size - 1);
+               e = make_number (SCHARS (object) - 1);
              fast_find_string_pos (w, XINT (b), object,
                                    &dpyinfo->mouse_face_beg_col,
                                    &dpyinfo->mouse_face_beg_row,
@@ -7249,7 +7415,7 @@ note_mouse_highlight (f, x, y)
            /* Try text properties.  */
            if (STRINGP (object)
                && charpos >= 0
-               && charpos < XSTRING (object)->size)
+               && charpos < SCHARS (object))
              {
                help = Fget_text_property (make_number (charpos),
                                           Qhelp_echo, object);
@@ -8332,7 +8498,7 @@ static Boolean xaw3d_pick_top;
 /* Action hook installed via XtAppAddActionHook when toolkit scroll
    bars are used..  The hook is responsible for detecting when
    the user ends an interaction with the scroll bar, and generates
-   a `end-scroll' scroll_bar_click' event if so.  */
+   a `end-scroll' SCROLL_BAR_CLICK_EVENT' event if so.  */
 
 static void
 xt_action_hook (widget, client_data, action_name, event, params,
@@ -8462,7 +8628,7 @@ x_scroll_bar_to_input_event (event, ievent)
   XSETWINDOW (window, w);
   f = XFRAME (w->frame);
   
-  ievent->kind = scroll_bar_click;
+  ievent->kind = SCROLL_BAR_CLICK_EVENT;
   ievent->frame_or_window = window;
   ievent->arg = Qnil;
   ievent->timestamp = XtLastTimestampProcessed (FRAME_X_DISPLAY (f));
@@ -8485,7 +8651,7 @@ x_scroll_bar_to_input_event (event, ievent)
 
 /* Scroll bar callback for Motif scroll bars.  WIDGET is the scroll
    bar widget.  CLIENT_DATA is a pointer to the scroll_bar structure.
-   CALL_DATA is a pointer a a XmScrollBarCallbackStruct.  */
+   CALL_DATA is a pointer to a XmScrollBarCallbackStruct.  */
 
 static void
 xm_scroll_callback (widget, client_data, call_data)
@@ -9520,7 +9686,7 @@ x_scroll_bar_expose (bar, event)
 }
 
 /* Handle a mouse click on the scroll bar BAR.  If *EMACS_EVENT's kind
-   is set to something other than no_event, it is enqueued.
+   is set to something other than NO_EVENT, it is enqueued.
 
    This may be called from a signal handler, so we have to ignore GC
    mark bits.  */
@@ -9536,7 +9702,7 @@ x_scroll_bar_handle_click (bar, event, emacs_event)
   if (! GC_WINDOWP (bar->window))
     abort ();
 
-  emacs_event->kind = scroll_bar_click;
+  emacs_event->kind = SCROLL_BAR_CLICK_EVENT;
   emacs_event->code = event->xbutton.button - Button1;
   emacs_event->modifiers
     = (x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO 
@@ -9903,7 +10069,7 @@ static struct x_display_info *next_noop_dpyinfo;
          bcopy (&event, f->output_data.x->saved_menu_event, size);     \
          if (numchars >= 1)                                            \
            {                                                           \
-             bufp->kind = menu_bar_activate_event;                     \
+             bufp->kind = MENU_BAR_ACTIVATE_EVENT;                     \
              XSETFRAME (bufp->frame_or_window, f);                     \
              bufp->arg = Qnil;                                         \
              bufp++;                                                   \
@@ -9959,18 +10125,6 @@ XTread_socket (sd, bufp, numchars, expected)
 
   ++handling_signal;
   
-  /* The input should be decoded if it is from XIM.  Currently the
-     locale of XIM is the same as that of the system.  So, we can use
-     Vlocale_coding_system which is initialized properly at Emacs
-     startup time.  */
-  setup_coding_system (Vlocale_coding_system, &coding);
-  coding.src_multibyte = 0;
-  coding.dst_multibyte = 1;
-  /* 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;
-
   /* Find the display we are supposed to read input for.
      It's the one communicating on descriptor SD.  */
   for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
@@ -10132,7 +10286,7 @@ XTread_socket (sd, bufp, numchars, expected)
                            if (numchars == 0)
                              abort ();
 
-                           bufp->kind = delete_window_event;
+                           bufp->kind = DELETE_WINDOW_EVENT;
                            XSETFRAME (bufp->frame_or_window, f);
                            bufp->arg = Qnil;
                            bufp++;
@@ -10222,7 +10376,7 @@ XTread_socket (sd, bufp, numchars, expected)
                if (numchars == 0)
                  abort ();
 
-               bufp->kind = selection_clear_event;
+               bufp->kind = SELECTION_CLEAR_EVENT;
                SELECTION_EVENT_DISPLAY (bufp) = eventp->display;
                SELECTION_EVENT_SELECTION (bufp) = eventp->selection;
                SELECTION_EVENT_TIME (bufp) = eventp->time;
@@ -10251,7 +10405,7 @@ XTread_socket (sd, bufp, numchars, expected)
                  if (numchars == 0)
                    abort ();
 
-                 bufp->kind = selection_request_event;
+                 bufp->kind = SELECTION_REQUEST_EVENT;
                  SELECTION_EVENT_DISPLAY (bufp) = eventp->display;
                  SELECTION_EVENT_REQUESTOR (bufp) = eventp->requestor;
                  SELECTION_EVENT_SELECTION (bufp) = eventp->selection;
@@ -10391,7 +10545,7 @@ XTread_socket (sd, bufp, numchars, expected)
                    {
                      f->async_iconified = 1;
 
-                     bufp->kind = iconify_event;
+                     bufp->kind = ICONIFY_EVENT;
                      XSETFRAME (bufp->frame_or_window, f);
                      bufp->arg = Qnil;
                      bufp++;
@@ -10423,7 +10577,7 @@ XTread_socket (sd, bufp, numchars, expected)
 
                  if (f->iconified)
                    {
-                     bufp->kind = deiconify_event;
+                     bufp->kind = DEICONIFY_EVENT;
                      XSETFRAME (bufp->frame_or_window, f);
                      bufp->arg = Qnil;
                      bufp++;
@@ -10440,6 +10594,11 @@ XTread_socket (sd, bufp, numchars, expected)
              goto OTHER;
 
            case KeyPress:
+
+             /* Dispatch KeyPress events when in menu.  */
+             if (popup_activated_flag)
+               goto OTHER;
+
              f = x_any_window_to_frame (dpyinfo, event.xkey.window);
 
              if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight))
@@ -10481,6 +10640,7 @@ XTread_socket (sd, bufp, numchars, expected)
                  unsigned char *copy_bufptr = copy_buffer;
                  int copy_bufsiz = sizeof (copy_buffer);
                  int modifiers;
+                 Lisp_Object coding_system = Qlatin_1;
 
                  event.xkey.state
                    |= x_emacs_to_x_modifiers (FRAME_X_DISPLAY_INFO (f),
@@ -10510,6 +10670,7 @@ XTread_socket (sd, bufp, numchars, expected)
                    {
                      Status status_return;
 
+                     coding_system = Vlocale_coding_system;
                      nbytes = XmbLookupString (FRAME_XIC (f),
                                                &event.xkey, copy_bufptr,
                                                copy_bufsiz, &keysym,
@@ -10523,6 +10684,27 @@ XTread_socket (sd, bufp, numchars, expected)
                                                    copy_bufsiz, &keysym,
                                                    &status_return);
                        }
+/* Xutf8LookupString is a new but already deprecated interface.  -stef  */
+#if 0 && defined X_HAVE_UTF8_STRING
+                     else if (status_return == XLookupKeySym)
+                       {  /* Try again but with utf-8.  */
+                         coding_system = Qutf_8;
+                         nbytes = Xutf8LookupString (FRAME_XIC (f),
+                                                     &event.xkey, copy_bufptr,
+                                                     copy_bufsiz, &keysym,
+                                                     &status_return);
+                         if (status_return == XBufferOverflow)
+                           {
+                             copy_bufsiz = nbytes + 1;
+                             copy_bufptr = (char *) alloca (copy_bufsiz);
+                             nbytes = Xutf8LookupString (FRAME_XIC (f),
+                                                         &event.xkey,
+                                                         copy_bufptr,
+                                                         copy_bufsiz, &keysym,
+                                                         &status_return);
+                           }
+                       }
+#endif
 
                      if (status_return == XLookupNone)
                        break;
@@ -10631,7 +10813,7 @@ XTread_socket (sd, bufp, numchars, expected)
                          if (temp_index == sizeof temp_buffer / sizeof (short))
                            temp_index = 0;
                          temp_buffer[temp_index++] = keysym;
-                         bufp->kind = non_ascii_keystroke;
+                         bufp->kind = NON_ASCII_KEYSTROKE_EVENT;
                          bufp->code = keysym;
                          XSETFRAME (bufp->frame_or_window, f);
                          bufp->arg = Qnil;
@@ -10649,6 +10831,17 @@ XTread_socket (sd, bufp, numchars, expected)
                          register int c;
                          int nchars, len;
 
+                         /* The input should be decoded with `coding_system'
+                            which depends on which X*LookupString function
+                            we used just above and the locale.  */
+                         setup_coding_system (coding_system, &coding);
+                         coding.src_multibyte = 0;
+                         coding.dst_multibyte = 1;
+                         /* 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;
+
                          for (i = 0; i < nbytes; i++)
                            {
                              if (temp_index == (sizeof temp_buffer
@@ -10657,31 +10850,25 @@ 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.  */
+                           int require;
+                           unsigned char *p;
+
+                           require = decoding_buffer_size (&coding, nbytes);
+                           p = (unsigned char *) alloca (require);
+                           coding.mode |= CODING_MODE_LAST_BLOCK;
+                           /* We explicitely disable composition
+                              handling because key data should
+                              not contain any composition
+                              sequence.  */
+                           coding.composing = COMPOSITION_DISABLED;
+                           decode_coding (&coding, copy_bufptr, p,
+                                          nbytes, require);
+                           nbytes = coding.produced;
+                           nchars = coding.produced_char;
+                           copy_bufptr = p;
+                         }
 
                          /* Convert the input data to a sequence of
                             character events.  */
@@ -10694,8 +10881,8 @@ XTread_socket (sd, bufp, numchars, expected)
                                                            nbytes - i, len);
                              
                              bufp->kind = (SINGLE_BYTE_CHAR_P (c)
-                                           ? ascii_keystroke
-                                           : multibyte_char_keystroke);
+                                           ? ASCII_KEYSTROKE_EVENT
+                                           : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
                              bufp->code = c;
                              XSETFRAME (bufp->frame_or_window, f);
                              bufp->arg = Qnil;
@@ -10737,15 +10924,16 @@ XTread_socket (sd, bufp, numchars, expected)
              goto OTHER;
 #endif
 
-             /* Here's a possible interpretation of the whole
-                FocusIn-EnterNotify FocusOut-LeaveNotify mess.  If
-                you get a FocusIn event, you have to get a FocusOut
-                event before you relinquish the focus.  If you
-                haven't received a FocusIn event, then a mere
-                LeaveNotify is enough to free you.  */
-
            case EnterNotify:
              {
+                int n;
+
+                n = x_detect_focus_change (dpyinfo, &event, bufp, numchars);
+                if (n > 0)
+                {
+                  bufp += n, count += n, numchars -= n;
+                }
+              
                f = x_any_window_to_frame (dpyinfo, event.xcrossing.window);
 
 #if 0
@@ -10772,34 +10960,29 @@ XTread_socket (sd, bufp, numchars, expected)
              }
 
            case FocusIn:
-             f = x_any_window_to_frame (dpyinfo, event.xfocus.window);
-             if (event.xfocus.detail != NotifyPointer)
-               dpyinfo->x_focus_event_frame = f;
-             if (f)
-               {
-                 x_new_focus_frame (dpyinfo, f);
+              {
+                int n;
 
-                 /* Don't stop displaying the initial startup message
-                    for a switch-frame event we don't need.  */
-                 if (GC_NILP (Vterminal_frame)
-                     && GC_CONSP (Vframe_list)
-                     && !GC_NILP (XCDR (Vframe_list)))
-                   {
-                     bufp->kind = FOCUS_IN_EVENT;
-                     XSETFRAME (bufp->frame_or_window, f);
-                     bufp->arg = Qnil;
-                     ++bufp, ++count, --numchars;
-                   }
-               }
-
-#ifdef HAVE_X_I18N
-             if (f && FRAME_XIC (f))
-               XSetICFocus (FRAME_XIC (f));
-#endif
+                n = x_detect_focus_change (dpyinfo, &event, bufp, numchars);
+                if (n > 0)
+                  {
+                    bufp += n, count += n, numchars -= n;
+                  }
+              }
 
              goto OTHER;
 
            case LeaveNotify:
+              {
+                int n;
+
+                n = x_detect_focus_change (dpyinfo, &event, bufp, numchars);
+                if (n > 0)
+                {
+                  bufp += n, count += n, numchars -= n;
+                }
+              }
+
              f = x_top_window_to_frame (dpyinfo, event.xcrossing.window);
              if (f)
                {
@@ -10827,32 +11010,19 @@ XTread_socket (sd, bufp, numchars, expected)
                      bufp += n, count += n, numchars -= n;
                    }
 
-#if 0
-                 if (event.xcrossing.focus)
-                   x_mouse_leave (dpyinfo);
-                 else
-                   {
-                     if (f == dpyinfo->x_focus_event_frame)
-                       dpyinfo->x_focus_event_frame = 0;
-                     if (f == dpyinfo->x_focus_frame)
-                       x_new_focus_frame (dpyinfo, 0);
-                   }
-#endif
                }
              goto OTHER;
 
            case FocusOut:
-             f = x_any_window_to_frame (dpyinfo, event.xfocus.window);
-             if (event.xfocus.detail != NotifyPointer
-                 && f == dpyinfo->x_focus_event_frame)
-               dpyinfo->x_focus_event_frame = 0;
-             if (f && f == dpyinfo->x_focus_frame)
-               x_new_focus_frame (dpyinfo, 0);
+              {
+                int n;
 
-#ifdef HAVE_X_I18N
-             if (f && FRAME_XIC (f))
-               XUnsetICFocus (FRAME_XIC (f));
-#endif
+                n = x_detect_focus_change (dpyinfo, &event, bufp, numchars);
+                if (n > 0)
+                {
+                  bufp += n, count += n, numchars -= n;
+                }
+              }
 
              goto OTHER;
 
@@ -10878,19 +11048,20 @@ XTread_socket (sd, bufp, numchars, expected)
                  {
 
                    /* Generate SELECT_WINDOW_EVENTs when needed.  */
-                   if (autoselect_window_p)
+                   if (mouse_autoselect_window)
                      {
                        Lisp_Object window;
                        int area;
 
                        window = window_from_coordinates (f,
-                                                         XINT (event.xmotion.x), XINT (event.xmotion.y),
+                                                         event.xmotion.x, event.xmotion.y,
                                                          &area, 0);
 
                        /* Window will be selected only when it is not selected now and
                           last mouse movement event was not in it.  Minibuffer window
                           will be selected iff it is active.  */
-                       if (!EQ (window, last_window)
+                       if (WINDOWP(window)
+                           && !EQ (window, last_window)
                            && !EQ (window, selected_window)
                            && numchars > 0)
                          {
@@ -11022,7 +11193,7 @@ XTread_socket (sd, bufp, numchars, expected)
                struct input_event emacs_event;
                int tool_bar_p = 0;
                
-               emacs_event.kind = no_event;
+               emacs_event.kind = NO_EVENT;
                bzero (&compose_status, sizeof (compose_status));
 
                if (dpyinfo->grabbed
@@ -11088,7 +11259,7 @@ XTread_socket (sd, bufp, numchars, expected)
                    dpyinfo->grabbed &= ~(1 << event.xbutton.button);
                  }
 
-               if (numchars >= 1 && emacs_event.kind != no_event)
+               if (numchars >= 1 && emacs_event.kind != NO_EVENT)
                  {
                    bcopy (&emacs_event, bufp, sizeof (struct input_event));
                    bufp++;
@@ -11233,13 +11404,36 @@ notice_overwritten_cursor (w, area, x0, x1, y0, y1)
      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;
+  if (area == TEXT_AREA && w->phys_cursor_on_p)
+    {
+      int cx0 = w->phys_cursor.x;
+      int cx1 = cx0 + w->phys_cursor_width;
+      int cy0 = w->phys_cursor.y;
+      int cy1 = cy0 + w->phys_cursor_height;
+
+      if (x0 <= cx0 && (x1 < 0 || x1 >= cx1))
+       {
+         /* The cursor image will be completely removed from the
+            screen if the output area intersects the cursor area in
+            y-direction.  When we draw in [y0 y1[, and some part of
+            the cursor is at y < y0, that part must have been drawn
+            before.  When scrolling, the cursor is erased before
+            actually scrolling, so we don't come here.  When not
+            scrolling, the rows above the old cursor row must have
+            changed, and in this case these rows must have written
+            over the cursor image.
+
+            Likewise if part of the cursor is below y1, with the
+            exception of the cursor being in the first blank row at
+            the buffer and window end because update_text_area
+            doesn't draw that row.  (Except when it does, but
+            that's handled in update_text_area.)  */
+         
+         if (((y0 >= cy0 && y0 < cy1) || (y1 > cy0 && y1 < cy1))
+             && w->current_matrix->rows[w->phys_cursor.vpos].displays_text_p)
+           w->phys_cursor_on_p = 0;
+       }
+    }
 }
 
 
@@ -11319,6 +11513,7 @@ x_draw_hollow_cursor (w, row)
   if (cursor_glyph->type == STRETCH_GLYPH
       && !x_stretch_cursor_p)
     wd = min (CANON_X_UNIT (f), wd);
+  w->phys_cursor_width = wd;
   
   /* The foreground of cursor_gc is typically the same as the normal
      background color, which can cause the cursor box to be invisible.  */
@@ -11345,10 +11540,11 @@ x_draw_hollow_cursor (w, row)
    --gerd.  */
 
 static void
-x_draw_bar_cursor (w, row, width)
+x_draw_bar_cursor (w, row, width, kind)
      struct window *w;
      struct glyph_row *row;
      int width;
+     enum text_cursor_kinds kind;
 {
   struct frame *f = XFRAME (w->frame);
   struct glyph *cursor_glyph;
@@ -11401,11 +11597,22 @@ x_draw_bar_cursor (w, row, width)
        width = f->output_data.x->cursor_width;
       width = min (cursor_glyph->pixel_width, width);
   
+      w->phys_cursor_width = width;
       x_clip_to_row (w, row, gc, 0);
-      XFillRectangle (dpy, window, gc,
-                     WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x),
-                     WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
-                     width, row->height);
+      
+      if (kind == BAR_CURSOR)
+         XFillRectangle (dpy, window, gc,
+                         WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x),
+                         WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
+                         width, row->height);
+      else
+         XFillRectangle (dpy, window, gc,
+                         WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x),
+                         WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y +
+                                                  row->height - width),
+                         cursor_glyph->pixel_width,
+                         width);
+
       XSetClipMask (dpy, gc, None);
     }
 }
@@ -11439,16 +11646,20 @@ x_draw_phys_cursor_glyph (w, row, hl)
   if (w->phys_cursor.hpos < row->used[TEXT_AREA])
     {
       int on_p = w->phys_cursor_on_p;
+      int x1;
       
-      x_draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
-                    w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
-                    hl, 0);
+      x1 = x_draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
+                         w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
+                         hl, 0);
       w->phys_cursor_on_p = on_p;
 
+      if (hl == DRAW_CURSOR)
+       w->phys_cursor_width = x1 - w->phys_cursor.x;
+
       /* When we erase the cursor, and ROW is overlapped by other
         rows, make sure that these overlapping parts of other rows
         are redrawn.  */
-      if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
+      else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
        {
          if (row > w->current_matrix->rows
              && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
@@ -11599,10 +11810,10 @@ x_display_and_set_cursor (w, on, hpos, vpos, x, y)
   struct frame *f = XFRAME (w->frame);
   int new_cursor_type;
   int new_cursor_width;
+  int cursor_off_state = 0;
   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
@@ -11638,54 +11849,62 @@ 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;
+  new_cursor_type = -2;
+
+  /* Echo area */
   if (cursor_in_echo_area
       && FRAME_HAS_MINIBUF_P (f)
       && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
     {
       if (w == XWINDOW (echo_area_window))
        new_cursor_type = FRAME_DESIRED_CURSOR (f);
-      else if (cursor_non_selected)
-       new_cursor_type = HOLLOW_BOX_CURSOR;
+      else if (NILP (Fbuffer_local_value (Qcursor_in_non_selected_windows,
+                                         w->buffer)))
+       new_cursor_type = NO_CURSOR;
       else
+       cursor_off_state = 1;
+    }
+
+  /* Nonselected window or nonselected frame.  */
+  else if (f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
+          || w != XWINDOW (f->selected_window))
+    {
+      if ((MINI_WINDOW_P (w) && minibuf_level == 0)
+         || NILP (Fbuffer_local_value (Qcursor_in_non_selected_windows,
+                                       w->buffer))
+         || NILP (XBUFFER (w->buffer)->cursor_type))
        new_cursor_type = NO_CURSOR;
+      else
+       cursor_off_state = 1;
     }
-  else
+
+  /* If new_cursor_type isn't decided yet, decide it now.  */
+  if (new_cursor_type == -2)
     {
-      if (f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
-         || w != XWINDOW (f->selected_window))
-       {
-         if ((MINI_WINDOW_P (w) && minibuf_level == 0)
-             || !cursor_non_selected
-             || NILP (XBUFFER (w->buffer)->cursor_type))
-           new_cursor_type = NO_CURSOR;
-         else
-           new_cursor_type = HOLLOW_BOX_CURSOR;
-       }
+      struct buffer *b = XBUFFER (w->buffer);
+
+      if (EQ (b->cursor_type, Qt))
+       new_cursor_type = FRAME_DESIRED_CURSOR (f);
       else
-       {
-         struct buffer *b = XBUFFER (w->buffer);
+       new_cursor_type = x_specified_cursor_type (b->cursor_type, 
+                                                  &new_cursor_width);
+    }
 
-         if (EQ (b->cursor_type, Qt))
-           new_cursor_type = FRAME_DESIRED_CURSOR (f);
-         else
-           new_cursor_type = x_specified_cursor_type (b->cursor_type, 
-                                                      &new_cursor_width);
-         if (w->cursor_off_p)
-           {
-             if (new_cursor_type == FILLED_BOX_CURSOR)
-               new_cursor_type = HOLLOW_BOX_CURSOR;
-             else if (new_cursor_type == BAR_CURSOR && new_cursor_width > 1)
-               new_cursor_width = 1;
-             else
-               new_cursor_type = NO_CURSOR;
-           }
-       }
+  /* Dim out or hollow out the cursor,
+     if it has blinked off or for nonselected windows.  */
+  if (w->cursor_off_p || cursor_off_state)
+    {
+      if (new_cursor_type == FILLED_BOX_CURSOR)
+       new_cursor_type = HOLLOW_BOX_CURSOR;
+      else if (new_cursor_type == BAR_CURSOR && new_cursor_width > 1)
+       new_cursor_width = 1;
+      else
+       new_cursor_type = NO_CURSOR;
     }
 
+  /* Now new_cursor_type is correct.  */
+
   /* If cursor is currently being shown and we don't want it to be or
      it is in the wrong place, or the cursor type is not what we want,
      erase it.  */
@@ -11698,9 +11917,12 @@ x_display_and_set_cursor (w, on, hpos, vpos, x, y)
              && new_cursor_width != w->phys_cursor_width)))
     x_erase_phys_cursor (w);
 
-  /* If the cursor is now invisible and we want it to be visible,
-     display it.  */
-  if (on && !w->phys_cursor_on_p)
+  /* Don't check phys_cursor_on_p here because that flag is only set
+     to zero in some cases where we know that the cursor has been
+     completely erased, to avoid the extra work of erasing the cursor
+     twice.  In other words, phys_cursor_on_p can be 1 and the cursor
+     still not be visible, or it has only been partly erased.  */
+  if (on)
     {
       w->phys_cursor_ascent = glyph_row->ascent;
       w->phys_cursor_height = glyph_row->height;
@@ -11712,7 +11934,6 @@ x_display_and_set_cursor (w, on, hpos, vpos, x, y)
       w->phys_cursor.hpos = hpos;
       w->phys_cursor.vpos = vpos;
       w->phys_cursor_type = new_cursor_type;
-      w->phys_cursor_width = new_cursor_width;
       w->phys_cursor_on_p = 1;
 
       switch (new_cursor_type)
@@ -11726,10 +11947,15 @@ x_display_and_set_cursor (w, on, hpos, vpos, x, y)
          break;
 
        case BAR_CURSOR:
-         x_draw_bar_cursor (w, glyph_row, new_cursor_width);
+         x_draw_bar_cursor (w, glyph_row, new_cursor_width, BAR_CURSOR);
+         break;
+
+       case HBAR_CURSOR:
+         x_draw_bar_cursor (w, glyph_row, new_cursor_width, HBAR_CURSOR);
          break;
 
        case NO_CURSOR:
+         w->phys_cursor_width = 0;
          break;
 
        default:
@@ -11921,7 +12147,7 @@ x_error_catcher (display, error)
      XErrorEvent *error;
 {
   XGetErrorText (display, error->error_code,
-                XSTRING (x_error_message_string)->data,
+                SDATA (x_error_message_string),
                 X_ERROR_MESSAGE_SIZE);
 }
 
@@ -11945,7 +12171,7 @@ int
 x_catch_errors (dpy)
      Display *dpy;
 {
-  int count = specpdl_ptr - specpdl;
+  int count = SPECPDL_INDEX ();
 
   /* Make sure any errors from previous requests have been dealt with.  */
   XSync (dpy, False);
@@ -11953,7 +12179,7 @@ x_catch_errors (dpy)
   record_unwind_protect (x_catch_errors_unwind, x_error_message_string);
 
   x_error_message_string = make_uninit_string (X_ERROR_MESSAGE_SIZE);
-  XSTRING (x_error_message_string)->data[0] = 0;
+  SSET (x_error_message_string, 0, 0);
 
   return count;
 }
@@ -11980,8 +12206,8 @@ x_check_errors (dpy, format)
   /* Make sure to catch any errors incurred so far.  */
   XSync (dpy, False);
 
-  if (XSTRING (x_error_message_string)->data[0])
-    error (format, XSTRING (x_error_message_string)->data);
+  if (SREF (x_error_message_string, 0))
+    error (format, SDATA (x_error_message_string));
 }
 
 /* Nonzero if we had any X protocol errors
@@ -11994,7 +12220,7 @@ x_had_errors_p (dpy)
   /* Make sure to catch any errors incurred so far.  */
   XSync (dpy, False);
 
-  return XSTRING (x_error_message_string)->data[0] != 0;
+  return SREF (x_error_message_string, 0) != 0;
 }
 
 /* Forget about any errors we have had, since we did x_catch_errors on DPY.  */
@@ -12003,7 +12229,7 @@ void
 x_clear_errors (dpy)
      Display *dpy;
 {
-  XSTRING (x_error_message_string)->data[0] = 0;
+  SSET (x_error_message_string, 0, 0);
 }
 
 /* Stop catching X protocol errors and let them make Emacs die.
@@ -12303,7 +12529,7 @@ x_new_fontset (f, fontsetname)
        to do.  */
     return fontset_name (fontset);
 
-  result = x_new_font (f, (XSTRING (fontset_ascii (fontset))->data));
+  result = x_new_font (f, (SDATA (fontset_ascii (fontset))));
 
   if (!STRINGP (result))
     /* Can't load ASCII font.  */
@@ -12315,7 +12541,7 @@ x_new_fontset (f, fontsetname)
 #ifdef HAVE_X_I18N
   if (FRAME_XIC (f)
       && (FRAME_XIC_STYLE (f) & (XIMPreeditPosition | XIMStatusArea)))
-    xic_set_xfontset (f, XSTRING (fontset_ascii (fontset))->data);
+    xic_set_xfontset (f, SDATA (fontset_ascii (fontset)));
 #endif
   
   return build_string (fontsetname);
@@ -13915,7 +14141,7 @@ x_list_fonts (f, pattern, size, maxnames)
          XFontStruct *font;
          unsigned long value;
 
-         font = XLoadQueryFont (dpy, XSTRING (pattern)->data);
+         font = XLoadQueryFont (dpy, SDATA (pattern));
          if (x_had_errors_p (dpy))
            {
              /* This error is perhaps due to insufficient memory on X
@@ -13958,7 +14184,7 @@ x_list_fonts (f, pattern, size, maxnames)
        {
          /* We try at least 10 fonts because XListFonts will return
             auto-scaled fonts at the head.  */
-         names = XListFonts (dpy, XSTRING (pattern)->data, max (maxnames, 10),
+         names = XListFonts (dpy, SDATA (pattern), max (maxnames, 10),
                              &num_fonts);
          if (x_had_errors_p (dpy))
            {
@@ -14059,7 +14285,7 @@ x_list_fonts (f, pattern, size, maxnames)
              BLOCK_INPUT;
              count = x_catch_errors (dpy);
              thisinfo = XLoadQueryFont (dpy,
-                                        XSTRING (XCAR (tem))->data);
+                                        SDATA (XCAR (tem)));
              if (x_had_errors_p (dpy))
                {
                  /* This error is perhaps due to insufficient memory on X
@@ -14239,9 +14465,9 @@ x_load_font (f, fontname, size)
        for (tail = font_names; CONSP (tail); tail = XCDR (tail))
          if (dpyinfo->font_table[i].name
              && (!strcmp (dpyinfo->font_table[i].name,
-                          XSTRING (XCAR (tail))->data)
+                          SDATA (XCAR (tail)))
                  || !strcmp (dpyinfo->font_table[i].full_name,
-                             XSTRING (XCAR (tail))->data)))
+                             SDATA (XCAR (tail)))))
            return (dpyinfo->font_table + i);
     }
 
@@ -14259,7 +14485,7 @@ x_load_font (f, fontname, size)
        a bug of not finding a font even if the font surely exists and
        is loadable by XLoadQueryFont.  */
     if (size > 0 && !NILP (font_names))
-      fontname = (char *) XSTRING (XCAR (font_names))->data;
+      fontname = (char *) SDATA (XCAR (font_names));
 
     BLOCK_INPUT;
     count = x_catch_errors (FRAME_X_DISPLAY (f));
@@ -14508,10 +14734,10 @@ static int x_initialized;
    the screen number from the server number.  */
 static int
 same_x_server (name1, name2)
-     char *name1, *name2;
+     const char *name1, *name2;
 {
   int seen_colon = 0;
-  unsigned char *system_name = XSTRING (Vsystem_name)->data;
+  const unsigned char *system_name = SDATA (Vsystem_name);
   int system_name_length = strlen (system_name);
   int length_until_period = 0;
 
@@ -14592,10 +14818,12 @@ x_term_init (display_name, xrm_option, resource_name)
        argv[argc++] = "-xrm";
        argv[argc++] = xrm_option;
       }
-    dpy = XtOpenDisplay (Xt_app_con, XSTRING (display_name)->data,
+    stop_polling ();
+    dpy = XtOpenDisplay (Xt_app_con, SDATA (display_name),
                         resource_name, EMACS_CLASS,
                         emacs_options, XtNumber (emacs_options),
                         &argc, argv);
+    start_polling ();
 
 #ifdef HAVE_X11XTR6
     /* I think this is to compensate for XtSetLanguageProc.  */
@@ -14607,7 +14835,7 @@ x_term_init (display_name, xrm_option, resource_name)
 #ifdef HAVE_X11R5
   XSetLocaleModifiers ("");
 #endif
-  dpy = XOpenDisplay (XSTRING (display_name)->data);
+  dpy = XOpenDisplay (SDATA (display_name));
 #endif /* not USE_X_TOOLKIT */
 
   /* Detect failure.  */
@@ -14629,8 +14857,8 @@ x_term_init (display_name, xrm_option, resource_name)
 
     for (share = x_display_list, tail = x_display_name_list; share;
         share = share->next, tail = XCDR (tail))
-      if (same_x_server (XSTRING (XCAR (XCAR (tail)))->data,
-                        XSTRING (display_name)->data))
+      if (same_x_server (SDATA (XCAR (XCAR (tail))),
+                        SDATA (display_name)))
        break;
     if (share)
       dpyinfo->kboard = share->kboard;
@@ -14676,11 +14904,11 @@ x_term_init (display_name, xrm_option, resource_name)
 #endif /* ! 0 */
 
   dpyinfo->x_id_name
-    = (char *) xmalloc (STRING_BYTES (XSTRING (Vinvocation_name))
-                       + STRING_BYTES (XSTRING (Vsystem_name))
+    = (char *) xmalloc (SBYTES (Vinvocation_name)
+                       + SBYTES (Vsystem_name)
                        + 2);
   sprintf (dpyinfo->x_id_name, "%s@%s",
-          XSTRING (Vinvocation_name)->data, XSTRING (Vsystem_name)->data);
+          SDATA (Vinvocation_name), SDATA (Vsystem_name));
 
   /* Figure out which modifier bits mean what.  */
   x_find_modifier_meanings (dpyinfo);
@@ -14743,8 +14971,8 @@ x_term_init (display_name, xrm_option, resource_name)
                                          build_string ("PrivateColormap"),
                                          Qnil, Qnil);
          if (STRINGP (value)
-             && (!strcmp (XSTRING (value)->data, "true")
-                 || !strcmp (XSTRING (value)->data, "on")))
+             && (!strcmp (SDATA (value), "true")
+                 || !strcmp (SDATA (value), "on")))
            dpyinfo->cmap = XCopyColormapAndFree (dpyinfo->display, dpyinfo->cmap);
        }
     }
@@ -14904,8 +15132,8 @@ x_term_init (display_name, xrm_option, resource_name)
                                    build_string ("Synchronous"),
                                    Qnil, Qnil);
     if (STRINGP (value)
-       && (!strcmp (XSTRING (value)->data, "true")
-           || !strcmp (XSTRING (value)->data, "on")))
+       && (!strcmp (SDATA (value), "true")
+           || !strcmp (SDATA (value), "on")))
       XSynchronize (dpyinfo->display, True);
   }
   
@@ -15078,7 +15306,7 @@ x_initialize ()
   /* Disable Window Change signals;  they are handled by X events.  */
 #ifdef SIGWINCH
   signal (SIGWINCH, SIG_DFL);
-#endif /* ! defined (SIGWINCH) */
+#endif /* SIGWINCH */
 
   signal (SIGPIPE, x_connection_signal);
 
@@ -15103,6 +15331,11 @@ syms_of_xterm ()
   staticpro (&Qvendor_specific_keysyms);
   Qvendor_specific_keysyms = intern ("vendor-specific-keysyms");
 
+  staticpro (&Qutf_8);
+  Qutf_8 = intern ("utf-8");
+  staticpro (&Qlatin_1);
+  Qlatin_1 = intern ("latin-1");
+
   staticpro (&last_mouse_press_frame);
   last_mouse_press_frame = Qnil;
 
@@ -15116,9 +15349,9 @@ syms_of_xterm ()
   staticpro (&previous_help_echo);
   help_echo_pos = -1;
 
-  DEFVAR_BOOL ("autoselect-window", &autoselect_window_p,
+  DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window,
     doc: /* *Non-nil means autoselect window with mouse pointer.  */);
-  autoselect_window_p = 0;
+  mouse_autoselect_window = 0;
 
   DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
     doc: /* *Non-nil means draw block cursor as wide as the glyph under it.