# HG changeset patch # User Gerd Moellmann # Date 951485538 0 # Node ID ea05cbe65943f558fc42699068adb165738fd9f5 # Parent 30eebaedce93ee0e549e60a4681760053a464349 (inhibit_busy_cursor, busy_count): Removed. (Fx_show_busy_cursor, Fx_hide_busy_cursor): Removed. (busy_cursor_atimer, busy_cursor_shown_p, Vbusy_cursor_delay): New variables. (DEFAULT_BUSY_CURSOR_DELAY): New define. (start_busy_cursor, cancel_busy_cursor, show_busy_cursor) (hide_busy_cursor): New functions. (syms_of_xfns): DEFVAR_LISP Vbusy_cursor_delay. diff -r 30eebaedce93 -r ea05cbe65943 src/xfns.c --- a/src/xfns.c Fri Feb 25 13:31:28 2000 +0000 +++ b/src/xfns.c Fri Feb 25 13:32:18 2000 +0000 @@ -42,6 +42,7 @@ #include "fontset.h" #include "systime.h" #include "termhooks.h" +#include "atimer.h" #ifdef HAVE_X_WINDOWS @@ -10057,48 +10058,102 @@ Busy cursor ***********************************************************************/ -/* The implementation partly follows a patch from - F.Pierresteguy@frcl.bull.fr dated 1994. */ - -/* Setting inhibit_busy_cursor to 2 inhibits busy-cursor display until - the next X event is read and we enter XTread_socket again. Setting - it to 1 inhibits busy-cursor display for direct commands. */ - -int inhibit_busy_cursor; - -/* Incremented with each call to x-display-busy-cursor. - Decremented in x-undisplay-busy-cursor. */ - -static int busy_count; - - -DEFUN ("x-show-busy-cursor", Fx_show_busy_cursor, - Sx_show_busy_cursor, 0, 0, 0, - "Show a busy cursor, if not already shown.\n\ -Each call to this function must be matched by a call to\n\ -`x-hide-busy-cursor' to make the busy pointer disappear again.") - () -{ - ++busy_count; - if (busy_count == 1) +/* If non-null, an asynchronous timer that, when it expires, displays + a busy cursor on all frames. */ + +static struct atimer *busy_cursor_atimer; + +/* Non-zero means a busy cursor is currently shown. */ + +static int busy_cursor_shown_p; + +/* Number of seconds to wait before displaying a busy cursor. */ + +static Lisp_Object Vbusy_cursor_delay; + +/* Default number of seconds to wait before displaying a busy + cursor. */ + +#define DEFAULT_BUSY_CURSOR_DELAY 1 + +/* Function prototypes. */ + +static void show_busy_cursor P_ ((struct atimer *)); +static void hide_busy_cursor P_ ((void)); + + +/* Cancel a currently active busy-cursor timer, and start a new one. */ + +void +start_busy_cursor () +{ + EMACS_TIME delay; + int secs; + + cancel_busy_cursor (); + + if (INTEGERP (Vbusy_cursor_delay) + && XINT (Vbusy_cursor_delay) > 0) + secs = XFASTINT (Vbusy_cursor_delay); + else + secs = DEFAULT_BUSY_CURSOR_DELAY; + + EMACS_SET_SECS_USECS (delay, secs, 0); + busy_cursor_atimer = start_atimer (ATIMER_RELATIVE, delay, + show_busy_cursor, NULL); +} + + +/* Cancel the busy cursor timer if active, hide a busy cursor if + shown. */ + +void +cancel_busy_cursor () +{ + if (busy_cursor_atimer) + cancel_atimer (busy_cursor_atimer); + if (busy_cursor_shown_p) + hide_busy_cursor (); +} + + +/* Timer function of busy_cursor_atimer. TIMER is equal to + busy_cursor_atimer. + + Display a busy cursor on all frames by mapping the frames' + busy_window. Set the busy_p flag in the frames' output_data.x + structure to indicate that a busy cursor is shown on the + frames. */ + +static void +show_busy_cursor (timer) + struct atimer *timer; +{ + /* The timer implementation will cancel this timer automatically + after this function has run. Set busy_cursor_atimer to null + so that we know the timer doesn't have to be canceled. */ + busy_cursor_atimer = NULL; + + if (!busy_cursor_shown_p) { Lisp_Object rest, frame; - + + BLOCK_INPUT; + FOR_EACH_FRAME (rest, frame) if (FRAME_X_P (XFRAME (frame))) { struct frame *f = XFRAME (frame); - - BLOCK_INPUT; + f->output_data.x->busy_p = 1; - + if (!f->output_data.x->busy_window) { unsigned long mask = CWCursor; XSetWindowAttributes attrs; - + attrs.cursor = f->output_data.x->busy_cursor; - + f->output_data.x->busy_window = XCreateWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), @@ -10107,58 +10162,46 @@ CopyFromParent, mask, &attrs); } - + XMapRaised (FRAME_X_DISPLAY (f), f->output_data.x->busy_window); - UNBLOCK_INPUT; + XFlush (FRAME_X_DISPLAY (f)); } - } - - return Qnil; -} - - -DEFUN ("x-hide-busy-cursor", Fx_hide_busy_cursor, - Sx_hide_busy_cursor, 0, 1, 0, - "Hide a busy-cursor.\n\ -A busy-cursor will actually be undisplayed when a matching\n\ -`x-hide-busy-cursor' is called for each `x-show-busy-cursor'\n\ -issued. FORCE non-nil means hide the busy-cursor forcibly,\n\ -not counting calls.") - (force) - Lisp_Object force; -{ - Lisp_Object rest, frame; - - if (busy_count == 0) - return Qnil; - - if (!NILP (force) && busy_count != 0) - busy_count = 1; - - --busy_count; - if (busy_count != 0) - return Qnil; - - FOR_EACH_FRAME (rest, frame) - { - struct frame *f = XFRAME (frame); + + busy_cursor_shown_p = 1; + UNBLOCK_INPUT; + } +} + + +/* Hide the busy cursor on all frames, if it is currently shown. */ + +static void +hide_busy_cursor () +{ + if (busy_cursor_shown_p) + { + Lisp_Object rest, frame; + + BLOCK_INPUT; + FOR_EACH_FRAME (rest, frame) + { + struct frame *f = XFRAME (frame); - if (FRAME_X_P (f) - /* Watch out for newly created frames. */ - && f->output_data.x->busy_window) - { - - BLOCK_INPUT; - XUnmapWindow (FRAME_X_DISPLAY (f), f->output_data.x->busy_window); - /* Sync here because XTread_socket looks at the busy_p flag - that is reset to zero below. */ - XSync (FRAME_X_DISPLAY (f), False); - UNBLOCK_INPUT; - f->output_data.x->busy_p = 0; + if (FRAME_X_P (f) + /* Watch out for newly created frames. */ + && f->output_data.x->busy_window) + { + XUnmapWindow (FRAME_X_DISPLAY (f), f->output_data.x->busy_window); + /* Sync here because XTread_socket looks at the busy_p flag + that is reset to zero below. */ + XSync (FRAME_X_DISPLAY (f), False); + f->output_data.x->busy_p = 0; + } } - } - - return Qnil; + + busy_cursor_shown_p = 0; + UNBLOCK_INPUT; + } } @@ -10945,6 +10988,11 @@ "Non-zero means Emacs displays a busy cursor on window systems."); display_busy_cursor_p = 1; + DEFVAR_LISP ("busy-cursor-delay", &Vbusy_cursor_delay, + "*Seconds to wait before displaying a busy-cursor.\n\ +Value must be an integer."); + Vbusy_cursor_delay = make_number (DEFAULT_BUSY_CURSOR_DELAY); + #if 0 /* This doesn't really do anything. */ DEFVAR_LISP ("x-mode-pointer-shape", &Vx_mode_pointer_shape, "The shape of the pointer when over the mode line.\n\ @@ -11128,11 +11176,8 @@ defsubr (&Slookup_image); #endif - /* Busy-cursor. */ - defsubr (&Sx_show_busy_cursor); - defsubr (&Sx_hide_busy_cursor); - busy_count = 0; - inhibit_busy_cursor = 0; + busy_cursor_atimer = NULL; + busy_cursor_shown_p = 0; defsubr (&Sx_show_tip); defsubr (&Sx_hide_tip);