emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master f38bdb0327 1/2: Take window shapes into account when processing d


From: Po Lu
Subject: master f38bdb0327 1/2: Take window shapes into account when processing drag and drop
Date: Fri, 25 Mar 2022 04:23:02 -0400 (EDT)

branch: master
commit f38bdb0327c5806286ab97687e2823d65d8e184a
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    Take window shapes into account when processing drag and drop
    
    * configure.ac: Test for the Nonrectangular Window Shape
    extension.
    * msdos/sed1v2.inp: Update.
    * src/xterm.c (struct x_client_list_window): New fields for
    shapes.
    (x_dnd_free_toplevels): Free shapes.
    (x_dnd_compute_toplevels): Populate window shapes.
    (x_dnd_get_target_window_2): New function.
    (x_dnd_get_target_window_1): Test WM state of window before
    taking it into account.
    (x_dnd_begin_drag_and_drop): Use outer window as the initial
    last seen window.
    (x_dnd_update_state): Small fixes to frame tracking.
    (handle_one_xevent): Handle ShapeNotify events correctly.
    (x_term_init): Test for the Nonrectangular Window Shape
    extension.
    * src/xterm.h (struct x_display_info): New atom `WM_STATE'.
---
 configure.ac     |  18 +++
 msdos/sed1v2.inp |   2 +
 src/xterm.c      | 403 ++++++++++++++++++++++++++++++++++++++++++++++++++++---
 src/xterm.h      |   9 ++
 4 files changed, 410 insertions(+), 22 deletions(-)

diff --git a/configure.ac b/configure.ac
index 6e63747733..4ac8c143e5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4538,6 +4538,24 @@ fi
 AC_SUBST(XDBE_CFLAGS)
 AC_SUBST(XDBE_LIBS)
 
+### Use the Nonrectangular Window Shape extension if available.
+HAVE_XSHAPE=no
+if test "${HAVE_X11}" = "yes"; then
+  AC_CHECK_HEADER(X11/extensions/shape.h,
+    [AC_CHECK_LIB(Xext, XShapeQueryVersion, HAVE_XSHAPE=yes)],
+    [],
+    [#include <X11/extensions/shape.h>
+    ])
+  if test $HAVE_XSHAPE = yes; then
+    XSHAPE_LIBS=-lXext
+  fi
+  if test $HAVE_XSHAPE = yes; then
+    AC_DEFINE(HAVE_XSHAPE, 1, [Define to 1 if you have the Nonrectangular 
Window Shape extension.])
+  fi
+fi
+AC_SUBST(XSHAPE_CFLAGS)
+AC_SUBST(XSHAPE_LIBS)
+
 ### Use Xcomposite (-lXcomposite) if available
 HAVE_XCOMPOSITE=no
 if test "${HAVE_X11}" = "yes"; then
diff --git a/msdos/sed1v2.inp b/msdos/sed1v2.inp
index 24ae079db1..4cc733ee79 100644
--- a/msdos/sed1v2.inp
+++ b/msdos/sed1v2.inp
@@ -119,6 +119,8 @@ s/ *@WEBP_LIBS@//
 /^XDBE_CFLAGS *=/s/@XDBE_CFLAGS@//
 /^XCOMPOSITE_LIBS *=/s/@XCOMPOSITE_LIBS@//
 /^XCOMPOSITE_CFLAGS *=/s/@XCOMPOSITE_CFLAGS@//
+/^XSHAPE_LIBS *=/s/@XSHAPE_LIBS@//
+/^XSHAPE_CFLAGS *=/s/@XSHAPE_CFLAGS@//
 /^XINPUT_LIBS *=/s/@XINPUT_LIBS@//
 /^XINPUT_CFLAGS *=/s/@XINPUT_CFLAGS@//
 /^XSYNC_LIBS *=/s/@XSYNC_LIBS@//
diff --git a/src/xterm.c b/src/xterm.c
index 0267ba7ec1..cd651f4667 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -546,6 +546,10 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
 #include <X11/extensions/Xcomposite.h>
 #endif
 
+#ifdef HAVE_XSHAPE
+#include <X11/extensions/shape.h>
+#endif
+
 /* Load sys/types.h if not already loaded.
    In some systems loading it twice is suicidal.  */
 #ifndef makedev
@@ -826,10 +830,21 @@ struct x_client_list_window
   Display *dpy;
   int x, y;
   int width, height;
-  bool visible_p;
+  bool mapped_p;
   long previous_event_mask;
+  unsigned long wm_state;
 
   struct x_client_list_window *next;
+
+#ifdef HAVE_XSHAPE
+  int border_width;
+
+  XRectangle *input_rects;
+  int n_input_rects;
+
+  XRectangle *bounding_rects;
+  int n_bounding_rects;
+#endif
 };
 
 static struct x_client_list_window *x_dnd_toplevels = NULL;
@@ -849,7 +864,18 @@ x_dnd_free_toplevels (void)
       x_catch_errors (last->dpy);
       XSelectInput (last->dpy, last->window,
                    last->previous_event_mask);
+#ifdef HAVE_XSHAPE
+      XShapeSelectInput (last->dpy, last->window, None);
+#endif
       x_uncatch_errors ();
+
+#ifdef HAVE_XSHAPE
+      if (last->n_input_rects != -1)
+       xfree (last->input_rects);
+      if (last->n_bounding_rects != -1)
+       xfree (last->bounding_rects);
+#endif
+
       xfree (last);
     }
 
@@ -862,11 +888,15 @@ x_dnd_compute_toplevels (struct x_display_info *dpyinfo)
   Atom type;
   Window *toplevels, child;
   int format, rc, dest_x, dest_y;
-  unsigned long nitems, bytes_after;
-  unsigned char *data = NULL;
+  unsigned long nitems, wmstate_items, bytes_after, *wmstate;
+  unsigned char *data = NULL, *wmstate_data = NULL;
   unsigned long i;
   XWindowAttributes attrs;
   struct x_client_list_window *tem;
+#ifdef HAVE_XSHAPE
+  int count, ordering;
+  XRectangle *rects;
+#endif
 
   rc = XGetWindowProperty (dpyinfo->display, dpyinfo->root_window,
                           dpyinfo->Xatom_net_client_list_stacking,
@@ -899,10 +929,22 @@ x_dnd_compute_toplevels (struct x_display_info *dpyinfo)
                                     -attrs.border_width, &dest_x,
                                     &dest_y, &child)
              && !x_had_errors_p (dpyinfo->display));
+      if (rc)
+       rc = ((XGetWindowProperty (dpyinfo->display,
+                                  toplevels[i],
+                                  dpyinfo->Xatom_wm_state,
+                                  0, 2, False, AnyPropertyType,
+                                  &type, &format, &wmstate_items,
+                                  &bytes_after, &wmstate_data)
+              == Success)
+             && !x_had_errors_p (dpyinfo->display)
+             && wmstate_data && wmstate_items == 2 && format == 32);
       x_uncatch_errors_after_check ();
 
       if (rc)
        {
+         wmstate = (unsigned long *) wmstate_data;
+
          tem = xmalloc (sizeof *tem);
          tem->window = toplevels[i];
          tem->dpy = dpyinfo->display;
@@ -910,13 +952,93 @@ x_dnd_compute_toplevels (struct x_display_info *dpyinfo)
          tem->y = dest_y;
          tem->width = attrs.width + attrs.border_width;
          tem->height = attrs.height + attrs.border_width;
-         tem->visible_p = (attrs.map_state == IsViewable);
+         tem->mapped_p = (attrs.map_state != IsUnmapped);
          tem->next = x_dnd_toplevels;
          tem->previous_event_mask = attrs.your_event_mask;
+         tem->wm_state = wmstate[0];
+
+         XFree (wmstate_data);
+
+#ifdef HAVE_XSHAPE
+         tem->border_width = attrs.border_width;
+         tem->n_bounding_rects = -1;
+         tem->n_input_rects = -1;
+
+         if (dpyinfo->xshape_supported_p)
+           {
+             x_catch_errors (dpyinfo->display);
+             XShapeSelectInput (dpyinfo->display,
+                                toplevels[i],
+                                ShapeNotifyMask);
+             x_uncatch_errors ();
+
+             x_catch_errors (dpyinfo->display);
+             rects = XShapeGetRectangles (dpyinfo->display,
+                                          toplevels[i],
+                                          ShapeBounding,
+                                          &count, &ordering);
+             rc = x_had_errors_p (dpyinfo->display);
+             x_uncatch_errors_after_check ();
+
+             /* Does XShapeGetRectangles allocate anything upon an
+                error?  */
+             if (!rc)
+               {
+                 tem->n_bounding_rects = count;
+                 tem->bounding_rects
+                   = xmalloc (sizeof *tem->bounding_rects * count);
+                 memcpy (tem->bounding_rects, rects,
+                         sizeof *tem->bounding_rects * count);
+
+                 XFree (rects);
+               }
+
+#ifdef ShapeInput
+             if (dpyinfo->xshape_major > 1
+                 || (dpyinfo->xshape_major == 1
+                     && dpyinfo->xshape_minor >= 1))
+               {
+                 x_catch_errors (dpyinfo->display);
+                 rects = XShapeGetRectangles (dpyinfo->display,
+                                              toplevels[i], ShapeInput,
+                                              &count, &ordering);
+                 rc = x_had_errors_p (dpyinfo->display);
+                 x_uncatch_errors_after_check ();
+
+                 /* Does XShapeGetRectangles allocate anything upon
+                    an error?  */
+                 if (!rc)
+                   {
+                     tem->n_input_rects = count;
+                     tem->input_rects
+                       = xmalloc (sizeof *tem->input_rects * count);
+                     memcpy (tem->input_rects, rects,
+                             sizeof *tem->input_rects * count);
+
+                     XFree (rects);
+                   }
+               }
+#endif
+           }
+
+         /* Handle the common case where the input shape equals the
+            bounding shape.  */
+
+         if (tem->n_input_rects != -1
+             && tem->n_bounding_rects == tem->n_input_rects
+             && !memcmp (tem->bounding_rects, tem->input_rects,
+                         tem->n_input_rects * sizeof *tem->input_rects))
+           {
+             xfree (tem->input_rects);
+             tem->n_input_rects = -1;
+           }
+#endif
 
          x_catch_errors (dpyinfo->display);
          XSelectInput (dpyinfo->display, toplevels[i],
-                       attrs.your_event_mask | StructureNotifyMask);
+                       (attrs.your_event_mask
+                        | StructureNotifyMask
+                        | PropertyChangeMask));
          x_uncatch_errors ();
 
          x_dnd_toplevels = tem;
@@ -931,6 +1053,28 @@ x_dnd_compute_toplevels (struct x_display_info *dpyinfo)
 static int x_dnd_get_window_proto (struct x_display_info *, Window);
 static Window x_dnd_get_window_proxy (struct x_display_info *, Window);
 
+#ifdef HAVE_XSHAPE
+static bool
+x_dnd_get_target_window_2 (XRectangle *rects, int nrects,
+                          int x, int y)
+{
+  int i;
+  XRectangle *tem;
+
+  for (i = 0; i < nrects; ++i)
+    {
+      tem = &rects[i];
+
+      if (x >= tem->x && y >= tem->y
+         && x < tem->x + tem->width
+         && y < tem->y + tem->height)
+       return true;
+    }
+
+  return false;
+}
+#endif
+
 static Window
 x_dnd_get_target_window_1 (struct x_display_info *dpyinfo,
                           int root_x, int root_y)
@@ -942,13 +1086,33 @@ x_dnd_get_target_window_1 (struct x_display_info 
*dpyinfo,
 
   for (tem = x_dnd_toplevels; tem; tem = tem->next)
     {
-      if (!tem->visible_p)
+      if (!tem->mapped_p || tem->wm_state != NormalState)
        continue;
 
       if (root_x >= tem->x && root_y >= tem->y
          && root_x < tem->x + tem->width
          && root_y < tem->y + tem->height)
-       return tem->window;
+       {
+#ifdef HAVE_XSHAPE
+         if (tem->n_bounding_rects == -1)
+#endif
+           return tem->window;
+
+#ifdef HAVE_XSHAPE
+         if (x_dnd_get_target_window_2 (tem->bounding_rects,
+                                        tem->n_bounding_rects,
+                                        tem->border_width + root_x - tem->x,
+                                        tem->border_width + root_y - tem->y))
+           {
+             if (tem->n_input_rects == -1
+                 || x_dnd_get_target_window_2 (tem->input_rects,
+                                               tem->n_input_rects,
+                                               tem->border_width + root_x - 
tem->x,
+                                               tem->border_width + root_y - 
tem->y))
+               return tem->window;
+           }
+#endif
+       }
     }
 
   return None;
@@ -7230,7 +7394,7 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, 
Atom xaction,
 
   x_dnd_in_progress = true;
   x_dnd_frame = f;
-  x_dnd_last_seen_window = FRAME_X_WINDOW (f);
+  x_dnd_last_seen_window = FRAME_OUTER_WINDOW (f);
   x_dnd_last_protocol_version = -1;
   x_dnd_mouse_rect_target = None;
   x_dnd_action = None;
@@ -10983,10 +11147,10 @@ x_dnd_update_state (struct x_display_info *dpyinfo)
        {
          if (x_dnd_last_seen_window != None
              && x_dnd_last_protocol_version != -1
-             && x_dnd_last_seen_window != FRAME_X_WINDOW (x_dnd_frame))
+             && x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame))
            x_dnd_send_leave (x_dnd_frame, x_dnd_last_seen_window);
 
-         if (x_dnd_last_seen_window == FRAME_X_WINDOW (x_dnd_frame)
+         if (target != FRAME_OUTER_WINDOW (x_dnd_frame)
              && x_dnd_return_frame == 1)
            x_dnd_return_frame = 2;
 
@@ -10999,6 +11163,8 @@ x_dnd_update_state (struct x_display_info *dpyinfo)
              x_dnd_return_frame_object
                = x_any_window_to_frame (dpyinfo, target);
              x_dnd_return_frame = 3;
+             x_dnd_waiting_for_finish = false;
+             target = None;
            }
 
          x_dnd_action = None;
@@ -11018,7 +11184,7 @@ x_dnd_update_state (struct x_display_info *dpyinfo)
                             x_dnd_wanted_action);
     }
   /* The pointer moved out of the screen.  */
-  else if (x_dnd_last_protocol_version)
+  else if (x_dnd_last_protocol_version != -1)
     {
       if (x_dnd_last_seen_window != None
          && x_dnd_last_protocol_version != -1)
@@ -11028,6 +11194,7 @@ x_dnd_update_state (struct x_display_info *dpyinfo)
       x_dnd_end_window = x_dnd_last_seen_window;
       x_dnd_last_seen_window = None;
       x_dnd_in_progress = false;
+      x_dnd_waiting_for_finish = false;
       x_dnd_frame = NULL;
     }
 }
@@ -11464,6 +11631,65 @@ handle_one_xevent (struct x_display_info *dpyinfo,
       break;
 
     case PropertyNotify:
+      if (x_dnd_in_progress && x_dnd_use_toplevels
+         && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame)
+         && event->xproperty.atom == dpyinfo->Xatom_wm_state)
+       {
+         struct x_client_list_window *tem, *last;
+
+         for (last = NULL, tem = x_dnd_toplevels; tem;
+              last = tem, tem = tem->next)
+           {
+             if (tem->window == event->xproperty.window)
+               {
+                 Atom actual_type;
+                 int actual_format, rc;
+                 unsigned long nitems, bytesafter;
+                 unsigned char *data = NULL;
+
+
+                 if (event->xproperty.state == PropertyDelete)
+                   {
+                     if (!last)
+                       x_dnd_toplevels = tem->next;
+                     else
+                       last->next = tem->next;
+
+#ifdef HAVE_XSHAPE
+                     if (tem->n_input_rects != -1)
+                       xfree (tem->input_rects);
+                     if (tem->n_bounding_rects != -1)
+                       xfree (tem->bounding_rects);
+#endif
+                     xfree (tem);
+                   }
+                 else
+                   {
+                     x_catch_errors (dpyinfo->display);
+                     rc = XGetWindowProperty (dpyinfo->display,
+                                              event->xproperty.window,
+                                              dpyinfo->Xatom_wm_state,
+                                              0, 2, False, AnyPropertyType,
+                                              &actual_type, &actual_format,
+                                              &nitems, &bytesafter, &data);
+
+                     if (!x_had_errors_p (dpyinfo->display) && rc == Success 
&& data
+                         && nitems == 2 && actual_format == 32)
+                       {
+                         tem->wm_state = ((unsigned long *) data)[0];
+                         XFree (data);
+                       }
+                     else
+                       tem->wm_state = WithdrawnState;
+                     x_uncatch_errors_after_check ();
+                   }
+
+                 x_dnd_update_state (dpyinfo);
+                 break;
+               }
+           }
+       }
+
       f = x_top_window_to_frame (dpyinfo, event->xproperty.window);
       if (f && event->xproperty.atom == dpyinfo->Xatom_net_wm_state)
        {
@@ -11697,14 +11923,15 @@ handle_one_xevent (struct x_display_info *dpyinfo,
       break;
 
     case UnmapNotify:
-      if (x_dnd_in_progress && x_dnd_use_toplevels)
+      if (x_dnd_in_progress && x_dnd_use_toplevels
+         && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
        {
          for (struct x_client_list_window *tem = x_dnd_toplevels; tem;
               tem = tem->next)
            {
-             if (tem->window == event->xmap.window)
+             if (tem->window == event->xunmap.window)
                {
-                 tem->visible_p = false;
+                 tem->mapped_p = false;
                  break;
                }
            }
@@ -11758,14 +11985,15 @@ handle_one_xevent (struct x_display_info *dpyinfo,
       if (x_dnd_in_progress)
        x_dnd_update_state (dpyinfo);
 
-      if (x_dnd_in_progress && x_dnd_use_toplevels)
+      if (x_dnd_in_progress && x_dnd_use_toplevels
+         && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
        {
          for (struct x_client_list_window *tem = x_dnd_toplevels; tem;
               tem = tem->next)
            {
              if (tem->window == event->xmap.window)
                {
-                 tem->visible_p = true;
+                 tem->mapped_p = true;
                  break;
                }
            }
@@ -12389,10 +12617,10 @@ handle_one_xevent (struct x_display_info *dpyinfo,
              {
                if (x_dnd_last_seen_window != None
                    && x_dnd_last_protocol_version != -1
-                   && x_dnd_last_seen_window != FRAME_X_WINDOW (x_dnd_frame))
+                   && x_dnd_last_seen_window != FRAME_OUTER_WINDOW 
(x_dnd_frame))
                  x_dnd_send_leave (x_dnd_frame, x_dnd_last_seen_window);
 
-               if (x_dnd_last_seen_window == FRAME_X_WINDOW (x_dnd_frame)
+               if (target != FRAME_OUTER_WINDOW (x_dnd_frame)
                    && x_dnd_return_frame == 1)
                  x_dnd_return_frame = 2;
 
@@ -12405,6 +12633,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
                    x_dnd_return_frame_object
                      = x_any_window_to_frame (dpyinfo, target);
                    x_dnd_return_frame = 3;
+                   x_dnd_waiting_for_finish = false;
+                   target = None;
                  }
 
                x_dnd_action = None;
@@ -12547,7 +12777,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
            configureEvent = next_event;
         }
 
-      if (x_dnd_in_progress && x_dnd_use_toplevels)
+      if (x_dnd_in_progress && x_dnd_use_toplevels
+         && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
        {
          int rc, dest_x, dest_y;
          Window child;
@@ -12589,6 +12820,12 @@ handle_one_xevent (struct x_display_info *dpyinfo,
                      else
                        last->next = tem->next;
 
+#ifdef HAVE_XSHAPE
+                     if (tem->n_input_rects != -1)
+                       xfree (tem->input_rects);
+                     if (tem->n_bounding_rects != -1)
+                       xfree (tem->bounding_rects);
+#endif
                      xfree (tem);
                    }
 
@@ -13699,20 +13936,24 @@ handle_one_xevent (struct x_display_info *dpyinfo,
                    {
                      if (x_dnd_last_seen_window != None
                          && x_dnd_last_protocol_version != -1
-                         && x_dnd_last_seen_window != FRAME_X_WINDOW 
(x_dnd_frame))
+                         && x_dnd_last_seen_window != FRAME_OUTER_WINDOW 
(x_dnd_frame))
                        x_dnd_send_leave (x_dnd_frame, x_dnd_last_seen_window);
 
-                     if (x_dnd_last_seen_window == FRAME_X_WINDOW (x_dnd_frame)
+                     if (target != FRAME_OUTER_WINDOW (x_dnd_frame)
                          && x_dnd_return_frame == 1)
                        x_dnd_return_frame = 2;
 
                      if (x_dnd_return_frame == 2
                          && x_any_window_to_frame (dpyinfo, target))
                        {
+                         x_dnd_end_window = x_dnd_last_seen_window;
+                         x_dnd_last_seen_window = None;
                          x_dnd_in_progress = false;
                          x_dnd_return_frame_object
                            = x_any_window_to_frame (dpyinfo, target);
                          x_dnd_return_frame = 3;
+                         x_dnd_waiting_for_finish = false;
+                         target = None;
                        }
 
                      x_dnd_action = None;
@@ -15043,7 +15284,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 
     default:
 #ifdef HAVE_XKB
-      if (event->type == dpyinfo->xkb_event_type)
+      if (dpyinfo->supports_xkb
+         && event->type == dpyinfo->xkb_event_type)
        {
          XkbEvent *xkbevent = (XkbEvent *) event;
 
@@ -15088,6 +15330,109 @@ handle_one_xevent (struct x_display_info *dpyinfo,
              x_find_modifier_meanings (dpyinfo);
            }
        }
+#endif
+#ifdef HAVE_XSHAPE
+      if (dpyinfo->xshape_supported_p
+         && event->type == dpyinfo->xshape_event_base + ShapeNotify
+         && x_dnd_in_progress && x_dnd_use_toplevels
+         && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
+       {
+         XEvent xevent;
+         XShapeEvent *xse = (XShapeEvent *) event;
+         XRectangle *rects;
+         int rc, ordering;
+
+         while (XPending (dpyinfo->display))
+           {
+             XNextEvent (dpyinfo->display, &xevent);
+
+             if (xevent.type == dpyinfo->xshape_event_base + ShapeNotify
+                 && ((XShapeEvent *) &xevent)->window == xse->window)
+               xse = (XShapeEvent *) &xevent;
+             else
+               {
+                 XPutBackEvent (dpyinfo->display, &xevent);
+                 break;
+               }
+           }
+
+         for (struct x_client_list_window *tem = x_dnd_toplevels; tem;
+              tem = tem->next)
+           {
+             if (tem->window == xse->window)
+               {
+                 if (tem->n_input_rects != -1)
+                   xfree (tem->input_rects);
+                 if (tem->n_bounding_rects != -1)
+                   xfree (tem->bounding_rects);
+
+                 tem->n_input_rects = -1;
+                 tem->n_bounding_rects = -1;
+
+                 x_catch_errors (dpyinfo->display);
+                 rects = XShapeGetRectangles (dpyinfo->display,
+                                              xse->window,
+                                              ShapeBounding,
+                                              &count, &ordering);
+                 rc = x_had_errors_p (dpyinfo->display);
+                 x_uncatch_errors_after_check ();
+
+                 /* Does XShapeGetRectangles allocate anything upon an
+                    error?  */
+                 if (!rc)
+                   {
+                     tem->n_bounding_rects = count;
+                     tem->bounding_rects
+                       = xmalloc (sizeof *tem->bounding_rects * count);
+                     memcpy (tem->bounding_rects, rects,
+                             sizeof *tem->bounding_rects * count);
+
+                     XFree (rects);
+                   }
+
+#ifdef ShapeInput
+                 if (dpyinfo->xshape_major > 1
+                     || (dpyinfo->xshape_major == 1
+                         && dpyinfo->xshape_minor >= 1))
+                   {
+                     x_catch_errors (dpyinfo->display);
+                     rects = XShapeGetRectangles (dpyinfo->display,
+                                                  xse->window, ShapeInput,
+                                                  &count, &ordering);
+                     rc = x_had_errors_p (dpyinfo->display);
+                     x_uncatch_errors_after_check ();
+
+                     /* Does XShapeGetRectangles allocate anything upon
+                        an error?  */
+                     if (!rc)
+                       {
+                         tem->n_input_rects = count;
+                         tem->input_rects
+                           = xmalloc (sizeof *tem->input_rects * count);
+                         memcpy (tem->input_rects, rects,
+                                 sizeof *tem->input_rects * count);
+
+                         XFree (rects);
+                       }
+                   }
+#endif
+
+                 /* Handle the common case where the input shape equals the
+                    bounding shape.  */
+
+                 if (tem->n_input_rects != -1
+                     && tem->n_bounding_rects == tem->n_input_rects
+                     && !memcmp (tem->bounding_rects, tem->input_rects,
+                                 tem->n_input_rects * sizeof 
*tem->input_rects))
+                   {
+                     xfree (tem->input_rects);
+                     tem->n_input_rects = -1;
+                   }
+
+                 break;
+               }
+           }
+       }
 #endif
     OTHER:
 #ifdef USE_X_TOOLKIT
@@ -19011,6 +19356,19 @@ x_term_init (Lisp_Object display_name, char 
*xrm_option, char *resource_name)
                                &dpyinfo->composite_minor);
 #endif
 
+#ifdef HAVE_XSHAPE
+  dpyinfo->xshape_supported_p
+    = XShapeQueryExtension (dpyinfo->display,
+                           &dpyinfo->xshape_event_base,
+                           &dpyinfo->xshape_error_base);
+
+  if (dpyinfo->xshape_supported_p)
+    dpyinfo->xshape_supported_p
+      = XShapeQueryVersion (dpyinfo->display,
+                           &dpyinfo->xshape_major,
+                           &dpyinfo->xshape_minor);
+#endif
+
   /* Put the rdb where we can find it in a way that works on
      all versions.  */
   dpyinfo->rdb = xrdb;
@@ -19391,6 +19749,7 @@ x_term_init (Lisp_Object display_name, char 
*xrm_option, char *resource_name)
       ATOM_REFS_INIT ("WM_SAVE_YOURSELF", Xatom_wm_save_yourself)
       ATOM_REFS_INIT ("WM_DELETE_WINDOW", Xatom_wm_delete_window)
       ATOM_REFS_INIT ("WM_CHANGE_STATE", Xatom_wm_change_state)
+      ATOM_REFS_INIT ("WM_STATE", Xatom_wm_state)
       ATOM_REFS_INIT ("WM_CONFIGURE_DENIED", Xatom_wm_configure_denied)
       ATOM_REFS_INIT ("WM_MOVED", Xatom_wm_window_moved)
       ATOM_REFS_INIT ("WM_CLIENT_LEADER", Xatom_wm_client_leader)
diff --git a/src/xterm.h b/src/xterm.h
index 4a71968b04..5a7b09925e 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -396,6 +396,7 @@ struct x_display_info
 
   /* Atom for indicating window state to the window manager.  */
   Atom Xatom_wm_change_state;
+  Atom Xatom_wm_state;
 
   /* Other WM communication */
   Atom Xatom_wm_configure_denied; /* When our config request is denied */
@@ -644,6 +645,14 @@ struct x_display_info
   int composite_major;
   int composite_minor;
 #endif
+
+#ifdef HAVE_XSHAPE
+  bool xshape_supported_p;
+  int xshape_major;
+  int xshape_minor;
+  int xshape_event_base;
+  int xshape_error_base;
+#endif
 };
 
 #ifdef HAVE_X_I18N



reply via email to

[Prev in Thread] Current Thread [Next in Thread]