Add somewhat complex Emacs hack to deal with complexities of
authorChris Hanson <org/chris-hanson/cph>
Sat, 12 Nov 2005 22:53:36 +0000 (22:53 +0000)
committerChris Hanson <org/chris-hanson/cph>
Sat, 12 Nov 2005 22:53:36 +0000 (22:53 +0000)
positioning windows.  Ignore non-synthetic reconfigure events when
interacting with a reparenting window manager.  Eliminate use of
deprecated size and position hints fields.  Improve X debugging
information.  Change default internal-border-width from 1 to 0.
Simplify method used to catch X errors.

v7/src/microcode/x11.h
v7/src/microcode/x11base.c
v7/src/microcode/x11term.c

index ec0c67db3f457680431983ddc04c30b90849b1d8..a8e8d9e36a23b3eadaffad942c400883c301612c 100644 (file)
@@ -1,8 +1,9 @@
 /* -*-C-*-
 
-$Id: x11.h,v 1.19 2003/02/14 18:28:24 cph Exp $
+$Id: x11.h,v 1.20 2005/11/12 22:53:29 cph Exp $
 
-Copyright (c) 1989-2000 Massachusetts Institute of Technology
+Copyright 1989,1990,1991,1992,1993,2000 Massachusetts Institute of Technology
+Copyright 2005 Massachusetts Institute of Technology
 
 This file is part of MIT/GNU Scheme.
 
@@ -40,6 +41,19 @@ struct xdisplay
   Atom wm_take_focus;
   XEvent cached_event;
   char cached_event_p;
+
+  /* The type of window manager we have.  If we move FRAME_OUTER_WINDOW
+     to x/y 0/0, some window managers (type A) puts the window manager
+     decorations outside the screen and FRAME_OUTER_WINDOW exactly at 0/0.
+     Other window managers (type B) puts the window including decorations
+     at 0/0, so FRAME_OUTER_WINDOW is a bit below 0/0.
+     Record the type of WM in use so we can compensate for type A WMs.  */
+  enum
+    {
+      X_WMTYPE_UNKNOWN,
+      X_WMTYPE_A,
+      X_WMTYPE_B
+    } wm_type;
 };
 
 #define XD_ALLOCATION_INDEX(xd) ((xd) -> allocation_index)
@@ -50,6 +64,7 @@ struct xdisplay
 #define XD_WM_TAKE_FOCUS(xd) ((xd) -> wm_take_focus)
 #define XD_CACHED_EVENT(xd) ((xd) -> cached_event)
 #define XD_CACHED_EVENT_P(xd) ((xd) -> cached_event_p)
+#define XD_WM_TYPE(xd) ((xd) -> wm_type)
 #define XD_TO_OBJECT(xd) (LONG_TO_UNSIGNED_FIXNUM (XD_ALLOCATION_INDEX (xd)))
 
 extern struct xdisplay * EXFUN (x_display_arg, (unsigned int arg));
@@ -130,6 +145,26 @@ struct xwindow
 
   unsigned long event_mask;
 
+  /* Geometry parameters for window-manager decoration window.  */
+  int wm_decor_x;
+  int wm_decor_y;
+  unsigned int wm_decor_pixel_width;
+  unsigned int wm_decor_pixel_height;
+  unsigned int wm_decor_border_width;
+
+  /* The latest move we made to the window.  Saved so we can
+     compensate for type A WMs (see wm_type above).  */
+  int expected_x;
+  int expected_y;
+
+  /* Nonzero if we have made a move and need to check if the WM placed
+     us at the right position.  */
+  int check_expected_move_p;
+
+  /* The offset we need to add to compensate for type A WMs.  */
+  int move_offset_x;
+  int move_offset_y;
+
 #ifdef __GNUC__
   PTR extra [0];
 #else
@@ -165,13 +200,24 @@ struct xwindow
 #define XW_Y_COORDINATE_MAP(xw) (((xw) -> methods) . y_coordinate_map)
 #define XW_UPDATE_NORMAL_HINTS(xw) (((xw) -> methods) . update_normal_hints)
 #define XW_EVENT_MASK(xw) ((xw) -> event_mask)
+#define XW_WM_DECOR_X(xw) ((xw) -> wm_decor_x)
+#define XW_WM_DECOR_Y(xw) ((xw) -> wm_decor_y)
+#define XW_WM_DECOR_PIXEL_WIDTH(xw) ((xw) -> wm_decor_pixel_width)
+#define XW_WM_DECOR_PIXEL_HEIGHT(xw) ((xw) -> wm_decor_pixel_height)
+#define XW_WM_DECOR_BORDER_WIDTH(xw) ((xw) -> wm_decor_border_width)
+#define XW_EXPECTED_X(xw) ((xw) -> expected_x)
+#define XW_EXPECTED_Y(xw) ((xw) -> expected_y)
+#define XW_CHECK_EXPECTED_MOVE_P(xw) ((xw) -> check_expected_move_p)
+#define XW_MOVE_OFFSET_X(xw) ((xw) -> move_offset_x)
+#define XW_MOVE_OFFSET_Y(xw) ((xw) -> move_offset_y)
 
 #define XW_TO_OBJECT(xw) (LONG_TO_UNSIGNED_FIXNUM (XW_ALLOCATION_INDEX (xw)))
 #define XW_DISPLAY(xw) (XD_DISPLAY (XW_XD (xw)))
+#define XW_WM_TYPE(xw) (XD_WM_TYPE (XW_XD (xw)))
 
-#define FONT_WIDTH(f)  (((f) -> max_bounds) . width)
-#define FONT_HEIGHT(f) (((f) -> ascent) + ((f) -> descent))
-#define FONT_BASE(f)    ((f) -> ascent)
+#define FONT_WIDTH(f) (((f) -> max_bounds) . width)
+#define FONT_HEIGHT(f) (((f) -> ascent) + ((f) -> descent))
+#define FONT_BASE(f) ((f) -> ascent)
 
 extern struct xwindow * EXFUN (x_window_arg, (unsigned int arg));
 \f
index 51f642d1c82b4f53e7de5a6bcf43ca5d851ba571..46650613cbe85f21535323ddb23a78df47c91828 100644 (file)
@@ -1,10 +1,10 @@
 /* -*-C-*-
 
-$Id: x11base.c,v 1.81 2004/02/03 18:46:50 cph Exp $
+$Id: x11base.c,v 1.82 2005/11/12 22:53:33 cph Exp $
 
 Copyright 1989,1990,1991,1992,1993,1994 Massachusetts Institute of Technology
 Copyright 1995,1996,1997,1998,2000,2001 Massachusetts Institute of Technology
-Copyright 2003,2004 Massachusetts Institute of Technology
+Copyright 2003,2004,2005 Massachusetts Institute of Technology
 
 This file is part of MIT/GNU Scheme.
 
@@ -40,7 +40,7 @@ extern void EXFUN (block_signals, (void));
 extern void EXFUN (unblock_signals, (void));
 
 #ifndef X_DEFAULT_FONT
-#define X_DEFAULT_FONT "fixed"
+#  define X_DEFAULT_FONT "fixed"
 #endif
 
 int x_debug = 0;
@@ -55,6 +55,9 @@ static const char * x_default_font = 0;
 
 static void EXFUN (initialize_once, (void));
 
+static void move_window (struct xwindow *, int, int);
+static void check_expected_move (struct xwindow *);
+
 PTR
 DEFUN (x_malloc, (size), unsigned int size)
 {
@@ -258,65 +261,86 @@ DEFUN (x_io_error_handler, (display), Display * display)
 {
   fprintf (stderr, "\nX IO Error\n");
   fflush (stderr);
-#if 0
-  error_external_return ();
-#else
   termination_eof ();
-#endif
   return (0);
 }
 
+typedef struct
+{
+  char message [2048];
+  char terminate_p;
+  unsigned char code;
+} x_error_info_t;
+
+static x_error_info_t x_error_info;
+
 static int
-DEFUN (x_error_handler, (display, error_event),
-       Display * display AND
-       XErrorEvent * error_event)
-{
-  char buffer [2048];
-  XGetErrorText (display, (error_event -> error_code),
-                buffer, (sizeof (buffer)));
-  fprintf (stderr, "\nX Error: %s\n", buffer);
-  fprintf (stderr, "         Request code: %d\n",
-          (error_event -> request_code));
-  fprintf (stderr, "         Error serial: %lx\n", (error_event -> serial));
-  fflush (stderr);
-#if 0
-  error_external_return ();
-#else
-  termination_eof ();
-#endif
+x_error_handler (Display * display, XErrorEvent * error_event)
+{
+  (x_error_info.code) = (error_event->error_code);
+  XGetErrorText (display,
+                (error_event->error_code),
+                (x_error_info.message),
+                (sizeof (x_error_info.message)));
+  if (x_error_info.terminate_p)
+    {
+      fprintf (stderr, "\nX Error: %s\n", (x_error_info.message));
+      fprintf (stderr, "         Request code: %d\n",
+              (error_event->request_code));
+      fprintf (stderr, "         Error serial: %lx\n", (error_event->serial));
+      fflush (stderr);
+      termination_eof ();
+    }
   return (0);
 }
 
-typedef int EXFUN ((* x_error_handler_t), (Display *, XErrorEvent *));
-
 static void
-DEFUN (unbind_x_error_handler, (storage), PTR storage)
+DEFUN (unbind_x_error_info, (storage), PTR storage)
+{
+  x_error_info = (* ((x_error_info_t *) storage));
+}
+
+static void *
+push_x_error_info (Display * display)
 {
-  (void) (XSetErrorHandler (* ((x_error_handler_t *) storage)));
+  void * handle;
+  x_error_info_t * storage;
+
+  XSync (display, False);
+  handle = dstack_position;
+  storage = (dstack_alloc (sizeof (x_error_info_t)));
+  (*storage) = x_error_info;
+  ((x_error_info.message) [0]) = '\0';
+  (x_error_info.terminate_p) = 0;
+  (x_error_info.code) = 0;
+  dstack_protect (unbind_x_error_info, storage);
+  return (handle);
 }
 
 static void
-DEFUN (bind_x_error_handler, (handler), x_error_handler_t handler)
+pop_x_error_info (void * position)
 {
-  x_error_handler_t * storage = (dstack_alloc (sizeof (x_error_handler_t)));
-  (*storage) = (XSetErrorHandler (handler));
-  dstack_protect (unbind_x_error_handler, storage);
+  dstack_set_position (position);
 }
 
-static jmp_buf x_prim_checkpoint;
+static unsigned char
+x_error_code (Display * display)
+{
+  XSync (display, False);
+  return (x_error_info.code);
+}
 
 static int
-DEFUN (catch_x_errors_handler, (display, event),
-       Display * display AND
-       XErrorEvent * event)
+any_x_errors_p (Display * display)
 {
-  longjmp (x_prim_checkpoint, (event -> error_code));
+  return ((x_error_code (display)) != 0);
 }
 
-#define CATCH_X_ERRORS(target)                                         \
-{                                                                      \
-  bind_x_error_handler (catch_x_errors_handler);                       \
-  (target) = (setjmp (x_prim_checkpoint));                             \
+static SCHEME_OBJECT
+x_error_message (void)
+{
+  return
+    (char_pointer_to_string_no_gc ((unsigned char *) (x_error_info.message)));
 }
 \f
 /* Defaults and Attributes */
@@ -462,7 +486,7 @@ DEFUN (x_default_attributes,
       (x_get_default
        (display, resource_name, resource_class,
        "borderWidth", "BorderWidth", 0));
-    (attributes -> border_width) = ((s == 0) ? 1 : (atoi (s)));
+    (attributes -> border_width) = ((s == 0) ? 0 : (atoi (s)));
   }
   {
     char * s =
@@ -499,6 +523,54 @@ DEFUN (x_default_attributes,
        "pointerColor", "Foreground", foreground_pixel));
   }
 }
+
+static int
+get_wm_decor_geometry (struct xwindow * xw)
+{
+  Display * display = (XW_DISPLAY (xw));
+  Window decor = (XW_WINDOW (xw));
+  void * handle = (push_x_error_info (display));
+  Window root;
+  unsigned int depth;
+
+  {
+    Window parent;
+    Window * children;
+    unsigned int n_children;
+    while (1)
+      {
+       if ((!XQueryTree (display, decor,
+                         (&root), (&parent), (&children), (&n_children)))
+           || (any_x_errors_p (display)))
+         {
+           pop_x_error_info (handle);
+           error_external_return ();
+         }
+       if (children != 0)
+         XFree (children);
+       if (parent == root)
+         break;
+       decor = parent;
+      }
+  }
+  if ((!XGetGeometry (display,
+                     decor,
+                     (&root),
+                     (& (XW_WM_DECOR_X (xw))),
+                     (& (XW_WM_DECOR_Y (xw))),
+                     (& (XW_WM_DECOR_PIXEL_WIDTH (xw))),
+                     (& (XW_WM_DECOR_PIXEL_HEIGHT (xw))),
+                     (& (XW_WM_DECOR_BORDER_WIDTH (xw))),
+                     (&depth)))
+      || (any_x_errors_p (display)))
+    {
+      pop_x_error_info (handle);
+      error_external_return ();
+    }
+  pop_x_error_info (handle);
+  /* Return true iff the window has been reparented by the WM.  */
+  return (decor != (XW_WINDOW (xw)));
+}
 \f
 /* Open/Close Windows and Displays */
 
@@ -545,8 +617,9 @@ DEFUN (x_make_window, (xd, window, x_size, y_size, attributes, methods, extra),
      background_pixel);
   XDefineCursor (display, window, mouse_cursor);
   XSelectInput (display, window, 0);
-  xw =
-    (x_malloc (((sizeof (struct xwindow)) - (sizeof (xw -> extra))) + extra));
+  xw
+    = (x_malloc (((sizeof (struct xwindow)) - (sizeof (xw -> extra)))
+                + extra));
   (XW_ALLOCATION_INDEX (xw)) = (allocate_table_index ((&x_window_table), xw));
   (XW_XD (xw)) = xd;
   (XW_WINDOW (xw)) = window;
@@ -563,6 +636,9 @@ DEFUN (x_make_window, (xd, window, x_size, y_size, attributes, methods, extra),
   (XW_CURSOR_GC (xw)) = cursor_gc;
   (XW_MOUSE_CURSOR (xw)) = mouse_cursor;
   (XW_EVENT_MASK (xw)) = 0;
+  (XW_CHECK_EXPECTED_MOVE_P (xw)) = 0;
+  (XW_MOVE_OFFSET_X (xw)) = 0;
+  (XW_MOVE_OFFSET_Y (xw)) = 0;
   return (xw);
 }
 
@@ -644,7 +720,7 @@ DEFUN (xw_set_class_hint, (xw, name, class),
   (class_hint -> res_name) = ((char *) name);
   (class_hint -> res_class) = ((char *) class);
   XSetClassHint ((XW_DISPLAY (xw)), (XW_WINDOW (xw)), class_hint);
-  XFree ((PTR) class_hint);
+  XFree (class_hint);
 }
 
 void
@@ -658,7 +734,7 @@ DEFUN (xw_set_wm_input_hint, (xw, input_hint),
   (hints -> flags) = InputHint;
   (hints -> input) = (input_hint != 0);
   XSetWMHints ((XW_DISPLAY (xw)), (XW_WINDOW (xw)), hints);
-  XFree ((PTR) hints);
+  XFree (hints);
 }
 
 void
@@ -733,16 +809,16 @@ DEFUN (xw_make_window_map, (xw, resource_name, resource_class, map_p),
 \f
 /* Event Processing */
 
-static void
-DEFUN (xw_process_event, (xw, event),
-       struct xwindow * xw AND
-       XEvent * event)
+/* Returns non-zero value if caller should ignore the event.  */
+
+static int
+xw_process_event (struct xwindow * xw, XEvent * event)
 {
   if (x_debug > 0)
     {
       char * type_name;
-      fprintf (stderr, "\nX event: ");
-      switch (event -> type)
+      fprintf (stderr, "\nX event on 0x%lx: ", ((event->xany) . window));
+      switch (event->type)
        {
        case ButtonPress:       type_name = "ButtonPress"; break;
        case ButtonRelease:     type_name = "ButtonRelease"; break;
@@ -766,24 +842,44 @@ DEFUN (xw_process_event, (xw, event),
        case SelectionClear:    type_name = "SelectionClear"; break;
        case SelectionRequest:  type_name = "SelectionRequest"; break;
        case UnmapNotify:       type_name = "UnmapNotify"; break;
-       case VisibilityNotify:  type_name = "VisibilityNotify"; break;
+
+       case VisibilityNotify:
+         fprintf (stderr, "VisibilityNotify; state=");
+         switch ((event->xvisibility) . state)
+           {
+           case VisibilityUnobscured:
+             fprintf (stderr, "unobscured");
+             break;
+           case VisibilityPartiallyObscured:
+             fprintf (stderr, "partially-obscured");
+             break;
+           case VisibilityFullyObscured:
+             fprintf (stderr, "fully-obscured");
+             break;
+           default:
+             fprintf (stderr, "%d", ((event->xvisibility) . state));
+             break;
+           }
+         goto debug_done;
+
        case ConfigureNotify:
-         {
-           fprintf (stderr, "ConfigureNotify; width = %d, height = %d",
-                    ((event -> xconfigure) . width),
-                    ((event -> xconfigure) . height));
-           goto debug_done;
-         }
+         fprintf (stderr, "ConfigureNotify; x=%d y=%d width=%d height=%d",
+                  ((event->xconfigure) . x),
+                  ((event->xconfigure) . y),
+                  ((event->xconfigure) . width),
+                  ((event->xconfigure) . height));
+         goto debug_done;
+
        case ClientMessage:
          {
            struct xdisplay * xd = (XW_XD (xw));
-           if ((((event -> xclient) . message_type) == (XD_WM_PROTOCOLS (xd)))
-               && (((event -> xclient) . format) == 32))
+           if ((((event->xclient) . message_type) == (XD_WM_PROTOCOLS (xd)))
+               && (((event->xclient) . format) == 32))
              {
-               if (((Atom) (((event -> xclient) . data . l) [0]))
+               if (((Atom) (((event->xclient) . data . l) [0]))
                    == (XD_WM_DELETE_WINDOW (xd)))
                  type_name = "WM_DELETE_WINDOW";
-               else if (((Atom) (((event -> xclient) . data . l) [0]))
+               else if (((Atom) (((event->xclient) . data . l) [0]))
                         == (XD_WM_TAKE_FOCUS (xd)))
                  type_name = "WM_TAKE_FOCUS";
                else
@@ -791,35 +887,29 @@ DEFUN (xw_process_event, (xw, event),
              }
            else
              {
-               fprintf (stderr,
-                        "ClientMessage; message_type = 0x%x, format = %d",
-                        ((unsigned int) ((event -> xclient) . message_type)),
-                        ((event -> xclient) . format));
+               fprintf (stderr, "ClientMessage; message_type=0x%x format=%d",
+                        ((unsigned int) ((event->xclient) . message_type)),
+                        ((event->xclient) . format));
                goto debug_done;
              }
          }
          break;
        case PropertyNotify:
          {
-           fprintf
-             (stderr,
-              "PropertyNotify; window=%ld, atom=%ld, time=%ld, state=%d",
-              ((event -> xproperty) . window),
-              ((event -> xproperty) . atom),
-              ((event -> xproperty) . time),
-              ((event -> xproperty) . state));
+           fprintf (stderr, "PropertyNotify; atom=%ld time=%ld state=%d",
+                    ((event->xproperty) . atom),
+                    ((event->xproperty) . time),
+                    ((event->xproperty) . state));
            goto debug_done;
          }
        case SelectionNotify:
          {
            fprintf
-             (stderr,
-              "SelectionNotify; req=%ld, sel=%ld, targ=%ld, prop=%ld, t=%ld",
-              ((event -> xselection) . requestor),
-              ((event -> xselection) . selection),
-              ((event -> xselection) . target),
-              ((event -> xselection) . property),
-              ((event -> xselection) . time));
+             (stderr, "SelectionNotify; sel=%ld targ=%ld prop=%ld t=%ld",
+              ((event->xselection) . selection),
+              ((event->xselection) . target),
+              ((event->xselection) . property),
+              ((event->xselection) . time));
            goto debug_done;
          }
        default:                type_name = 0; break;
@@ -827,25 +917,47 @@ DEFUN (xw_process_event, (xw, event),
       if (type_name != 0)
        fprintf (stderr, "%s", type_name);
       else
-       fprintf (stderr, "%d", (event -> type));
+       fprintf (stderr, "%d", (event->type));
     debug_done:
-      fprintf (stderr, "\n");
+      fprintf (stderr, "%s\n",
+              (((event->xany) . send_event) ? "; synthetic" : ""));
       fflush (stderr);
     }
-  switch (event -> type)
+  switch (event->type)
     {
     case MappingNotify:
-      switch ((event -> xmapping) . request)
+      switch ((event->xmapping) . request)
        {
        case MappingKeyboard:
        case MappingModifier:
-         XRefreshKeyboardMapping (& (event -> xmapping));
+         XRefreshKeyboardMapping (& (event->xmapping));
          break;
        }
       break;
     }
   if (xw != 0)
-    (* (XW_EVENT_PROCESSOR (xw))) (xw, event);
+    {
+      switch (event->type)
+       {
+       case ReparentNotify:
+         get_wm_decor_geometry (xw);
+         /* Perhaps reparented due to a WM restart.  Reset this.  */
+         (XW_WM_TYPE (xw)) = X_WMTYPE_UNKNOWN;
+         break;
+
+       case ConfigureNotify:
+         /* If the window has been reparented, ignore non-synthetic
+            events.  */
+         if ((get_wm_decor_geometry (xw))
+             && (! ((event->xconfigure) . send_event)))
+           return (1);
+         if (XW_CHECK_EXPECTED_MOVE_P (xw))
+           check_expected_move (xw);
+         break;
+       }
+      (* (XW_EVENT_PROCESSOR (xw))) (xw, event);
+    }
+  return (0);
 }
 
 enum event_type
@@ -1357,7 +1469,8 @@ DEFUN (xd_process_events, (xd, non_block_p, use_select_p),
                   || ((event . type) == SelectionNotify)
                   || ((event . type) == SelectionRequest))))
          continue;
-       xw_process_event (xw, (&event));
+       if (xw_process_event (xw, (&event)))
+         continue;
       }
       (XD_CACHED_EVENT (xd)) = event;
       (XD_CACHED_EVENT_P (xd)) = 1;
@@ -1391,6 +1504,9 @@ DEFUN_VOID (initialize_once)
   allocation_table_initialize (&x_display_table);
   allocation_table_initialize (&x_window_table);
   allocation_table_initialize (&x_image_table);
+  ((x_error_info.message) [0]) = '\0';
+  (x_error_info.terminate_p) = 1;
+  (x_error_info.code) = 0;
   XSetErrorHandler (x_error_handler);
   XSetIOErrorHandler (x_io_error_handler);
   add_reload_cleanup (x_close_all_displays);
@@ -1973,29 +2089,20 @@ DEFINE_PRIMITIVE ("X-WINDOW-SET-INPUT-FOCUS", Prim_x_window_set_input_focus, 2,
 {
   PRIMITIVE_HEADER (2);
   {
-    PTR VOLATILE position = dstack_position;
     struct xwindow * xw = (x_window_arg (1));
-    unsigned char status;
+    Display * display = (XW_DISPLAY (xw));
+    void * handle = (push_x_error_info (display));
 
-    CATCH_X_ERRORS (status);
-    if (status == 0)
-      {
-       Display * display = (XW_DISPLAY (xw));
-       XSetInputFocus
-         (display,
-          (XW_WINDOW (xw)),
-          RevertToParent,
-          ((Time) (arg_ulong_integer (2))));
-       /* Force the message out now; otherwise the error-catching
-          code will be ineffective.  */
-       XSync (display, 0);
-      }
-    else
+    XSetInputFocus (display,
+                   (XW_WINDOW (xw)),
+                   RevertToParent,
+                   ((Time) (arg_ulong_integer (2))));
+    if (any_x_errors_p (display))
       {
-       dstack_set_position (position);
+       pop_x_error_info (handle);
        error_bad_range_arg (1);
       }
-    dstack_set_position (position);
+    pop_x_error_info (handle);
   }
   PRIMITIVE_RETURN (UNSPECIFIC);
 }
@@ -2098,39 +2205,18 @@ DEFINE_PRIMITIVE ("X-WINDOW-LOWER", Prim_x_window_lower, 1, 1, 0)
   PRIMITIVE_RETURN (UNSPECIFIC);
 }
 \f
-static Window
-DEFUN (get_window_frame, (display, w), Display * display AND Window w)
-{
-  Window root;
-  Window parent;
-  Window * children;
-  unsigned int n_children;
-  while (1)
-    {
-      if (! (XQueryTree (display, w,
-                        (&root), (&parent), (&children), (&n_children))))
-       error_external_return ();
-      XFree ((PTR) children);
-      if (parent == root)
-       return (w);
-      w = parent;
-    }
-}
-
 DEFINE_PRIMITIVE ("X-WINDOW-GET-SIZE", Prim_x_window_get_size, 1, 1, 0)
 {
   PRIMITIVE_HEADER (1);
   {
     struct xwindow * xw = (x_window_arg (1));
-    Display * display = (XW_DISPLAY (xw));
-    Window w = (get_window_frame (display, (XW_WINDOW (xw))));
-    XWindowAttributes a;
-    int extra;
-    if (! (XGetWindowAttributes (display, w, (&a))))
-      error_external_return ();
-    extra = (2 * (a . border_width));
-    PRIMITIVE_RETURN (cons ((long_to_integer ((a . width) + extra)),
-                           (long_to_integer ((a . height) + extra))));
+    unsigned int extra;
+
+    get_wm_decor_geometry (xw);
+    extra = (2 * (XW_WM_DECOR_BORDER_WIDTH (xw)));
+    PRIMITIVE_RETURN
+      (cons ((ulong_to_integer ((XW_WM_DECOR_PIXEL_WIDTH (xw)) + extra)),
+            (ulong_to_integer ((XW_WM_DECOR_PIXEL_HEIGHT (xw)) + extra))));
   }
 }
 
@@ -2139,58 +2225,63 @@ DEFINE_PRIMITIVE ("X-WINDOW-GET-POSITION", Prim_x_window_get_position, 1, 1, 0)
   PRIMITIVE_HEADER (1);
   {
     struct xwindow * xw = (x_window_arg (1));
-    Display * display = (XW_DISPLAY (xw));
-    Window w = (get_window_frame (display, (XW_WINDOW (xw))));
-    XWindowAttributes a;
-    if (! (XGetWindowAttributes (display, w, (&a))))
-      error_external_return ();
-    PRIMITIVE_RETURN (cons ((long_to_integer (a . x)),
-                           (long_to_integer (a . y))));
+    get_wm_decor_geometry (xw);
+    PRIMITIVE_RETURN (cons ((long_to_integer (XW_WM_DECOR_X (xw))),
+                           (long_to_integer (XW_WM_DECOR_Y (xw)))));
   }
 }
 
 DEFINE_PRIMITIVE ("X-WINDOW-SET-POSITION", Prim_x_window_set_position, 3, 3, 0)
 {
   PRIMITIVE_HEADER (3);
-  {
-    struct xwindow * xw = (x_window_arg (1));
-    int x = (arg_integer (2));
-    int y = (arg_integer (3));
-    Display * display = (XW_DISPLAY (xw));
-    Window me = (XW_WINDOW (xw));
-    Window frame = (get_window_frame (display, me));
-    if (me != frame)
-      {
-       int px;
-       int py;
-       Window child;
-
-       if (! (XTranslateCoordinates
-              (display, me, frame, x, y, (&px), (&py), (&child))))
-         error_bad_range_arg (1);
-       x = px;
-       y = py;
-      }
-    /* This is a kludge; Emacs does the same thing.  Apparently,
-       failing to do this results in incorrect behavior, but the need
-       for this offset is not documented and the Emacs maintainers are
-       mystified as to why it is necessary.  */
+  move_window ((x_window_arg (1)),
+              (arg_integer (2)),
+              (arg_integer (3)));
+  PRIMITIVE_RETURN (UNSPECIFIC);
+}
+
+static void
+move_window (struct xwindow * xw, int x, int y)
+{
+  if ((XW_UPDATE_NORMAL_HINTS (xw)) != 0)
+    (* (XW_UPDATE_NORMAL_HINTS (xw))) (xw);
+  if ((XW_WM_TYPE (xw)) == X_WMTYPE_A)
     {
-      XWindowAttributes a;
-      if (! (XGetWindowAttributes (display, frame, (&a))))
-       error_external_return ();
-      x += (a . border_width);
-      y += (a . border_width);
+      x += (XW_MOVE_OFFSET_X (xw));
+      y += (XW_MOVE_OFFSET_Y (xw));
+    }
+  XMoveWindow ((XW_DISPLAY (xw)), (XW_WINDOW (xw)), x, y);
+  if ((XW_WM_TYPE (xw)) == X_WMTYPE_UNKNOWN)
+    {
+      (XW_EXPECTED_X (xw)) = x;
+      (XW_EXPECTED_Y (xw)) = y;
+      (XW_CHECK_EXPECTED_MOVE_P (xw)) = 1;
     }
-    XMoveWindow (display, me, x, y);
-  }
-  PRIMITIVE_RETURN (UNSPECIFIC);
+}
+
+static void
+check_expected_move (struct xwindow * xw)
+{
+  if (((XW_WM_DECOR_X (xw)) == (XW_EXPECTED_X (xw)))
+      && ((XW_WM_DECOR_Y (xw)) == (XW_EXPECTED_Y (xw))))
+    {
+      if ((XW_WM_TYPE (xw)) == X_WMTYPE_UNKNOWN)
+       (XW_WM_TYPE (xw)) = X_WMTYPE_B;
+    }
+  else
+    {
+      (XW_WM_TYPE (xw)) = X_WMTYPE_A;
+      (XW_MOVE_OFFSET_X (xw)) = ((XW_EXPECTED_X (xw)) - (XW_WM_DECOR_X (xw)));
+      (XW_MOVE_OFFSET_Y (xw)) = ((XW_EXPECTED_Y (xw)) - (XW_WM_DECOR_Y (xw)));
+      move_window (xw, (XW_EXPECTED_X (xw)), (XW_EXPECTED_Y (xw)));
+    }
+  (XW_CHECK_EXPECTED_MOVE_P (xw)) = 0;
 }
 \f
 /* Font Structure Primitive */
 
 #define FONT_STRUCTURE_MAX_CONVERTED_SIZE (10+1 + 256+1 + ((5+1) * (256+2)))
-  /* font-structure-words  +
+  /* font-structure-words +
      char-struct-vector +
      char-struct-words * maximum-number-possible */
 
@@ -2354,22 +2445,18 @@ DEFINE_PRIMITIVE ("X-GET-ATOM-NAME", Prim_x_get_atom_name, 2, 2, 0)
 {
   PRIMITIVE_HEADER (2);
   {
-    PTR VOLATILE position = dstack_position;
-    unsigned char status;
-    SCHEME_OBJECT result;
-
-    CATCH_X_ERRORS (status);
-    if (status == 0)
-      {
-       char * name
-         = (XGetAtomName ((XD_DISPLAY (x_display_arg (1))),
-                          (arg_ulong_integer (2))));
-       result = (char_pointer_to_string ((unsigned char *) name));
-       XFree (name);
-      }
-    else
-      result = (ulong_to_integer (status));
-    dstack_set_position (position);
+    struct xdisplay * xd = (x_display_arg (1));
+    Display * display = (XD_DISPLAY (xd));
+    void * handle = (push_x_error_info (display));
+    char * name = (XGetAtomName (display, (arg_ulong_integer (2))));
+    unsigned char error_code = (x_error_code (display));
+    SCHEME_OBJECT result
+      = ((error_code == 0)
+        ? (char_pointer_to_string ((unsigned char *) name))
+        : (ulong_to_integer (error_code)));
+    if (name != 0)
+      XFree (name);
+    pop_x_error_info (handle);
     PRIMITIVE_RETURN (result);
   }
 }
@@ -2400,14 +2487,14 @@ DEFUN (char_ptr_to_prop_data_16, (data, nitems),
   return (result);
 }
 
-static CONST char *
+static const unsigned char *
 DEFUN (prop_data_32_to_char_ptr, (vector, length_return),
        SCHEME_OBJECT vector AND
        unsigned long * length_return)
 {
   unsigned long nitems = (VECTOR_LENGTH (vector));
   unsigned long length = (nitems * 4);
-  char * data = (dstack_alloc (length));
+  unsigned char * data = (dstack_alloc (length));
   unsigned long index;
   for (index = 0; (index < nitems); index += 1)
     {
@@ -2420,14 +2507,14 @@ DEFUN (prop_data_32_to_char_ptr, (vector, length_return),
   return (data);
 }
 
-static CONST char *
+static const unsigned char *
 DEFUN (prop_data_16_to_char_ptr, (vector, length_return),
        SCHEME_OBJECT vector AND
        unsigned long * length_return)
 {
   unsigned long nitems = (VECTOR_LENGTH (vector));
   unsigned long length = (nitems * 2);
-  char * data = (dstack_alloc (length));
+  unsigned char * data = (dstack_alloc (length));
   unsigned long index;
   for (index = 0; (index < nitems); index += 1)
     {
@@ -2501,16 +2588,16 @@ DEFINE_PRIMITIVE ("X-CHANGE-PROPERTY", Prim_x_change_property, 7, 7, 0)
 {
   PRIMITIVE_HEADER (7);
   {
-    PTR VOLATILE position = dstack_position;
     Display * display = (XD_DISPLAY (x_display_arg (1)));
     Window window = (arg_ulong_integer (2));
     Atom property = (arg_ulong_integer (3));
     Atom type = (arg_ulong_integer (4));
     int format = (arg_nonnegative_integer (5));
     int mode = (arg_index_integer (6, 3));
-    CONST char * VOLATILE data = 0;
+    const unsigned char * data = 0;
     unsigned long dlen;
-    unsigned char status;
+    void * handle;
+    unsigned char error_code;
 
     switch (format)
       {
@@ -2535,17 +2622,12 @@ DEFINE_PRIMITIVE ("X-CHANGE-PROPERTY", Prim_x_change_property, 7, 7, 0)
        error_bad_range_arg (5);
        break;
       }
-    CATCH_X_ERRORS (status);
-    if (status == 0)
-      {
-       XChangeProperty (display, window, property, type, format, mode,
-                        data, dlen);
-       /* Flush the display queue, because we need to see the errors
-          immediately while we're looking for them.  */
-       XFlush (display);
-      }
-    dstack_set_position (position);
-    PRIMITIVE_RETURN (ulong_to_integer (status));
+
+    handle = (push_x_error_info (display));
+    XChangeProperty (display, window, property, type, format, mode, data, dlen);
+    error_code = (x_error_code (display));
+    pop_x_error_info (handle);
+    PRIMITIVE_RETURN (ulong_to_integer (error_code));
   }
 }
 
index 77522ce69ff477d1cd40194db5581bae89d70c4b..fff16f424b439c277089d93e2207027004e5c748 100644 (file)
@@ -1,8 +1,9 @@
 /* -*-C-*-
 
-$Id: x11term.c,v 1.29 2003/02/14 18:28:24 cph Exp $
+$Id: x11term.c,v 1.30 2005/11/12 22:53:36 cph Exp $
 
-Copyright (c) 1989-2000 Massachusetts Institute of Technology
+Copyright 1989,1990,1991,1992,1993,1995 Massachusetts Institute of Technology
+Copyright 2000,2005 Massachusetts Institute of Technology
 
 This file is part of MIT/GNU Scheme.
 
@@ -167,39 +168,20 @@ DEFUN (xterm_make_size_hints, (font, extra),
 }
 
 static void
-DEFUN (xterm_set_wm_normal_hints, (xw, size_hints, geometry_mask, x, y),
-       struct xwindow * xw AND
-       XSizeHints * size_hints AND
-       int geometry_mask AND
-       unsigned int x AND
-       unsigned int y)
-{
-  (size_hints -> flags) |=
-    ((((geometry_mask & XValue) && (geometry_mask & YValue))
-      ? USPosition : PPosition)
-     | (((geometry_mask & WidthValue) && (geometry_mask & HeightValue))
-       ? USSize : PSize));
-  (size_hints -> x) = x;
-  (size_hints -> y) = y;
-  (size_hints -> width) =
-    (((XW_X_CSIZE (xw)) * (size_hints -> width_inc))
-     + (size_hints -> base_width));
-  (size_hints -> height) =
-    (((XW_Y_CSIZE (xw)) * (size_hints -> height_inc))
-     + (size_hints -> base_height));
+xterm_set_wm_normal_hints (struct xwindow * xw, XSizeHints * size_hints)
+{
   XSetWMNormalHints ((XW_DISPLAY (xw)), (XW_WINDOW (xw)), size_hints);
-  XFree ((caddr_t) size_hints);
+  XFree ((void *) size_hints);
 }
 
 static void
-DEFUN (xterm_update_normal_hints, (xw), struct xwindow * xw)
+xterm_update_normal_hints (struct xwindow * xw)
 {
   xterm_set_wm_normal_hints
     (xw,
      (xterm_make_size_hints
       ((XW_FONT (xw)),
-       (2 * (XW_INTERNAL_BORDER_WIDTH (xw))))),
-     0, 0, 0);
+       (2 * (XW_INTERNAL_BORDER_WIDTH (xw))))));
 }
 
 static void
@@ -582,8 +564,7 @@ DEFINE_PRIMITIVE ("XTERM-OPEN-WINDOW", Prim_xterm_open_window, 3, 3, 0)
            (*scan++) = DEFAULT_HL;
        }
        (size_hints -> flags) |= PWinGravity;
-       xterm_set_wm_normal_hints
-         (xw, size_hints, geometry_mask, x_pos, y_pos);
+       xterm_set_wm_normal_hints (xw, size_hints);
        xw_set_wm_input_hint (xw, 1);
        xw_set_wm_name (xw, "scheme-terminal");
        xw_set_wm_icon_name (xw, "scheme-terminal");