(input_signal_count): New variable.
[bpt/emacs.git] / src / xterm.c
index 7177d82..bb29073 100644 (file)
@@ -22,11 +22,12 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 /* On 4.3 these lose if they come after xterm.h.  */
 /* On HP-UX 8.0 signal.h loses if it comes after config.h.  */
 /* Putting these at the beginning seems to be standard for other .c files.  */
-#include <stdio.h>
 #include <signal.h>
 
 #include <config.h>
 
+#include <stdio.h>
+
 /* Need syssignal.h for various externs and definitions that may be required
    by some configurations for calls to signal later in this source file.  */
 #include "syssignal.h"
@@ -51,11 +52,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 #ifdef BSD
 #include <sys/ioctl.h>
-#include <strings.h>
-#else /* ! defined (BSD) */
-#ifndef VMS
-#include <string.h>
-#endif
 #endif /* ! defined (BSD) */
 
 #include "systty.h"
@@ -83,6 +79,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "disptab.h"
 #include "buffer.h"
 #include "window.h"
+#include "keyboard.h"
+#include "intervals.h"
 
 #ifdef USE_X_TOOLKIT
 extern XtAppContext Xt_app_con;
@@ -96,12 +94,13 @@ extern void _XEditResCheckMessages ();
 #define x_top_window_to_frame x_window_to_frame
 #endif
 
-#ifdef HAVE_X11
+#ifdef USE_X_TOOLKIT
+#ifndef XtNinitialState
+#define XtNinitialState "initialState"
+#endif
+#endif
+
 #define XMapWindow XMapRaised          /* Raise them when mapping. */
-#else /* ! defined (HAVE_X11) */
-#include <X/Xkeyboard.h>
-/*#include <X/Xproto.h>        */
-#endif /* ! defined (HAVE_X11) */
 
 #ifdef FD_SET
 /* We could get this from param.h, but better not to depend on finding that.
@@ -141,18 +140,6 @@ static int expose_all_windows;
 
 static int expose_all_icons;
 
-#ifndef HAVE_X11
-/* ExposeRegion events, when received, are copied into this queue
-   for later processing.  */
-
-static struct event_queue x_expose_queue;
-
-/* ButtonPress and ButtonReleased events, when received,
-   are copied into this queue for later processing.  */
-
-struct event_queue x_mouse_queue;
-#endif /* HAVE_X11 */
-
 #if defined (SIGIO) && defined (FIONREAD)
 int BLOCK_INPUT_mask;
 #endif /* ! defined (SIGIO) && defined (FIONREAD) */
@@ -169,8 +156,12 @@ static FONT_TYPE *icon_font_info;
 
 /* Stuff for dealing with the main icon title. */
 
-extern Lisp_Object Vcommand_line_args;
-char *hostname, *x_id_name;
+extern Lisp_Object Vcommand_line_args, Vsystem_name;
+char *x_id_name;
+
+/* Initial values of argv and argc.  */
+extern char **initial_argv;
+extern int initial_argc;
 
 /* This is the X connection that we are using.  */
 
@@ -228,6 +219,9 @@ static int highlight;
 static int curs_x;
 static int curs_y;
 
+/* Reusable Graphics Context for drawing a cursor in a non-default face. */
+static GC scratch_cursor_gc;
+
 /* Mouse movement.
 
    In order to avoid asking for motion events and then throwing most
@@ -261,7 +255,7 @@ static XRectangle last_mouse_glyph;
    to Qnil, to tell XTmouse_position to return an ordinary motion event.  */
 static Lisp_Object last_mouse_scroll_bar;
 
-/* Record which buttons are currently pressed. */
+/* Record which buttons are currently pressed.  */
 unsigned int x_mouse_grabbed;
 
 /* This is a hack.  We would really prefer that XTmouse_position would
@@ -276,7 +270,9 @@ static Time last_mouse_movement_time;
    in its mouse-face, together with the window they apply to.
    As long as the mouse stays within this range, we need not
    redraw anything on its account.  */
-static int mouse_face_beg, mouse_face_end;
+static int mouse_face_beg_row, mouse_face_beg_col;
+static int mouse_face_end_row, mouse_face_end_col;
+static int mouse_face_past_end;
 static Lisp_Object mouse_face_window;
 static int mouse_face_face_id;
 
@@ -284,14 +280,21 @@ static int mouse_face_face_id;
    gc was in progress.  */
 static int mouse_face_deferred_gc;
 
-/* FRAME and X, Y position of mouse when last checked for highlighting.  */
+/* FRAME and X, Y position of mouse when last checked for
+   highlighting.  X and Y can be negative or out of range for the frame.  */
 static FRAME_PTR mouse_face_mouse_frame;
 static int mouse_face_mouse_x, mouse_face_mouse_y;
 
 /* Nonzero means defer mouse-motion highlighting.  */
 static int mouse_face_defer;
 
-#ifdef HAVE_X11
+/* Incremented by XTread_socket whenever it really tries to read events.  */
+#ifdef __STDC__
+static int volatile input_signal_count;
+#else
+static int input_signal_count;
+#endif
+
 /* `t' if a mouse button is depressed. */
 
 extern Lisp_Object Vmouse_depressed;
@@ -311,27 +314,8 @@ extern int _Xdebug;
 
 extern Lisp_Object Qface, Qmouse_face;
 
-#else /* ! defined (HAVE_X11) */
-
-/* Bit patterns for the mouse cursor.  */
-
-short MouseCursor[] = {
-  0x0000, 0x0008, 0x0018, 0x0038,
-  0x0078, 0x00f8, 0x01f8, 0x03f8,
-  0x07f8, 0x00f8, 0x00d8, 0x0188,
-  0x0180, 0x0300, 0x0300, 0x0000};
-
-short MouseMask[] = {
-  0x000c, 0x001c, 0x003c, 0x007c,
-  0x00fc, 0x01fc, 0x03fc, 0x07fc,
-  0x0ffc, 0x0ffc, 0x01fc, 0x03dc,
-  0x03cc, 0x0780, 0x0780, 0x0300};
+static int x_noop_count;
 
-static short grey_bits[] = {
-  0x0005, 0x000a, 0x0005, 0x000a};
-
-static Pixmap GreyPixmap = 0;
-#endif /* ! defined (HAVE_X11) */
 
 /* From time to time we get info on an Emacs window, here.  */
 
@@ -353,14 +337,11 @@ static void redraw_previous_char ();
 static void redraw_following_char ();
 static unsigned int x_x_to_emacs_modifiers ();
 
+static int fast_find_position ();
 static void note_mouse_highlight ();
 static void clear_mouse_face ();
 static void show_mouse_face ();
 
-#ifndef HAVE_X11
-static void dumpqueue ();
-#endif /* HAVE_X11 */
-
 void dumpborder ();
 static int XTcursor_to ();
 static int XTclear_end_of_line ();
@@ -422,16 +403,10 @@ XTupdate_begin (f)
            clear_mouse_face ();
        }
     }
-#ifndef HAVE_X11
-  dumpqueue ();
-#endif /* HAVE_X11 */
+
   UNBLOCK_INPUT;
 }
 
-#ifndef HAVE_X11
-static void x_do_pending_expose ();
-#endif
-
 static
 XTupdate_end (f)
      struct frame *f;
@@ -439,10 +414,6 @@ XTupdate_end (f)
   int mask;
 
   BLOCK_INPUT;
-#ifndef HAVE_X11
-  dumpqueue ();
-  x_do_pending_expose ();
-#endif /* HAVE_X11 */
 
   x_display_cursor (f, 1);
 
@@ -610,7 +581,6 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground)
        struct face *face = FRAME_DEFAULT_FACE (f);
        FONT_TYPE *font = FACE_FONT (face);
        GC gc = FACE_GC (face);
-       int gc_temporary = 0;
 
        /* HL = 3 means use a mouse face previously chosen.  */
        if (hl == 3)
@@ -648,8 +618,11 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground)
        /* Now override that if the cursor's on this character.  */
        if (hl == 2)
          {
-           if (!face->font
-               || (int) face->font == FACE_DEFAULT)
+           if ((!face->font
+                || (int) face->font == FACE_DEFAULT
+                || face->font == f->display.x->font)
+               && face->background == f->display.x->background_pixel
+               && face->foreground == f->display.x->foreground_pixel)
              {
                gc = f->display.x->cursor_gc;
              }
@@ -660,14 +633,11 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground)
                unsigned long mask;
 
                xgcv.background = f->display.x->cursor_pixel;
-               if (face == FRAME_DEFAULT_FACE (f))
-                 xgcv.foreground = f->display.x->cursor_foreground_pixel;
-               else
-                 xgcv.foreground = face->foreground;
+               xgcv.foreground = face->background;
                /* If the glyph would be invisible,
                   try a different foreground.  */
                if (xgcv.foreground == xgcv.background)
-                 xgcv.foreground = face->background;
+                 xgcv.foreground = face->foreground;
                if (xgcv.foreground == xgcv.background)
                  xgcv.foreground = f->display.x->cursor_foreground_pixel;
                if (xgcv.foreground == xgcv.background)
@@ -682,13 +652,18 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground)
                xgcv.font = face->font->fid;
                xgcv.graphics_exposures = 0;
                mask = GCForeground | GCBackground | GCFont | GCGraphicsExposures;
-               gc = XCreateGC (x_current_display, FRAME_X_WINDOW (f),
-                               mask, &xgcv);
+               if (scratch_cursor_gc)
+                 XChangeGC (x_current_display, scratch_cursor_gc, mask, &xgcv);
+               else
+                 scratch_cursor_gc =
+                   XCreateGC (x_current_display, window, mask, &xgcv);
+               gc = scratch_cursor_gc;
 #if 0
+/* If this code is restored, it must also reset to the default stipple
+   if necessary. */
                if (face->stipple && face->stipple != FACE_DEFAULT)
                  XSetStipple (x_current_display, gc, face->stipple);
 #endif
-               gc_temporary = 1;
              }
          }
 
@@ -726,9 +701,6 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground)
          }
 #endif
 
-       if (gc_temporary)
-         XFreeGC (x_current_display, gc);
-
        /* We should probably check for XA_UNDERLINE_POSITION and
           XA_UNDERLINE_THICKNESS properties on the font, but let's
           just get the thing working, and come back to that.  */
@@ -866,7 +838,6 @@ XTclear_end_of_line (first_unused)
       && f->phys_cursor_x < first_unused)
     f->phys_cursor_x = -1;
 
-#ifdef HAVE_X11
   XClearArea (x_current_display, FRAME_X_WINDOW (f),
              CHAR_TO_PIXEL_COL (f, curs_x),
              CHAR_TO_PIXEL_ROW (f, curs_y),
@@ -875,14 +846,6 @@ XTclear_end_of_line (first_unused)
 #if 0
   redraw_previous_char (f, curs_x, curs_y, highlight);
 #endif
-#else /* ! defined (HAVE_X11) */
-  XPixSet (FRAME_X_WINDOW (f),
-          CHAR_TO_PIXEL_COL (f, curs_x),
-          CHAR_TO_PIXEL_ROW (f, curs_y),
-          FONT_WIDTH (f->display.x->font) * (first_unused - curs_x),
-          f->display.x->line_height,
-          f->display.x->background_pixel);     
-#endif /* ! defined (HAVE_X11) */
 
   UNBLOCK_INPUT;
 }
@@ -908,10 +871,6 @@ XTclear_frame ()
      colors or something like that, then they should be notified.  */
   x_scroll_bar_clear (f);
 
-#ifndef HAVE_X11
-  dumpborder (f, 0);
-#endif /* HAVE_X11 */
-
   XFlushQueue ();
   UNBLOCK_INPUT;
 }
@@ -1198,11 +1157,7 @@ XTflash (f)
 
 /* Make audible bell.  */
 
-#ifdef HAVE_X11
 #define XRINGBELL XBell (x_current_display, 0)
-#else /* ! defined (HAVE_X11) */
-#define XRINGBELL XFeep (0);
-#endif /* ! defined (HAVE_X11) */
 
 XTring_bell ()
 {
@@ -1279,51 +1234,21 @@ stufflines (n)
   newtop = topregion + n;
   length = (bottomregion - topregion) + 1;
 
-#ifndef HAVE_X11
-  dumpqueue ();
-#endif /* HAVE_X11 */
-
   if ((length > 0) && (newtop <= flexlines))
-    {
-#ifdef HAVE_X11
-      XCopyArea (x_current_display, FRAME_X_WINDOW (f),
-                FRAME_X_WINDOW (f), f->display.x->normal_gc,
-                intborder, CHAR_TO_PIXEL_ROW (f, topregion),
-                f->width * FONT_WIDTH (f->display.x->font),
-                length * f->display.x->line_height, intborder,
-                CHAR_TO_PIXEL_ROW (f, newtop));
-#else /* ! defined (HAVE_X11) */
-      XMoveArea (FRAME_X_WINDOW (f),
-                intborder, CHAR_TO_PIXEL_ROW (f, topregion),
-                intborder, CHAR_TO_PIXEL_ROW (f, newtop),
-                f->width * FONT_WIDTH (f->display.x->font),
-                length * f->display.x->line_height);
-      /* Now we must process any ExposeRegion events that occur
-        if the area being copied from is obscured.
-        We can't let it wait because further i/d operations
-        may want to copy this area to another area.  */
-      x_read_exposes ();
-#endif /* ! defined (HAVE_X11) */
-    }
+    XCopyArea (x_current_display, FRAME_X_WINDOW (f),
+              FRAME_X_WINDOW (f), f->display.x->normal_gc,
+              intborder, CHAR_TO_PIXEL_ROW (f, topregion),
+              f->width * FONT_WIDTH (f->display.x->font),
+              length * f->display.x->line_height, intborder,
+              CHAR_TO_PIXEL_ROW (f, newtop));
 
   newtop = min (newtop, (flexlines - 1));
   length = newtop - topregion;
   if (length > 0)
-    {
-#ifdef HAVE_X11
-      XClearArea (x_current_display, FRAME_X_WINDOW (f), intborder, 
-                 CHAR_TO_PIXEL_ROW (f, topregion),
-                 f->width * FONT_WIDTH (f->display.x->font),
-                 n * f->display.x->line_height, False);
-#else /* ! defined (HAVE_X11) */
-      XPixSet (FRAME_X_WINDOW (f),
-              intborder,
-              CHAR_TO_PIXEL_ROW (f, topregion),
-              f->width * FONT_WIDTH (f->display.x->font),
-              n * f->display.x->line_height,
-              f->display.x->background_pixel);
-#endif /* ! defined (HAVE_X11) */
-    }
+    XClearArea (x_current_display, FRAME_X_WINDOW (f), intborder, 
+               CHAR_TO_PIXEL_ROW (f, topregion),
+               f->width * FONT_WIDTH (f->display.x->font),
+               n * f->display.x->line_height, False);
 }
 
 /* Perform a delete-lines operation, deleting N lines
@@ -1340,31 +1265,16 @@ scraplines (n)
   if (curs_y >= flexlines)
     return;
 
-#ifndef HAVE_X11
-  dumpqueue ();
-#endif /* HAVE_X11 */
-
   if ((curs_y + n) >= flexlines)
     {
       if (flexlines >= (curs_y + 1))
-       {
-#ifdef HAVE_X11
-         XClearArea (x_current_display, FRAME_X_WINDOW (f), intborder,
-                     CHAR_TO_PIXEL_ROW (f, curs_y),
-                     f->width * FONT_WIDTH (f->display.x->font),
-                     (flexlines - curs_y) * f->display.x->line_height, False);
-#else /* ! defined (HAVE_X11) */
-         XPixSet (FRAME_X_WINDOW (f),
-                  intborder, CHAR_TO_PIXEL_ROW (f, curs_y),
-                  f->width * FONT_WIDTH (f->display.x->font),
-                  (flexlines - curs_y) * f->display.x->line_height,
-                  f->display.x->background_pixel);
-#endif /* ! defined (HAVE_X11) */
-       }
+       XClearArea (x_current_display, FRAME_X_WINDOW (f), intborder,
+                   CHAR_TO_PIXEL_ROW (f, curs_y),
+                   f->width * FONT_WIDTH (f->display.x->font),
+                   (flexlines - curs_y) * f->display.x->line_height, False);
     }
   else
     {
-#ifdef HAVE_X11
       XCopyArea (x_current_display, FRAME_X_WINDOW (f),
                 FRAME_X_WINDOW (f), f->display.x->normal_gc,
                 intborder,
@@ -1377,23 +1287,6 @@ scraplines (n)
                  CHAR_TO_PIXEL_ROW (f, flexlines - n),
                  f->width * FONT_WIDTH (f->display.x->font),
                  n * f->display.x->line_height, False);
-#else /* ! defined (HAVE_X11) */
-      XMoveArea (FRAME_X_WINDOW (f),
-                intborder,
-                CHAR_TO_PIXEL_ROW (f, curs_y + n),
-                intborder, CHAR_TO_PIXEL_ROW (f, curs_y),
-                f->width * FONT_WIDTH (f->display.x->font),
-                (flexlines - (curs_y + n)) * f->display.x->line_height);
-      /* Now we must process any ExposeRegion events that occur
-        if the area being copied from is obscured.
-        We can't let it wait because further i/d operations
-        may want to copy this area to another area.  */
-      x_read_exposes ();
-      XPixSet (FRAME_X_WINDOW (f), intborder,
-              CHAR_TO_PIXEL_ROW (f, flexlines - n),
-              f->width * FONT_WIDTH (f->display.x->font),
-              n * f->display.x->line_height, f->display.x->background_pixel);
-#endif /* ! defined (HAVE_X11) */
     }
 }
 
@@ -1445,19 +1338,6 @@ dumprectangle (f, left, top, cols, rows)
   /* Express rectangle as four edges, instead of position-and-size.  */
   bottom = top + rows;
   right = left + cols;
-
-#ifndef HAVE_X11               /* Window manger does this for X11. */
-  {
-    int intborder = f->display.x->internal_border_width;
-
-    /* If the rectangle includes any of the internal border area,
-       redisplay the border emphasis.  */
-    if (top < intborder || left < intborder
-       || bottom > intborder + f->height * f->display.x->line_height
-       || right > intborder + f->width * f->display.x->line_height)
-      dumpborder (f, 0);
-  }
-#endif /* not HAVE_X11         Window manger does this for X11. */
   
   /* Convert rectangle edges in pixels to edges in chars.
      Round down for left and top, up for right and bottom.  */
@@ -1516,99 +1396,7 @@ dumprectangle (f, left, top, cols, rows)
   if (cursor_cleared)
     x_display_cursor (f, 1);
 }
-
-#ifndef HAVE_X11
-/* Process all queued ExposeRegion events. */
-
-static void
-dumpqueue ()
-{
-  register int i;
-  XExposeRegionEvent r;
-
-  while (dequeue_event (&r, &x_expose_queue))
-    {
-      struct frame *f = x_window_to_frame (r.window);
-      if (f->display.x->icon_desc == r.window)
-       refreshicon (f);
-      else
-       dumprectangle (f, r.x, r.y, r.width, r.height);
-    }
-  XFlushQueue ();
-}
-#endif /* HAVE_X11 */
 \f
-/* Process all expose events that are pending, for X10.
-   Redraws the cursor if necessary on any frame that
-   is not in the process of being updated with update_frame.  */
-
-#ifndef HAVE_X11
-static void
-x_do_pending_expose ()
-{
-  int mask;
-  struct frame *f;
-  Lisp_Object tail, frame;
-
-  if (expose_all_windows)
-    {
-      expose_all_windows = 0;
-      for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
-       {
-         register int temp_width, temp_height;
-         int intborder;
-
-         frame = XCONS (tail)->car;
-         if (XGCTYPE (frame) != Lisp_Frame)
-           continue;
-         f = XFRAME (frame);
-         if (! FRAME_X_P (f))
-           continue;
-         if (!f->async_visible)
-           continue;
-         if (!f->display.x->needs_exposure)
-           continue;
-
-         intborder = f->display.x->internal_border_width;
-
-         clear_cursor (f);
-         XGetWindowInfo (FRAME_X_WINDOW (f), &windowinfo);
-         temp_width = ((windowinfo.width - 2 * intborder
-                        - f->display.x->v_scroll_bar_width)
-                       / FONT_WIDTH (f->display.x->font));
-         temp_height = ((windowinfo.height- 2 * intborder
-                         - f->display.x->h_scroll_bar_height)
-                        / f->display.x->line_height);
-         if (temp_width != f->width || temp_height != f->height)
-           {
-             change_frame_size (f, max (1, temp_height),
-                                 max (1, temp_width), 0, 1);
-             x_resize_scroll_bars (f);
-           }
-         f->display.x->left_pos = windowinfo.x;
-         f->display.x->top_pos = windowinfo.y;
-         dumprectangle (f, 0, 0, PIXEL_WIDTH (f), PIXEL_HEIGHT (f));
-#if 0
-         dumpborder (f, 0);
-#endif /* ! 0 */
-         f->display.x->needs_exposure = 0;
-         if (updating_frame != f)
-           x_display_cursor (f, 1);
-         XFlushQueue ();
-       }
-    }
-  else
-    /* Handle any individual-rectangle expose events queued
-       for various windows.  */
-#ifdef HAVE_X11
-    ;
-#else /* ! defined (HAVE_X11) */
-    dumpqueue ();
-#endif /* ! defined (HAVE_X11) */
-}
-#endif
-
-#ifdef HAVE_X11
 static void
 frame_highlight (frame)
      struct frame *frame;
@@ -1638,50 +1426,6 @@ frame_unhighlight (frame)
   UNBLOCK_INPUT;
   x_display_cursor (frame, 1);
 }
-#else /* ! defined (HAVE_X11) */
-/* Dump the border-emphasis of frame F.
-   If F is selected, this is a lining of the same color as the border,
-   just within the border, occupying a portion of the internal border.
-   If F is not selected, it is background in the same place.
-   If ALWAYS is 0, don't bother explicitly drawing if it's background.
-
-   ALWAYS = 1 is used when a frame becomes selected or deselected.
-   In that case, we also turn the cursor off and on again
-   so it will appear in the proper shape (solid if selected; else hollow.)  */
-
-static void
-dumpborder (f, always)
-     struct frame *f;
-     int always;
-{
-  int thickness = f->display.x->internal_border_width / 2;
-  int width = PIXEL_WIDTH (f);
-  int height = PIXEL_HEIGHT (f);
-  int pixel;
-
-  if (f != selected_frame)
-    {
-      if (!always)
-       return;
-
-      pixel = f->display.x->background_pixel;
-    }
-  else
-    {
-      pixel = f->display.x->border_pixel;
-    }
-
-  XPixSet (FRAME_X_WINDOW (f), 0, 0, width, thickness, pixel);
-  XPixSet (FRAME_X_WINDOW (f), 0, 0, thickness, height, pixel);
-  XPixSet (FRAME_X_WINDOW (f), 0, height - thickness, width,
-          thickness, pixel);
-  XPixSet (FRAME_X_WINDOW (f), width - thickness, 0, thickness,
-          height, pixel);
-
-  if (always)
-    x_display_cursor (f, 1);
-}
-#endif /* ! defined (HAVE_X11) */
 
 static void XTframe_rehighlight ();
 
@@ -1909,25 +1653,8 @@ x_emacs_to_x_modifiers (state)
          | ((state & ctrl_modifier)            ? ControlMask      : 0)
          | ((state & meta_modifier)            ? x_meta_mod_mask  : 0));
 }
-
-/* Return true iff KEYSYM is a vendor-specific keysym that we should
-   return as a function key.  If you add a keysym to this, you should
-   make sure that the tables make_lispy_event uses contain a suitable
-   name for it.  */
-static int
-x_is_vendor_fkey (sym)
-     KeySym sym;
-{
-  return 0
-#ifdef DXK_Remove
-    || (sym == DXK_Remove)
-#endif
-      ;
-}
-
 \f
 /* Mouse clicks and mouse movement.  Rah.  */
-#ifdef HAVE_X11
 
 /* Given a pixel position (PIX_X, PIX_Y) on the frame F, return
    glyph co-ordinates in (*X, *Y).  Set *BOUNDS to the rectangle
@@ -2008,21 +1735,6 @@ construct_mouse_click (result, event, f)
                          ? up_modifier 
                          : down_modifier));
 
-  /* Notice if the mouse is still grabbed.  */
-  if (event->type == ButtonPress)
-    {
-      if (! x_mouse_grabbed)
-       Vmouse_depressed = Qt;
-      x_mouse_grabbed |= (1 << event->button);
-      last_mouse_frame = f;
-    }
-  else if (event->type == ButtonRelease)
-    {
-      x_mouse_grabbed &= ~(1 << event->button);
-      if (!x_mouse_grabbed)
-       Vmouse_depressed = Qnil;
-    }
-
   {
     int row, column;
 
@@ -2076,11 +1788,30 @@ note_mouse_movement (frame, event)
 {
   last_mouse_movement_time = event->time;
 
+  if (event->window != FRAME_X_WINDOW (frame))
+    {
+      mouse_moved = 1;
+      last_mouse_scroll_bar = Qnil;
+
+      note_mouse_highlight (frame, -1, -1);
+
+      /* Ask for another mouse motion event.  */
+      {
+       int dummy;
+       Window dummy_window;
+
+       XQueryPointer (event->display, FRAME_X_WINDOW (frame),
+                      &dummy_window, &dummy_window,
+                      &dummy, &dummy, &dummy, &dummy,
+                      (unsigned int *) &dummy);
+      }
+    }
+
   /* Has the mouse moved off the glyph it was on at the last sighting?  */
-  if (event->x < last_mouse_glyph.x
-      || event->x >= last_mouse_glyph.x + last_mouse_glyph.width
-      || event->y < last_mouse_glyph.y
-      || event->y >= last_mouse_glyph.y + last_mouse_glyph.height)
+  else if (event->x < last_mouse_glyph.x
+          || event->x >= last_mouse_glyph.x + last_mouse_glyph.width
+          || event->y < last_mouse_glyph.y
+          || event->y >= last_mouse_glyph.y + last_mouse_glyph.height)
     {
       mouse_moved = 1;
       last_mouse_scroll_bar = Qnil;
@@ -2090,9 +1821,10 @@ note_mouse_movement (frame, event)
       /* Ask for another mouse motion event.  */
       {
        int dummy;
+       Window dummy_window;
 
-       XQueryPointer (event->display, event->window,
-                      (Window *) &dummy, (Window *) &dummy,
+       XQueryPointer (event->display, FRAME_X_WINDOW (frame),
+                      &dummy_window, &dummy_window,
                       &dummy, &dummy, &dummy, &dummy,
                       (unsigned int *) &dummy);
       }
@@ -2103,9 +1835,10 @@ note_mouse_movement (frame, event)
         event the next time the mouse moves and we can see if it's
         *still* on the same glyph.  */
       int dummy;
+      Window dummy_window;
       
-      XQueryPointer (event->display, event->window,
-                    (Window *) &dummy, (Window *) &dummy,
+      XQueryPointer (event->display, FRAME_X_WINDOW (frame),
+                    &dummy_window, &dummy_window,
                     &dummy, &dummy, &dummy, &dummy,
                     (unsigned int *) &dummy);
     }
@@ -2116,7 +1849,8 @@ static int disable_mouse_highlight;
 
 /* Take proper action when the mouse has moved to position X, Y on frame F
    as regards highlighting characters that have mouse-face properties.
-   Also dehighlighting chars where the mouse was before.  */
+   Also dehighlighting chars where the mouse was before.
+   X and Y can be negative or out of range.  */
 
 static void
 note_mouse_highlight (f, x, y)
@@ -2157,7 +1891,8 @@ note_mouse_highlight (f, x, y)
 
   /* Are we in a window whose display is up to date?
      And verify the buffer's text has not changed.  */
-  if (WINDOWP (window) && portion == 0
+  if (WINDOWP (window) && portion == 0 && row >= 0 && column >= 0
+      && row < FRAME_HEIGHT (f) && column < FRAME_WIDTH (f)
       && EQ (w->window_end_valid, w->buffer)
       && w->last_modified == BUF_MODIFF (XBUFFER (w->buffer)))
     {
@@ -2170,9 +1905,14 @@ note_mouse_highlight (f, x, y)
          break;
       pos = ptr[i];
       /* Is it outside the displayed active region (if any)?  */
-      if (pos > 0
-         && ! (EQ (window, mouse_face_window)
-               && pos >= mouse_face_beg && pos < mouse_face_end))
+      if (pos <= 0)
+       clear_mouse_face ();
+      else if (! (EQ (window, mouse_face_window)
+                 && row >= mouse_face_beg_row
+                 && row <= mouse_face_end_row
+                 && (row > mouse_face_beg_row || column >= mouse_face_beg_col)
+                 && (row < mouse_face_end_row || column < mouse_face_end_col
+                     || mouse_face_past_end)))
        {
          Lisp_Object mouse_face, overlay, position;
          Lisp_Object *overlay_vec;
@@ -2204,7 +1944,8 @@ note_mouse_highlight (f, x, y)
 
          /* Put all the overlays we want in a vector in overlay_vec.
             Store the length in len.  */
-         noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len, &ignor1);
+         noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len,
+                                  NULL, NULL);
          noverlays = sort_overlays (overlay_vec, noverlays, w);
 
          /* Find the highest priority overlay that has a mouse-face prop.  */
@@ -2234,8 +1975,11 @@ note_mouse_highlight (f, x, y)
              before = Foverlay_start (overlay);
              after = Foverlay_end (overlay);
              /* Record this as the current active region.  */
-             mouse_face_beg = XFASTINT (before);
-             mouse_face_end = XFASTINT (after);
+             fast_find_position (window, before, &mouse_face_beg_col,
+                                 &mouse_face_beg_row);
+             mouse_face_past_end
+               = !fast_find_position (window, after, &mouse_face_end_col,
+                                      &mouse_face_end_row);
              mouse_face_window = window;
              mouse_face_face_id = compute_char_face (f, w, pos, 0, 0,
                                                      &ignore, pos + 1, 1);
@@ -2263,8 +2007,11 @@ note_mouse_highlight (f, x, y)
                = Fnext_single_property_change (position, Qmouse_face,
                                                w->buffer, end);
              /* Record this as the current active region.  */
-             mouse_face_beg = XFASTINT (before);
-             mouse_face_end = XFASTINT (after);
+             fast_find_position (window, before, &mouse_face_beg_col,
+                                 &mouse_face_beg_row);
+             mouse_face_past_end
+               = !fast_find_position (window, after, &mouse_face_end_col,
+                                      &mouse_face_end_row);
              mouse_face_window = window;
              mouse_face_face_id
                = compute_char_face (f, w, pos, 0, 0,
@@ -2277,8 +2024,6 @@ note_mouse_highlight (f, x, y)
          ZV = ozv;
          current_buffer = obuf;
        }
-      else if (pos <= 0)
-       clear_mouse_face ();
     }
 }
 \f
@@ -2287,7 +2032,9 @@ note_mouse_highlight (f, x, y)
    This assumes display in WINDOW is up to date.
    If POS is above start of WINDOW, return coords
    of start of first screen line.
-   If POS is after end of WINDOW, return coords of end of last screen line.  */
+   If POS is after end of WINDOW, return coords of end of last screen line.
+
+   Value is 1 if POS is in range, 0 if it was off screen.  */
 
 static int
 fast_find_position (window, pos, columnp, rowp)
@@ -2298,7 +2045,7 @@ fast_find_position (window, pos, columnp, rowp)
   struct window *w = XWINDOW (window);
   FRAME_PTR f = XFRAME (WINDOW_FRAME (w));
   int i;
-  int row;
+  int row = 0;
   int left = w->left;
   int top = w->top;
   int height = XFASTINT (w->height) - ! MINI_WINDOW_P (w);
@@ -2306,6 +2053,7 @@ fast_find_position (window, pos, columnp, rowp)
   int *charstarts;
   int lastcol;
 
+  /* Find the right row.  */
   for (i = 0;
        i < height;
        i++)
@@ -2317,6 +2065,7 @@ fast_find_position (window, pos, columnp, rowp)
        row = i;
     }
 
+  /* Find the right column with in it.  */
   charstarts = FRAME_CURRENT_GLYPHS (f)->charstarts[top + row];
   lastcol = left;
   for (i = 0; i < width; i++)
@@ -2328,6 +2077,8 @@ fast_find_position (window, pos, columnp, rowp)
          return 1;
        }
       else if (charstarts[left + i] > pos)
+       break;
+      else if (charstarts[left + i] > 0)
        lastcol = left + i;
     }
 
@@ -2343,30 +2094,30 @@ static void
 show_mouse_face (hl)
      int hl;
 {
-  int begcol, begrow, endcol, endrow;
   struct window *w = XWINDOW (mouse_face_window);
   int width = window_internal_width (w);
   FRAME_PTR f = XFRAME (WINDOW_FRAME (w));
   int i;
-  int curs_x = f->phys_cursor_x;
-  int curs_y = f->phys_cursor_y;
   int cursor_off = 0;
+  int old_curs_x = curs_x;
+  int old_curs_y = curs_y;
 
-  fast_find_position (mouse_face_window, mouse_face_beg,
-                     &begcol, &begrow);
-  fast_find_position (mouse_face_window, mouse_face_end,
-                     &endcol, &endrow);
+  /* Set these variables temporarily
+     so that if we have to turn the cursor off and on again
+     we will put it back at the same place.  */
+  curs_x = f->phys_cursor_x;
+  curs_y = f->phys_cursor_y;
 
-  for (i = begrow; i <= endrow; i++)
+  for (i = mouse_face_beg_row; i <= mouse_face_end_row; i++)
     {
-      int column = (i == begrow ? begcol : w->left);
-      int endcolumn = (i == endrow ? endcol : w->left + width);
-      endcolumn = min (endcolumn, FRAME_CURRENT_GLYPHS (f)->used[i] - w->left);
+      int column = (i == mouse_face_beg_row ? mouse_face_beg_col : w->left);
+      int endcolumn = (i == mouse_face_end_row ? mouse_face_end_col : w->left + width);
+      endcolumn = min (endcolumn, FRAME_CURRENT_GLYPHS (f)->used[i]);
 
       /* If the cursor's in the text we are about to rewrite,
         turn the cursor off.  */
       if (i == curs_y
-         && (curs_x >= begrow - 1 || curs_x <= endrow))
+         && curs_x >= mouse_face_beg_col - 1 && curs_x <= mouse_face_end_col)
        {
          x_display_cursor (f, 0);
          cursor_off = 1;
@@ -2385,6 +2136,9 @@ show_mouse_face (hl)
   if (cursor_off)
     x_display_cursor (f, 1);
 
+  curs_x = old_curs_x;
+  curs_y = old_curs_y;
+
   /* Change the mouse cursor according to the value of HL.  */
   if (hl > 0)
     XDefineCursor (XDISPLAY FRAME_X_WINDOW (f), f->display.x->cross_cursor);
@@ -2401,8 +2155,8 @@ clear_mouse_face ()
   if (! NILP (mouse_face_window))
     show_mouse_face (0);
 
-  mouse_face_beg = -1;
-  mouse_face_end = -1;
+  mouse_face_beg_row = mouse_face_beg_col = -1;
+  mouse_face_end_row = mouse_face_end_col = -1;
   mouse_face_window = Qnil;
 }
 \f
@@ -2485,7 +2239,8 @@ XTmouse_position (f, bar_window, part, x, y, time)
 
        win = root;
 
-       if (x_mouse_grabbed)
+       if (x_mouse_grabbed && last_mouse_frame
+           && FRAME_LIVE_P (last_mouse_frame))
          {
            /* If mouse was grabbed on a frame, give coords for that frame
               even if the mouse is now outside it.  */
@@ -2573,10 +2328,6 @@ XTmouse_position (f, bar_window, part, x, y, time)
 
   UNBLOCK_INPUT;
 }
-
-#else /* ! defined (HAVE_X11) */
-#define XEvent XKeyPressedEvent
-#endif /* ! defined (HAVE_X11) */
 \f
 /* Scroll bar support.  */
 
@@ -2864,7 +2615,10 @@ XTset_vertical_scroll_bar (window, portion, whole, position)
   /* Where should this scroll bar be, pixelwise?  */
   int pixel_top  = CHAR_TO_PIXEL_ROW (f, top);
   int pixel_left = CHAR_TO_PIXEL_COL (f, left);
-  int pixel_width = VERTICAL_SCROLL_BAR_PIXEL_WIDTH (f);
+  int pixel_width
+    = (FRAME_SCROLL_BAR_PIXEL_WIDTH (f) > 0
+       ? FRAME_SCROLL_BAR_PIXEL_WIDTH (f)
+       : (FRAME_SCROLL_BAR_COLS (f) * FONT_WIDTH (f->display.x->font)));
   int pixel_height = VERTICAL_SCROLL_BAR_PIXEL_HEIGHT (f, height);
 
   struct scroll_bar *bar;
@@ -3140,9 +2894,10 @@ x_scroll_bar_note_movement (bar, event)
      moves and we can see *still* on the same position.  */
   {
     int dummy;
+    Window dummy_window;
       
     XQueryPointer (event->xmotion.display, event->xmotion.window,
-                  (Window *) &dummy, (Window *) &dummy,
+                  &dummy_window, &dummy_window,
                   &dummy, &dummy, &dummy, &dummy,
                   (unsigned int *) &dummy);
   }
@@ -3233,8 +2988,7 @@ x_scroll_bar_clear (f)
 {
   Lisp_Object bar;
 
-  for (bar = FRAME_SCROLL_BARS (f);
-       XTYPE (bar) == Lisp_Vector;
+  for (bar = FRAME_SCROLL_BARS (f); VECTORP (bar);
        bar = XSCROLL_BAR (bar)->next)
     XClearArea (x_current_display, SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar)),
                0, 0, 0, 0, True);
@@ -3279,7 +3033,68 @@ process_expose_from_menu (event)
 
   UNBLOCK_INPUT;
 }
+\f
+/* Define a queue to save up SelectionRequest events for later handling.  */
+
+struct selection_event_queue
+  {
+    XEvent event;
+    struct selection_event_queue *next;
+  };
+
+static struct selection_event_queue *queue;
+
+/* Nonzero means queue up certain events--don't process them yet.  */
+static int x_queue_selection_requests;
+
+/* Queue up an X event *EVENT, to be processed later.  */
+
+static void
+x_queue_event (event)
+     XEvent *event;
+{
+  struct selection_event_queue *queue_tmp
+    = (struct selection_event_queue *) malloc (sizeof (struct selection_event_queue));
+
+  if (queue_tmp != NULL) 
+    {
+      queue_tmp->event = *event;
+      queue_tmp->next = queue;
+      queue = queue_tmp;
+    }
+}
+
+/* Take all the queued events and put them back
+   so that they get processed afresh.  */
+
+static void
+x_unqueue_events ()
+{
+  while (queue != NULL) 
+    {
+      struct selection_event_queue *queue_tmp = queue;
+      XPutBackEvent (XDISPLAY &queue_tmp->event);
+      queue = queue_tmp->next;
+      free ((char *)queue_tmp);
+    }
+}
+
+/* Start queuing SelectionRequest events.  */
+
+void
+x_start_queuing_selection_requests ()
+{
+  x_queue_selection_requests++;
+}
+
+/* Stop queuing SelectionRequest events.  */
 
+void
+x_stop_queuing_selection_requests ()
+{
+  x_queue_selection_requests--;
+  x_unqueue_events ();
+}
 \f
 /* The main X event-reading loop - XTread_socket.  */
 
@@ -3358,7 +3173,10 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
 
   interrupt_input_pending = 0;
   BLOCK_INPUT;
-       
+
+  /* So people can tell when we have read the available input.  */
+  input_signal_count++;
+
   if (numchars <= 0)
     abort ();                  /* Don't think this happens. */
 
@@ -3389,7 +3207,6 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
 
       switch (event.type)
        {
-#ifdef HAVE_X11
        case ClientMessage:
          {
            if (event.xclient.message_type == Xatom_wm_protocols
@@ -3398,13 +3215,10 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
                if (event.xclient.data.l[0] == Xatom_wm_take_focus)
                  {
                    f = x_window_to_frame (event.xclient.window);
-#if 0 /* x_focus_on_frame is a no-op anyway.  */
+                   /* Since we set WM_TAKE_FOCUS, we must call
+                      XSetInputFocus explicitly.  But not if f is null,
+                      since that might be an event for a deleted frame.  */
                    if (f)
-                     x_focus_on_frame (f);
-                   else
-#endif
-                     /* Since we set WM_TAKE_FOCUS, we must call
-                        XSetInputFocus explicitly.  */
                      XSetInputFocus (event.xclient.display,
                                      event.xclient.window,
                                      RevertToPointerRoot,
@@ -3420,6 +3234,17 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
                       a keyboard or mouse event arrives. */
                    if (numchars > 0)
                      {
+                       /* This is just so we only give real data once
+                          for a single Emacs process.  */
+                       if (x_top_window_to_frame (event.xclient.window)
+                           == selected_frame)
+                         XSetCommand (x_current_display,
+                                      event.xclient.window,
+                                      initial_argv, initial_argc);
+                       else
+                         XSetCommand (x_current_display,
+                                      event.xclient.window,
+                                      0, 0);
                      }
                  }
                else if (event.xclient.data.l[0] == Xatom_wm_delete_window)
@@ -3502,24 +3327,27 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
          if (!x_window_to_frame (event.xselectionrequest.owner))
            goto OTHER;
 #endif /* USE_X_TOOLKIT */
-         {
-           XSelectionRequestEvent *eventp = (XSelectionRequestEvent *) &event;
+         if (x_queue_selection_requests)
+           x_queue_event (&event);
+         else
+           {
+             XSelectionRequestEvent *eventp = (XSelectionRequestEvent *) &event;
 
-           if (numchars == 0)
-             abort ();
+             if (numchars == 0)
+               abort ();
 
-           bufp->kind = selection_request_event;
-           SELECTION_EVENT_DISPLAY (bufp) = eventp->display;
-           SELECTION_EVENT_REQUESTOR (bufp) = eventp->requestor;
-           SELECTION_EVENT_SELECTION (bufp) = eventp->selection;
-           SELECTION_EVENT_TARGET (bufp) = eventp->target;
-           SELECTION_EVENT_PROPERTY (bufp) = eventp->property;
-           SELECTION_EVENT_TIME (bufp) = eventp->time;
-           bufp++;
+             bufp->kind = selection_request_event;
+             SELECTION_EVENT_DISPLAY (bufp) = eventp->display;
+             SELECTION_EVENT_REQUESTOR (bufp) = eventp->requestor;
+             SELECTION_EVENT_SELECTION (bufp) = eventp->selection;
+             SELECTION_EVENT_TARGET (bufp) = eventp->target;
+             SELECTION_EVENT_PROPERTY (bufp) = eventp->property;
+             SELECTION_EVENT_TIME (bufp) = eventp->time;
+             bufp++;
 
-           count += 1;
-           numchars -= 1;
-         }
+             count += 1;
+             numchars -= 1;
+           }
          break;
 
        case PropertyNotify:
@@ -3531,9 +3359,15 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
          break;
 
        case ReparentNotify:
-         f = x_window_to_frame (event.xreparent.window);
+         f = x_top_window_to_frame (event.xreparent.window);
          if (f)
-           f->display.x->parent_desc = event.xreparent.parent;
+           {
+             int x, y;
+             f->display.x->parent_desc = event.xreparent.parent;
+             x_real_positions (f, &x, &y);
+             f->display.x->left_pos = x;
+             f->display.x->top_pos = y;
+           }
          break;
 
        case Expose:
@@ -3586,55 +3420,7 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
                                  source area was completely
                                  available */
          break;
-#else /* ! defined (HAVE_X11) */
-       case ExposeWindow:
-         if (event.subwindow != 0)
-           break;              /* duplicate event */
-         f = x_window_to_frame (event.window);
-         if (event.window == f->display.x->icon_desc)
-           {
-             refreshicon (f);
-             f->async_iconified = 1;
-           }
-         if (event.window == FRAME_X_WINDOW (f))
-           {
-             /* Say must check all windows' needs_exposure flags.  */
-             expose_all_windows = 1;
-             f->display.x->needs_exposure = 1;
-             f->async_visible = 1;
-           }
-         break;
-
-       case ExposeRegion:
-         if (event.subwindow != 0)
-           break;              /* duplicate event */
-         f = x_window_to_frame (event.window);
-         if (event.window == f->display.x->icon_desc)
-           {
-             refreshicon (f);
-             break;
-           }
-         /* If window already needs full redraw, ignore this rectangle.  */
-         if (expose_all_windows && f->display.x->needs_exposure)
-           break;
-         /* Put the event on the queue of rectangles to redraw.  */
-         if (enqueue_event (&event, &x_expose_queue))
-           /* If it is full, we can't record the rectangle,
-              so redraw this entire window.  */
-           {
-             /* Say must check all windows' needs_exposure flags.  */
-             expose_all_windows = 1;
-             f->display.x->needs_exposure = 1;
-           }
-         break;
-
-       case ExposeCopy:
-         /* This should happen only when we are expecting it,
-            in x_read_exposes.  */
-         abort ();
-#endif /* ! defined (HAVE_X11) */
 
-#ifdef HAVE_X11
        case UnmapNotify:
          f = x_any_window_to_frame (event.xunmap.window);
          if (f)                /* F may no longer exist if
@@ -3678,17 +3464,6 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
        case VisibilityNotify:
          break;
 
-#else /* ! defined (HAVE_X11) */
-       case UnmapWindow:
-         f = x_window_to_frame (event.window);
-         if (event.window == f->display.x->icon_desc)
-           f->async_iconified = 0;
-         if (event.window == FRAME_X_WINDOW (f))
-           f->async_visible = 0;
-         break;
-#endif /* ! defined (HAVE_X11) */
-
-#ifdef HAVE_X11
        case KeyPress:
          f = x_any_window_to_frame (event.xkey.window);
 
@@ -3713,11 +3488,7 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
                XLookupString (&event.xkey, copy_buffer, 80, &keysym,
                               &compose_status);
 
-             /* Strip off the vendor-specific keysym bit, and take a shot
-                at recognizing the codes.  HP servers have extra keysyms
-                that fit into the MiscFunctionKey category.  */
              orig_keysym = keysym;
-             keysym &= ~(1<<28);
 
              if (numchars > 1)
                {
@@ -3774,7 +3545,8 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
 #endif
                       || IsKeypadKey (keysym) /* 0xff80 <= x < 0xffbe */
                       || IsFunctionKey (keysym) /* 0xffbe <= x < 0xffe1 */
-                      || x_is_vendor_fkey (orig_keysym))
+                      /* Any "vendor-specific" key is ok.  */
+                      || (orig_keysym & (1 << 28)))
                      && ! (IsModifierKey (orig_keysym)
 #ifndef HAVE_X11R5
 #ifdef XK_Mode_switch
@@ -3825,56 +3597,6 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
                abort ();
            }
          break;
-#else /* ! defined (HAVE_X11) */
-       case KeyPressed:
-         {
-           register char *where_mapping;
-
-           f = x_window_to_frame (event.window);
-           /* Ignore keys typed on icon windows.  */
-           if (f != 0 && event.window == f->display.x->icon_desc)
-             break;
-           where_mapping = XLookupMapping (&event, &nbytes);
-           /* Nasty fix for arrow keys */
-           if (!nbytes && IsCursorKey (event.detail & 0xff))
-             {
-               switch (event.detail & 0xff)
-                 {
-                 case KC_CURSOR_LEFT:
-                   where_mapping = "\002";
-                   break;
-                 case KC_CURSOR_RIGHT:
-                   where_mapping = "\006";
-                   break;
-                 case KC_CURSOR_UP:
-                   where_mapping = "\020";
-                   break;
-                 case KC_CURSOR_DOWN:
-                   where_mapping = "\016";
-                   break;
-                 }
-               nbytes = 1;
-             }
-           if (numchars - nbytes > 0)
-             {
-               register int i;
-
-               for (i = 0; i < nbytes; i++)
-                 {
-                   bufp->kind = ascii_keystroke;
-                   bufp->code = where_mapping[i];
-                   XSET (bufp->time, Lisp_Int, event.xkey.time);
-                   XSET (bufp->frame_or_window, Lisp_Frame, f);
-                   bufp++;
-                 }
-               count += nbytes;
-               numchars -= nbytes;
-             }
-         }
-         break;
-#endif /* ! defined (HAVE_X11) */
-
-#ifdef HAVE_X11
 
          /* Here's a possible interpretation of the whole
             FocusIn-EnterNotify FocusOut-LeaveNotify mess.  If you get a
@@ -3898,6 +3620,10 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
            }
          else if (f == x_focus_frame)
            x_new_focus_frame (0);
+         /* EnterNotify counts as mouse movement,
+            so update things that depend on mouse position.  */
+         if (f)
+           note_mouse_movement (f, &event.xmotion);
 #ifdef USE_X_TOOLKIT
          goto OTHER;
 #endif /* USE_X_TOOLKIT */
@@ -3916,26 +3642,28 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
 
 
        case LeaveNotify:
-         f = x_any_window_to_frame (event.xcrossing.window);
-
-         if (f == mouse_face_mouse_frame)
-           /* If we move outside the frame,
-              then we're certainly no longer on any text in the frame.  */
-           clear_mouse_face ();
-
-         if (event.xcrossing.focus)
-           {
-             if (! x_focus_event_frame)
-               x_new_focus_frame (0);
-             else
-               x_new_focus_frame (f);
-           }
-         else 
+         f = x_top_window_to_frame (event.xcrossing.window);
+         if (f)
            {
-             if (f == x_focus_event_frame)
-               x_focus_event_frame = 0;
-             if (f == x_focus_frame)
-               x_new_focus_frame (0);
+             if (f == mouse_face_mouse_frame)
+               /* If we move outside the frame,
+                  then we're certainly no longer on any text in the frame.  */
+               clear_mouse_face ();
+
+             if (event.xcrossing.focus)
+               {
+                 if (! x_focus_event_frame)
+                   x_new_focus_frame (0);
+                 else
+                   x_new_focus_frame (f);
+               }
+             else 
+               {
+                 if (f == x_focus_event_frame)
+                   x_focus_event_frame = 0;
+                 if (f == x_focus_frame)
+                   x_new_focus_frame (0);
+               }
            }
 #ifdef USE_X_TOOLKIT
          goto OTHER;
@@ -3954,46 +3682,10 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
 #endif /* USE_X_TOOLKIT */
          break;
 
-#else /* ! defined (HAVE_X11) */
-
-       case EnterWindow:
-         if ((event.detail & 0xFF) == 1)
-           break;              /* Coming from our own subwindow */
-         if (event.subwindow != 0)
-           break;              /* Entering our own subwindow.  */
-
+       case MotionNotify:
          {
-           f = x_window_to_frame (event.window);
-           x_mouse_frame = f;
-
-           x_new_focus_frame (f);
-         }
-         break;
-
-       case LeaveWindow:
-         if ((event.detail & 0xFF) == 1)
-           break;              /* Entering our own subwindow */
-         if (event.subwindow != 0)
-           break;              /* Leaving our own subwindow.  */
-
-         x_mouse_frame = 0;
-         if (x_focus_frame == 0
-             && x_input_frame != 0
-             && x_input_frame == x_window_to_frame (event.window)
-             && event.window == FRAME_X_WINDOW (x_input_frame))
-           {
-             f = x_input_frame;
-             x_input_frame = 0;
-             if (f)
-               frame_unhighlight (f);
-           }
-         break;
-#endif /* ! defined (HAVE_X11) */
-
-#ifdef HAVE_X11
-       case MotionNotify:
-         {
-           if (x_mouse_grabbed)
+           if (x_mouse_grabbed && last_mouse_frame
+               && FRAME_LIVE_P (last_mouse_frame))
              f = last_mouse_frame;
            else
              f = x_window_to_frame (event.xmotion.window);
@@ -4012,16 +3704,23 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
                clear_mouse_face ();
              }
          }
+#if 0 /* This should be unnecessary, since the toolkit has no use
+        for motion events that happen outside of the menu event loop,
+        and it seems to cause the bug that mouse events stop coming
+        after a while.  */
 #ifdef USE_X_TOOLKIT
          goto OTHER;
 #endif /* USE_X_TOOLKIT */
+#endif
          break;
 
        case ConfigureNotify:
           f = x_any_window_to_frame (event.xconfigure.window);
 #ifdef USE_X_TOOLKIT
           if (f
+#if 0
               && ! event.xconfigure.send_event
+#endif
               && (event.xconfigure.window == XtWindow (f->display.x->widget)))
             {
               Window win, child;
@@ -4052,6 +3751,15 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
               f->display.x->pixel_height = event.xconfigure.height;
               f->display.x->left_pos = event.xconfigure.x;
               f->display.x->top_pos = event.xconfigure.y;
+
+             /* What we have now is the position of Emacs's own window.
+                Convert that to the position of the window manager window.  */
+             {
+               int x, y;
+               x_real_positions (f, &x, &y);
+               f->display.x->left_pos = x;
+               f->display.x->top_pos = y;
+             }
             }
           goto OTHER;
 #else /* not USE_X_TOOLKIT */
@@ -4103,6 +3811,22 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
              f->display.x->pixel_height = event.xconfigure.height;
              f->display.x->left_pos = event.xconfigure.x;
              f->display.x->top_pos = event.xconfigure.y;
+
+             /* What we have now is the position of Emacs's own window.
+                Convert that to the position of the window manager window.  */
+             {
+               int x, y;
+               x_real_positions (f, &x, &y);
+               f->display.x->left_pos = x;
+               f->display.x->top_pos = y;
+               if (y != event.xconfigure.y)
+                 {
+                   /* Since the WM decorations come below top_pos now,
+                      we must put them below top_pos in the future.  */
+                   f->display.x->win_gravity = NorthWestGravity;
+                   x_wm_set_size_hint (f, 0, 0);
+                 }
+             }
            }
 #endif /* not USE_X_TOOLKIT */
          break;
@@ -4115,6 +3839,8 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
            struct input_event emacs_event;
            emacs_event.kind = no_event;
 
+           bzero (&compose_status, sizeof (compose_status));
+
            f = x_window_to_frame (event.xbutton.window);
            if (f)
              {
@@ -4123,22 +3849,35 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
              }
            else
              {
-               struct scroll_bar *bar =
-                 x_window_to_scroll_bar (event.xbutton.window);
+               struct scroll_bar *bar
+                 x_window_to_scroll_bar (event.xbutton.window);
 
                if (bar)
                  x_scroll_bar_handle_click (bar, &event, &emacs_event);
 #ifdef USE_X_TOOLKIT
                else
                  {
-                   f = x_any_window_to_frame (event.xbutton.window);
-                   if (f && event.type == ButtonPress)
-                     construct_menu_click (&emacs_event,
-                                           &event, f);
+                   /* Assume we have a menubar button press. A bad
+                       assumption should behave benignly. */
+                   popup_get_selection (&event);
+                   break;
                  }
 #endif /* USE_X_TOOLKIT */
              }
 
+           if (event.type == ButtonPress)
+             {
+               x_mouse_grabbed |= (1 << event.xbutton.button);
+               Vmouse_depressed = Qt;
+               last_mouse_frame = f;
+             }
+           else
+             {
+               x_mouse_grabbed &= ~(1 << event.xbutton.button);
+               if (!x_mouse_grabbed)
+                 Vmouse_depressed = Qnil;
+             }
+
            if (numchars >= 1 && emacs_event.kind != no_event)
              {
                bcopy (&emacs_event, bufp, sizeof (struct input_event));
@@ -4153,56 +3892,11 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
          }
          break;
 
-#else /* ! defined (HAVE_X11) */
-       case ButtonPressed:
-       case ButtonReleased:
-         f = x_window_to_frame (event.window);
-         if (f)
-           {
-             if (event.window == f->display.x->icon_desc)
-               {
-                 x_make_frame_visible (f);
-
-                 if (warp_mouse_on_deiconify)
-                   XWarpMouse (FRAME_X_WINDOW (f), 10, 10);
-                 break;
-               }
-             if (event.window == FRAME_X_WINDOW (f))
-               {
-                 if (f->auto_raise)
-                   x_raise_frame (f);
-               }
-           }
-         enqueue_event (&event, &x_mouse_queue);
-         if (numchars >= 2)
-           {
-             bufp->kind = ascii_keystroke;
-             bufp->code = 'X' & 037; /* C-x */
-             XSET (bufp->frame_or_window, Lisp_Frame, f);
-             XSET (bufp->time, Lisp_Int, event.xkey.time);
-             bufp++;
-
-             bufp->kind = ascii_keystroke;
-             bufp->code = 0; /* C-@ */
-             XSET (bufp->frame_or_window, Lisp_Frame, f);
-             XSET (bufp->time, Lisp_Int, event.xkey.time);
-             bufp++;
-
-             count += 2;
-             numchars -= 2;
-           }
-         break;
-#endif /* ! defined (HAVE_X11) */
-
-#ifdef HAVE_X11
-
        case CirculateNotify:
          break;
        case CirculateRequest:
          break;
 
-#endif /* ! defined (HAVE_X11) */
-
        case MappingNotify:
          /* Someone has changed the keyboard mapping - update the
             local cache.  */
@@ -4230,12 +3924,20 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
        }
     }
 
-#ifdef X_IO_BUG
-  if (! event_found)
-    /* On some systems, an X bug causes Emacs to get no more events
-       when the window is destroyed.  Detect that.  (1994.)  */
-    XNoOp (x_current_display);
-#endif /* X_IO_BUG */
+  /* On some systems, an X bug causes Emacs to get no more events
+     when the window is destroyed.  Detect that.  (1994.)  */
+  if (! event_found) 
+    {
+      /* Emacs and the X Server eats up CPU time if XNoOp is done every time.
+        One XNOOP in 100 loops will make Emacs terminate.
+        B. Bretthauer, 1994 */
+      x_noop_count++;
+      if (x_noop_count >= 100) 
+       {
+         x_noop_count=0;
+         XNoOp (x_current_display);
+       }
+    }
 
 #if 0 /* This fails for serial-line connections to the X server, 
         because the characters arrive one by one, and a partial
@@ -4264,90 +3966,17 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
 #endif /* HAVE_SELECT */
 #endif /* 0 */
 
-#ifndef HAVE_X11
-  if (updating_frame == 0)
-    x_do_pending_expose ();
-#endif
-
   /* If the focus was just given to an autoraising frame,
      raise it now.  */
-#ifdef HAVE_X11
   if (pending_autoraise_frame)
     {
       x_raise_frame (pending_autoraise_frame);
       pending_autoraise_frame = 0;
     }
-#endif
 
   UNBLOCK_INPUT;
   return count;
 }
-
-#ifndef HAVE_X11
-/* Read and process only Expose events
-   until we get an ExposeCopy event; then return.
-   This is used in insert/delete line.
-   We assume input is already blocked.  */
-
-static void
-x_read_exposes ()
-{
-  struct frame *f;
-  XKeyPressedEvent event;
-
-  while (1)
-    {
-      /* while there are more events*/
-      XMaskEvent (ExposeWindow | ExposeRegion | ExposeCopy, &event);
-      switch (event.type)
-       {
-       case ExposeWindow:
-         if (event.subwindow != 0)
-           break;                      /* duplicate event */
-         f = x_window_to_frame (event.window);
-         if (event.window == f->display.x->icon_desc)
-           {
-             refreshicon (f);
-             break;
-           }
-         if (event.window == FRAME_X_WINDOW (f))
-           {
-             expose_all_windows = 1;
-             f->display.x->needs_exposure = 1;
-             break;
-           }
-         break;
-
-       case ExposeRegion:
-         if (event.subwindow != 0)
-           break;                      /* duplicate event */
-         f = x_window_to_frame (event.window);
-         if (event.window == f->display.x->icon_desc)
-           {
-             refreshicon (f);
-             break;
-           }
-         /* If window already needs full redraw, ignore this rectangle.  */
-         if (expose_all_windows && f->display.x->needs_exposure)
-           break;
-         /* Put the event on the queue of rectangles to redraw.  */
-         if (enqueue_event (&event, &x_expose_queue))
-           /* If it is full, we can't record the rectangle,
-              so redraw this entire window.  */
-           {
-             /* Say must check all windows' needs_exposure flags.  */
-             expose_all_windows = 1;
-             f->display.x->needs_exposure = 1;
-           }
-         break;
-
-       case ExposeCopy:
-         return;
-       }
-    }
-}
-#endif /* HAVE_X11 */
-
 \f
 /* Drawing the cursor.  */
 
@@ -4358,32 +3987,14 @@ static void
 x_draw_box (f)
      struct frame *f;
 {
-  int left = CHAR_TO_PIXEL_COL (f, f->cursor_x);
-  int top  = CHAR_TO_PIXEL_ROW (f, f->cursor_y);
+  int left = CHAR_TO_PIXEL_COL (f, curs_x);
+  int top  = CHAR_TO_PIXEL_ROW (f, curs_y);
   int width = FONT_WIDTH (f->display.x->font);
   int height = f->display.x->line_height;
 
-#ifdef HAVE_X11
   XDrawRectangle (x_current_display, FRAME_X_WINDOW (f),
                  f->display.x->cursor_gc,
                  left, top, width - 1, height - 1);
-#else /* ! defined (HAVE_X11) */
-  XPixSet (FRAME_X_WINDOW (f),
-          left, top, width, 1,
-          f->display.x->cursor_pixel);
-
-  XPixSet (FRAME_X_WINDOW (f),
-          left, top, 1, height,
-          f->display.x->cursor_pixel);
-
-  XPixSet (FRAME_X_WINDOW (f),
-          left+width-1, top, 1, height,
-          f->display.x->cursor_pixel);
-
-  XPixSet (FRAME_X_WINDOW (f),
-          left, top+height-1, width, 1,
-          f->display.x->cursor_pixel);
-#endif /* ! defined (HAVE_X11) */
 }
 
 /* Clear the cursor of frame F to background color,
@@ -4401,15 +4012,7 @@ clear_cursor (f)
       || f->phys_cursor_x < 0)
     return;
 
-#ifdef HAVE_X11
   x_display_cursor (f, 0);
-#else /* ! defined (HAVE_X11) */
-  XPixSet (FRAME_X_WINDOW (f),
-          CHAR_TO_PIXEL_COL (f, f->phys_cursor_x),
-          CHAR_TO_PIXEL_ROW (f, f->phys_cursor_y),
-          FONT_WIDTH (f->display.x->font), f->display.x->line_height,
-          f->display.x->background_pixel);
-#endif /* ! defined (HAVE_X11) */
   f->phys_cursor_x = -1;
 }
 
@@ -4535,6 +4138,21 @@ x_display_box_cursor (f, on)
          || (f->display.x->current_cursor != hollow_box_cursor
              && (f != x_highlight_frame))))
     {
+      int mouse_face_here = 0;
+
+      /* If the cursor is in the mouse face area, redisplay that when
+        we clear the cursor.  */
+      if (f == mouse_face_mouse_frame
+         &&
+         (f->phys_cursor_y > mouse_face_beg_row
+          || (f->phys_cursor_y == mouse_face_beg_row
+              && f->phys_cursor_x >= mouse_face_beg_col))
+         &&
+         (f->phys_cursor_y < mouse_face_end_row
+          || (f->phys_cursor_y == mouse_face_end_row
+              && f->phys_cursor_x < mouse_face_end_col)))
+       mouse_face_here = 1;
+
       /* If the font is not as tall as a whole line,
         we must explicitly clear the line's whole height.  */
       if (FONT_HEIGHT (f->display.x->font) != f->display.x->line_height)
@@ -4546,7 +4164,9 @@ x_display_box_cursor (f, on)
       /* Erase the cursor by redrawing the character underneath it.  */
       x_draw_single_glyph (f, f->phys_cursor_y, f->phys_cursor_x,
                           f->phys_cursor_glyph,
-                          current_glyphs->highlight[f->phys_cursor_y]);
+                          (mouse_face_here
+                           ? 3
+                           : current_glyphs->highlight[f->phys_cursor_y]));
       f->phys_cursor_x = -1;
     }
 
@@ -4608,38 +4228,7 @@ x_display_cursor (f, on)
 refreshicon (f)
      struct frame *f;
 {
-#ifdef HAVE_X11
   /* Normally, the window manager handles this function. */
-#else /* ! defined (HAVE_X11) */
-  int mask;
-
-  if (f->display.x->icon_bitmap_flag)
-    XBitmapBitsPut (f->display.x->icon_desc, 0,  0, sink_width, sink_height,
-                   sink_bits, BlackPixel, WHITE_PIX_DEFAULT, 
-                   icon_bitmap, GXcopy, AllPlanes);
-  else
-    {
-      extern struct frame *selected_frame;
-      struct Lisp_String *str;
-      unsigned char *string;
-
-      string
-       = XSTRING (XBUFFER (XWINDOW (f->selected_window)->buffer)->name)->data;
-
-      if (f->display.x->icon_label != string)
-       {
-         f->display.x->icon_label = string;
-         XChangeWindow (f->display.x->icon_desc,
-                        XQueryWidth (string, icon_font_info->id) + 10,
-                        icon_font_info->height + 10);
-       }
-
-      XText (f->display.x->icon_desc, 5, 5, string,
-            str->size, icon_font_info->id,
-            BLACK_PIX_DEFAULT, WHITE_PIX_DEFAULT);
-    }
-  XFlushQueue ();
-#endif /* ! defined (HAVE_X11) */
 }
 
 /* Make the x-window of frame F use the gnu icon bitmap.  */
@@ -4654,37 +4243,12 @@ x_bitmap_icon (f)
   if (FRAME_X_WINDOW (f) == 0)
     return 1;
 
-#ifdef HAVE_X11
   if (! icon_bitmap)
     icon_bitmap =
       XCreateBitmapFromData (x_current_display, FRAME_X_WINDOW (f),
                             gnu_bits, gnu_width, gnu_height);
   x_wm_set_icon_pixmap (f, icon_bitmap);
   f->display.x->icon_bitmap_flag = 1;
-#else /* ! defined (HAVE_X11) */
-  if (f->display.x->icon_desc)
-    {
-      XClearIconWindow (FRAME_X_WINDOW (f));
-      XDestroyWindow (f->display.x->icon_desc);
-    }
-
-  icon_window = XCreateWindow (f->display.x->parent_desc,
-                              0, 0, sink_width, sink_height,
-                              2, WhitePixmap, (Pixmap) NULL);
-
-  if (icon_window == 0)
-    return 1;
-
-  XSetIconWindow (FRAME_X_WINDOW (f), icon_window);
-  XSelectInput (icon_window, ExposeWindow | UnmapWindow);
-
-  f->display.x->icon_desc = icon_window;
-  f->display.x->icon_bitmap_flag = 1;
-
-  if (icon_bitmap == 0)
-    icon_bitmap
-      = XStoreBitmap (sink_mask_width, sink_mask_height, sink_mask_bits);
-#endif /* ! defined (HAVE_X11) */
 
   return 0;
 }
@@ -4697,26 +4261,9 @@ x_text_icon (f, icon_name)
      struct frame *f;
      char *icon_name;
 {
-#ifndef HAVE_X11
-  int mask;
-  int width;
-  Window icon_window;
-  char *X_DefaultValue;
-  Bitmap b1;
-
-#ifndef WhitePixel
-#define WhitePixel 1
-#endif /* WhitePixel */
-
-#ifndef BlackPixel
-#define BlackPixel 0
-#endif /* BlackPixel */
-#endif /* HAVE_X11 */
-  
   if (FRAME_X_WINDOW (f) == 0)
     return 1;
 
-#ifdef HAVE_X11
   if (icon_name)
     f->display.x->icon_label = icon_name;
   else
@@ -4730,42 +4277,6 @@ x_text_icon (f, icon_name)
   
   f->display.x->icon_bitmap_flag = 0;
   x_wm_set_icon_pixmap (f, 0);
-#else /* ! defined (HAVE_X11) */
-  if (icon_font_info == 0)
-    icon_font_info
-      = XGetFont (XGetDefault (XDISPLAY
-                              (char *) XSTRING (Vinvocation_name)->data,
-                              "BodyFont"));
-
-  if (f->display.x->icon_desc)
-    {
-      XClearIconWindow (XDISPLAY FRAME_X_WINDOW (f));
-      XDestroyWindow (XDISPLAY f->display.x->icon_desc);
-    }
-
-  if (icon_name)
-    f->display.x->icon_label = (unsigned char *) icon_name;
-  else
-    if (! f->display.x->icon_label)
-      f->display.x->icon_label = XSTRING (f->name)->data;
-
-  width = XStringWidth (f->display.x->icon_label, icon_font_info, 0, 0);
-  icon_window = XCreateWindow (f->display.x->parent_desc,
-                              f->display.x->left_pos,
-                              f->display.x->top_pos,
-                              width + 10, icon_font_info->height + 10,
-                              2, BlackPixmap, WhitePixmap);
-
-  if (icon_window == 0)
-    return 1;
-
-  XSetIconWindow (FRAME_X_WINDOW (f), icon_window);
-  XSelectInput (icon_window, ExposeWindow | ExposeRegion | UnmapWindow | ButtonPressed);
-
-  f->display.x->icon_desc = icon_window;
-  f->display.x->icon_bitmap_flag = 0;
-  f->display.x->icon_label = 0;
-#endif /* ! defined (HAVE_X11) */
 
   return 0;
 }
@@ -4932,12 +4443,11 @@ x_trace_wire ()
    to the font named NEWNAME.  This is safe to use
    even before F has an actual x-window.  */
 
-#ifdef HAVE_X11
-
 struct font_info
 {
   XFontStruct *font;
   char *name;
+  char *full_name;
 };
 
 /* A table of all the fonts we have already loaded.  */
@@ -4951,6 +4461,11 @@ static int x_font_table_size;
    0 <= n_fonts <= x_font_table_size.  */
 static int n_fonts;
 
+/* Give frame F the font named FONTNAME as its default font, and
+   return the full name of that font.  FONTNAME may be a wildcard
+   pattern; in that case, we choose some font that fits the pattern.
+   The return value shows which font we chose.  */
+
 Lisp_Object
 x_new_font (f, fontname)
      struct frame *f;
@@ -4983,10 +4498,11 @@ x_new_font (f, fontname)
 
       for (i = 0; i < n_fonts; i++)
        for (j = 0; j < n_matching_fonts; j++)
-         if (!strcmp (x_font_table[i].name, font_names[j]))
+         if (!strcmp (x_font_table[i].name, font_names[j])
+             || !strcmp (x_font_table[i].full_name, font_names[j]))
            {
              already_loaded = i;
-             fontname = font_names[j];
+             fontname = x_font_table[i].full_name;
              goto found_font;
            }
     }
@@ -4995,11 +4511,11 @@ x_new_font (f, fontname)
   /* If we have, just return it from the table.  */
   if (already_loaded >= 0)
     f->display.x->font = x_font_table[already_loaded].font;
-  
   /* Otherwise, load the font and add it to the table.  */
   else
     {
       int i;
+      char *full_name;
       XFontStruct *font;
 
       /* Try to find a character-cell font in the list.  */
@@ -5043,11 +4559,59 @@ x_new_font (f, fontname)
                                              * sizeof (x_font_table[0])));
        }
 
+      /* Try to get the full name of FONT.  Put it in full_name.  */
+      full_name = 0;
+      for (i = 0; i < font->n_properties; i++)
+       {
+         char *atom
+           = XGetAtomName (x_current_display, font->properties[i].name);
+         if (!strcmp (atom, "FONT"))
+           {
+             char *name = XGetAtomName (x_current_display,
+                                        (Atom) (font->properties[i].card32));
+             char *p = name;
+             int dashes = 0;
+
+             /* Count the number of dashes in the "full name".
+                If it is too few, this isn't really the font's full name,
+                so don't use it.
+                In X11R4, the fonts did not come with their canonical names
+                stored in them.  */
+             while (*p)
+               {
+                 if (*p == '-')
+                   dashes++;
+                 p++;
+               }
+
+             if (dashes >= 13)
+               full_name = name;
+           }
+
+         XFree (atom);
+       }
+
       x_font_table[n_fonts].name = (char *) xmalloc (strlen (fontname) + 1);
       bcopy (fontname, x_font_table[n_fonts].name, strlen (fontname) + 1);
+      if (full_name != 0)
+       x_font_table[n_fonts].full_name = full_name;
+      else
+       x_font_table[n_fonts].full_name = x_font_table[n_fonts].name;
       f->display.x->font = x_font_table[n_fonts++].font = font;
+
+      if (full_name)
+       fontname = full_name;
     }
 
+  /* Compute the scroll bar width in character columns.  */
+  if (f->scroll_bar_pixel_width > 0)
+    {
+      int wid = FONT_WIDTH (f->display.x->font);
+      f->scroll_bar_cols = (f->scroll_bar_pixel_width + wid-1) / wid;
+    }
+  else
+    f->scroll_bar_cols = 2;
+
   /* Now make the frame display the given font.  */
   if (FRAME_X_WINDOW (f) != 0)
     {
@@ -5078,36 +4642,13 @@ x_new_font (f, fontname)
     return lispy_name;
   }
 }
-#else /* ! defined (HAVE_X11) */
-x_new_font (f, newname)
-     struct frame *f;
-     register char *newname;
-{
-  FONT_TYPE *temp;
-  int mask;
-
-  temp = XGetFont (newname);
-  if (temp == (FONT_TYPE *) 0)
-    return 1;
-
-  if (f->display.x->font)
-    XLoseFont (f->display.x->font);
-
-  f->display.x->font = temp;
-
-  if (FRAME_X_WINDOW (f) != 0)
-    x_set_window_size (f, 0, f->width, f->height);
-
-  return 0;
-}
-#endif /* ! defined (HAVE_X11) */
 \f
 x_calc_absolute_position (f)
      struct frame *f;
 {
-#ifdef HAVE_X11
   Window win, child;
   int win_x = 0, win_y = 0;
+  int flags = f->display.x->size_hint_flags;
 
   /* Find the position of the outside upper-left corner of
      the inner window, with respect to the outer window.  */
@@ -5130,43 +4671,49 @@ x_calc_absolute_position (f)
 
   /* Treat negative positions as relative to the leftmost bottommost
      position that fits on the screen.  */
-  if (f->display.x->left_pos < 0)
+  if (flags & XNegative)
     f->display.x->left_pos = (x_screen_width 
                              - 2 * f->display.x->border_width - win_x
                              - PIXEL_WIDTH (f)
                              + f->display.x->left_pos);
 
-  if (f->display.x->top_pos < 0)
+  if (flags & YNegative)
     f->display.x->top_pos = (x_screen_height
                             - 2 * f->display.x->border_width - win_y
                             - PIXEL_HEIGHT (f)
                             + f->display.x->top_pos);
-
-#else /* ! defined (HAVE_X11) */
-  WINDOWINFO_TYPE parentinfo;
-
-  XGetWindowInfo (FRAME_X_WINDOW (f), &parentinfo);
-
-  if (f->display.x->left_pos < 0)
-    f->display.x->left_pos = parentinfo.width + (f->display.x->left_pos + 1)
-      - PIXEL_WIDTH (f) - 2 * f->display.x->internal_border_width;
-
-  if (f->display.x->top_pos < 0)
-    f->display.x->top_pos = parentinfo.height + (f->display.x->top_pos + 1)
-      - PIXEL_HEIGHT (f) - 2 * f->display.x->internal_border_width;
-#endif /* ! defined (HAVE_X11) */
+  /* The left_pos and top_pos
+     are now relative to the top and left screen edges,
+     so the flags should correspond.  */
+  f->display.x->size_hint_flags &= ~ (XNegative | YNegative);
 }
 
+/* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
+   to really change the position, and 0 when calling from
+   x_make_frame_visible (in that case, XOFF and YOFF are the current
+   position values).  */
+
 x_set_offset (f, xoff, yoff, change_gravity)
      struct frame *f;
      register int xoff, yoff;
      int change_gravity;
 {
-  f->display.x->top_pos = yoff;
-  f->display.x->left_pos = xoff;
+  if (change_gravity)
+    {
+      f->display.x->top_pos = yoff;
+      f->display.x->left_pos = xoff;
+      f->display.x->size_hint_flags &= ~ (XNegative | YNegative);
+      if (xoff < 0)
+       f->display.x->size_hint_flags |= XNegative;
+      if (yoff < 0)
+       f->display.x->size_hint_flags |= YNegative;
+      f->display.x->win_gravity = NorthWestGravity;
+    }
   x_calc_absolute_position (f);
 
   BLOCK_INPUT;
+  x_wm_set_size_hint (f, 0, 0);
+
 #ifdef USE_X_TOOLKIT
   XMoveWindow (XDISPLAY XtWindow (f->display.x->widget),
               f->display.x->left_pos, f->display.x->top_pos);
@@ -5174,12 +4721,6 @@ x_set_offset (f, xoff, yoff, change_gravity)
   XMoveWindow (XDISPLAY FRAME_X_WINDOW (f),
               f->display.x->left_pos, f->display.x->top_pos);
 #endif /* not USE_X_TOOLKIT */
-#ifdef HAVE_X11
-  if (change_gravity)
-    f->display.x->win_gravity = NorthWestGravity;
-
-  x_wm_set_size_hint (f, 0, 1);
-#endif /* ! defined (HAVE_X11) */
   UNBLOCK_INPUT;
 }
 
@@ -5198,7 +4739,17 @@ x_set_window_size (f, change_gravity, cols, rows)
 
 #ifdef USE_X_TOOLKIT
   BLOCK_INPUT;
-  EmacsFrameSetCharSize (f->display.x->edit_widget, cols, rows);
+  {
+    /* The x and y position of the widget is clobbered by the
+       call to XtSetValues within EmacsFrameSetCharSize.
+       This is a real kludge, but I don't understand Xt so I can't
+       figure out a correct fix.  Can anyone else tell me? -- rms.  */
+    int xpos = f->display.x->widget->core.x;
+    int ypos = f->display.x->widget->core.y;
+    EmacsFrameSetCharSize (f->display.x->edit_widget, cols, rows);
+    f->display.x->widget->core.x = xpos;
+    f->display.x->widget->core.y = ypos;
+  }
   UNBLOCK_INPUT;
 
 #else /* not USE_X_TOOLKIT */
@@ -5207,15 +4758,17 @@ x_set_window_size (f, change_gravity, cols, rows)
 
   check_frame_size (f, &rows, &cols);
   f->display.x->vertical_scroll_bar_extra
-    = (FRAME_HAS_VERTICAL_SCROLL_BARS (f)
-       ? VERTICAL_SCROLL_BAR_PIXEL_WIDTH (f)
-       : 0);
+    = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f)
+       ? 0
+       : FRAME_SCROLL_BAR_PIXEL_WIDTH (f) > 0
+       ? FRAME_SCROLL_BAR_PIXEL_WIDTH (f)
+       : (FRAME_SCROLL_BAR_COLS (f) * FONT_WIDTH (f->display.x->font)));
   pixelwidth = CHAR_TO_PIXEL_WIDTH (f, cols);
   pixelheight = CHAR_TO_PIXEL_HEIGHT (f, rows);
 
-#ifdef HAVE_X11
-  x_wm_set_size_hint (f, 0, change_gravity);
-#endif /* ! defined (HAVE_X11) */
+  f->display.x->win_gravity = NorthWestGravity;
+  x_wm_set_size_hint (f, 0, 0);
+
   XSync (x_current_display, False);
   XChangeWindowSize (FRAME_X_WINDOW (f), pixelwidth, pixelheight);
 
@@ -5233,6 +4786,14 @@ x_set_window_size (f, change_gravity, cols, rows)
   PIXEL_WIDTH (f) = pixelwidth;
   PIXEL_HEIGHT (f) = pixelheight;
 
+  /* If cursor was outside the new size, mark it as off.  */
+  if (f->phys_cursor_y >= rows
+      || f->phys_cursor_x >= cols)
+    {
+      f->phys_cursor_x = -1;
+      f->phys_cursor_y = -1;
+    }
+
   /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
      receive in the ConfigureNotify event; if we get what we asked
      for, then the event won't cause the screen to become garbaged, so
@@ -5243,31 +4804,16 @@ x_set_window_size (f, change_gravity, cols, rows)
   UNBLOCK_INPUT;
 #endif /* not USE_X_TOOLKIT */
 }
-
-#ifndef HAVE_X11
-x_set_resize_hint (f)
-     struct frame *f;
-{
-  XSetResizeHint (FRAME_X_WINDOW (f),
-                 2 * f->display.x->internal_border_width,
-                 2 * f->display.x->internal_border_width,
-                 FONT_WIDTH (f->display.x->font),
-                 f->display.x->line_height);
-}
-#endif /* HAVE_X11 */
 \f
 /* Mouse warping, focus shifting, raising and lowering.  */
 
+void
 x_set_mouse_position (f, x, y)
      struct frame *f;
      int x, y;
 {
   int pix_x, pix_y;
 
-#if 0 /* Let the user ask for this if he wants it.  */
-  x_raise_frame (f);
-#endif
-
   pix_x = CHAR_TO_PIXEL_COL (f, x) + FONT_WIDTH  (f->display.x->font) / 2;
   pix_y = CHAR_TO_PIXEL_ROW (f, y) + f->display.x->line_height / 2;
 
@@ -5283,7 +4829,19 @@ x_set_mouse_position (f, x, y)
   UNBLOCK_INPUT;
 }
 
-#ifdef HAVE_X11
+/* Move the mouse to position pixel PIX_X, PIX_Y relative to frame F.  */
+
+void
+x_set_mouse_pixel_position (f, pix_x, pix_y)
+     struct frame *f;
+     int pix_x, pix_y;
+{
+  BLOCK_INPUT;
+
+  XWarpMousePointer (FRAME_X_WINDOW (f), pix_x, pix_y);
+  UNBLOCK_INPUT;
+}
+
 x_focus_on_frame (f)
      struct frame *f;
 {
@@ -5310,8 +4868,6 @@ x_unfocus_frame (f)
 #endif /* ! 0 */
 }
 
-#endif /* ! defined (HAVE_X11) */
-
 /* Raise frame F.  */
 
 x_raise_frame (f)
@@ -5359,8 +4915,8 @@ XTframe_raise_lower (f, raise)
     x_lower_frame (f);
 }
 
-
-/* Change from withdrawn state to mapped state. */
+/* Change from withdrawn state to mapped state,
+   or deiconify. */
 
 x_make_frame_visible (f)
      struct frame *f;
@@ -5371,13 +4927,16 @@ x_make_frame_visible (f)
 
   if (! FRAME_VISIBLE_P (f))
     {
-#ifdef HAVE_X11
-      x_set_offset (f, f->display.x->left_pos, f->display.x->top_pos, 0);
+#ifndef USE_X_TOOLKIT
+      if (! FRAME_ICONIFIED_P (f))
+       x_set_offset (f, f->display.x->left_pos, f->display.x->top_pos, 0);
+#endif
 
       if (! EQ (Vx_no_window_manager, Qt))
        x_wm_set_window_state (f, NormalState);
 #ifdef USE_X_TOOLKIT
-      XtPopup (f->display.x->widget, XtGrabNone);
+      /* This was XtPopup, but that did nothing for an iconified frame.  */
+      XtMapWidget (f->display.x->widget);
 #else /* not USE_X_TOOLKIT */
       XMapWindow (XDISPLAY FRAME_X_WINDOW (f));
 #endif /* not USE_X_TOOLKIT */
@@ -5387,23 +4946,54 @@ x_make_frame_visible (f)
       if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
        XMapSubwindows (x_current_display, FRAME_X_WINDOW (f));
 #endif
-#else /* ! defined (HAVE_X11) */
-      XMapWindow (XDISPLAY FRAME_X_WINDOW (f));
-      if (f->display.x->icon_desc != 0)
-       XUnmapWindow (f->display.x->icon_desc);
-
-      /* Handled by the MapNotify event for X11 */
-      f->async_visible = 1;
-      f->async_iconified = 0;
-
-      /* NOTE: this may cause problems for the first frame. */
-      XTcursor_to (0, 0);
-#endif /* ! defined (HAVE_X11) */
     }
 
   XFlushQueue ();
 
-  UNBLOCK_INPUT;
+  /* Synchronize to ensure Emacs knows the frame is visible
+     before we do anything else.  We do this loop with input not blocked
+     so that incoming events are handled.  */
+  {
+    Lisp_Object frame;
+    int count = input_signal_count;
+
+    /* This must come after we set COUNT.  */
+    UNBLOCK_INPUT;
+
+    XSET (frame, Lisp_Frame, f);
+
+    while (1)
+      {
+       x_sync (frame);
+       /* Once we have handled input events,
+          we should have received the MapNotify if one is coming.
+          So if we have not got it yet, stop looping.
+          Some window managers make their own decisions
+          about visibility.  */
+       if (input_signal_count != count)
+         break;
+       /* Machines that do polling rather than SIGIO have been observed
+          to go into a busy-wait here.  So we'll fake an alarm signal
+          to let the handler know that there's something to be read.
+          We used to raise a real alarm, but it seems that the handler
+          isn't always enabled here.  This is probably a bug.  */
+       if (input_polling_used ())
+         {
+           /* It could be confusing if a real alarm arrives while processing
+              the fake one.  Turn it off and let the handler reset it.  */
+           alarm (0);
+           input_poll_signal ();
+         }
+       /* Once we have handled input events,
+          we should have received the MapNotify if one is coming.
+          So if we have not got it yet, stop looping.
+          Some window managers make their own decisions
+          about visibility.  */
+       if (input_signal_count != count)
+         break;
+      }
+    FRAME_SAMPLE_VISIBILITY (f);
+  }
 }
 
 /* Change from mapped state to withdrawn state. */
@@ -5412,6 +5002,14 @@ x_make_frame_invisible (f)
      struct frame *f;
 {
   int mask;
+  Window window;
+
+#ifdef USE_X_TOOLKIT
+  /* Use the frame's outermost window, not the one we normally draw on.  */
+  window = XtWindow (f->display.x->widget);
+#else /* not USE_X_TOOLKIT */
+  window = FRAME_X_WINDOW (f);
+#endif /* not USE_X_TOOLKIT */
 
   /* Don't keep the highlight on an invisible frame.  */
   if (x_highlight_frame == f)
@@ -5424,21 +5022,22 @@ x_make_frame_invisible (f)
 
   BLOCK_INPUT;
 
+  /* Before unmapping the window, update the WM_SIZE_HINTS property to claim
+     that the current position of the window is user-specified, rather than
+     program-specified, so that when the window is mapped again, it will be
+     placed at the same location, without forcing the user to position it
+     by hand again (they have already done that once for this window.)  */
+  x_wm_set_size_hint (f, 0, 1);
+
 #ifdef HAVE_X11R4
 
-#ifdef USE_X_TOOLKIT
-  XtPopdown (f->display.x->widget);
-#else /* not USE_X_TOOLKIT */
-  if (! XWithdrawWindow (x_current_display, FRAME_X_WINDOW (f),
+  if (! XWithdrawWindow (x_current_display, window,
                         DefaultScreen (x_current_display)))
     {
       UNBLOCK_INPUT_RESIGNAL;
-      error ("can't notify window manager of window withdrawal");
+      error ("Can't notify window manager of window withdrawal");
     }
-#endif /* not USE_X_TOOLKIT */
-
 #else /* ! defined (HAVE_X11R4) */
-#ifdef HAVE_X11
 
   /*  Tell the window manager what we're going to do.  */
   if (! EQ (Vx_no_window_manager, Qt))
@@ -5446,11 +5045,7 @@ x_make_frame_invisible (f)
       XEvent unmap;
 
       unmap.xunmap.type = UnmapNotify;
-#ifdef USE_X_TOOLKIT
-      unmap.xunmap.window = XtWindow (f->display.x->widget);
-#else /* not USE_X_TOOLKIT */
-      unmap.xunmap.window = FRAME_X_WINDOW (f);
-#endif /* not USE_X_TOOLKIT */
+      unmap.xunmap.window = window;
       unmap.xunmap.event = DefaultRootWindow (x_current_display);
       unmap.xunmap.from_configure = False;
       if (! XSendEvent (x_current_display,
@@ -5460,23 +5055,12 @@ x_make_frame_invisible (f)
                        &unmap))
        {
          UNBLOCK_INPUT_RESIGNAL;
-         error ("can't notify window manager of withdrawal");
+         error ("Can't notify window manager of withdrawal");
        }
     }
 
   /* Unmap the window ourselves.  Cheeky!  */
-#ifdef USE_X_TOOLKIT
-  XUnmapWindow (x_current_display, XtWindow (f->display.x->widget));
-#else /* not USE_X_TOOLKIT */
-  XUnmapWindow (x_current_display, FRAME_X_WINDOW (f));
-#endif /* not USE_X_TOOLKIT */
-#else /* ! defined (HAVE_X11) */
-
-  XUnmapWindow (FRAME_X_WINDOW (f));
-  if (f->display.x->icon_desc != 0)
-    XUnmapWindow (f->display.x->icon_desc);
-
-#endif /* ! defined (HAVE_X11) */
+  XUnmapWindow (x_current_display, window);
 #endif /* ! defined (HAVE_X11R4) */
 
   /* We can't distinguish this from iconification
@@ -5511,13 +5095,24 @@ x_iconify_frame (f)
 
 #ifdef USE_X_TOOLKIT
   BLOCK_INPUT;
+
+  if (! FRAME_VISIBLE_P (f))
+    {
+      if (! EQ (Vx_no_window_manager, Qt))
+       x_wm_set_window_state (f, IconicState);
+      /* This was XtPopup, but that did nothing for an iconified frame.  */
+      XtMapWidget (f->display.x->widget);
+      UNBLOCK_INPUT;
+      return;
+    }
+
   result = XIconifyWindow (x_current_display,
                           XtWindow (f->display.x->widget),
                           DefaultScreen (x_current_display));
   UNBLOCK_INPUT;
 
   if (!result)
-    error ("Can't notify window manager of iconification.");
+    error ("Can't notify window manager of iconification");
 
   f->async_iconified = 1;
 
@@ -5528,7 +5123,11 @@ x_iconify_frame (f)
 
   BLOCK_INPUT;
 
-#ifdef HAVE_X11
+  /* Make sure the X server knows where the window should be positioned,
+     in case the user deiconifies with the window manager.  */
+  if (! FRAME_VISIBLE_P (f) && !FRAME_ICONIFIED_P (f))
+    x_set_offset (f, f->display.x->left_pos, f->display.x->top_pos, 0);
+
   /* Since we don't know which revision of X we're running, we'll use both
      the X11R3 and X11R4 techniques.  I don't know if this is a good idea.  */
 
@@ -5550,7 +5149,7 @@ x_iconify_frame (f)
                      &message))
       {
        UNBLOCK_INPUT_RESIGNAL;
-       error ("Can't notify window manager of iconification.");
+       error ("Can't notify window manager of iconification");
       }
   }
 
@@ -5569,16 +5168,6 @@ x_iconify_frame (f)
     }
 
   f->async_iconified = 1;
-#else /* ! defined (HAVE_X11) */
-  XUnmapWindow (XDISPLAY FRAME_X_WINDOW (f));
-
-  f->async_visible = 0;                /* Handled in the UnMap event for X11. */
-  if (f->display.x->icon_desc != 0)
-    {
-      XMapWindow (XDISPLAY f->display.x->icon_desc);
-      refreshicon (f);
-    }
-#endif /* ! defined (HAVE_X11) */
 
   XFlushQueue ();
   UNBLOCK_INPUT;
@@ -5603,6 +5192,12 @@ x_destroy_window (f)
   free_frame_faces (f);
   XFlushQueue ();
 
+  FRAME_X_SCREEN (f)->reference_count--;
+#if 0
+  if (FRAME_X_SCREEN (f)->reference_count == 0)
+    free (FRAME_X_SCREEN (f));
+#endif
+
   xfree (f->display.x);
   f->display.x = 0;
   if (f == x_focus_frame)
@@ -5612,100 +5207,26 @@ x_destroy_window (f)
 
   if (f == mouse_face_mouse_frame)
     {
-      mouse_face_beg = -1;
-      mouse_face_end = -1;
+      mouse_face_beg_row = mouse_face_beg_col = -1;
+      mouse_face_end_row = mouse_face_end_col = -1;
       mouse_face_window = Qnil;
     }
 
   UNBLOCK_INPUT;
 }
 \f
-/* Manage event queues for X10.  */
-
-#ifndef HAVE_X11
-
-/* Manage event queues.
-
-   This code is only used by the X10 support.
-
-   We cannot leave events in the X queue and get them when we are ready
-   because X does not provide a subroutine to get only a certain kind
-   of event but not block if there are no queued events of that kind.
-
-   Therefore, we must examine events as they come in and copy events
-   of certain kinds into our private queues.
-
-   All ExposeRegion events are put in x_expose_queue.
-   All ButtonPress and ButtonRelease events are put in x_mouse_queue.  */
-
-
-/* Write the event *P_XREP into the event queue *QUEUE.
-   If the queue is full, do nothing, but return nonzero.  */
-
-int
-enqueue_event (p_xrep, queue)
-     register XEvent *p_xrep;
-     register struct event_queue *queue;
-{
-  int newindex = queue->windex + 1;
-  if (newindex == EVENT_BUFFER_SIZE)
-    newindex = 0;
-  if (newindex == queue->rindex)
-    return -1;
-  queue->xrep[queue->windex] = *p_xrep;
-  queue->windex = newindex;
-  return 0;
-}
-
-/* Fetch the next event from queue *QUEUE and store it in *P_XREP.
-   If *QUEUE is empty, do nothing and return 0.  */
-
-int
-dequeue_event (p_xrep, queue)
-     register XEvent *p_xrep;
-     register struct event_queue *queue;
-{
-  if (queue->windex == queue->rindex)
-    return 0;
-  *p_xrep = queue->xrep[queue->rindex++];
-  if (queue->rindex == EVENT_BUFFER_SIZE)
-    queue->rindex = 0;
-  return 1;
-}
-
-/* Return the number of events buffered in *QUEUE.  */
-
-int
-queue_event_count (queue)
-     register struct event_queue *queue;
-{
-  int tem = queue->windex - queue->rindex;
-  if (tem >= 0)
-    return tem;
-  return EVENT_BUFFER_SIZE + tem;
-}
-
-/* Return nonzero if mouse input is pending.  */
-
-int
-mouse_event_pending_p ()
-{
-  return queue_event_count (&x_mouse_queue);
-}
-#endif /* HAVE_X11 */
-\f
 /* Setting window manager hints.  */
 
-#ifdef HAVE_X11
-
-/* SPEC_X and SPEC_Y are the specified positions.
-   We look only at their sign, to decide the gravity.
-   If CHANGE_GRAVITY is 0, we may set PWinGravity.  */
+/* Set the normal size hints for the window manager, for frame F.
+   FLAGS is the flags word to use--or 0 meaning preserve the flags
+   that the window now has.
+   If USER_POSITION is nonzero, we set the USPosition
+   flag (this is useful when FLAGS is 0).  */
 
-x_wm_set_size_hint (f, prompting, change_gravity)
+x_wm_set_size_hint (f, flags, user_position)
      struct frame *f;
-     long prompting;
-     int change_gravity;
+     long flags;
+     int user_position;
 {
   XSizeHints size_hints;
 
@@ -5718,12 +5239,14 @@ x_wm_set_size_hint (f, prompting, change_gravity)
   Window window = FRAME_X_WINDOW (f);
 #endif /* not USE_X_TOOLKIT */
 
+  /* Setting PMaxSize caused various problems.  */
   size_hints.flags = PResizeInc | PMinSize /* | PMaxSize */;
 
   flexlines = f->height;
 
   size_hints.x = f->display.x->left_pos;
   size_hints.y = f->display.x->top_pos;
+
 #ifdef USE_X_TOOLKIT
   XtSetArg (al[ac], XtNwidth, &widget_width); ac++;
   XtSetArg (al[ac], XtNheight, &widget_height); ac++;
@@ -5734,8 +5257,11 @@ x_wm_set_size_hint (f, prompting, change_gravity)
   size_hints.height = PIXEL_HEIGHT (f);
   size_hints.width = PIXEL_WIDTH (f);
 #endif /* not USE_X_TOOLKIT */
+
   size_hints.width_inc = FONT_WIDTH (f->display.x->font);
   size_hints.height_inc = f->display.x->line_height;
+  size_hints.max_width = x_screen_width - CHAR_TO_PIXEL_WIDTH (f, 0);
+  size_hints.max_height = x_screen_height - CHAR_TO_PIXEL_HEIGHT (f, 0);
 
   {
     int base_width, base_height;
@@ -5768,13 +5294,22 @@ x_wm_set_size_hint (f, prompting, change_gravity)
 #endif
   }
 
-  if (prompting)
-    size_hints.flags |= prompting;
+  if (flags)
+    size_hints.flags |= flags;
   else
     {
       XSizeHints hints;                /* Sometimes I hate X Windows... */
+      long supplied_return;
+      int value;
+
+#ifdef HAVE_X11R4
+      value = XGetWMNormalHints (x_current_display, window, &hints,
+                                &supplied_return);
+#else
+      value = XGetNormalHints (x_current_display, window, &hints);
+#endif
       
-      if (XGetNormalHints (x_current_display, window, &hints) == 0)
+      if (value == 0)
        hints.flags = 0;
       if (hints.flags & PSize)
        size_hints.flags |= PSize;
@@ -5786,13 +5321,14 @@ x_wm_set_size_hint (f, prompting, change_gravity)
        size_hints.flags |= USSize;
     }
 
+#ifdef PWinGravity
   size_hints.win_gravity = f->display.x->win_gravity;
+  size_hints.flags |= PWinGravity;
 
-#if defined (PWinGravity)
-  if (change_gravity)
+  if (user_position)
     {
-      if (! (size_hints.flags & USPosition))
-       size_hints.flags |= PWinGravity;
+      size_hints.flags &= ~ PPosition;
+      size_hints.flags |= USPosition;
     }
 #endif /* PWinGravity */
 
@@ -5809,22 +5345,29 @@ x_wm_set_window_state (f, state)
      int state;
 {
 #ifdef USE_X_TOOLKIT
-  Window window = XtWindow (f->display.x->widget);
+  Arg al[1];
+
+  XtSetArg (al[0], XtNinitialState, state);
+  XtSetValues (f->display.x->widget, al, 1);
 #else /* not USE_X_TOOLKIT */
   Window window = FRAME_X_WINDOW (f);
-#endif /* not USE_X_TOOLKIT */
 
   f->display.x->wm_hints.flags |= StateHint;
   f->display.x->wm_hints.initial_state = state;
 
   XSetWMHints (x_current_display, window, &f->display.x->wm_hints);
+#endif /* not USE_X_TOOLKIT */
 }
 
 x_wm_set_icon_pixmap (f, icon_pixmap)
      struct frame *f;
      Pixmap icon_pixmap;
 {
+#ifdef USE_X_TOOLKIT
+  Window window = XtWindow (f->display.x->widget);
+#else
   Window window = FRAME_X_WINDOW (f);
+#endif
 
   if (icon_pixmap)
     {
@@ -5841,7 +5384,11 @@ x_wm_set_icon_position (f, icon_x, icon_y)
      struct frame *f;
      int icon_x, icon_y;
 {
+#ifdef USE_X_TOOLKIT
+  Window window = XtWindow (f->display.x->widget);
+#else
   Window window = FRAME_X_WINDOW (f);
+#endif
 
   f->display.x->wm_hints.flags |= IconPositionHint;
   f->display.x->wm_hints.icon_x = icon_x;
@@ -5873,8 +5420,10 @@ static XrmOptionDescRec emacs_options[] = {
 #endif /* USE_X_TOOLKIT */
 
 void
-x_term_init (display_name)
+x_term_init (display_name, xrm_option, resource_name)
      char *display_name;
+     char *xrm_option;
+     char *resource_name;
 {
   Lisp_Object frame;
   char *defaultvalue;
@@ -5886,21 +5435,29 @@ x_term_init (display_name)
 #endif /* ! defined (F_SETOWN) */
 #endif /* F_SETOWN_BUG */
   
+  x_noop_count = 0;
+
   x_focus_frame = x_highlight_frame = 0;
 
 #ifdef USE_X_TOOLKIT
-  argv = (char **) XtMalloc (5 * sizeof (char *));
-  argv [0] = "";
-  argv [1] = "-display";
-  argv [2] = display_name;
-  argv [3] = "-name";
-  argv [4] = "emacs";
+  argv = (char **) XtMalloc (7 * sizeof (char *));
+  argv[0] = "";
+  argv[1] = "-display";
+  argv[2] = display_name;
+  argv[3] = "-name";
+  /* Usually `emacs', but not always.  */
+  argv[4] = resource_name;
   argc = 5;
+  if (xrm_option)
+    {
+      argv[argc++] = "-xrm";
+      argv[argc++] = xrm_option;
+    }
   Xt_app_shell = XtAppInitialize (&Xt_app_con, "Emacs",
                                  emacs_options, XtNumber (emacs_options),
                                  &argc, argv,
                                  NULL, NULL, 0);
-  XtFree (argv);
+  XtFree ((char *)argv);
   x_current_display = XtDisplay (Xt_app_shell);
 
 #else /* not USE_X_TOOLKIT */
@@ -5911,16 +5468,15 @@ x_term_init (display_name)
 Check the DISPLAY environment variable or use \"-d\"\n",
           display_name);
 
-#ifdef HAVE_X11
   {
 #if 0
     XSetAfterFunction (x_current_display, x_trace_wire);
 #endif /* ! 0 */
-    hostname = get_system_name ();
     x_id_name = (char *) xmalloc (XSTRING (Vinvocation_name)->size
-                               + strlen (hostname)
+                               + XSTRING (Vsystem_name)->size
                                + 2);
-    sprintf (x_id_name, "%s@%s", XSTRING (Vinvocation_name)->data, hostname);
+    sprintf (x_id_name, "%s@%s",
+            XSTRING (Vinvocation_name)->data, XSTRING (Vsystem_name)->data);
   }
 
   /* Figure out which modifier bits mean what.  */
@@ -5940,8 +5496,6 @@ Check the DISPLAY environment variable or use \"-d\"\n",
     change_keyboard_wait_descriptor (ConnectionNumber (x_current_display));
   change_input_fd (ConnectionNumber (x_current_display));
 
-#endif /* ! defined (HAVE_X11) */
-  
 #ifndef F_SETOWN_BUG
 #ifdef F_SETOWN
   old_fcntl_owner = fcntl (ConnectionNumber (x_current_display), F_GETOWN, 0);
@@ -6017,5 +5571,4 @@ syms_of_xterm ()
   staticpro (&mouse_face_window);
   mouse_face_window = Qnil;
 }
-#endif /* ! defined (HAVE_X11) */
 #endif /* ! defined (HAVE_X_WINDOWS) */