]> code.delx.au - gnu-emacs/blobdiff - src/xterm.c
(XTread_socket, Xatom_wm_save_yourself clause):
[gnu-emacs] / src / xterm.c
index ce426fb0afdec473012c2a634e9ad413ef68226a..977e1b8020f8966df0a5faf39047b0fd403cc202 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,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
-   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;
@@ -225,9 +235,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;
@@ -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);
     }
 }
 
@@ -2261,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
-   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 +2974,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 +3062,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
@@ -3338,7 +3300,12 @@ 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
          event_found = 1;
 
          switch (event.type)
@@ -3387,7 +3354,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 +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 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;
 
@@ -4516,9 +4483,6 @@ 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.  */
 
   dpyinfo->display = 0;
@@ -4555,7 +4519,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);
     }
@@ -4567,6 +4531,12 @@ x_connection_closed (display, error_message)
   sigunblock (sigmask (SIGALRM));
   TOTALLY_UNBLOCK_INPUT;
 
+  if (waiting_for_input)
+    {
+      message ("%s", error_message);
+      quit_throw_to_read_char ();
+    }
+
   error ("%s", error_message);
 }
 
@@ -4606,55 +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.
-   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. */
 {
-  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.  */
@@ -4818,6 +4752,7 @@ x_new_font (f, fontname)
       char *full_name;
       XFontStruct *font;
       int n_fonts;
+      Atom FONT_atom;
 
       /* 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;
+      FONT_atom = XInternAtom (FRAME_X_DISPLAY (f), "FONT", False);
       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));
@@ -4891,8 +4825,6 @@ x_new_font (f, fontname)
 
              break;
            }
-
-         XFree (atom);
        }
 
       n_fonts = FRAME_X_DISPLAY_INFO (f)->n_fonts;
@@ -5479,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);
+      /* 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;
     }
@@ -5564,7 +5501,12 @@ x_destroy_window (f)
       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);
@@ -5774,6 +5716,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
@@ -5782,7 +5726,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
@@ -5801,8 +5745,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)
@@ -5890,6 +5846,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
@@ -5919,6 +5878,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
@@ -6244,49 +6204,5 @@ 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 */
-}
-
-/* Don't put any additional functions here!  */
 
 #endif /* not HAVE_X_WINDOWS */