comparison src/event-msw.c @ 231:557eaa0339bf r20-5b14

Import from CVS: tag r20-5b14
author cvs
date Mon, 13 Aug 2007 10:13:48 +0200
parents 0e522484dd2a
children 52952cbfc5b5
comparison
equal deleted inserted replaced
230:39ed1d2bdd9d 231:557eaa0339bf
83 /* Number of wait handles */ 83 /* Number of wait handles */
84 static mswindows_waitable_count=0; 84 static mswindows_waitable_count=0;
85 85
86 /* This is the event signaled by the event pump. 86 /* This is the event signaled by the event pump.
87 See mswindows_pump_outstanding_events for comments */ 87 See mswindows_pump_outstanding_events for comments */
88 static Lisp_Object mswindows_error_caught_by_event_pump; 88 static Lisp_Object mswindows_error_caught_in_modal_loop;
89 static int mswindows_in_event_pump; 89 static int mswindows_in_modal_loop;
90 90
91 /* Count of wound timers */ 91 /* Count of wound timers */
92 static int mswindows_pending_timers_count; 92 static int mswindows_pending_timers_count;
93 93
94 static int 94 static int
201 } 201 }
202 previous_event = event; 202 previous_event = event;
203 } 203 }
204 } 204 }
205 205
206 static Lisp_Object
207 mswindows_modal_loop_error_handler (Lisp_Object cons_sig_data,
208 Lisp_Object u_n_u_s_e_d)
209 {
210 mswindows_error_caught_in_modal_loop = cons_sig_data;
211 return Qunbound;
212 }
213
214 Lisp_Object
215 mswindows_protect_modal_loop (Lisp_Object (*bfun) (Lisp_Object barg),
216 Lisp_Object barg)
217 {
218 Lisp_Object tmp;
219
220 ++mswindows_in_modal_loop;
221 tmp = condition_case_1 (Qt,
222 bfun, barg,
223 mswindows_modal_loop_error_handler, Qnil);
224 --mswindows_in_modal_loop;
225
226 return tmp;
227 }
228
229 void
230 mswindows_unmodalize_signal_maybe (void)
231 {
232 if (!NILP (mswindows_error_caught_in_modal_loop))
233 {
234 /* Got an error while messages were pumped while
235 in window procedure - have to resignal */
236 Lisp_Object sym = XCAR (mswindows_error_caught_in_modal_loop);
237 Lisp_Object data = XCDR (mswindows_error_caught_in_modal_loop);
238 mswindows_error_caught_in_modal_loop = Qnil;
239 Fsignal (sym, data);
240 }
241 }
242
206 /* 243 /*
207 * This is an unsafe part of event pump, guarded by 244 * This is an unsafe part of event pump, guarded by
208 * condition_case. See mswindows_pump_outstanding_events 245 * condition_case. See mswindows_pump_outstanding_events
209 */ 246 */
210 static Lisp_Object 247 static Lisp_Object
232 /* Qt becomes return value of mswindows_pump_outstanding_events 269 /* Qt becomes return value of mswindows_pump_outstanding_events
233 once we get here */ 270 once we get here */
234 return Qt; 271 return Qt;
235 } 272 }
236 273
237 /* See mswindows_pump_outstanding_events */
238 static Lisp_Object
239 mswindows_event_pump_error_handler (Lisp_Object cons_sig_data,
240 Lisp_Object u_n_u_s_e_d)
241 {
242 mswindows_error_caught_by_event_pump = cons_sig_data;
243 return Qnil;
244 }
245
246 /* 274 /*
247 * This function pumps emacs events, while available, by using 275 * This function pumps emacs events, while available, by using
248 * next_message/dispatch_message loop. Errors are trapped around 276 * next_message/dispatch_message loop. Errors are trapped around
249 * the loop so the function always returns. 277 * the loop so the function always returns.
250 * 278 *
251 * Windows message queue is not looked into during the call, 279 * Windows message queue is not looked into during the call,
252 * neither are waitable handles checked. The function pumps 280 * neither are waitable handles checked. The function pumps
253 * thus only dispatch events already queued, as well as those 281 * thus only dispatch events already queued, as well as those
254 * resulted in dispatching thereof. This is done by setting 282 * resulted in dispatching thereof. This is done by setting
255 * module local variable mswidows_in_event_pump to nonzero. 283 * module local variable mswidows_in_modal_loop to nonzero.
256 * 284 *
257 * Return value is Qt if no errors was trapped, or Qnil if 285 * Return value is Qt if no errors was trapped, or Qunbound if
258 * there was an error. 286 * there was an error.
259 * 287 *
260 * In case of error, a cons representing the error, in the 288 * In case of error, a cons representing the error, in the
261 * form (SIGNAL . DATA), is stored in the module local variable 289 * form (SIGNAL . DATA), is stored in the module local variable
262 * mswindows_error_caught_by_event_pump. This error is signaled 290 * mswindows_error_caught_in_modal_loop. This error is signaled
263 * again when DispatchMessage returns. Thus, Windows internal 291 * again when DispatchMessage returns. Thus, Windows internal
264 * modal loops are protected against throws, which are proven 292 * modal loops are protected against throws, which are proven
265 * to corrupt internal Windows structures. 293 * to corrupt internal Windows structures.
266 * 294 *
267 * In case of success, mswindows_error_caught_by_event_pump is 295 * In case of success, mswindows_error_caught_in_modal_loop is
268 * assigned Qnil. 296 * assigned Qnil.
269 * 297 *
270 * If the value of mswindows_error_caught_by_event_pump is not 298 * If the value of mswindows_error_caught_in_modal_loop is not
271 * nil already upon entry, the function just returns non-nil. 299 * nil already upon entry, the function just returns non-nil.
272 * This situation means that a new event has been queued while 300 * This situation means that a new event has been queued while
273 * cancleng mode. The event will be dequeued on the next regular 301 * cancleng mode. The event will be dequeued on the next regular
274 * call of next-event; the pump is off since error is caught. 302 * call of next-event; the pump is off since error is caught.
275 * The caller must *unconditionally* cancel modal loop if the 303 * The caller must *unconditionally* cancel modal loop if the
282 { 310 {
283 /* This function can call lisp */ 311 /* This function can call lisp */
284 312
285 Lisp_Object result = Qt; 313 Lisp_Object result = Qt;
286 314
287 if (NILP(mswindows_error_caught_by_event_pump)) 315 if (NILP(mswindows_error_caught_in_modal_loop))
288 { 316 result = mswindows_protect_modal_loop (mswindows_unsafe_pump_events, Qnil);
289
290 mswindows_in_event_pump = 1;
291
292 result = condition_case_1 (Qt,
293 mswindows_unsafe_pump_events, Qnil,
294 mswindows_event_pump_error_handler, Qnil);
295
296 mswindows_in_event_pump = 0;
297 }
298 return result; 317 return result;
299 } 318 }
300 319
301 /* 320 /*
302 * Find a free waitable slot 321 * Find a free waitable slot
326 case mswindows_waitable_type_dispatch: 345 case mswindows_waitable_type_dispatch:
327 assert (0); /* kkm - should not get here */ 346 assert (0); /* kkm - should not get here */
328 /* Can only have one waitable for the dispatch queue, and it's the first one */ 347 /* Can only have one waitable for the dispatch queue, and it's the first one */
329 assert (mswindows_waitable_count++ == 0); 348 assert (mswindows_waitable_count++ == 0);
330 waitable=0; 349 waitable=0;
331 // InitializeCriticalSection(&mswindows_dispatch_crit); 350 #if 0
351 InitializeCriticalSection(&mswindows_dispatch_crit);
352 #endif
332 assert (mswindows_waitable[0] = CreateSemaphore (NULL, 0, 0x7fffffff, NULL)); 353 assert (mswindows_waitable[0] = CreateSemaphore (NULL, 0, 0x7fffffff, NULL));
333 return mswindows_waitable_info+0; 354 return mswindows_waitable_info+0;
334 355
335 default: 356 default:
336 assert(0); 357 assert(0);
386 { 407 {
387 MSG msg; 408 MSG msg;
388 while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) 409 while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
389 { 410 {
390 DispatchMessage (&msg); 411 DispatchMessage (&msg);
391 if (!NILP (mswindows_error_caught_by_event_pump)) 412 mswindows_unmodalize_signal_maybe ();
392 {
393 /* Got an error while messages were pumped while
394 in window procedure - have to resignal */
395 Lisp_Object sym = XCAR (mswindows_error_caught_by_event_pump);
396 Lisp_Object data = XCDR (mswindows_error_caught_by_event_pump);
397 mswindows_error_caught_by_event_pump = Qnil;
398 Fsignal (sym, data);
399 }
400 } 413 }
401 } 414 }
402 415
403 /* 416 /*
404 * This is a special flavour of the mswindows_need_event function, 417 * This is a special flavour of the mswindows_need_event function,
414 * to deadlock, we simply signal an error. 427 * to deadlock, we simply signal an error.
415 * 428 *
416 * The implementation does not honor user_p by design. 429 * The implementation does not honor user_p by design.
417 */ 430 */
418 static void 431 static void
419 mswindows_need_event_in_event_pump (int user_p, int badly_p) 432 mswindows_need_event_in_modal_loop (int user_p, int badly_p)
420 { 433 {
421 MSG msg; 434 MSG msg;
422 435
423 /* Check if already have one */ 436 /* Check if already have one */
424 if (!NILP (mswindows_u_dispatch_event_queue) 437 if (!NILP (mswindows_u_dispatch_event_queue)
461 static void 474 static void
462 mswindows_need_event (int user_p, int badly_p) 475 mswindows_need_event (int user_p, int badly_p)
463 { 476 {
464 int active; 477 int active;
465 478
466 if (mswindows_in_event_pump) 479 if (mswindows_in_modal_loop)
467 { 480 {
468 mswindows_need_event_in_event_pump (user_p, badly_p); 481 mswindows_need_event_in_modal_loop (user_p, badly_p);
469 return; 482 return;
470 } 483 }
471 484
472 /* Have to drain Windows message queue first, otherwise, we may miss 485 /* Have to drain Windows message queue first, otherwise, we may miss
473 quit char when called from quit_p */ 486 quit char when called from quit_p */
737 750
738 mswindows_s_dispatch_event_queue = Qnil; 751 mswindows_s_dispatch_event_queue = Qnil;
739 staticpro (&mswindows_s_dispatch_event_queue); 752 staticpro (&mswindows_s_dispatch_event_queue);
740 mswindows_s_dispatch_event_queue_tail = Qnil; 753 mswindows_s_dispatch_event_queue_tail = Qnil;
741 754
742 mswindows_error_caught_by_event_pump = Qnil; 755 mswindows_error_caught_in_modal_loop = Qnil;
743 staticpro (&mswindows_error_caught_by_event_pump); 756 staticpro (&mswindows_error_caught_in_modal_loop);
744 mswindows_in_event_pump = 0; 757 mswindows_in_modal_loop = 0;
745 mswindows_pending_timers_count = 0; 758 mswindows_pending_timers_count = 0;
746 759
747 mswindows_event_stream = xnew (struct event_stream); 760 mswindows_event_stream = xnew (struct event_stream);
748 761
749 mswindows_event_stream->event_pending_p = emacs_mswindows_event_pending_p; 762 mswindows_event_stream->event_pending_p = emacs_mswindows_event_pending_p;