Mercurial > hg > xemacs-beta
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; |