Kludge to terminate filtering threads

This commit is contained in:
mainzelm 2003-07-15 09:02:55 +00:00
parent 716c2ede20
commit 4384ee6b60
1 changed files with 34 additions and 13 deletions

View File

@ -41,7 +41,8 @@
(set! *most-recent-sync-x-event* (set! *most-recent-sync-x-event*
(placeholder-value (really-next-sync-x-event (placeholder-value (really-next-sync-x-event
*most-recent-sync-x-event*))))) *most-recent-sync-x-event*)))))
(lp)))))) (lp))))
'init-sync-x-events))
(define (most-recent-sync-x-event) (define (most-recent-sync-x-event)
*most-recent-sync-x-event*) *most-recent-sync-x-event*)
@ -100,26 +101,46 @@
(define (call-with-event-channel display window event-mask fun) (define (call-with-event-channel display window event-mask fun)
(let ((r (make-request display window event-mask)) (let ((r (make-request display window event-mask))
(channel (make-channel))) (x-event-channel (make-channel))
(spawn-event-filter channel display window event-mask) (filter-control-channel (make-channel))
(dead?-box (cons #f #f)))
(spawn-event-filter x-event-channel filter-control-channel
display window event-mask fun dead?-box)
;; we send the first sync-event to the thread to really have the ;; we send the first sync-event to the thread to really have the
;; most recent one, without keeping it in an environment. ;; most recent one, without keeping it in an environment.
(send channel (most-recent-sync-x-event)) (send filter-control-channel (most-recent-sync-x-event))
(let ((first? #t))
(dynamic-wind (dynamic-wind
(lambda () (add-request! r)) (lambda ()
(lambda () (fun channel)) (add-request! r)
(lambda () (remove-request! r))))) (if first?
(set! first? #f)
(warn "throwing back into call-with-event-channel")))
(lambda () (call-with-values
(lambda () (fun x-event-channel))
(lambda args
(apply values args))))
(lambda ()
(set-car! dead?-box #t)
(remove-request! r))))))
(define (spawn-event-filter out-channel display window event-mask) (define (true x) #t)
(define (spawn-event-filter out-channel control-channel display window event-mask fun dead?-box)
(let ((pred (lambda (e) (let ((pred (lambda (e)
(and (eq? (any-event-display e) display) (and (eq? (any-event-display e) display)
(matches-event-mask? window event-mask e))))) (matches-event-mask? window event-mask e)))))
(spawn (lambda () (spawn (lambda ()
;; the first sync-event is send to us through the channel ;; the first sync-event is send to us through the channel
(let loop ((se (receive out-channel))) (let loop ((se (receive control-channel)))
(let ((nse (next-sync-x-event se pred))) (if (not (car dead?-box))
(send out-channel (sync-x-event-event nse)) (let ((nse (next-sync-x-event se true)))
(if (not (car dead?-box))
(if (pred (sync-x-event-event nse))
(begin (send out-channel (sync-x-event-event nse))
(loop nse))
(loop nse))))))) (loop nse)))))))
(cons 'spawn-event-filter fun))))
(define (matches-event-mask? window event-mask event) (define (matches-event-mask? window event-mask event)
(let ((type (any-event-type event))) (let ((type (any-event-type event)))