(read_minibuf_unwind): Clear last_overlay_modified field.
[bpt/emacs.git] / src / xterm.c
index 28931a3..2be321e 100644 (file)
@@ -84,6 +84,10 @@ Boston, MA 02111-1307, USA.  */
 #include "keyboard.h"
 #include "intervals.h"
 
+#ifdef USE_X_TOOLKIT
+#include <X11/Shell.h>
+#endif
+
 #ifdef USE_X_TOOLKIT
 extern void free_frame_menubar ();
 extern FRAME_PTR x_menubar_window_to_frame ();
@@ -105,13 +109,16 @@ extern void _XEditResCheckMessages ();
 #endif
 #endif
 
-#ifdef HAVE_X11XTR6
+#ifdef HAVE_SETLOCALE
 /* So we can do setlocale.  */
 #include <locale.h>
 #endif
 
 #ifdef SOLARIS2
-#define X_CONNECTION_LOCK_FLAG XlibDisplayWriting
+/* memmove will be defined as a macro in Xfuncs.h unless
+   <string.h> is included beforehand.  The declaration for memmove in
+   <string.h> will cause a syntax error when Xfuncs.h later includes it.  */
+#include <string.h>
 #endif
 
 #ifndef min
@@ -137,6 +144,8 @@ Lisp_Object x_display_name_list;
    is the frame to apply to.  */
 extern struct frame *updating_frame;
 
+extern waiting_for_input;
+
 /* This is a frame waiting to be autoraised, within XTread_socket.  */
 struct frame *pending_autoraise_frame;
 
@@ -166,6 +175,13 @@ static int curs_y;
 
 /* Mouse movement.
 
+   Formerly, we used PointerMotionHintMask (in STANDARD_EVENT_MASK)
+   so that we would have to call XQueryPointer after each MotionNotify
+   event to ask for another such event.  However, this made mouse tracking
+   slow, and there was a bug that made it eventually stop.
+
+   Simply asking for MotionNotify all the time seems to work better.
+
    In order to avoid asking for motion events and then throwing most
    of them away or busy-polling the server for mouse positions, we ask
    the server for pointer motion hints.  This means that we get only
@@ -175,18 +191,14 @@ static int curs_y;
    get another MotionNotify event the next time the mouse moves.  This
    is at least as efficient as getting motion events when mouse
    tracking is on, and I suspect only negligibly worse when tracking
-   is off.
-
-   The silly O'Reilly & Associates Nutshell guides barely document
-   pointer motion hints at all (I think you have to infer how they
-   work from an example), and the description of XQueryPointer doesn't
-   mention that calling it causes you to get another motion hint from
-   the server, which is very important.  */
+   is off.  */
 
 /* Where the mouse was last time we reported a mouse event.  */
 static FRAME_PTR last_mouse_frame;
 static XRectangle last_mouse_glyph;
 
+static Lisp_Object last_mouse_press_frame;
+
 /* The scroll bar in which the last X motion event occurred.
 
    If the last X motion event occurred in a scroll bar, we set this
@@ -225,9 +237,6 @@ extern Lisp_Object Vcommand_line_args, Vsystem_name;
 
 extern Lisp_Object Vx_no_window_manager;
 
-/* Nonzero enables some debugging for the X interface code. */
-extern int _Xdebug;
-
 extern Lisp_Object Qface, Qmouse_face;
 
 extern int errno;
@@ -325,6 +334,9 @@ XTupdate_begin (f)
 
   BLOCK_INPUT;
 
+  curs_x = FRAME_CURSOR_X (f);
+  curs_y = FRAME_CURSOR_Y (f);
+
   if (f == FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_frame)
     {
       /* Don't do highlighting for mouse motion during the update.  */
@@ -377,10 +389,9 @@ XTupdate_end (f)
   BLOCK_INPUT;
 
   do_line_dance ();
-  x_display_cursor (f, 1);
+  x_display_cursor (f, 1, curs_x, curs_y);
 
-  if (f == FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_frame)
-    FRAME_X_DISPLAY_INFO (f)->mouse_face_defer = 0;
+  FRAME_X_DISPLAY_INFO (f)->mouse_face_defer = 0;
 #if 0
   /* This fails in the case of having updated only the echo area
      if we have switched buffers.  In that case, FRAME_CURRENT_GLYPHS
@@ -473,7 +484,7 @@ XTcursor_to (row, col)
   if (updating_frame == 0)
     {
       BLOCK_INPUT;
-      x_display_cursor (selected_frame, 1);
+      x_display_cursor (selected_frame, 1, curs_x, curs_y);
       XFlush (FRAME_X_DISPLAY (selected_frame));
       UNBLOCK_INPUT;
     }
@@ -794,11 +805,7 @@ XTwrite_glyphs (start, len)
     f->phys_cursor_x = -1;
 
   if (updating_frame == 0)
-    {
-      f->cursor_x += len;
-      x_display_cursor (f, 1);
-      f->cursor_x -= len;
-    }
+    x_display_cursor (f, 1, FRAME_CURSOR_X (f) + len, FRAME_CURSOR_Y (f));
   else
     curs_x += len;
 
@@ -1296,7 +1303,7 @@ do_line_dance ()
   ht = f->height;
   intborder = f->output_data.x->internal_border_width;
 
-  x_display_cursor (updating_frame, 0);
+  x_update_cursor (updating_frame, 0);
 
   for (i = 0; i < ht; ++i)
     if (line_dance[i] != -1 && (distance = line_dance[i]-i) > 0)
@@ -1423,7 +1430,7 @@ dumprectangle (f, left, top, cols, rows)
   /* Turn the cursor on if we turned it off.  */
 
   if (cursor_cleared)
-    x_display_cursor (f, 1);
+    x_update_cursor (f, 1);
 }
 \f
 static void
@@ -1840,17 +1847,6 @@ note_mouse_movement (frame, event)
       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?  */
@@ -1863,30 +1859,6 @@ note_mouse_movement (frame, event)
       last_mouse_scroll_bar = Qnil;
 
       note_mouse_highlight (frame, event->x, event->y);
-
-      /* 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);
-      }
-    }
-  else
-    {
-      /* It's on the same glyph.  Call XQueryPointer so we'll get an
-        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, FRAME_X_WINDOW (frame),
-                    &dummy_window, &dummy_window,
-                    &dummy, &dummy, &dummy, &dummy,
-                    (unsigned int *) &dummy);
     }
 }
 
@@ -1941,7 +1913,8 @@ note_mouse_highlight (f, x, y)
   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)))
+      && w->last_modified == BUF_MODIFF (XBUFFER (w->buffer))
+      && w->last_overlay_modified == BUF_OVERLAY_MODIFF (XBUFFER (w->buffer)))
     {
       int *ptr = FRAME_CURRENT_GLYPHS (f)->charstarts[row];
       int i, pos;
@@ -2024,11 +1997,11 @@ note_mouse_highlight (f, x, y)
              before = Foverlay_start (overlay);
              after = Foverlay_end (overlay);
              /* Record this as the current active region.  */
-             fast_find_position (window, before,
+             fast_find_position (window, XFASTINT (before),
                                  &FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_col,
                                  &FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_row);
              FRAME_X_DISPLAY_INFO (f)->mouse_face_past_end
-               = !fast_find_position (window, after,
+               = !fast_find_position (window, XFASTINT (after),
                                       &FRAME_X_DISPLAY_INFO (f)->mouse_face_end_col,
                                       &FRAME_X_DISPLAY_INFO (f)->mouse_face_end_row);
              FRAME_X_DISPLAY_INFO (f)->mouse_face_window = window;
@@ -2058,11 +2031,11 @@ note_mouse_highlight (f, x, y)
                = Fnext_single_property_change (position, Qmouse_face,
                                                w->buffer, end);
              /* Record this as the current active region.  */
-             fast_find_position (window, before,
+             fast_find_position (window, XFASTINT (before),
                                  &FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_col,
                                  &FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_row);
              FRAME_X_DISPLAY_INFO (f)->mouse_face_past_end
-               = !fast_find_position (window, after,
+               = !fast_find_position (window, XFASTINT (after),
                                       &FRAME_X_DISPLAY_INFO (f)->mouse_face_end_col,
                                       &FRAME_X_DISPLAY_INFO (f)->mouse_face_end_row);
              FRAME_X_DISPLAY_INFO (f)->mouse_face_window = window;
@@ -2149,7 +2122,7 @@ fast_find_position (window, pos, columnp, rowp)
   if (maybe_next_line)
     {
       row++;
-      i = 0;
+      lastcol = left;
     }
 
   *rowp = row + top;
@@ -2170,14 +2143,6 @@ show_mouse_face (dpyinfo, hl)
   FRAME_PTR f = XFRAME (WINDOW_FRAME (w));
   int i;
   int cursor_off = 0;
-  int old_curs_x = curs_x;
-  int old_curs_y = curs_y;
-
-  /* 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 = FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_row;
        i <= FRAME_X_DISPLAY_INFO (f)->mouse_face_end_row; i++)
@@ -2196,7 +2161,7 @@ show_mouse_face (dpyinfo, hl)
          && curs_x >= column - 1
          && curs_x <= endcolumn)
        {
-         x_display_cursor (f, 0);
+         x_update_cursor (f, 0);
          cursor_off = 1;
        }
 
@@ -2211,10 +2176,7 @@ show_mouse_face (dpyinfo, hl)
 
   /* If we turned the cursor off, turn it back on.  */
   if (cursor_off)
-    x_display_cursor (f, 1);
-
-  curs_x = old_curs_x;
-  curs_y = old_curs_y;
+    x_update_cursor (f, 1);
 
   /* Change the mouse cursor according to the value of HL.  */
   if (hl > 0)
@@ -2261,9 +2223,7 @@ static void x_scroll_bar_report_motion ();
    Don't store anything if we don't have a valid set of values to report.
 
    This clears the mouse_moved flag, so we can wait for the next mouse
-   movement.  This also calls XQueryPointer, which will cause the
-   server to give us another MotionNotify when the mouse moves
-   again. */
+   movement.  */
 
 static void
 XTmouse_position (fp, insist, bar_window, part, x, y, time)
@@ -3004,18 +2964,6 @@ x_scroll_bar_note_movement (bar, event)
          x_scroll_bar_set_handle (bar, new_start, new_end, 0);
        }
     }
-
-  /* Call XQueryPointer so we'll get an event the next time the mouse
-     moves and we can see *still* on the same position.  */
-  {
-    int dummy;
-    Window dummy_window;
-
-    XQueryPointer (event->xmotion.display, event->xmotion.window,
-                  &dummy_window, &dummy_window,
-                  &dummy, &dummy, &dummy, &dummy,
-                  (unsigned int *) &dummy);
-  }
 }
 
 /* Return information to the user about the current position of the mouse
@@ -3104,10 +3052,14 @@ x_scroll_bar_clear (f)
 {
   Lisp_Object bar;
 
-  for (bar = FRAME_SCROLL_BARS (f); VECTORP (bar);
-       bar = XSCROLL_BAR (bar)->next)
-    XClearArea (FRAME_X_DISPLAY (f), SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar)),
-               0, 0, 0, 0, True);
+  /* We can have scroll bars even if this is 0,
+     if we just turned off scroll bar mode.
+     But in that case we should not clear them.  */
+  if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
+    for (bar = FRAME_SCROLL_BARS (f); VECTORP (bar);
+        bar = XSCROLL_BAR (bar)->next)
+      XClearArea (FRAME_X_DISPLAY (f), SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar)),
+                 0, 0, 0, 0, True);
 }
 
 /* This processes Expose events from the menubar specific X event
@@ -3249,6 +3201,22 @@ struct x_display_info *XTread_socket_fake_io_error;
    This variable is used for cycling thru the displays.  */
 static struct x_display_info *next_noop_dpyinfo;
 
+#define SET_SAVED_MENU_EVENT(size) { \
+  if (f->output_data.x->saved_menu_event == 0) \
+    f->output_data.x->saved_menu_event = (XEvent*)xmalloc (sizeof (XEvent)); \
+  bcopy (&event, f->output_data.x->saved_menu_event, size); \
+  if (numchars >= 1) \
+    { \
+      bufp->kind = menu_bar_activate_event; \
+      XSETFRAME (bufp->frame_or_window, f); \
+      bufp++; \
+      count++; \
+      numchars--; \
+    } \
+  }
+#define SET_SAVED_BUTTON_EVENT SET_SAVED_MENU_EVENT (sizeof (XButtonEvent))
+#define SET_SAVED_KEY_EVENT SET_SAVED_MENU_EVENT (sizeof (XKeyEvent))
+
 /* Read events coming from the X server.
    This routine is called by the SIGIO handler.
    We return as soon as there are no more events to be read.
@@ -3264,8 +3232,8 @@ static struct x_display_info *next_noop_dpyinfo;
 int
 XTread_socket (sd, bufp, numchars, waitp, expected)
      register int sd;
-     register struct input_event *bufp;
-     register int numchars;
+     /* register */ struct input_event *bufp;
+     /* register */ int numchars;
      int waitp;
      int expected;
 {
@@ -3338,7 +3306,22 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
 
       while (XPending (dpyinfo->display) != 0)
        {
+#ifdef USE_X_TOOLKIT
+          /* needed to raise Motif submenus */
+         XtAppNextEvent (Xt_app_con, &event);
+#else
          XNextEvent (dpyinfo->display, &event);
+#endif
+#ifdef HAVE_X_I18N
+         {
+           struct frame *f1 = x_any_window_to_frame (dpyinfo,
+                                                     &event.xclient.window);
+           /* The necessity of the following line took me
+              a full work-day to decipher from the docs!!  */
+           if (f1 != 0 && FRAME_XIC (f1) && XFilterEvent (&event, None))
+             break;
+         }
+#endif
          event_found = 1;
 
          switch (event.type)
@@ -3387,7 +3370,7 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
                              XSetCommand (FRAME_X_DISPLAY (f),
                                           event.xclient.window,
                                           initial_argv, initial_argc);
-                           else
+                           else if (f)
                              XSetCommand (FRAME_X_DISPLAY (f),
                                           event.xclient.window,
                                           0, 0);
@@ -3592,7 +3575,7 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
                  /* We can't distinguish, from the event, whether the window
                     has become iconified or invisible.  So assume, if it
                     was previously visible, than now it is iconified.
-                    We depend on x_make_frame_invisible to mark it iconified.  */
+                    We depend on x_make_frame_invisible to mark it invisible.  */
                  if (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f))
                    f->async_iconified = 1;
 
@@ -3625,7 +3608,8 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
                      count++;
                      numchars--;
                    }
-                 else
+                 else if (! NILP(Vframe_list)
+                          && ! NILP (XCONS (Vframe_list)->cdr))
                    /* Force a redisplay sooner or later
                       to update the frame titles
                       in case this is the second frame.  */
@@ -3648,6 +3632,21 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
                  unsigned char copy_buffer[81];
                  int modifiers;
 
+#if 0 /* This was how we made f10 work in Motif.
+        The drawback is, you can't type at Emacs when the
+        the mouse is in the menu bar.  So it is better to
+        turn off f10 in Motif and let Emacs handle it.  */
+#ifdef USE_MOTIF
+                  if (lw_window_is_in_menubar (event.xkey.window,
+                                               f->output_data.x->menubar_widget
+                                               ))
+                    {
+                      SET_SAVED_KEY_EVENT;
+                      break;
+                    }
+#endif /* USE_MOTIF */
+#endif /* 0 */
+
                  event.xkey.state
                    |= x_emacs_to_x_modifiers (FRAME_X_DISPLAY_INFO (f),
                                               extra_keyboard_modifiers);
@@ -3666,10 +3665,6 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
 #ifdef HAVE_X_I18N
                  if (FRAME_XIC (f))
                    {
-                     /* The necessity of the following line took me
-                        a full work-day to decipher from the docs!!  */
-                     if (XFilterEvent (&event, None))
-                       break;
                      nbytes = XmbLookupString (FRAME_XIC (f),
                                                &event.xkey, copy_buffer,
                                                80, &keysym,
@@ -4052,20 +4047,30 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
                    && event.xbutton.y < f->output_data.x->menubar_height
                    && event.xbutton.same_screen)
                  {
-                   if (f->output_data.x->saved_button_event == 0)
-                     f->output_data.x->saved_button_event
-                       = (XButtonEvent *) xmalloc (sizeof (XButtonEvent)); 
-                   bcopy (&event, f->output_data.x->saved_button_event,
-                          sizeof (XButtonEvent));
-                   if (numchars >= 1)
+                   SET_SAVED_BUTTON_EVENT;
+                   XSETFRAME (last_mouse_press_frame, f);
+                 }
+               else if (event.type == ButtonPress)
+                 {
+                   last_mouse_press_frame = Qnil;
+                   goto OTHER;
+                 }
+#ifdef USE_MOTIF /* This should do not harm for Lucid,
+                   but I am trying to be cautious.  */
+               else if (event.type == ButtonRelease)
+                 {
+                   if (!NILP (last_mouse_press_frame))
                      {
-                       bufp->kind = menu_bar_activate_event;
-                       XSETFRAME (bufp->frame_or_window, f);
-                       bufp++;
-                       count++;
-                       numchars--;
+                       f = XFRAME (last_mouse_press_frame);
+                       if (f->output_data.x)
+                         {
+                           SET_SAVED_BUTTON_EVENT;
+                         }
                      }
+                   else 
+                     goto OTHER;
                  }
+#endif /* USE_MOTIF */
                else
                  goto OTHER;
 #endif /* USE_X_TOOLKIT */
@@ -4173,7 +4178,7 @@ clear_cursor (f)
       || f->phys_cursor_x < 0)
     return;
 
-  x_display_cursor (f, 0);
+  x_update_cursor (f, 0);
   f->phys_cursor_x = -1;
 }
 
@@ -4356,29 +4361,19 @@ x_display_box_cursor (f, on, x, y)
 }
 
 /* Display the cursor on frame F, or clear it, according to ON.
-   Use the position specified by curs_x and curs_y
-   if we are doing an update of frame F now.
-   Otherwise use the position in the FRAME_CURSOR_X and FRAME_CURSOR_Y fields
-   of F.  */
+   Also set the frame's cursor position to X and Y.  */
 
-x_display_cursor (f, on)
+x_display_cursor (f, on, x, y)
      struct frame *f;
      int on;
+     int x, y;
 {
   BLOCK_INPUT;
 
-  /* If we're not updating, then don't change the physical cursor
-     position.  Just change (if appropriate) the style of display.  */
-  if (f != updating_frame)
-    {
-      curs_x = FRAME_CURSOR_X (f);
-      curs_y = FRAME_CURSOR_Y (f);
-    }
-
   if (FRAME_DESIRED_CURSOR (f) == filled_box_cursor)
-    x_display_box_cursor (f, on, curs_x, curs_y);
+    x_display_box_cursor (f, on, x, y);
   else if (FRAME_DESIRED_CURSOR (f) == bar_cursor)
-    x_display_bar_cursor (f, on, curs_x, curs_y);
+    x_display_bar_cursor (f, on, x, y);
   else
     /* Those are the only two we have implemented!  */
     abort ();
@@ -4515,11 +4510,12 @@ x_connection_closed (display, error_message)
   struct x_display_info *dpyinfo = x_display_info_for_display (display);
   Lisp_Object frame, tail;
 
-  if (_Xdebug)
-    abort ();
-
   /* Indicate that this display is dead.  */
 
+  #ifdef USE_X_TOOLKIT
+  XtCloseDisplay (display);
+  #endif
+
   dpyinfo->display = 0;
 
   /* First delete frames whose minibuffers are on frames
@@ -4554,7 +4550,7 @@ x_connection_closed (display, error_message)
 
   if (x_display_list == 0)
     {
-      fprintf (stderr, "%s", error_message);
+      fprintf (stderr, "%s\n", error_message);
       shut_down_emacs (0, 0, Qnil);
       exit (70);
     }
@@ -4566,6 +4562,7 @@ x_connection_closed (display, error_message)
   sigunblock (sigmask (SIGALRM));
   TOTALLY_UNBLOCK_INPUT;
 
+  clear_waiting_for_input ();
   error ("%s", error_message);
 }
 
@@ -4584,7 +4581,7 @@ x_error_quitter (display, error)
      original error handler.  */
 
   XGetErrorText (display, error->error_code, buf, sizeof (buf));
-  sprintf (buf1, "X protocol error: %s on protocol request %d\n",
+  sprintf (buf1, "X protocol error: %s on protocol request %d",
           buf, error->request_code);
   x_connection_closed (display, buf1);
 }
@@ -4605,55 +4602,19 @@ x_io_error_quitter (display)
 \f
 /* Handle SIGPIPE, which can happen when the connection to a server
    simply goes away.  SIGPIPE is handled by x_connection_signal.
-   It works by sending a no-op command to each X server connection.
-   When we try a connection that has closed, we get SIGPIPE again.
-   But this time, it is handled by x_connection_signal_1.
-   That function knows which connection we were testing,
-   so it closes that one.
-   
-   x_connection_closed never returns,
-   so if more than one connection was lost at once,
-   we only find one.  But XTread_socket keeps trying them all,
-   so it will notice the other closed one sooner or later.  */
+   Don't need to do anything, because the write which caused the 
+   SIGPIPE will fail, causing Xlib to invoke the X IO error handler,
+   which will do the appropriate cleanup for us. */
    
-
-static struct x_display_info *x_connection_signal_dpyinfo;
-
-static SIGTYPE x_connection_signal ();
-
-static SIGTYPE
-x_connection_signal_1 (signalnum)      /* If we don't have an argument, */
-     int signalnum;            /* some compilers complain in signal calls. */
-{
-  signal (SIGPIPE, x_connection_signal);
-  x_connection_closed (x_connection_signal_dpyinfo,
-                      "connection was lost");
-}
-
 static SIGTYPE
 x_connection_signal (signalnum)        /* If we don't have an argument, */
      int signalnum;            /* some compilers complain in signal calls. */
 {
-  x_connection_signal_dpyinfo = x_display_list;
-
-  sigunblock (SIGPIPE);
-
-  while (x_connection_signal_dpyinfo)
-    {
-      signal (SIGPIPE, x_connection_signal_1);
-
-      x_connection_close_if_hung (x_connection_signal_dpyinfo);
-
-      XNoOp (x_connection_signal_dpyinfo->display);
-
-      XSync (x_connection_signal_dpyinfo->display, False);
-
-      /* Each time we get here, cycle through the displays now open.  */
-      x_connection_signal_dpyinfo = x_connection_signal_dpyinfo->next;
-    }
-
-  /* We should have found some closed connection.  */
-  abort ();
+#ifdef USG
+  /* USG systems forget handlers when they are used;
+     must reestablish each time */
+  signal (signalnum, x_connection_signal);
+#endif /* USG */
 }
 \f
 /* A buffer for storing X error messages.  */
@@ -4864,9 +4825,7 @@ x_new_font (f, fontname)
       full_name = 0;
       for (i = 0; i < font->n_properties; i++)
        {
-         char *atom
-           = XGetAtomName (FRAME_X_DISPLAY (f), font->properties[i].name);
-         if (!strcmp (atom, "FONT"))
+         if (FRAME_X_DISPLAY_INFO (f)->Xatom_FONT == font->properties[i].name)
            {
              char *name = XGetAtomName (FRAME_X_DISPLAY (f),
                                         (Atom) (font->properties[i].card32));
@@ -4890,8 +4849,6 @@ x_new_font (f, fontname)
 
              break;
            }
-
-         XFree (atom);
        }
 
       n_fonts = FRAME_X_DISPLAY_INFO (f)->n_fonts;
@@ -5478,6 +5435,11 @@ x_iconify_frame (f)
        x_wm_set_window_state (f, IconicState);
       /* This was XtPopup, but that did nothing for an iconified frame.  */
       XtMapWidget (f->output_data.x->widget);
+      /* The server won't give us any event to indicate
+        that an invisible frame was changed to an icon,
+        so we have to record it here.  */
+      f->iconified = 1;
+      f->async_iconified = 1;
       UNBLOCK_INPUT;
       return;
     }
@@ -5559,6 +5521,18 @@ x_destroy_window (f)
     {
       if (f->output_data.x->icon_desc != 0)
        XDestroyWindow (FRAME_X_DISPLAY (f), f->output_data.x->icon_desc);
+#ifdef HAVE_X_I18N
+      if (FRAME_XIM (f))
+       {
+         XDestroyIC (FRAME_XIC (f));
+#if ! defined (SOLARIS2) || defined (HAVE_X11R6)
+         /* This line causes crashes on Solaris with Openwin,
+            due to an apparent bug in XCloseIM.
+            X11R6 seems not to have the bug.  */
+         XCloseIM (FRAME_XIM (f));
+#endif
+       }
+#endif
       XDestroyWindow (FRAME_X_DISPLAY (f), f->output_data.x->window_desc);
 #ifdef USE_X_TOOLKIT
       XtDestroyWidget (f->output_data.x->widget);
@@ -5766,6 +5740,8 @@ x_wm_set_icon_pixmap (f, pixmap_id)
      struct frame *f;
      int pixmap_id;
 {
+  Pixmap icon_pixmap;
+
 #ifdef USE_X_TOOLKIT
   Window window = XtWindow (f->output_data.x->widget);
 #else
@@ -5774,7 +5750,7 @@ x_wm_set_icon_pixmap (f, pixmap_id)
 
   if (pixmap_id > 0)
     {
-      Pixmap icon_pixmap = x_bitmap_pixmap (f, pixmap_id);
+      icon_pixmap = x_bitmap_pixmap (f, pixmap_id);
       f->output_data.x->wm_hints.icon_pixmap = icon_pixmap;
     }
   else
@@ -5793,8 +5769,20 @@ x_wm_set_icon_pixmap (f, pixmap_id)
 #endif
     }
 
+#ifdef USE_X_TOOLKIT /* same as in x_wm_set_window_state.  */
+
+  {
+    Arg al[1];
+    XtSetArg (al[0], XtNiconPixmap, icon_pixmap);
+    XtSetValues (f->output_data.x->widget, al, 1);
+  }
+
+#else /* not USE_X_TOOLKIT */
+  
   f->output_data.x->wm_hints.flags |= IconPixmapHint;
   XSetWMHints (FRAME_X_DISPLAY (f), window, &f->output_data.x->wm_hints);
+
+#endif /* not USE_X_TOOLKIT */
 }
 
 x_wm_set_icon_position (f, icon_x, icon_y)
@@ -5882,6 +5870,9 @@ x_term_init (display_name, xrm_option, resource_name)
 
 #ifdef HAVE_X_I18N
   setlocale (LC_ALL, "");
+  /* In case we just overrode what init_lread did, redo it.  */
+  setlocale (LC_NUMERIC, "C");
+  setlocale (LC_TIME, "C");
 #endif
 
 #ifdef USE_X_TOOLKIT
@@ -5911,6 +5902,7 @@ x_term_init (display_name, xrm_option, resource_name)
                         &argc, argv);
 
 #ifdef HAVE_X11XTR6
+    /* I think this is to compensate for XtSetLanguageProc.  */
     setlocale (LC_NUMERIC, "C");
     setlocale (LC_TIME, "C");
 #endif
@@ -6054,6 +6046,8 @@ x_term_init (display_name, xrm_option, resource_name)
     = XInternAtom (dpyinfo->display, "WM_MOVED", False);
   dpyinfo->Xatom_editres
     = XInternAtom (dpyinfo->display, "Editres", False);
+  dpyinfo->Xatom_FONT
+    = XInternAtom (dpyinfo->display, "FONT", False);
   dpyinfo->Xatom_CLIPBOARD
     = XInternAtom (dpyinfo->display, "CLIPBOARD", False);
   dpyinfo->Xatom_TIMESTAMP
@@ -6102,6 +6096,30 @@ x_term_init (display_name, xrm_option, resource_name)
     init_sigio (connection);
 #endif /* ! defined (SIGIO) */
 
+#ifdef USE_LUCID
+  /* Make sure that we have a valid font for dialog boxes
+     so that Xt does not crash.  */
+  {
+    Display *dpy = dpyinfo->display;
+    XrmValue d, fr, to;
+    Font font;
+    
+    d.addr = (XPointer)&dpy;
+    d.size = sizeof (Display *);
+    fr.addr = XtDefaultFont;
+    fr.size = sizeof (XtDefaultFont);
+    to.size = sizeof (Font *);
+    to.addr = (XPointer)&font;
+    x_catch_errors (dpy);
+    if (!XtCallConverter (dpy, XtCvtStringToFont, &d, 1, &fr, &to, NULL))
+      abort ();
+    if (x_had_errors_p (dpy) || !XQueryFont (dpy, font))
+      XrmPutLineResource (&xrdb, "Emacs.dialog.*.font: 9x15");
+    x_uncatch_errors (dpy);
+  }
+#endif
+
+
   UNBLOCK_INPUT;
 
   return dpyinfo;
@@ -6235,50 +6253,9 @@ syms_of_xterm ()
 
   staticpro (&Qvendor_specific_keysyms);
   Qvendor_specific_keysyms = intern ("vendor-specific-keysyms");
-}
-\f
-/* Avoid warnings or errors from including Xlibint.h.
-   We don't need these functions for the rest of this file.  */
-#undef bzero
-#undef bcopy
-#undef bcmp
-#undef min
-#undef max
-
-#ifdef X_CONNECTION_LOCK_FLAG
-#define free loserfree
-#define malloc losermalloc
-#define exit loserexit
-#define abort loserabort
-/* For XlibDisplayWriting */
-#include <X11/Xlibint.h>
-#endif
 
-/* Check whether display connection DPYINFO is hung
-   because its thread-interlock is locked.
-   If it is, close the connection.
-   Do nothing if this system does not have a thread interlock.  */
-
-x_connection_close_if_hung (dpyinfo)
-     struct x_display_info *dpyinfo;
-{      
-  /* This tests (1) whether X_CONNECTION_LOCK_FLAG is defined at all,
-     and (2) whether the name it is defined as is itself defined.
-     (It ought to have been defined by Xlibint.h.  */
-#if X_CONNECTION_LOCK_FLAG
-
-  if (dpyinfo->display->flags & X_CONNECTION_LOCK_FLAG)
-    {
-      /* If the thread-interlock is locked, assume this connection is dead.
-        This assumes that the library does not make other threads
-        that can be locking the display legitimately.  */
-
-      dpyinfo->display->flags &= ~X_CONNECTION_LOCK_FLAG;
-      x_connection_closed (dpyinfo->display, "connection was lost");
-    }
-#endif /* X_CONNECTION_LOCK_FLAG */
+  staticpro (&last_mouse_press_frame);
+  last_mouse_press_frame = Qnil;
 }
 
-/* Don't put any additional functions here!  */
-
 #endif /* not HAVE_X_WINDOWS */