]> git.eshelyaron.com Git - emacs.git/commitdiff
If available, use Xfixes extension to do pointer blanking.
authorDmitry Antipov <dmantipov@yandex.ru>
Tue, 13 May 2014 14:18:54 +0000 (18:18 +0400)
committerDmitry Antipov <dmantipov@yandex.ru>
Tue, 13 May 2014 14:18:54 +0000 (18:18 +0400)
* configure.ac (HAVE_XFIXES): Define if available.
(XFIXES_CFLAGS, XFIXES_LIBS): New AC_SUBSTs.
* src/Makefile.in (XFIXES_CFLAGS, XFIXES_LIBS): New var.
* src/xfns.c (x_set_mouse_color): Do not call make_invisible_cursor here.
(make_invisible_cursor): Move to...
* src/xterm.c (make_invisible_cursor): ...here.
(x_probe_xfixes_extension, xfixes_toggle_visible_pointer)
(x_toggle_visible_pointer, x_setup_pointer_blanking): New functions.
(x_term_init): Call to x_setup_pointer_blanking.
(XTtoggle_invisible_pointer): Use blanking specific to this display.
* src/xterm.h (struct x_display_info): New member toggle_visible_pointer.

ChangeLog
configure.ac
src/ChangeLog
src/Makefile.in
src/xfns.c
src/xterm.c
src/xterm.h

index c4ee59eb844e5b81be33bf9f0a14dc235af6a683..072871cc82104fe8d39f858bb36c58ee7556690f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,8 @@
 2014-05-13  Dmitry Antipov  <dmantipov@yandex.ru>
 
-       * configure.ac (--enable-link-time-optimization): Add clang support.
+       * configure.ac (HAVE_XFIXES): Define if available.
+       (XFIXES_CFLAGS, XFIXES_LIBS): New AC_SUBSTs.
+       (--enable-link-time-optimization): Add clang support.
        * INSTALL: Mention it.
 
 2014-05-12  Katsumi Yamaoka  <yamaoka@jpl.org>
index b2ce64adeb7d8cae0680775bf4a9f824aab6344b..bb1bdd84b292922bafa186b1a3e0a04d8280a8f7 100644 (file)
@@ -3304,6 +3304,26 @@ fi
 AC_SUBST(XINERAMA_CFLAGS)
 AC_SUBST(XINERAMA_LIBS)
 
+### Use Xfixes (-lXfixes) if available
+HAVE_XFIXES=no
+if test "${HAVE_X11}" = "yes"; then
+  XFIXES_REQUIRED=4.0.0
+  XFIXES_MODULES="xfixes >= $XFIXES_REQUIRED"
+  EMACS_CHECK_MODULES([XFIXES], [$XFIXES_MODULES])
+  if test $HAVE_XFIXES = no; then
+    # Test old way in case pkg-config doesn't have it (older machines).
+    AC_CHECK_HEADER(X11/extensions/Xfixes.h,
+      [AC_CHECK_LIB(Xfixes, XFixesHideCursor, HAVE_XFIXES=yes)])
+    if test $HAVE_XFIXES = yes; then
+      XFIXES_LIBS=-lXfixes
+    fi
+  fi
+  if test $HAVE_XFIXES = yes; then
+    AC_DEFINE(HAVE_XFIXES, 1, [Define to 1 if you have the Xfixes extension.])
+  fi
+fi
+AC_SUBST(XFIXES_CFLAGS)
+AC_SUBST(XFIXES_LIBS)
 
 ### Use libxml (-lxml2) if available
 ### mingw32 doesn't use -lxml2, since it loads the library dynamically.
index cc16cf8f274efcfe2f6666bba9f2f0e4ba794293..e79c163cb0c7f5fcf8f3856ecc3511b32a442f0e 100644 (file)
@@ -1,3 +1,16 @@
+2014-05-13  Dmitry Antipov  <dmantipov@yandex.ru>
+
+       If available, use Xfixes extension to do pointer blanking.
+       * Makefile.in (XFIXES_CFLAGS, XFIXES_LIBS): New var.
+       * xfns.c (x_set_mouse_color): Do not call make_invisible_cursor here.
+       (make_invisible_cursor): Move to...
+       * xterm.c (make_invisible_cursor): ...here.
+       (x_probe_xfixes_extension, xfixes_toggle_visible_pointer)
+       (x_toggle_visible_pointer, x_setup_pointer_blanking): New functions.
+       (x_term_init): Call to x_setup_pointer_blanking.
+       (XTtoggle_invisible_pointer): Use blanking specific to this display.
+       * xterm.h (struct x_display_info): New member toggle_visible_pointer.
+
 2014-05-12  YAMAMOTO Mitsuharu  <mituharu@math.s.chiba-u.ac.jp>
 
        * xdisp.c (draw_glyphs): Set clipping to highlight boundaries.
index c35e38bb290ca324c4d7de6ce67f7b1400d3f430..b4e9eae330b8f23ec6ffdae080c9ab0357564387 100644 (file)
@@ -231,6 +231,9 @@ XRANDR_CFLAGS = @XRANDR_CFLAGS@
 XINERAMA_LIBS = @XINERAMA_LIBS@
 XINERAMA_CFLAGS = @XINERAMA_CFLAGS@
 
+XFIXES_LIBS = @XFIXES_LIBS@
+XFIXES_CFLAGS = @XFIXES_CFLAGS@
+
 ## widget.o if USE_X_TOOLKIT, otherwise empty.
 WIDGET_OBJ=@WIDGET_OBJ@
 
@@ -326,8 +329,8 @@ ALL_CFLAGS=-Demacs $(MYCPPFLAGS) -I. -I$(srcdir) \
   -I$(lib) -I$(srcdir)/../lib \
   $(C_SWITCH_MACHINE) $(C_SWITCH_SYSTEM) $(C_SWITCH_X_SITE) \
   $(GNUSTEP_CFLAGS) $(CFLAGS_SOUND) $(RSVG_CFLAGS) $(IMAGEMAGICK_CFLAGS) \
-  $(PNG_CFLAGS) \
-  $(LIBXML2_CFLAGS) $(DBUS_CFLAGS) $(XRANDR_CFLAGS) $(XINERAMA_CFLAGS) \
+  $(PNG_CFLAGS) $(LIBXML2_CFLAGS) $(DBUS_CFLAGS) \
+  $(XRANDR_CFLAGS) $(XINERAMA_CFLAGS) $(XFIXES_CFLAGS) \
   $(SETTINGS_CFLAGS) $(FREETYPE_CFLAGS) $(FONTCONFIG_CFLAGS) \
   $(LIBOTF_CFLAGS) $(M17N_FLT_CFLAGS) $(DEPFLAGS) \
   $(LIBGNUTLS_CFLAGS) $(GFILENOTIFY_CFLAGS) \
@@ -407,7 +410,7 @@ LIBES = $(LIBS) $(W32_LIBS) $(LIBS_GNUSTEP) $(LIBX_BASE) $(LIBIMAGE) \
    $(LIBX_OTHER) $(LIBSOUND) \
    $(RSVG_LIBS) $(IMAGEMAGICK_LIBS) $(LIB_ACL) $(LIB_CLOCK_GETTIME) \
    $(LIB_EACCESS) $(LIB_FDATASYNC) $(LIB_TIMER_TIME) $(DBUS_LIBS) \
-   $(LIB_EXECINFO) $(XRANDR_LIBS) $(XINERAMA_LIBS) \
+   $(LIB_EXECINFO) $(XRANDR_LIBS) $(XINERAMA_LIBS) $(XFIXES_LIBS) \
    $(LIBXML2_LIBS) $(LIBGPM) $(LIBRESOLV) $(LIBS_SYSTEM) \
    $(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \
    $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \
index 13b4c6e7879de9821446b3834a762d745498c605..8e00a1cfbd6dd09ccf138d4c5184751d623e3498 100644 (file)
@@ -577,35 +577,6 @@ x_set_background_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
     }
 }
 
-static Cursor
-make_invisible_cursor (struct frame *f)
-{
-  Display *dpy = FRAME_X_DISPLAY (f);
-  static char const no_data[] = { 0 };
-  Pixmap pix;
-  XColor col;
-  Cursor c = 0;
-
-  x_catch_errors (dpy);
-  pix = XCreateBitmapFromData (dpy, FRAME_DISPLAY_INFO (f)->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;
-}
-
 static void
 x_set_mouse_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
 {
@@ -723,9 +694,6 @@ x_set_mouse_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
     XDefineCursor (dpy, FRAME_X_WINDOW (f),
                    f->output_data.x->current_cursor = cursor);
 
-  if (FRAME_DISPLAY_INFO (f)->invisible_cursor == 0)
-    FRAME_DISPLAY_INFO (f)->invisible_cursor = make_invisible_cursor (f);
-
   if (cursor != x->text_cursor
       && x->text_cursor != 0)
     XFreeCursor (dpy, x->text_cursor);
index 85daee6671723ece92f2e9f6d4e66fc988685b81..5c21bfae144226a96e95244ac8fe7cc98e2d4d74 100644 (file)
@@ -32,6 +32,11 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "xterm.h"
 #include <X11/cursorfont.h>
 
+/* If we have Xfixes extension, use it for pointer blanking.  */
+#ifdef HAVE_XFIXES
+#include <X11/extensions/Xfixes.h>
+#endif
+
 /* Load sys/types.h if not already loaded.
    In some systems loading it twice is suicidal.  */
 #ifndef makedev
@@ -3096,16 +3101,7 @@ static void
 XTtoggle_invisible_pointer (struct frame *f, int invisible)
 {
   block_input ();
-  if (invisible)
-    {
-      if (FRAME_DISPLAY_INFO (f)->invisible_cursor != 0)
-        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;
+  FRAME_DISPLAY_INFO (f)->toggle_visible_pointer (f, invisible);
   unblock_input ();
 }
 
@@ -9720,6 +9716,94 @@ 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
+  int major, minor;
+  return XFixesQueryVersion (dpy, &major, &minor) && 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)
+{
+  if (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;
@@ -10148,6 +10232,8 @@ 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);
+  
 #ifdef HAVE_X_I18N
   xim_initialize (dpyinfo, resource_name);
 #endif
index 90d2e131717e04cc8ae23677657fae535653eb54..3e79de109768667d7b92affc4de283e328354b27 100644 (file)
@@ -174,9 +174,13 @@ struct x_display_info
   /* The cursor to use for vertical scroll bars.  */
   Cursor vertical_scroll_bar_cursor;
 
-  /* The invisible cursor used for pointer blanking.  */
+  /* The invisible cursor used for pointer blanking.
+     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 USE_GTK
   /* The GDK cursor for scroll bars and popup menus.  */
   GdkCursor *xg_cursor;