]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix deadlocks with very old versions of libXi
authorPo Lu <luangruo@yahoo.com>
Sun, 3 Jul 2022 06:33:02 +0000 (14:33 +0800)
committerPo Lu <luangruo@yahoo.com>
Sun, 3 Jul 2022 06:33:16 +0000 (14:33 +0800)
* src/xfns.c (setup_xi_event_mask, Fx_create_frame): Set
`xi_mask' ourselves if the version of libXi is too old to have
working XIGetSelectedEvents.
* src/xterm.c (x_destroy_window): Free `xi_mask' with xfree in
that case.

src/xfns.c
src/xterm.c

index ea2b1c0b3d38c014af95e9a27e9b2de900549d50..331f22763ee0c1ed940fe1fd0065e82048567406 100644 (file)
@@ -3712,6 +3712,16 @@ setup_xi_event_mask (struct frame *f)
   XIEventMask mask;
   ptrdiff_t l = XIMaskLen (XI_LASTEVENT);
   unsigned char *m;
+#ifndef HAVE_XINPUT2_1
+  /* Set up fallback values, since XIGetSelectedEvents doesn't work
+     with this version of libXi.  */
+  XIEventMask *selected;
+
+  selected = xzalloc (sizeof *selected + l);
+  selected->mask = ((unsigned char *) selected) + sizeof *selected;
+  selected->mask_len = l;
+  selected->deviceid = XIAllMasterDevices;
+#endif
 
   mask.mask = m = alloca (l);
   memset (m, 0, l);
@@ -3736,6 +3746,12 @@ setup_xi_event_mask (struct frame *f)
                  FRAME_X_WINDOW (f),
                  &mask, 1);
 
+  /* Fortunately `xi_masks' isn't used on GTK 3, where we really have
+     to get the event mask from the X server.  */
+#ifndef HAVE_XINPUT2_1
+  memcpy (selected->mask, m, l);
+#endif
+
   memset (m, 0, l);
 #endif /* !HAVE_GTK3 */
 
@@ -3775,6 +3791,12 @@ setup_xi_event_mask (struct frame *f)
   XISelectEvents (FRAME_X_DISPLAY (f),
                  FRAME_X_WINDOW (f),
                  &mask, 1);
+
+#ifndef HAVE_XINPUT2_1
+  FRAME_X_OUTPUT (f)->xi_masks = selected;
+  FRAME_X_OUTPUT (f)->num_xi_masks = 1;
+#endif
+
   unblock_input ();
 }
 #endif
@@ -4935,7 +4957,10 @@ This function is an internal primitive--use `make-frame' instead.  */)
   x_icon (f, parms);
   x_make_gc (f);
 
-#ifdef HAVE_XINPUT2
+  /* While this function is present in versions of libXi that only
+     support 2.0, it does not release the display lock after
+     finishing, leading to a deadlock.  */
+#if defined HAVE_XINPUT2 && defined HAVE_XINPUT2_1
   if (dpyinfo->supports_xi2)
     FRAME_X_OUTPUT (f)->xi_masks
       = XIGetSelectedEvents (dpyinfo->display, FRAME_X_WINDOW (f),
index 4353b173cab6df41d264078031c72a53d9c37f4c..0aca949dbc7f3d4761c4960b4c898d0f6fe48eac 100644 (file)
@@ -25728,8 +25728,15 @@ x_destroy_window (struct frame *f)
 #endif
 
 #ifdef HAVE_XINPUT2
+#ifdef HAVE_XINPUT2_1
   if (f->output_data.x->xi_masks)
     XFree (f->output_data.x->xi_masks);
+#else
+  /* This is allocated by us under very old versions of libXi; see
+     `setup_xi_event_mask'.  */
+  if (f->output_data.x->xi_masks)
+    xfree (f->output_data.x->xi_masks);
+#endif
 #endif
 
   xfree (f->output_data.x);