Commit d012c62b authored by Kim F. Storm's avatar Kim F. Storm
Browse files

Modify preemptive redisplay to be based on periodic checks for input.

(PERIODIC_PREEMPTION_CHECKING): Define to 1 iff EMACS_HAS_USECS.
(Vredisplay_preemption_period): New variable.
(syms_of_display): DEFVAR_LISP and initialize it.
(preemption_period, preemption_next_check): New variables.
(update_frame, update_single_window): Initialize them based on
Vredisplay_preemption_period if !force_p.
(update_window, update_frame_1): Use them to determine when to
check for input.
parent 15a8ea0c
...@@ -192,6 +192,28 @@ struct window *frame_row_to_window P_ ((struct window *, int)); ...@@ -192,6 +192,28 @@ struct window *frame_row_to_window P_ ((struct window *, int));
int redisplay_dont_pause; int redisplay_dont_pause;
/* Define PERIODIC_PREEMPTION_CHECKING to 1, if micro-second timers
are supported, so we can check for input during redisplay at
regular intervals. */
#ifdef EMACS_HAS_USECS
#define PERIODIC_PREEMPTION_CHECKING 1
#else
#define PERIODIC_PREEMPTION_CHECKING 0
#endif
#if PERIODIC_PREEMPTION_CHECKING
/* If a number (float), check for user input every N seconds. */
Lisp_Object Vredisplay_preemption_period;
/* Redisplay preemption timers. */
static EMACS_TIME preemption_period;
static EMACS_TIME preemption_next_check;
#endif
/* Nonzero upon entry to redisplay means do not assume anything about /* Nonzero upon entry to redisplay means do not assume anything about
current contents of actual terminal frame; clear and redraw it. */ current contents of actual terminal frame; clear and redraw it. */
...@@ -3820,6 +3842,22 @@ update_frame (f, force_p, inhibit_hairy_id_p) ...@@ -3820,6 +3842,22 @@ update_frame (f, force_p, inhibit_hairy_id_p)
int paused_p; int paused_p;
struct window *root_window = XWINDOW (f->root_window); struct window *root_window = XWINDOW (f->root_window);
#if PERIODIC_PREEMPTION_CHECKING
if (!force_p && NUMBERP (Vredisplay_preemption_period))
{
EMACS_TIME tm;
double p = XFLOATINT (Vredisplay_preemption_period);
int sec, usec;
sec = (int) p;
usec = (p - sec) * 1000000;
EMACS_GET_TIME (tm);
EMACS_SET_SECS_USECS (preemption_period, sec, usec);
EMACS_ADD_TIME (preemption_next_check, tm, preemption_period);
}
#endif
if (FRAME_WINDOW_P (f)) if (FRAME_WINDOW_P (f))
{ {
/* We are working on window matrix basis. All windows whose /* We are working on window matrix basis. All windows whose
...@@ -3952,6 +3990,22 @@ update_single_window (w, force_p) ...@@ -3952,6 +3990,22 @@ update_single_window (w, force_p)
/* Record that this is not a frame-based redisplay. */ /* Record that this is not a frame-based redisplay. */
set_frame_matrix_frame (NULL); set_frame_matrix_frame (NULL);
#if PERIODIC_PREEMPTION_CHECKING
if (!force_p && NUMBERP (Vredisplay_preemption_period))
{
EMACS_TIME tm;
double p = XFLOATINT (Vredisplay_preemption_period);
int sec, usec;
sec = (int) p;
usec = (p - sec) * 1000000;
EMACS_GET_TIME (tm);
EMACS_SET_SECS_USECS (preemption_period, sec, usec);
EMACS_ADD_TIME (preemption_next_check, tm, preemption_period);
}
#endif
/* Update W. */ /* Update W. */
update_begin (f); update_begin (f);
update_window (w, force_p); update_window (w, force_p);
...@@ -4107,7 +4161,9 @@ update_window (w, force_p) ...@@ -4107,7 +4161,9 @@ update_window (w, force_p)
{ {
struct glyph_matrix *desired_matrix = w->desired_matrix; struct glyph_matrix *desired_matrix = w->desired_matrix;
int paused_p; int paused_p;
#if !PERIODIC_PREEMPTION_CHECKING
int preempt_count = baud_rate / 2400 + 1; int preempt_count = baud_rate / 2400 + 1;
#endif
extern int input_pending; extern int input_pending;
extern Lisp_Object do_mouse_tracking; extern Lisp_Object do_mouse_tracking;
#if GLYPH_DEBUG #if GLYPH_DEBUG
...@@ -4119,8 +4175,13 @@ update_window (w, force_p) ...@@ -4119,8 +4175,13 @@ update_window (w, force_p)
/* Check pending input the first time so that we can quickly return. */ /* Check pending input the first time so that we can quickly return. */
if (redisplay_dont_pause) if (redisplay_dont_pause)
force_p = 1; force_p = 1;
else #if PERIODIC_PREEMPTION_CHECKING
else if (NILP (Vredisplay_preemption_period))
force_p = 1;
#else
else if (!force_p)
detect_input_pending_ignore_squeezables (); detect_input_pending_ignore_squeezables ();
#endif
/* If forced to complete the update, or if no input is pending, do /* If forced to complete the update, or if no input is pending, do
the update. */ the update. */
...@@ -4192,9 +4253,22 @@ update_window (w, force_p) ...@@ -4192,9 +4253,22 @@ update_window (w, force_p)
detect_input_pending. If it's done too often, detect_input_pending. If it's done too often,
scrolling large windows with repeated scroll-up scrolling large windows with repeated scroll-up
commands will too quickly pause redisplay. */ commands will too quickly pause redisplay. */
#if PERIODIC_PREEMPTION_CHECKING
if (!force_p)
{
EMACS_TIME tm, dif;
EMACS_GET_TIME (tm);
EMACS_SUB_TIME (dif, preemption_next_check, tm);
if (EMACS_TIME_NEG_P (dif))
{
EMACS_ADD_TIME (preemption_next_check, tm, preemption_period);
detect_input_pending_ignore_squeezables ();
}
}
#else
if (!force_p && ++n_updated % preempt_count == 0) if (!force_p && ++n_updated % preempt_count == 0)
detect_input_pending_ignore_squeezables (); detect_input_pending_ignore_squeezables ();
#endif
changed_p |= update_window_line (w, vpos, changed_p |= update_window_line (w, vpos,
&mouse_face_overwritten_p); &mouse_face_overwritten_p);
...@@ -5145,11 +5219,16 @@ update_frame_1 (f, force_p, inhibit_id_p) ...@@ -5145,11 +5219,16 @@ update_frame_1 (f, force_p, inhibit_id_p)
if (redisplay_dont_pause) if (redisplay_dont_pause)
force_p = 1; force_p = 1;
#if PERIODIC_PREEMPTION_CHECKING
else if (NILP (Vredisplay_preemption_period))
force_p = 1;
#else
else if (!force_p && detect_input_pending_ignore_squeezables ()) else if (!force_p && detect_input_pending_ignore_squeezables ())
{ {
pause = 1; pause = 1;
goto do_pause; goto do_pause;
} }
#endif
/* If we cannot insert/delete lines, it's no use trying it. */ /* If we cannot insert/delete lines, it's no use trying it. */
if (!line_ins_del_ok) if (!line_ins_del_ok)
...@@ -5200,8 +5279,22 @@ update_frame_1 (f, force_p, inhibit_id_p) ...@@ -5200,8 +5279,22 @@ update_frame_1 (f, force_p, inhibit_id_p)
} }
} }
if ((i - 1) % preempt_count == 0) #if PERIODIC_PREEMPTION_CHECKING
if (!force_p)
{
EMACS_TIME tm, dif;
EMACS_GET_TIME (tm);
EMACS_SUB_TIME (dif, preemption_next_check, tm);
if (EMACS_TIME_NEG_P (dif))
{
EMACS_ADD_TIME (preemption_next_check, tm, preemption_period);
detect_input_pending_ignore_squeezables ();
}
}
#else
if (!force_p && (i - 1) % preempt_count == 0)
detect_input_pending_ignore_squeezables (); detect_input_pending_ignore_squeezables ();
#endif
update_frame_line (f, i); update_frame_line (f, i);
} }
...@@ -6936,7 +7029,14 @@ See `buffer-display-table' for more information. */); ...@@ -6936,7 +7029,14 @@ See `buffer-display-table' for more information. */);
doc: /* *Non-nil means update isn't paused when input is detected. */); doc: /* *Non-nil means update isn't paused when input is detected. */);
redisplay_dont_pause = 0; redisplay_dont_pause = 0;
/* Initialize `window-system', unless init_display already decided it. */ #if PERIODIC_PREEMPTION_CHECKING
DEFVAR_LISP ("redisplay-preemption-period", &Vredisplay_preemption_period,
doc: /* *The period in seconds between checking for input during redisplay.
If input is detected, redisplay is pre-empted, and the input is processed.
If nil, never pre-empt redisplay. */);
Vredisplay_preemption_period = make_float (0.10);
#endif
#ifdef CANNOT_DUMP #ifdef CANNOT_DUMP
if (noninteractive) if (noninteractive)
#endif #endif
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment