diff options
| author | Kim F. Storm | 2006-06-12 22:32:47 +0000 |
|---|---|---|
| committer | Kim F. Storm | 2006-06-12 22:32:47 +0000 |
| commit | d012c62b91b0f8f549563db81fbbfabaf030c56c (patch) | |
| tree | fb93dbda6d0632deb88a2e341b17128317036e03 | |
| parent | 15a8ea0ca622d10b8abc325af746c7597a707fff (diff) | |
| download | emacs-d012c62b91b0f8f549563db81fbbfabaf030c56c.tar.gz emacs-d012c62b91b0f8f549563db81fbbfabaf030c56c.zip | |
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.
| -rw-r--r-- | src/dispnew.c | 108 |
1 files changed, 104 insertions, 4 deletions
diff --git a/src/dispnew.c b/src/dispnew.c index cbe0e3fb521..e205105536c 100644 --- a/src/dispnew.c +++ b/src/dispnew.c | |||
| @@ -192,6 +192,28 @@ struct window *frame_row_to_window P_ ((struct window *, int)); | |||
| 192 | 192 | ||
| 193 | int redisplay_dont_pause; | 193 | int redisplay_dont_pause; |
| 194 | 194 | ||
| 195 | /* Define PERIODIC_PREEMPTION_CHECKING to 1, if micro-second timers | ||
| 196 | are supported, so we can check for input during redisplay at | ||
| 197 | regular intervals. */ | ||
| 198 | #ifdef EMACS_HAS_USECS | ||
| 199 | #define PERIODIC_PREEMPTION_CHECKING 1 | ||
| 200 | #else | ||
| 201 | #define PERIODIC_PREEMPTION_CHECKING 0 | ||
| 202 | #endif | ||
| 203 | |||
| 204 | #if PERIODIC_PREEMPTION_CHECKING | ||
| 205 | |||
| 206 | /* If a number (float), check for user input every N seconds. */ | ||
| 207 | |||
| 208 | Lisp_Object Vredisplay_preemption_period; | ||
| 209 | |||
| 210 | /* Redisplay preemption timers. */ | ||
| 211 | |||
| 212 | static EMACS_TIME preemption_period; | ||
| 213 | static EMACS_TIME preemption_next_check; | ||
| 214 | |||
| 215 | #endif | ||
| 216 | |||
| 195 | /* Nonzero upon entry to redisplay means do not assume anything about | 217 | /* Nonzero upon entry to redisplay means do not assume anything about |
| 196 | current contents of actual terminal frame; clear and redraw it. */ | 218 | current contents of actual terminal frame; clear and redraw it. */ |
| 197 | 219 | ||
| @@ -3820,6 +3842,22 @@ update_frame (f, force_p, inhibit_hairy_id_p) | |||
| 3820 | int paused_p; | 3842 | int paused_p; |
| 3821 | struct window *root_window = XWINDOW (f->root_window); | 3843 | struct window *root_window = XWINDOW (f->root_window); |
| 3822 | 3844 | ||
| 3845 | #if PERIODIC_PREEMPTION_CHECKING | ||
| 3846 | if (!force_p && NUMBERP (Vredisplay_preemption_period)) | ||
| 3847 | { | ||
| 3848 | EMACS_TIME tm; | ||
| 3849 | double p = XFLOATINT (Vredisplay_preemption_period); | ||
| 3850 | int sec, usec; | ||
| 3851 | |||
| 3852 | sec = (int) p; | ||
| 3853 | usec = (p - sec) * 1000000; | ||
| 3854 | |||
| 3855 | EMACS_GET_TIME (tm); | ||
| 3856 | EMACS_SET_SECS_USECS (preemption_period, sec, usec); | ||
| 3857 | EMACS_ADD_TIME (preemption_next_check, tm, preemption_period); | ||
| 3858 | } | ||
| 3859 | #endif | ||
| 3860 | |||
| 3823 | if (FRAME_WINDOW_P (f)) | 3861 | if (FRAME_WINDOW_P (f)) |
| 3824 | { | 3862 | { |
| 3825 | /* We are working on window matrix basis. All windows whose | 3863 | /* We are working on window matrix basis. All windows whose |
| @@ -3952,6 +3990,22 @@ update_single_window (w, force_p) | |||
| 3952 | /* Record that this is not a frame-based redisplay. */ | 3990 | /* Record that this is not a frame-based redisplay. */ |
| 3953 | set_frame_matrix_frame (NULL); | 3991 | set_frame_matrix_frame (NULL); |
| 3954 | 3992 | ||
| 3993 | #if PERIODIC_PREEMPTION_CHECKING | ||
| 3994 | if (!force_p && NUMBERP (Vredisplay_preemption_period)) | ||
| 3995 | { | ||
| 3996 | EMACS_TIME tm; | ||
| 3997 | double p = XFLOATINT (Vredisplay_preemption_period); | ||
| 3998 | int sec, usec; | ||
| 3999 | |||
| 4000 | sec = (int) p; | ||
| 4001 | usec = (p - sec) * 1000000; | ||
| 4002 | |||
| 4003 | EMACS_GET_TIME (tm); | ||
| 4004 | EMACS_SET_SECS_USECS (preemption_period, sec, usec); | ||
| 4005 | EMACS_ADD_TIME (preemption_next_check, tm, preemption_period); | ||
| 4006 | } | ||
| 4007 | #endif | ||
| 4008 | |||
| 3955 | /* Update W. */ | 4009 | /* Update W. */ |
| 3956 | update_begin (f); | 4010 | update_begin (f); |
| 3957 | update_window (w, force_p); | 4011 | update_window (w, force_p); |
| @@ -4107,7 +4161,9 @@ update_window (w, force_p) | |||
| 4107 | { | 4161 | { |
| 4108 | struct glyph_matrix *desired_matrix = w->desired_matrix; | 4162 | struct glyph_matrix *desired_matrix = w->desired_matrix; |
| 4109 | int paused_p; | 4163 | int paused_p; |
| 4164 | #if !PERIODIC_PREEMPTION_CHECKING | ||
| 4110 | int preempt_count = baud_rate / 2400 + 1; | 4165 | int preempt_count = baud_rate / 2400 + 1; |
| 4166 | #endif | ||
| 4111 | extern int input_pending; | 4167 | extern int input_pending; |
| 4112 | extern Lisp_Object do_mouse_tracking; | 4168 | extern Lisp_Object do_mouse_tracking; |
| 4113 | #if GLYPH_DEBUG | 4169 | #if GLYPH_DEBUG |
| @@ -4119,8 +4175,13 @@ update_window (w, force_p) | |||
| 4119 | /* Check pending input the first time so that we can quickly return. */ | 4175 | /* Check pending input the first time so that we can quickly return. */ |
| 4120 | if (redisplay_dont_pause) | 4176 | if (redisplay_dont_pause) |
| 4121 | force_p = 1; | 4177 | force_p = 1; |
| 4122 | else | 4178 | #if PERIODIC_PREEMPTION_CHECKING |
| 4179 | else if (NILP (Vredisplay_preemption_period)) | ||
| 4180 | force_p = 1; | ||
| 4181 | #else | ||
| 4182 | else if (!force_p) | ||
| 4123 | detect_input_pending_ignore_squeezables (); | 4183 | detect_input_pending_ignore_squeezables (); |
| 4184 | #endif | ||
| 4124 | 4185 | ||
| 4125 | /* If forced to complete the update, or if no input is pending, do | 4186 | /* If forced to complete the update, or if no input is pending, do |
| 4126 | the update. */ | 4187 | the update. */ |
| @@ -4192,9 +4253,22 @@ update_window (w, force_p) | |||
| 4192 | detect_input_pending. If it's done too often, | 4253 | detect_input_pending. If it's done too often, |
| 4193 | scrolling large windows with repeated scroll-up | 4254 | scrolling large windows with repeated scroll-up |
| 4194 | commands will too quickly pause redisplay. */ | 4255 | commands will too quickly pause redisplay. */ |
| 4256 | #if PERIODIC_PREEMPTION_CHECKING | ||
| 4257 | if (!force_p) | ||
| 4258 | { | ||
| 4259 | EMACS_TIME tm, dif; | ||
| 4260 | EMACS_GET_TIME (tm); | ||
| 4261 | EMACS_SUB_TIME (dif, preemption_next_check, tm); | ||
| 4262 | if (EMACS_TIME_NEG_P (dif)) | ||
| 4263 | { | ||
| 4264 | EMACS_ADD_TIME (preemption_next_check, tm, preemption_period); | ||
| 4265 | detect_input_pending_ignore_squeezables (); | ||
| 4266 | } | ||
| 4267 | } | ||
| 4268 | #else | ||
| 4195 | if (!force_p && ++n_updated % preempt_count == 0) | 4269 | if (!force_p && ++n_updated % preempt_count == 0) |
| 4196 | detect_input_pending_ignore_squeezables (); | 4270 | detect_input_pending_ignore_squeezables (); |
| 4197 | 4271 | #endif | |
| 4198 | changed_p |= update_window_line (w, vpos, | 4272 | changed_p |= update_window_line (w, vpos, |
| 4199 | &mouse_face_overwritten_p); | 4273 | &mouse_face_overwritten_p); |
| 4200 | 4274 | ||
| @@ -5145,11 +5219,16 @@ update_frame_1 (f, force_p, inhibit_id_p) | |||
| 5145 | 5219 | ||
| 5146 | if (redisplay_dont_pause) | 5220 | if (redisplay_dont_pause) |
| 5147 | force_p = 1; | 5221 | force_p = 1; |
| 5222 | #if PERIODIC_PREEMPTION_CHECKING | ||
| 5223 | else if (NILP (Vredisplay_preemption_period)) | ||
| 5224 | force_p = 1; | ||
| 5225 | #else | ||
| 5148 | else if (!force_p && detect_input_pending_ignore_squeezables ()) | 5226 | else if (!force_p && detect_input_pending_ignore_squeezables ()) |
| 5149 | { | 5227 | { |
| 5150 | pause = 1; | 5228 | pause = 1; |
| 5151 | goto do_pause; | 5229 | goto do_pause; |
| 5152 | } | 5230 | } |
| 5231 | #endif | ||
| 5153 | 5232 | ||
| 5154 | /* If we cannot insert/delete lines, it's no use trying it. */ | 5233 | /* If we cannot insert/delete lines, it's no use trying it. */ |
| 5155 | if (!line_ins_del_ok) | 5234 | if (!line_ins_del_ok) |
| @@ -5200,8 +5279,22 @@ update_frame_1 (f, force_p, inhibit_id_p) | |||
| 5200 | } | 5279 | } |
| 5201 | } | 5280 | } |
| 5202 | 5281 | ||
| 5203 | if ((i - 1) % preempt_count == 0) | 5282 | #if PERIODIC_PREEMPTION_CHECKING |
| 5283 | if (!force_p) | ||
| 5284 | { | ||
| 5285 | EMACS_TIME tm, dif; | ||
| 5286 | EMACS_GET_TIME (tm); | ||
| 5287 | EMACS_SUB_TIME (dif, preemption_next_check, tm); | ||
| 5288 | if (EMACS_TIME_NEG_P (dif)) | ||
| 5289 | { | ||
| 5290 | EMACS_ADD_TIME (preemption_next_check, tm, preemption_period); | ||
| 5291 | detect_input_pending_ignore_squeezables (); | ||
| 5292 | } | ||
| 5293 | } | ||
| 5294 | #else | ||
| 5295 | if (!force_p && (i - 1) % preempt_count == 0) | ||
| 5204 | detect_input_pending_ignore_squeezables (); | 5296 | detect_input_pending_ignore_squeezables (); |
| 5297 | #endif | ||
| 5205 | 5298 | ||
| 5206 | update_frame_line (f, i); | 5299 | update_frame_line (f, i); |
| 5207 | } | 5300 | } |
| @@ -6936,7 +7029,14 @@ See `buffer-display-table' for more information. */); | |||
| 6936 | doc: /* *Non-nil means update isn't paused when input is detected. */); | 7029 | doc: /* *Non-nil means update isn't paused when input is detected. */); |
| 6937 | redisplay_dont_pause = 0; | 7030 | redisplay_dont_pause = 0; |
| 6938 | 7031 | ||
| 6939 | /* Initialize `window-system', unless init_display already decided it. */ | 7032 | #if PERIODIC_PREEMPTION_CHECKING |
| 7033 | DEFVAR_LISP ("redisplay-preemption-period", &Vredisplay_preemption_period, | ||
| 7034 | doc: /* *The period in seconds between checking for input during redisplay. | ||
| 7035 | If input is detected, redisplay is pre-empted, and the input is processed. | ||
| 7036 | If nil, never pre-empt redisplay. */); | ||
| 7037 | Vredisplay_preemption_period = make_float (0.10); | ||
| 7038 | #endif | ||
| 7039 | |||
| 6940 | #ifdef CANNOT_DUMP | 7040 | #ifdef CANNOT_DUMP |
| 6941 | if (noninteractive) | 7041 | if (noninteractive) |
| 6942 | #endif | 7042 | #endif |