Mercurial > emacs
comparison src/dispnew.c @ 71323:e882f189c3af
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.
author | Kim F. Storm <storm@cua.dk> |
---|---|
date | Mon, 12 Jun 2006 22:32:47 +0000 |
parents | 623f01d9e470 |
children | a8cbcce39bd0 |
comparison
equal
deleted
inserted
replaced
71322:35554e4f7699 | 71323:e882f189c3af |
---|---|
190 for debugging and for a future implementation of EDT-like | 190 for debugging and for a future implementation of EDT-like |
191 scrolling. */ | 191 scrolling. */ |
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 |
198 int frame_garbaged; | 220 int frame_garbaged; |
199 | 221 |
3818 { | 3840 { |
3819 /* 1 means display has been paused because of pending input. */ | 3841 /* 1 means display has been paused because of pending input. */ |
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 |
3826 flag must_be_updated_p is set have to be updated. */ | 3864 flag must_be_updated_p is set have to be updated. */ |
3827 | 3865 |
3949 { | 3987 { |
3950 struct frame *f = XFRAME (WINDOW_FRAME (w)); | 3988 struct frame *f = XFRAME (WINDOW_FRAME (w)); |
3951 | 3989 |
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); |
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 | |
3954 | 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); |
3958 update_end (f); | 4012 update_end (f); |
4105 struct window *w; | 4159 struct window *w; |
4106 int force_p; | 4160 int 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 |
4114 /* Check that W's frame doesn't have glyph matrices. */ | 4170 /* Check that W's frame doesn't have glyph matrices. */ |
4115 xassert (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w)))); | 4171 xassert (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w)))); |
4117 #endif | 4173 #endif |
4118 | 4174 |
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. */ |
4127 if (force_p || !input_pending || !NILP (do_mouse_tracking)) | 4188 if (force_p || !input_pending || !NILP (do_mouse_tracking)) |
4128 { | 4189 { |
4190 | 4251 |
4191 /* We'll have to play a little bit with when to | 4252 /* We'll have to play a little bit with when to |
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 |
4201 /* Mark all rows below the last visible one in the current | 4275 /* Mark all rows below the last visible one in the current |
4202 matrix as invalid. This is necessary because of | 4276 matrix as invalid. This is necessary because of |
5143 if (preempt_count <= 0) | 5217 if (preempt_count <= 0) |
5144 preempt_count = 1; | 5218 preempt_count = 1; |
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) |
5156 inhibit_id_p = 1; | 5235 inhibit_id_p = 1; |
5157 | 5236 |
5198 sleep (outq / baud_rate); | 5277 sleep (outq / baud_rate); |
5199 } | 5278 } |
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 } |
5208 } | 5301 } |
5209 | 5302 |
6934 | 7027 |
6935 DEFVAR_BOOL ("redisplay-dont-pause", &redisplay_dont_pause, | 7028 DEFVAR_BOOL ("redisplay-dont-pause", &redisplay_dont_pause, |
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 |
6943 { | 7043 { |
6944 Vwindow_system = Qnil; | 7044 Vwindow_system = Qnil; |