]> code.delx.au - gnu-emacs/blobdiff - src/xterm.c
(XTread_socket, Xatom_wm_save_yourself clause):
[gnu-emacs] / src / xterm.c
index eb79e883d025ad426e67e5ed3363cefcb6714cf7..977e1b8020f8966df0a5faf39047b0fd403cc202 100644 (file)
@@ -1,5 +1,5 @@
 /* X Communication module for terminals which understand the X protocol.
 /* X Communication module for terminals which understand the X protocol.
-   Copyright (C) 1989, 1993, 1994, 1995 Free Software Foundation, Inc.
+   Copyright (C) 1989, 93, 94, 95, 1996 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
 
 This file is part of GNU Emacs.
 
@@ -15,7 +15,8 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with GNU Emacs; see the file COPYING.  If not, write to
 
 You should have received a copy of the GNU General Public License
 along with GNU Emacs; see the file COPYING.  If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
 
 /* Xt features made by Fred Pierresteguy.  */
 
 
 /* Xt features made by Fred Pierresteguy.  */
 
@@ -83,6 +84,10 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "keyboard.h"
 #include "intervals.h"
 
 #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 ();
 #ifdef USE_X_TOOLKIT
 extern void free_frame_menubar ();
 extern FRAME_PTR x_menubar_window_to_frame ();
@@ -104,13 +109,24 @@ extern void _XEditResCheckMessages ();
 #endif
 #endif
 
 #endif
 #endif
 
-#ifdef HAVE_X11XTR6
+#ifdef HAVE_SETLOCALE
 /* So we can do setlocale.  */
 #include <locale.h>
 #endif
 
 /* So we can do setlocale.  */
 #include <locale.h>
 #endif
 
+#ifdef SOLARIS2
+/* 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
 #define min(a,b) ((a)<(b) ? (a) : (b))
 #define min(a,b) ((a)<(b) ? (a) : (b))
+#endif
+#ifndef max
 #define max(a,b) ((a)>(b) ? (a) : (b))
 #define max(a,b) ((a)>(b) ? (a) : (b))
+#endif
 \f
 /* This is a chain of structures for all the X displays currently in use.  */
 struct x_display_info *x_display_list;
 \f
 /* This is a chain of structures for all the X displays currently in use.  */
 struct x_display_info *x_display_list;
@@ -128,6 +144,8 @@ Lisp_Object x_display_name_list;
    is the frame to apply to.  */
 extern struct frame *updating_frame;
 
    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;
 
 /* This is a frame waiting to be autoraised, within XTread_socket.  */
 struct frame *pending_autoraise_frame;
 
@@ -157,6 +175,13 @@ static int curs_y;
 
 /* Mouse movement.
 
 
 /* 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
    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
@@ -166,13 +191,7 @@ 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
    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;
 
 /* Where the mouse was last time we reported a mouse event.  */
 static FRAME_PTR last_mouse_frame;
@@ -216,9 +235,6 @@ extern Lisp_Object Vcommand_line_args, Vsystem_name;
 
 extern Lisp_Object Vx_no_window_manager;
 
 
 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;
 extern Lisp_Object Qface, Qmouse_face;
 
 extern int errno;
@@ -394,6 +410,7 @@ static
 XTframe_up_to_date (f)
      FRAME_PTR f;
 {
 XTframe_up_to_date (f)
      FRAME_PTR f;
 {
+  BLOCK_INPUT;
   if (FRAME_X_DISPLAY_INFO (f)->mouse_face_deferred_gc
       || f == FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_frame)
     {
   if (FRAME_X_DISPLAY_INFO (f)->mouse_face_deferred_gc
       || f == FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_frame)
     {
@@ -402,6 +419,7 @@ XTframe_up_to_date (f)
                            FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_y);
       FRAME_X_DISPLAY_INFO (f)->mouse_face_deferred_gc = 0;
     }
                            FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_y);
       FRAME_X_DISPLAY_INFO (f)->mouse_face_deferred_gc = 0;
     }
+  UNBLOCK_INPUT;
 }
 \f
 /* External interface to control of standout mode.
 }
 \f
 /* External interface to control of standout mode.
@@ -1562,8 +1580,8 @@ x_find_modifier_meanings (dpyinfo)
 #ifdef HAVE_X11R4
   XDisplayKeycodes (dpyinfo->display, &min_code, &max_code);
 #else
 #ifdef HAVE_X11R4
   XDisplayKeycodes (dpyinfo->display, &min_code, &max_code);
 #else
-  min_code = display->min_keycode;
-  max_code = display->max_keycode;
+  min_code = dpyinfo->display->min_keycode;
+  max_code = dpyinfo->display->max_keycode;
 #endif
 
   syms = XGetKeyboardMapping (dpyinfo->display,
 #endif
 
   syms = XGetKeyboardMapping (dpyinfo->display,
@@ -1829,17 +1847,6 @@ note_mouse_movement (frame, event)
       last_mouse_scroll_bar = Qnil;
 
       note_mouse_highlight (frame, -1, -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?  */
     }
 
   /* Has the mouse moved off the glyph it was on at the last sighting?  */
@@ -1852,30 +1859,6 @@ note_mouse_movement (frame, event)
       last_mouse_scroll_bar = Qnil;
 
       note_mouse_highlight (frame, event->x, event->y);
       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);
     }
 }
 
     }
 }
 
@@ -2182,8 +2165,8 @@ show_mouse_face (dpyinfo, hl)
       /* If the cursor's in the text we are about to rewrite,
         turn the cursor off.  */
       if (i == curs_y
       /* If the cursor's in the text we are about to rewrite,
         turn the cursor off.  */
       if (i == curs_y
-         && curs_x >= FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_col - 1
-         && curs_x <= FRAME_X_DISPLAY_INFO (f)->mouse_face_end_col)
+         && curs_x >= column - 1
+         && curs_x <= endcolumn)
        {
          x_display_cursor (f, 0);
          cursor_off = 1;
        {
          x_display_cursor (f, 0);
          cursor_off = 1;
@@ -2250,9 +2233,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
    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)
 
 static void
 XTmouse_position (fp, insist, bar_window, part, x, y, time)
@@ -2354,7 +2335,7 @@ XTmouse_position (fp, insist, bar_window, part, x, y, time)
                                       /* Child of win.  */
                                       &child);
 
                                       /* Child of win.  */
                                       &child);
 
-               if (child == None)
+               if (child == None || child == win)
                  break;
 
                win = child;
                  break;
 
                win = child;
@@ -2993,18 +2974,6 @@ x_scroll_bar_note_movement (bar, event)
          x_scroll_bar_set_handle (bar, new_start, new_end, 0);
        }
     }
          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
 }
 
 /* Return information to the user about the current position of the mouse
@@ -3093,10 +3062,14 @@ x_scroll_bar_clear (f)
 {
   Lisp_Object bar;
 
 {
   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
 }
 
 /* This processes Expose events from the menubar specific X event
@@ -3295,7 +3268,7 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
 #ifdef FIOSNBIO
       /* If available, Xlib uses FIOSNBIO to make the socket
         non-blocking, and then looks for EWOULDBLOCK.  If O_NDELAY is set,
 #ifdef FIOSNBIO
       /* If available, Xlib uses FIOSNBIO to make the socket
         non-blocking, and then looks for EWOULDBLOCK.  If O_NDELAY is set,
-        FIOSNBIO is ignored, and instead of signalling EWOULDBLOCK,
+        FIOSNBIO is ignored, and instead of signaling EWOULDBLOCK,
         a read returns 0, which Xlib interprets as equivalent to EPIPE. */
       fcntl (dpyinfo->connection, F_SETFL, 0);
 #endif /* ! defined (FIOSNBIO) */
         a read returns 0, which Xlib interprets as equivalent to EPIPE. */
       fcntl (dpyinfo->connection, F_SETFL, 0);
 #endif /* ! defined (FIOSNBIO) */
@@ -3327,7 +3300,12 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
 
       while (XPending (dpyinfo->display) != 0)
        {
 
       while (XPending (dpyinfo->display) != 0)
        {
+#ifdef USE_X_TOOLKIT
+          /* needed to raise Motif submenus */
+         XtAppNextEvent (Xt_app_con, &event);
+#else
          XNextEvent (dpyinfo->display, &event);
          XNextEvent (dpyinfo->display, &event);
+#endif
          event_found = 1;
 
          switch (event.type)
          event_found = 1;
 
          switch (event.type)
@@ -3376,7 +3354,7 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
                              XSetCommand (FRAME_X_DISPLAY (f),
                                           event.xclient.window,
                                           initial_argv, initial_argc);
                              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);
                              XSetCommand (FRAME_X_DISPLAY (f),
                                           event.xclient.window,
                                           0, 0);
@@ -3459,6 +3437,7 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
                SELECTION_EVENT_DISPLAY (bufp) = eventp->display;
                SELECTION_EVENT_SELECTION (bufp) = eventp->selection;
                SELECTION_EVENT_TIME (bufp) = eventp->time;
                SELECTION_EVENT_DISPLAY (bufp) = eventp->display;
                SELECTION_EVENT_SELECTION (bufp) = eventp->selection;
                SELECTION_EVENT_TIME (bufp) = eventp->time;
+               bufp->frame_or_window = Qnil;
                bufp++;
 
                count += 1;
                bufp++;
 
                count += 1;
@@ -3488,6 +3467,7 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
                  SELECTION_EVENT_TARGET (bufp) = eventp->target;
                  SELECTION_EVENT_PROPERTY (bufp) = eventp->property;
                  SELECTION_EVENT_TIME (bufp) = eventp->time;
                  SELECTION_EVENT_TARGET (bufp) = eventp->target;
                  SELECTION_EVENT_PROPERTY (bufp) = eventp->property;
                  SELECTION_EVENT_TIME (bufp) = eventp->time;
+                 bufp->frame_or_window = Qnil;
                  bufp++;
 
                  count += 1;
                  bufp++;
 
                  count += 1;
@@ -3579,7 +3559,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 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;
 
                  if (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f))
                    f->async_iconified = 1;
 
@@ -3589,10 +3569,7 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
                  count++;
                  numchars--;
                }
                  count++;
                  numchars--;
                }
-#ifdef USE_X_TOOLKIT
              goto OTHER;
              goto OTHER;
-#endif /* USE_X_TOOLKIT */
-             break;
 
            case MapNotify:
              /* We use x_top_window_to_frame because map events can come
 
            case MapNotify:
              /* We use x_top_window_to_frame because map events can come
@@ -3615,16 +3592,14 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
                      count++;
                      numchars--;
                    }
                      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.  */
                    record_asynch_buffer_change ();
                }
                    /* Force a redisplay sooner or later
                       to update the frame titles
                       in case this is the second frame.  */
                    record_asynch_buffer_change ();
                }
-#ifdef USE_X_TOOLKIT
              goto OTHER;
              goto OTHER;
-#endif /* USE_X_TOOLKIT */
-             break;
 
              /* Turn off processing if we become fully obscured. */
            case VisibilityNotify:
 
              /* Turn off processing if we become fully obscured. */
            case VisibilityNotify:
@@ -3788,7 +3763,7 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
                  else
                    abort ();
                }
                  else
                    abort ();
                }
-             break;
+             goto OTHER;
 
              /* Here's a possible interpretation of the whole
                 FocusIn-EnterNotify FocusOut-LeaveNotify mess.  If you get a
 
              /* Here's a possible interpretation of the whole
                 FocusIn-EnterNotify FocusOut-LeaveNotify mess.  If you get a
@@ -3816,10 +3791,7 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
                 so update things that depend on mouse position.  */
              if (f)
                note_mouse_movement (f, &event.xmotion);
                 so update things that depend on mouse position.  */
              if (f)
                note_mouse_movement (f, &event.xmotion);
-#ifdef USE_X_TOOLKIT
              goto OTHER;
              goto OTHER;
-#endif /* USE_X_TOOLKIT */
-             break;
 
            case FocusIn:
              f = x_any_window_to_frame (dpyinfo, event.xfocus.window);
 
            case FocusIn:
              f = x_any_window_to_frame (dpyinfo, event.xfocus.window);
@@ -3833,11 +3805,7 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
                XSetICFocus (FRAME_XIC (f));
 #endif
 
                XSetICFocus (FRAME_XIC (f));
 #endif
 
-#ifdef USE_X_TOOLKIT
              goto OTHER;
              goto OTHER;
-#endif /* USE_X_TOOLKIT */
-             break;
-
 
            case LeaveNotify:
              f = x_top_window_to_frame (dpyinfo, event.xcrossing.window);
 
            case LeaveNotify:
              f = x_top_window_to_frame (dpyinfo, event.xcrossing.window);
@@ -3858,10 +3826,7 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
                        x_new_focus_frame (dpyinfo, 0);
                    }
                }
                        x_new_focus_frame (dpyinfo, 0);
                    }
                }
-#ifdef USE_X_TOOLKIT
              goto OTHER;
              goto OTHER;
-#endif /* USE_X_TOOLKIT */
-             break;
 
            case FocusOut:
              f = x_any_window_to_frame (dpyinfo, event.xfocus.window);
 
            case FocusOut:
              f = x_any_window_to_frame (dpyinfo, event.xfocus.window);
@@ -3876,10 +3841,7 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
                XUnsetICFocus (FRAME_XIC (f));
 #endif
 
                XUnsetICFocus (FRAME_XIC (f));
 #endif
 
-#ifdef USE_X_TOOLKIT
              goto OTHER;
              goto OTHER;
-#endif /* USE_X_TOOLKIT */
-             break;
 
            case MotionNotify:
              {
 
            case MotionNotify:
              {
@@ -3903,10 +3865,7 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
                    clear_mouse_face (dpyinfo);
                  }
              }
                    clear_mouse_face (dpyinfo);
                  }
              }
-#ifdef USE_X_TOOLKIT
              goto OTHER;
              goto OTHER;
-#endif /* USE_X_TOOLKIT */
-             break;
 
            case ConfigureNotify:
              f = x_any_window_to_frame (dpyinfo, event.xconfigure.window);
 
            case ConfigureNotify:
              f = x_any_window_to_frame (dpyinfo, event.xconfigure.window);
@@ -3995,11 +3954,7 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
 /* #endif */
                  }
                }
 /* #endif */
                  }
                }
-#ifdef USE_X_TOOLKIT
              goto OTHER;
              goto OTHER;
-#else
-             break;
-#endif
 
            case ButtonPress:
            case ButtonRelease:
 
            case ButtonPress:
            case ButtonRelease:
@@ -4056,7 +4011,14 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
                   Instead, save it away
                   and we will pass it to Xt from kbd_buffer_get_event.
                   That way, we can run some Lisp code first.  */
                   Instead, save it away
                   and we will pass it to Xt from kbd_buffer_get_event.
                   That way, we can run some Lisp code first.  */
-               if (f && event.type == ButtonPress)
+               if (f && event.type == ButtonPress
+                   /* Verify the event is really within the menu bar
+                      and not just sent to it due to grabbing.  */
+                   && event.xbutton.x >= 0
+                   && event.xbutton.x < f->output_data.x->pixel_width
+                   && event.xbutton.y >= 0
+                   && 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
                  {
                    if (f->output_data.x->saved_button_event == 0)
                      f->output_data.x->saved_button_event
@@ -4094,14 +4056,11 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
                case MappingKeyboard:
                  XRefreshKeyboardMapping (&event.xmapping);
                }
                case MappingKeyboard:
                  XRefreshKeyboardMapping (&event.xmapping);
                }
-#ifdef USE_X_TOOLKIT
              goto OTHER;
              goto OTHER;
-#endif /* USE_X_TOOLKIT */
-             break;
 
            default:
 
            default:
-#ifdef USE_X_TOOLKIT
            OTHER:
            OTHER:
+#ifdef USE_X_TOOLKIT
              BLOCK_INPUT;
              XtDispatchEvent (&event);
              UNBLOCK_INPUT;
              BLOCK_INPUT;
              XtDispatchEvent (&event);
              UNBLOCK_INPUT;
@@ -4402,6 +4361,11 @@ x_update_cursor (f, on)
      struct frame *f;
      int on;
 {
      struct frame *f;
      int on;
 {
+  /* If we don't have any previous cursor position to use,
+     leave the cursor off.  */
+  if (f->phys_cursor_x < 0)
+    return;
+
   BLOCK_INPUT;
 
   if (FRAME_DESIRED_CURSOR (f) == filled_box_cursor)
   BLOCK_INPUT;
 
   if (FRAME_DESIRED_CURSOR (f) == filled_box_cursor)
@@ -4519,13 +4483,9 @@ x_connection_closed (display, error_message)
   struct x_display_info *dpyinfo = x_display_info_for_display (display);
   Lisp_Object frame, tail;
 
   struct x_display_info *dpyinfo = x_display_info_for_display (display);
   Lisp_Object frame, tail;
 
-  /* Whatever we were in the middle of, we are going to throw out of it,
-     so reassure various things that have error checks about being
-     called with input blocked.  */
-  TOTALLY_UNBLOCK_INPUT;
+  /* Indicate that this display is dead.  */
 
 
-  if (_Xdebug)
-    abort ();
+  dpyinfo->display = 0;
 
   /* First delete frames whose minibuffers are on frames
      that are on the dead display.  */
 
   /* First delete frames whose minibuffers are on frames
      that are on the dead display.  */
@@ -4554,11 +4514,12 @@ x_connection_closed (display, error_message)
        Fdelete_frame (frame, Qt);
       }
 
        Fdelete_frame (frame, Qt);
       }
 
-  x_delete_display (dpyinfo);
+  if (dpyinfo)
+    x_delete_display (dpyinfo);
 
   if (x_display_list == 0)
     {
 
   if (x_display_list == 0)
     {
-      fprintf (stderr, "%s", error_message);
+      fprintf (stderr, "%s\n", error_message);
       shut_down_emacs (0, 0, Qnil);
       exit (70);
     }
       shut_down_emacs (0, 0, Qnil);
       exit (70);
     }
@@ -4570,6 +4531,12 @@ x_connection_closed (display, error_message)
   sigunblock (sigmask (SIGALRM));
   TOTALLY_UNBLOCK_INPUT;
 
   sigunblock (sigmask (SIGALRM));
   TOTALLY_UNBLOCK_INPUT;
 
+  if (waiting_for_input)
+    {
+      message ("%s", error_message);
+      quit_throw_to_read_char ();
+    }
+
   error ("%s", error_message);
 }
 
   error ("%s", error_message);
 }
 
@@ -4588,7 +4555,7 @@ x_error_quitter (display, error)
      original error handler.  */
 
   XGetErrorText (display, error->error_code, buf, sizeof (buf));
      original error handler.  */
 
   XGetErrorText (display, error->error_code, buf, sizeof (buf));
-  sprintf (buf1, "X protocol error: %s on protocol request %d",
+  sprintf (buf1, "X protocol error: %s on protocol request %d\n",
           buf, error->request_code);
   x_connection_closed (display, buf1);
 }
           buf, error->request_code);
   x_connection_closed (display, buf1);
 }
@@ -4609,52 +4576,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.
 \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.
+   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. */
    
    
-   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.  */
-   
-
-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. */
 {
 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);
-
-      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.  */
 }
 \f
 /* A buffer for storing X error messages.  */
@@ -4818,6 +4752,7 @@ x_new_font (f, fontname)
       char *full_name;
       XFontStruct *font;
       int n_fonts;
       char *full_name;
       XFontStruct *font;
       int n_fonts;
+      Atom FONT_atom;
 
       /* Try to find a character-cell font in the list.  */
 #if 0
 
       /* Try to find a character-cell font in the list.  */
 #if 0
@@ -4863,11 +4798,10 @@ x_new_font (f, fontname)
 
       /* Try to get the full name of FONT.  Put it in full_name.  */
       full_name = 0;
 
       /* Try to get the full name of FONT.  Put it in full_name.  */
       full_name = 0;
+      FONT_atom = XInternAtom (FRAME_X_DISPLAY (f), "FONT", False);
       for (i = 0; i < font->n_properties; i++)
        {
       for (i = 0; i < font->n_properties; i++)
        {
-         char *atom
-           = XGetAtomName (FRAME_X_DISPLAY (f), font->properties[i].name);
-         if (!strcmp (atom, "FONT"))
+         if (FONT_atom == font->properties[i].name)
            {
              char *name = XGetAtomName (FRAME_X_DISPLAY (f),
                                         (Atom) (font->properties[i].card32));
            {
              char *name = XGetAtomName (FRAME_X_DISPLAY (f),
                                         (Atom) (font->properties[i].card32));
@@ -4891,8 +4825,6 @@ x_new_font (f, fontname)
 
              break;
            }
 
              break;
            }
-
-         XFree (atom);
        }
 
       n_fonts = FRAME_X_DISPLAY_INFO (f)->n_fonts;
        }
 
       n_fonts = FRAME_X_DISPLAY_INFO (f)->n_fonts;
@@ -4949,6 +4881,9 @@ x_new_font (f, fontname)
   }
 }
 \f
   }
 }
 \f
+/* Calculate the absolute position in frame F
+   from its current recorded position values and gravity.  */
+
 x_calc_absolute_position (f)
      struct frame *f;
 {
 x_calc_absolute_position (f)
      struct frame *f;
 {
@@ -4986,17 +4921,18 @@ x_calc_absolute_position (f)
      position that fits on the screen.  */
   if (flags & XNegative)
     f->output_data.x->left_pos = (FRAME_X_DISPLAY_INFO (f)->width
      position that fits on the screen.  */
   if (flags & XNegative)
     f->output_data.x->left_pos = (FRAME_X_DISPLAY_INFO (f)->width
-                             - 2 * f->output_data.x->border_width - win_x
-                             - PIXEL_WIDTH (f)
-                             + f->output_data.x->left_pos);
+                                 - 2 * f->output_data.x->border_width - win_x
+                                 - PIXEL_WIDTH (f)
+                                 + f->output_data.x->left_pos);
 
   if (flags & YNegative)
 
   if (flags & YNegative)
+    /* We used to subtract f->output_data.x->menubar_height here
+       in the toolkit case, but PIXEL_HEIGHT already includes that.  */
     f->output_data.x->top_pos = (FRAME_X_DISPLAY_INFO (f)->height
     f->output_data.x->top_pos = (FRAME_X_DISPLAY_INFO (f)->height
-                            - 2 * f->output_data.x->border_width - win_y
-                            - PIXEL_HEIGHT (f)
-                            - (FRAME_EXTERNAL_MENU_BAR (f)
-                               ? f->output_data.x->menubar_height : 0)
-                            + f->output_data.x->top_pos);
+                                - 2 * f->output_data.x->border_width - win_y
+                                - PIXEL_HEIGHT (f)
+                                + f->output_data.x->top_pos);
+
   /* The left_pos and top_pos
      are now relative to the top and left screen edges,
      so the flags should correspond.  */
   /* The left_pos and top_pos
      are now relative to the top and left screen edges,
      so the flags should correspond.  */
@@ -5064,9 +5000,12 @@ x_set_window_size (f, change_gravity, cols, rows)
 {
   int pixelwidth, pixelheight;
   int mask;
 {
   int pixelwidth, pixelheight;
   int mask;
+  Lisp_Object window;
+  struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
 
 
-#ifdef USE_X_TOOLKIT
   BLOCK_INPUT;
   BLOCK_INPUT;
+
+#ifdef USE_X_TOOLKIT
   {
     /* The x and y position of the widget is clobbered by the
        call to XtSetValues within EmacsFrameSetCharSize.
   {
     /* The x and y position of the widget is clobbered by the
        call to XtSetValues within EmacsFrameSetCharSize.
@@ -5078,12 +5017,9 @@ x_set_window_size (f, change_gravity, cols, rows)
     f->output_data.x->widget->core.x = xpos;
     f->output_data.x->widget->core.y = ypos;
   }
     f->output_data.x->widget->core.x = xpos;
     f->output_data.x->widget->core.y = ypos;
   }
-  UNBLOCK_INPUT;
 
 #else /* not USE_X_TOOLKIT */
 
 
 #else /* not USE_X_TOOLKIT */
 
-  BLOCK_INPUT;
-
   check_frame_size (f, &rows, &cols);
   f->output_data.x->vertical_scroll_bar_extra
     = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f)
   check_frame_size (f, &rows, &cols);
   f->output_data.x->vertical_scroll_bar_extra
     = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f)
@@ -5115,6 +5051,16 @@ x_set_window_size (f, change_gravity, cols, rows)
   PIXEL_WIDTH (f) = pixelwidth;
   PIXEL_HEIGHT (f) = pixelheight;
 
   PIXEL_WIDTH (f) = pixelwidth;
   PIXEL_HEIGHT (f) = pixelheight;
 
+  /* 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
+     we have to make sure to do it here.  */
+  SET_FRAME_GARBAGED (f);
+
+  XFlush (FRAME_X_DISPLAY (f));
+
+#endif /* not USE_X_TOOLKIT */
+
   /* If cursor was outside the new size, mark it as off.  */
   if (f->phys_cursor_y >= rows
       || f->phys_cursor_x >= cols)
   /* If cursor was outside the new size, mark it as off.  */
   if (f->phys_cursor_y >= rows
       || f->phys_cursor_x >= cols)
@@ -5123,15 +5069,19 @@ x_set_window_size (f, change_gravity, cols, rows)
       f->phys_cursor_y = -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
-     we have to make sure to do it here.  */
-  SET_FRAME_GARBAGED (f);
+  /* Clear out any recollection of where the mouse highlighting was,
+     since it might be in a place that's outside the new frame size. 
+     Actually checking whether it is outside is a pain in the neck,
+     so don't try--just let the highlighting be done afresh with new size.  */
+  window = dpyinfo->mouse_face_window;
+  if (! NILP (window) && XFRAME (window) == f)
+    {
+      dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
+      dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
+      dpyinfo->mouse_face_window = Qnil;
+    }
 
 
-  XFlush (FRAME_X_DISPLAY (f));
   UNBLOCK_INPUT;
   UNBLOCK_INPUT;
-#endif /* not USE_X_TOOLKIT */
 }
 \f
 /* Mouse warping.  */
 }
 \f
 /* Mouse warping.  */
@@ -5238,11 +5188,11 @@ x_lower_frame (f)
 }
 
 static void
 }
 
 static void
-XTframe_raise_lower (f, raise)
+XTframe_raise_lower (f, raise_flag)
      FRAME_PTR f;
      FRAME_PTR f;
-     int raise;
+     int raise_flag;
 {
 {
-  if (raise)
+  if (raise_flag)
     x_raise_frame (f);
   else
     x_lower_frame (f);
     x_raise_frame (f);
   else
     x_lower_frame (f);
@@ -5447,6 +5397,8 @@ x_iconify_frame (f)
 
   BLOCK_INPUT;
 
 
   BLOCK_INPUT;
 
+  FRAME_SAMPLE_VISIBILITY (f);
+
   type = x_icon_type (f);
   if (!NILP (type))
     x_bitmap_icon (f, type);
   type = x_icon_type (f);
   if (!NILP (type))
     x_bitmap_icon (f, type);
@@ -5459,6 +5411,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);
        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;
     }
       UNBLOCK_INPUT;
       return;
     }
@@ -5534,16 +5491,33 @@ x_destroy_window (f)
 
   BLOCK_INPUT;
 
 
   BLOCK_INPUT;
 
-  if (f->output_data.x->icon_desc != 0)
-    XDestroyWindow (FRAME_X_DISPLAY (f), f->output_data.x->icon_desc);
-  XDestroyWindow (FRAME_X_DISPLAY (f), f->output_data.x->window_desc);
+  /* If a display connection is dead, don't try sending more
+     commands to the X server.  */
+  if (dpyinfo->display != 0)
+    {
+      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
 #ifdef USE_X_TOOLKIT
-  XtDestroyWidget (f->output_data.x->widget);
-  free_frame_menubar (f);
+      XtDestroyWidget (f->output_data.x->widget);
+      free_frame_menubar (f);
 #endif /* USE_X_TOOLKIT */
 
 #endif /* USE_X_TOOLKIT */
 
-  free_frame_faces (f);
-  XFlush (FRAME_X_DISPLAY (f));
+      free_frame_faces (f);
+      XFlush (FRAME_X_DISPLAY (f));
+    }
 
   xfree (f->output_data.x);
   f->output_data.x = 0;
 
   xfree (f->output_data.x);
   f->output_data.x = 0;
@@ -5742,6 +5716,8 @@ x_wm_set_icon_pixmap (f, pixmap_id)
      struct frame *f;
      int pixmap_id;
 {
      struct frame *f;
      int pixmap_id;
 {
+  Pixmap icon_pixmap;
+
 #ifdef USE_X_TOOLKIT
   Window window = XtWindow (f->output_data.x->widget);
 #else
 #ifdef USE_X_TOOLKIT
   Window window = XtWindow (f->output_data.x->widget);
 #else
@@ -5750,7 +5726,7 @@ x_wm_set_icon_pixmap (f, pixmap_id)
 
   if (pixmap_id > 0)
     {
 
   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
       f->output_data.x->wm_hints.icon_pixmap = icon_pixmap;
     }
   else
@@ -5769,8 +5745,20 @@ x_wm_set_icon_pixmap (f, pixmap_id)
 #endif
     }
 
 #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);
   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)
 }
 
 x_wm_set_icon_position (f, icon_x, icon_y)
@@ -5857,7 +5845,10 @@ x_term_init (display_name, xrm_option, resource_name)
     }
 
 #ifdef HAVE_X_I18N
     }
 
 #ifdef HAVE_X_I18N
-  setlocale (LC_ALL, NULL);
+  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
 #endif
 
 #ifdef USE_X_TOOLKIT
@@ -5887,6 +5878,7 @@ x_term_init (display_name, xrm_option, resource_name)
                         &argc, argv);
 
 #ifdef HAVE_X11XTR6
                         &argc, argv);
 
 #ifdef HAVE_X11XTR6
+    /* I think this is to compensate for XtSetLanguageProc.  */
     setlocale (LC_NUMERIC, "C");
     setlocale (LC_TIME, "C");
 #endif
     setlocale (LC_NUMERIC, "C");
     setlocale (LC_TIME, "C");
 #endif
@@ -6212,4 +6204,5 @@ syms_of_xterm ()
   staticpro (&Qvendor_specific_keysyms);
   Qvendor_specific_keysyms = intern ("vendor-specific-keysyms");
 }
   staticpro (&Qvendor_specific_keysyms);
   Qvendor_specific_keysyms = intern ("vendor-specific-keysyms");
 }
-#endif /* ! defined (HAVE_X_WINDOWS) */
+
+#endif /* not HAVE_X_WINDOWS */