]> git.eshelyaron.com Git - emacs.git/commitdiff
Clean up pointer blanking code
authorPo Lu <luangruo@yahoo.com>
Wed, 27 Apr 2022 01:10:18 +0000 (09:10 +0800)
committerPo Lu <luangruo@yahoo.com>
Wed, 27 Apr 2022 01:10:18 +0000 (09:10 +0800)
* src/xterm.c (XTtoggle_invisible_pointer): Dispatch to correct
function directly.
(x_probe_xfixes_extension): Return directly based on dpyinfo.
(xfixes_toggle_visible_pointer): Make conditional on
`HAVE_XFIXES'.
(make_invisible_cursor): Initialize `c' correctly.
(x_toggle_visible_pointer): Handle cursor allocation failures.
(x_free_frame_resources): Dispatch with
XTtoggle_visible_pointer.
(x_setup_pointer_blanking): Delete function.
(x_term_init): Initialize blank cursor here instead.
* src/xterm.h (struct x_display_info): New field
`fixes_pointer_blanking'.

src/xterm.c
src/xterm.h

index 56add92f8b56c98e1b0de8b5f1cbdc13b2a8f5cc..891a242012205686f088b6362be9bf3f2d3cf900 100644 (file)
@@ -8947,16 +8947,6 @@ XTflash (struct frame *f)
   unblock_input ();
 }
 
-
-static void
-XTtoggle_invisible_pointer (struct frame *f, bool invisible)
-{
-  block_input ();
-  FRAME_DISPLAY_INFO (f)->toggle_visible_pointer (f, invisible);
-  unblock_input ();
-}
-
-
 /* Make audible bell.  */
 
 static void
@@ -9300,6 +9290,105 @@ x_new_focus_frame (struct x_display_info *dpyinfo, struct frame *frame)
   x_frame_rehighlight (dpyinfo);
 }
 
+/* True if the display in DPYINFO supports a version of Xfixes
+   sufficient for pointer blanking.  */
+#ifdef HAVE_XFIXES
+static bool
+x_probe_xfixes_extension (struct x_display_info *dpyinfo)
+{
+  return (dpyinfo->xfixes_supported_p
+         && dpyinfo->xfixes_major >= 4);
+}
+#endif /* HAVE_XFIXES */
+
+/* Toggle mouse pointer visibility on frame F using the XFixes
+   extension.  */
+#ifdef HAVE_XFIXES
+static void
+xfixes_toggle_visible_pointer (struct frame *f, bool invisible)
+
+{
+  if (invisible)
+    XFixesHideCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
+  else
+    XFixesShowCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
+  f->pointer_invisible = invisible;
+}
+#endif /* HAVE_XFIXES */
+
+/* Create invisible cursor on the X display referred by DPYINFO.  */
+static Cursor
+make_invisible_cursor (struct x_display_info *dpyinfo)
+{
+  Display *dpy = dpyinfo->display;
+  static char const no_data[] = { 0 };
+  Pixmap pix;
+  XColor col;
+  Cursor c;
+
+  c = None;
+
+  x_catch_errors (dpy);
+  pix = XCreateBitmapFromData (dpy, dpyinfo->root_window, no_data, 1, 1);
+  if (!x_had_errors_p (dpy) && pix != None)
+    {
+      Cursor pixc;
+      col.pixel = 0;
+      col.red = col.green = col.blue = 0;
+      col.flags = DoRed | DoGreen | DoBlue;
+      pixc = XCreatePixmapCursor (dpy, pix, pix, &col, &col, 0, 0);
+      if (! x_had_errors_p (dpy) && pixc != None)
+        c = pixc;
+      XFreePixmap (dpy, pix);
+    }
+
+  x_uncatch_errors ();
+
+  return c;
+}
+
+/* Toggle mouse pointer visibility on frame F by using an invisible
+   cursor.  */
+static void
+x_toggle_visible_pointer (struct frame *f, bool invisible)
+{
+  struct x_display_info *dpyinfo;
+
+  dpyinfo = FRAME_DISPLAY_INFO (f);
+
+  /* We could have gotten a BadAlloc error while creating the
+     invisible cursor.  Try to create it again, but if that fails,
+     just give up.  */
+  if (dpyinfo->invisible_cursor == None)
+    dpyinfo->invisible_cursor = make_invisible_cursor (dpyinfo);
+
+  if (dpyinfo->invisible_cursor == None)
+    invisible = false;
+
+  if (invisible)
+    XDefineCursor (dpyinfo->display, FRAME_X_WINDOW (f),
+                  dpyinfo->invisible_cursor);
+  else
+    XDefineCursor (dpyinfo->display, FRAME_X_WINDOW (f),
+                  f->output_data.x->current_cursor);
+
+  f->pointer_invisible = invisible;
+}
+
+static void
+XTtoggle_invisible_pointer (struct frame *f, bool invisible)
+{
+  block_input ();
+#ifdef HAVE_XFIXES
+  if (FRAME_DISPLAY_INFO (f)->fixes_pointer_blanking
+      && x_probe_xfixes_extension (FRAME_DISPLAY_INFO (f)))
+    xfixes_toggle_visible_pointer (f, invisible);
+  else
+#endif
+    x_toggle_visible_pointer (f, invisible);
+  unblock_input ();
+}
+
 /* Handle FocusIn and FocusOut state changes for FRAME.
    If FRAME has focus and there exists more than one frame, puts
    a FOCUS_IN_EVENT into *BUFP.  */
@@ -22032,7 +22121,7 @@ x_free_frame_resources (struct frame *f)
       /* Always exit with visible pointer to avoid weird issue
         with Xfixes (Bug#17609).  */
       if (f->pointer_invisible)
-       FRAME_DISPLAY_INFO (f)->toggle_visible_pointer (f, 0);
+       XTtoggle_invisible_pointer (f, 0);
 
       /* We must free faces before destroying windows because some
         font-driver (e.g. xft) access a window while finishing a
@@ -22652,100 +22741,6 @@ my_log_handler (const gchar *log_domain, GLogLevelFlags log_level,
 }
 #endif
 
-/* Create invisible cursor on X display referred by DPYINFO.  */
-
-static Cursor
-make_invisible_cursor (struct x_display_info *dpyinfo)
-{
-  Display *dpy = dpyinfo->display;
-  static char const no_data[] = { 0 };
-  Pixmap pix;
-  XColor col;
-  Cursor c = 0;
-
-  x_catch_errors (dpy);
-  pix = XCreateBitmapFromData (dpy, dpyinfo->root_window, no_data, 1, 1);
-  if (! x_had_errors_p (dpy) && pix != None)
-    {
-      Cursor pixc;
-      col.pixel = 0;
-      col.red = col.green = col.blue = 0;
-      col.flags = DoRed | DoGreen | DoBlue;
-      pixc = XCreatePixmapCursor (dpy, pix, pix, &col, &col, 0, 0);
-      if (! x_had_errors_p (dpy) && pixc != None)
-        c = pixc;
-      XFreePixmap (dpy, pix);
-    }
-
-  x_uncatch_errors ();
-
-  return c;
-}
-
-/* True if DPY supports Xfixes extension >= 4.  */
-
-static bool
-x_probe_xfixes_extension (Display *dpy)
-{
-#ifdef HAVE_XFIXES
-  struct x_display_info *info
-    = x_display_info_for_display (dpy);
-
-  return (info
-         && info->xfixes_supported_p
-         && info->xfixes_major >= 4);
-#else
-  return false;
-#endif /* HAVE_XFIXES */
-}
-
-/* Toggle mouse pointer visibility on frame F by using Xfixes functions.  */
-
-static void
-xfixes_toggle_visible_pointer (struct frame *f, bool invisible)
-{
-#ifdef HAVE_XFIXES
-  if (invisible)
-    XFixesHideCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
-  else
-    XFixesShowCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
-  f->pointer_invisible = invisible;
-#else
-  emacs_abort ();
-#endif /* HAVE_XFIXES */
-}
-
-/* Toggle mouse pointer visibility on frame F by using invisible cursor.  */
-
-static void
-x_toggle_visible_pointer (struct frame *f, bool invisible)
-{
-  eassert (FRAME_DISPLAY_INFO (f)->invisible_cursor != 0);
-  if (invisible)
-    XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                  FRAME_DISPLAY_INFO (f)->invisible_cursor);
-  else
-    XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                  f->output_data.x->current_cursor);
-  f->pointer_invisible = invisible;
-}
-
-/* Setup pointer blanking, prefer Xfixes if available.  */
-
-static void
-x_setup_pointer_blanking (struct x_display_info *dpyinfo)
-{
-  /* FIXME: the brave tester should set EMACS_XFIXES because we're suspecting
-     X server bug, see https://debbugs.gnu.org/cgi/bugreport.cgi?bug=17609.  */
-  if (egetenv ("EMACS_XFIXES") && x_probe_xfixes_extension (dpyinfo->display))
-    dpyinfo->toggle_visible_pointer = xfixes_toggle_visible_pointer;
-  else
-    {
-      dpyinfo->toggle_visible_pointer = x_toggle_visible_pointer;
-      dpyinfo->invisible_cursor = make_invisible_cursor (dpyinfo);
-    }
-}
-
 /* Current X display connection identifier.  Incremented for each next
    connection established.  */
 static unsigned x_display_id;
@@ -23630,7 +23625,10 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
                                   gray_bits, gray_width, gray_height,
                                   1, 0, 1);
 
-  x_setup_pointer_blanking (dpyinfo);
+  dpyinfo->invisible_cursor = make_invisible_cursor (dpyinfo);
+#ifdef HAVE_XFIXES
+  dpyinfo->fixes_pointer_blanking = egetenv ("EMACS_XFIXES");
+#endif
 
 #ifdef HAVE_X_I18N
   xim_initialize (dpyinfo, resource_name);
index 37dfa57947842e38dffa1e9fb7befd1cc28290a5..65349834c9b2e006297cb7dcf793c9b2a85fd48d 100644 (file)
@@ -321,8 +321,10 @@ struct x_display_info
      Unused if this display supports Xfixes extension.  */
   Cursor invisible_cursor;
 
-  /* Function used to toggle pointer visibility on this display.  */
-  void (*toggle_visible_pointer) (struct frame *, bool);
+#ifdef HAVE_XFIXES
+  /* Whether or not to use Xfixes for pointer blanking.  */
+  bool fixes_pointer_blanking;
+#endif
 
 #ifdef USE_GTK
   /* The GDK cursor for scroll bars and popup menus.  */