diff options
| author | Dmitry Antipov | 2014-05-13 18:18:54 +0400 |
|---|---|---|
| committer | Dmitry Antipov | 2014-05-13 18:18:54 +0400 |
| commit | d3e5c0ea8f4c5902a11b6bc36170336a7a7f01b6 (patch) | |
| tree | 62a09fcdabf646d80f7bae5bfbcd802e14c6182b /src/xterm.c | |
| parent | bd098f41af3d0201d6b8156ecb577dbff53fa50c (diff) | |
| download | emacs-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.c | 106 |
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 | |||
| 3096 | XTtoggle_invisible_pointer (struct frame *f, int invisible) | 3101 | XTtoggle_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 | |||
| 9721 | static Cursor | ||
| 9722 | make_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 | |||
| 9751 | static bool | ||
| 9752 | x_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 | |||
| 9764 | static void | ||
| 9765 | xfixes_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 | |||
| 9780 | static void | ||
| 9781 | x_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 | |||
| 9795 | static void | ||
| 9796 | x_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. */ |
| 9725 | static unsigned x_display_id; | 9809 | static 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 |