aboutsummaryrefslogtreecommitdiffstats
path: root/src/xterm.c
diff options
context:
space:
mode:
authorDmitry Antipov2014-05-13 18:18:54 +0400
committerDmitry Antipov2014-05-13 18:18:54 +0400
commitd3e5c0ea8f4c5902a11b6bc36170336a7a7f01b6 (patch)
tree62a09fcdabf646d80f7bae5bfbcd802e14c6182b /src/xterm.c
parentbd098f41af3d0201d6b8156ecb577dbff53fa50c (diff)
downloademacs-d3e5c0ea8f4c5902a11b6bc36170336a7a7f01b6.tar.gz
emacs-d3e5c0ea8f4c5902a11b6bc36170336a7a7f01b6.zip
If available, use Xfixes extension to do pointer blanking.
* 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.
Diffstat (limited to 'src/xterm.c')
-rw-r--r--src/xterm.c106
1 files changed, 96 insertions, 10 deletions
diff --git a/src/xterm.c b/src/xterm.c
index 85daee66717..5c21bfae144 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -32,6 +32,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
32#include "xterm.h" 32#include "xterm.h"
33#include <X11/cursorfont.h> 33#include <X11/cursorfont.h>
34 34
35/* If we have Xfixes extension, use it for pointer blanking. */
36#ifdef HAVE_XFIXES
37#include <X11/extensions/Xfixes.h>
38#endif
39
35/* Load sys/types.h if not already loaded. 40/* Load sys/types.h if not already loaded.
36 In some systems loading it twice is suicidal. */ 41 In some systems loading it twice is suicidal. */
37#ifndef makedev 42#ifndef makedev
@@ -3096,16 +3101,7 @@ static void
3096XTtoggle_invisible_pointer (struct frame *f, int invisible) 3101XTtoggle_invisible_pointer (struct frame *f, int invisible)
3097{ 3102{
3098 block_input (); 3103 block_input ();
3099 if (invisible) 3104 FRAME_DISPLAY_INFO (f)->toggle_visible_pointer (f, invisible);
3100 {
3101 if (FRAME_DISPLAY_INFO (f)->invisible_cursor != 0)
3102 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3103 FRAME_DISPLAY_INFO (f)->invisible_cursor);
3104 }
3105 else
3106 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3107 f->output_data.x->current_cursor);
3108 f->pointer_invisible = invisible;
3109 unblock_input (); 3105 unblock_input ();
3110} 3106}
3111 3107
@@ -9720,6 +9716,94 @@ my_log_handler (const gchar *log_domain, GLogLevelFlags log_level,
9720} 9716}
9721#endif 9717#endif
9722 9718
9719/* Create invisible cursor on X display referred by DPYINFO. */
9720
9721static Cursor
9722make_invisible_cursor (struct x_display_info *dpyinfo)
9723{
9724 Display *dpy = dpyinfo->display;
9725 static char const no_data[] = { 0 };
9726 Pixmap pix;
9727 XColor col;
9728 Cursor c = 0;
9729
9730 x_catch_errors (dpy);
9731 pix = XCreateBitmapFromData (dpy, dpyinfo->root_window, no_data, 1, 1);
9732 if (! x_had_errors_p (dpy) && pix != None)
9733 {
9734 Cursor pixc;
9735 col.pixel = 0;
9736 col.red = col.green = col.blue = 0;
9737 col.flags = DoRed | DoGreen | DoBlue;
9738 pixc = XCreatePixmapCursor (dpy, pix, pix, &col, &col, 0, 0);
9739 if (! x_had_errors_p (dpy) && pixc != None)
9740 c = pixc;
9741 XFreePixmap (dpy, pix);
9742 }
9743
9744 x_uncatch_errors ();
9745
9746 return c;
9747}
9748
9749/* True if DPY supports Xfixes extension >= 4. */
9750
9751static bool
9752x_probe_xfixes_extension (Display *dpy)
9753{
9754#ifdef HAVE_XFIXES
9755 int major, minor;
9756 return XFixesQueryVersion (dpy, &major, &minor) && major >= 4;
9757#else
9758 return false;
9759#endif /* HAVE_XFIXES */
9760}
9761
9762/* Toggle mouse pointer visibility on frame F by using Xfixes functions. */
9763
9764static void
9765xfixes_toggle_visible_pointer (struct frame *f, bool invisible)
9766{
9767#ifdef HAVE_XFIXES
9768 if (invisible)
9769 XFixesHideCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
9770 else
9771 XFixesShowCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
9772 f->pointer_invisible = invisible;
9773#else
9774 emacs_abort ();
9775#endif /* HAVE_XFIXES */
9776}
9777
9778/* Toggle mouse pointer visibility on frame F by using invisible cursor. */
9779
9780static void
9781x_toggle_visible_pointer (struct frame *f, bool invisible)
9782{
9783 eassert (FRAME_DISPLAY_INFO (f)->invisible_cursor != 0);
9784 if (invisible)
9785 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
9786 FRAME_DISPLAY_INFO (f)->invisible_cursor);
9787 else
9788 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
9789 f->output_data.x->current_cursor);
9790 f->pointer_invisible = invisible;
9791}
9792
9793/* Setup pointer blanking, prefer Xfixes if available. */
9794
9795static void
9796x_setup_pointer_blanking (struct x_display_info *dpyinfo)
9797{
9798 if (x_probe_xfixes_extension (dpyinfo->display))
9799 dpyinfo->toggle_visible_pointer = xfixes_toggle_visible_pointer;
9800 else
9801 {
9802 dpyinfo->toggle_visible_pointer = x_toggle_visible_pointer;
9803 dpyinfo->invisible_cursor = make_invisible_cursor (dpyinfo);
9804 }
9805}
9806
9723/* Current X display connection identifier. Incremented for each next 9807/* Current X display connection identifier. Incremented for each next
9724 connection established. */ 9808 connection established. */
9725static unsigned x_display_id; 9809static unsigned x_display_id;
@@ -10148,6 +10232,8 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
10148 gray_bits, gray_width, gray_height, 10232 gray_bits, gray_width, gray_height,
10149 1, 0, 1); 10233 1, 0, 1);
10150 10234
10235 x_setup_pointer_blanking (dpyinfo);
10236
10151#ifdef HAVE_X_I18N 10237#ifdef HAVE_X_I18N
10152 xim_initialize (dpyinfo, resource_name); 10238 xim_initialize (dpyinfo, resource_name);
10153#endif 10239#endif