changeset 1020:7c2565dd644c

* xterm.c (x_wm_hints): Variable deleted. This has to be per-screen. Duh. * xterm.c (x_wm_set_window_state, x_wm_set_icon_pixmap, x_wm_set_icon_position): Use F->display.x->wm_hints, rather than x_wm_hints. (x_term_init): Don't initialize x_wm_hints here. * xterm.c (x_set_text_property): Properly balance the BLOCK_INPUTs and UNBLOCK_INPUTs. And remember that VALUE is the strin we want to set the name to, not PROPERTY. * xterm.c (x_set_text_property): Define this appropriately for X11R3 and X11R4. * xterm.c (x_set_text_property): Make this take a Lisp_Object string as an argument, rather than a pointer and a length. * xterm.c: Doc fixes. * xterm.c [USG5]: Don't include <sys/types.h>. * xterm.c (x_make_frame_invisible): Instead of calling XWithdraw window, which isn't widely available, write out what it does, since that's not much. (x_iconify_frame): Explicitly perform both the X11R3 and X11R4 methods for iconification; don't use XIconifyWindow, since that's not present in R3. * xterm.c (x_wm_set_size_hint): Don't bother setting the base_width and base_height members; their function is performed just as well by the min_width and min_height members, and if we use XSetNormalHints instead of XSetWMNormalHints, we can be compatible with R3. * xterm.c (x_error_handler): There is no way to invoke the default error handler which works on all versions of X11, so don't bother; call XGetErrorText and print the message ourselves. * xterm.c (x_term_init): Don't use MAXHOSTNAMELEN; this isn't defined on all systems. Since we only use that as an initial guess anyway, it's not very important. * xterm.c (x_set_text_property): New function.
author Jim Blandy <jimb@redhat.com>
date Wed, 19 Aug 1992 06:51:44 +0000
parents aaa628aaf808
children 22f807391bec
files src/xterm.c
diffstat 1 files changed, 147 insertions(+), 132 deletions(-) [+]
line wrap: on
line diff
--- a/src/xterm.c	Wed Aug 19 06:51:17 1992 +0000
+++ b/src/xterm.c	Wed Aug 19 06:51:44 1992 +0000
@@ -38,11 +38,13 @@
    if this is not done before the other system files.  */
 #include "xterm.h"
 
+#ifndef USG
 /* Load sys/types.h if not already loaded.
    In some systems loading it twice is suicidal.  */
 #ifndef makedev
 #include <sys/types.h>
 #endif
+#endif
 
 #ifdef BSD
 #include <sys/ioctl.h>
@@ -153,19 +155,6 @@
 char *hostname, *x_id_name;
 Lisp_Object invocation_name;
 
-/* These are the current window manager hints.  It seems that
-   XSetWMHints, when presented with an unset bit in the `flags' member
-   of the hints structure, does not leave the corresponding attribute
-   unchanged; rather, it resets that attribute to its default value.
-   For example, unless you set the `icon_pixmap' field and the
-   `IconPixmapHint' bit, XSetWMHints will forget what your icon pixmap
-   was.  This is rather troublesome, since some of the members (for
-   example, `input' and `icon_pixmap') want to stay the same
-   throughout the execution of Emacs.  So, we keep this structure
-   around, just leaving values in it and adding new bits to the mask
-   as we go.  */
-XWMHints x_wm_hints;
-
 /* This is the X connection that we are using.  */
 
 Display *x_current_display;
@@ -270,6 +259,62 @@
 static int XTcursor_to ();
 static int XTclear_end_of_line ();
 
+/* R3/R4 compatibility stuff.  Rah.  */
+
+
+/* Set the property PROPERTY on the window displaying FRAME to VALUE.
+   VALUE must be a string.
+   
+   We use this function instead of XSetWMName and XStoreName, since
+   the former isn't present in R3, while the latter isn't likely to
+   stay around.  XChangeProperty, however, is likely to be around.
+
+   I have no idea if this is the right thing to do.  Someone who is more
+   hip on how X is supposed to work should let us know if this is wrong.  */
+
+x_set_text_property (f, property, value)
+     FRAME_PTR f;
+     Atom property;
+     Lisp_Object value;
+{
+  BLOCK_INPUT;
+
+#ifdef HAVE_X11R4
+  {
+    XTextProperty text;
+    text.value = XSTRING (value)->data;
+    text.encoding = XA_STRING;
+    text.format = 8;
+    text.nitems = XSTRING (value)->size;
+    switch (property)
+      {
+      case XA_WM_NAME:
+	XSetWMName (x_current_display, f->display.x->window_desc, &text);
+	break;
+      case XA_WM_ICON_NAME:
+	XSetWMIconName (x_current_display, f->display.x->window_desc, &text);
+	break;
+      default:
+	/* If you want to use this function, you have to make sure it supports
+	   the atoms you want!  Dummy.  */
+	abort ();
+      }
+  }
+#else
+  XChangeProperty (x_current_display,
+		   f->display.x->window_desc,
+		   prop,
+		   XA_STRING,	/* type */
+		   8,		/* format */
+		   PropModeReplace, /* mode */
+		   XSTRING (value)->data,
+		   XSTRING (value)->size);
+#endif
+
+  UNBLOCK_INPUT;
+}
+
+
 /* These hooks are called by update_frame at the beginning and end
    of a frame update.  We record in `updating_frame' the identity
    of the frame being updated, so that the XT... functions do not
@@ -2862,7 +2907,10 @@
 /* Handling X errors.  */
 
 /* A handler for SIGPIPE, when it occurs on the X server's connection.
-   This basically does an orderly shutdown of Emacs.  */
+   This basically does an orderly shutdown of Emacs.  The arg to
+   Fkill_emacs is an exit status value and also prevents any
+   questions.  */
+
 static SIGTYPE
 x_death_handler ()
 {
@@ -2996,6 +3044,11 @@
   "NoOperation"
 };
 
+/* 94 is the code for X_CreateGlyphCursor.  The idea is that we
+   probably shouldn't let a bad mouse cursor request crash Emacs.
+   You'd think we could #include <X11/Xproto.h> and use a symbolic
+   constant for this, but that's been commented out above; perhaps
+   that file is not available on all systems.  */
 #define acceptable_x_error_p(type) ((type) == 94)
 
 x_handle_error_gracefully (event)
@@ -3018,11 +3071,7 @@
 
 /* Handle X Errors.  If the error is not traumatic,
    just call error ().  Otherwise print a (hopefully) interesting
-   message and quit.
-
-   The arg to Fkill_emacs is an exit status value
-   and also prevents any questions.  */
-
+   message and quit.  */
 x_error_handler (disp, event)
      Display *disp;
 #ifdef HAVE_X11
@@ -3048,14 +3097,15 @@
 #endif
       if (acceptable_x_error_p (event->request_code))
 	x_handle_error_gracefully (event);
-      else
-	_XDefaultError (disp, event);
     }
-  else
-    {
-      disp->flags |= XlibDisplayIOError;
-      _XDefaultIOError (disp);
-    }
+
+  {
+    char message[80];
+
+    XGetErrorText (disp, event->error_code, message, sizeof (message));
+    fprintf (stderr, "Fatal X error:\n%s\n", message);
+  }
+
   UNBLOCK_INPUT;
 
   x_death_handler ();
@@ -3430,34 +3480,32 @@
 
   BLOCK_INPUT;
 #ifdef HAVE_X11
-#if 0
+  /* It would be nice if we didn't have to be backward compatible with
+     very old versions of X, because then we could use the
+     XWithdrawWindow function in R4 instead of writing it out ourselves.  */
+
+  /*  Tell the window manager what we've done.  */
   if (! EQ (Vx_no_window_manager, Qt))
     {
-      XUnmapEvent unmap;
-
-      unmap.type = UnmapNotify;
-      unmap.window = f->display.x->window_desc;
-      unmap.event = DefaultRootWindow (x_current_display);
-      unmap.from_configure = False;
-      XSendEvent (x_current_display, DefaultRootWindow (x_current_display),
-		  False, SubstructureRedirectMask|SubstructureNotifyMask,
-		  &unmap);
+      XEvent unmap;
+
+      unmap.xunmap.type = UnmapNotify;
+      unmap.xunmap.window = f->display.x->window_desc;
+      unmap.xunmap.event = DefaultRootWindow (x_current_display);
+      unmap.xunmap.from_configure = False;
+      if (! XSendEvent (x_current_display,
+			DefaultRootWindow (x_current_display),
+			False,
+			SubstructureRedirectMask|SubstructureNotifyMask,
+			&unmap))
+	{
+	  UNBLOCK_INPUT_RESIGNAL;
+	  error ("can't notify window manager of withdrawal");
+	}
     }
 
-  /* The new function below does the same as the above code, plus unmapping
-     the window.  Sending the event without actually unmapping can make
-     the window manager start ignoring the window (i.e., no more title bar,
-     icon manager stuff.) */
-#endif
-
-  /* New function available with R4 */
-  if (! XWithdrawWindow (x_current_display, f->display.x->window_desc,
-			 DefaultScreen (x_current_display)))
-    {
-      UNBLOCK_INPUT_RESIGNAL;
-      error ("Can't notify window manager of iconification.");
-    }
-
+  /* Unmap the window ourselves.  Cheeky!  */
+  XUnmapWindow (x_current_display, f->display.x->window_desc);
 #else
   XUnmapWindow (XDISPLAY f->display.x->window_desc);
 
@@ -3470,7 +3518,7 @@
   UNBLOCK_INPUT;
 }
 
- /* Window manager communication.  Created in Fx_open_connection. */
+/* Window manager communication.  Created in Fx_open_connection. */
 extern Atom Xatom_wm_change_state;
 
 /* Change window state from mapped to iconified. */
@@ -3486,37 +3534,36 @@
   BLOCK_INPUT;
 
 #ifdef HAVE_X11
-  if (! EQ (Vx_no_window_manager, Qt))
-    if (! XIconifyWindow (x_current_display, f->display.x->window_desc,
-			  DefaultScreen (x_current_display)))
+  /* 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.  */
+
+  /* X11R4: send a ClientMessage to the window manager using the
+     WM_CHANGE_STATE type.  */
+  {
+    XEvent message;
+    
+    message.xclient.window = f->display.x->window_desc;
+    message.xclient.type = ClientMessage;
+    message.xclient.message_type = Xatom_wm_change_state;
+    message.xclient.format = 32;
+    message.xclient.data.l[0] = IconicState;
+
+    if (! XSendEvent (x_current_display,
+		      DefaultRootWindow (x_current_display),
+		      False,
+		      SubstructureRedirectMask | SubstructureNotifyMask,
+		      &message))
       {
 	UNBLOCK_INPUT_RESIGNAL;
 	error ("Can't notify window manager of iconification.");
       }
+  }
+
+  /* X11R3: set the initial_state field of the window manager hints to 
+     IconicState.  */
+  x_wm_set_window_state (f, IconicState);
 
   f->iconified = 1;
-  
-#if 0
-    {
-      XClientMessageEvent message;
-    
-      message.window = f->display.x->window_desc;
-      message.type = ClientMessage;
-      message.message_type = Xatom_wm_change_state;
-      message.format = 32;
-      message.data.l[0] = IconicState;
-
-      if (! XSendEvent (x_current_display,
-			DefaultRootWindow (x_current_display),
-			False,
-			SubstructureRedirectMask | SubstructureNotifyMask,
-			&message))
-	{
-	  UNBLOCK_INPUT_RESIGNAL;
-	  error ("Can't notify window manager of iconification.");
-	}
-    }
-#endif
 #else /* X10 */
   XUnmapWindow (XDISPLAY f->display.x->window_desc);
 
@@ -3654,23 +3701,15 @@
     (x_screen_height - ((2 * f->display.x->internal_border_width)
 			+ f->display.x->h_scrollbar_height));
   {
-    int base_width = ((2 * f->display.x->internal_border_width)
-		      + f->display.x->v_scrollbar_width);
-    int base_height = ((2 * f->display.x->internal_border_width)
-		       + f->display.x->h_scrollbar_height);
-
-#ifdef PBaseSize
-    size_hints.flags |= PBaseSize;
-    size_hints.base_width = base_width;
-    size_hints.base_height = base_height;
-#endif
-
-    {
-      int min_rows = 0, min_cols = 0;
-      check_frame_size (f, &min_rows, &min_cols);
-      size_hints.min_width  = base_width  + min_cols * size_hints.width_inc;
-      size_hints.min_height = base_height + min_rows * size_hints.height_inc;
-    }
+    int min_rows = 0, min_cols = 0;
+    check_frame_size (f, &min_rows, &min_cols);
+    size_hints.min_width  = ((2 * f->display.x->internal_border_width)
+			     + min_cols * size_hints.width_inc
+			     + f->display.x->v_scrollbar_width);
+    size_hints.min_height = ((2 * f->display.x->internal_border_width)
+			     + min_rows * size_hints.height_inc
+			     + f->display.x->h_scrollbar_height);
+
   }
 
   if (prompting)
@@ -3689,11 +3728,8 @@
       if (hints.flags & USSize)
 	size_hints.flags |= USSize;
     }
-  
-#if 0				/* R3 */
+
   XSetNormalHints (x_current_display, window, &size_hints);
-#endif
-  XSetWMNormalHints (x_current_display, window, &size_hints);
 }
 
 /* Used for IconicState or NormalState */
@@ -3703,10 +3739,10 @@
 {
   Window window = f->display.x->window_desc;
 
-  x_wm_hints.flags |= StateHint;
-  x_wm_hints.initial_state = state;
-
-  XSetWMHints (x_current_display, window, &x_wm_hints);
+  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);
 }
 
 x_wm_set_icon_pixmap (f, icon_pixmap)
@@ -3715,15 +3751,10 @@
 {
   Window window = f->display.x->window_desc;
 
-  if (icon_pixmap)
-    {
-      x_wm_hints.flags |= IconPixmapHint;
-      x_wm_hints.icon_pixmap = icon_pixmap;
-    }
-  else
-    x_wm_hints.flags &= ~IconPixmapHint;
-
-  XSetWMHints (x_current_display, window, &x_wm_hints);
+  f->display.x->wm_hints.flags |= IconPixmapHint;
+  f->display.x->wm_hints.icon_pixmap = icon_pixmap ? icon_pixmap : None;
+
+  XSetWMHints (x_current_display, window, &f->display.x->wm_hints);
 }
 
 x_wm_set_icon_position (f, icon_x, icon_y)
@@ -3732,11 +3763,11 @@
 {
   Window window = f->display.x->window_desc;
 
-  x_wm_hints.flags |= IconPositionHint;
-  x_wm_hints.icon_x = icon_x;
-  x_wm_hints.icon_y = icon_y;
-
-  XSetWMHints (x_current_display, window, &x_wm_hints);
+  f->display.x->wm_hints.flags |= IconPositionHint;
+  f->display.x->wm_hints.icon_x = icon_x;
+  f->display.x->wm_hints.icon_y = icon_y;
+
+  XSetWMHints (x_current_display, window, &f->display.x->wm_hints);
 }
 
 
@@ -3759,7 +3790,7 @@
 
 #ifdef HAVE_X11
   {
-    int hostname_size = MAXHOSTNAMELEN + 1;
+    int hostname_size = 256;
 
     hostname = (char *) xmalloc (hostname_size);
 
@@ -3861,22 +3892,6 @@
 #endif /* SIGWINCH */
 
   signal (SIGPIPE, x_death_handler);
-
-  /* When XSetWMHints eventually gets called, this will indicate that
-     we use the "Passive Input" input model.  Unless we do this, we
-     don't get the Focus{In,Out} events that we need to draw the
-     cursor correctly.  Accursed bureaucrats.
-
-     We set this here and leave it, because we know, being decidedly
-     non-humble programmers (nay, weigh'd low by our hubris!), that
-     Fx_create_frame calls x_icon which begat x_wm_set_window_state
-     which begat XSetWMHints, which will get this information to the
-     right parties.
-
-  XWhipsAndChains (x_current_display, IronMaiden, &TheRack);  */
-
-  x_wm_hints.input = True;
-  x_wm_hints.flags |= InputHint;
 }
 
 void