fix gtk collecting blit to revert immediately when gc ends

original commit: bff39a1832548796a06e58d0810827b89a5bc984
This commit is contained in:
Matthew Flatt 2010-09-15 07:52:22 -06:00
parent 0b03ac3345
commit 4babb26533
3 changed files with 43 additions and 29 deletions

View File

@ -595,29 +595,33 @@
(define reg-blits null)
(define/private (register-one-blit x y w h pixbuf)
(define/private (register-one-blit x y w h on-pixbuf off-pixbuf)
(let* ([cwin (widget-window client-gtk)])
(atomically
(let ([win (create-gc-window cwin x y w h pixbuf)])
(let ([win (create-gc-window cwin x y w h)])
(let ([r (scheme_add_gc_callback
(make-gc-show-desc win pixbuf w h)
(make-gc-hide-desc win))])
(make-gc-show-desc win on-pixbuf w h)
(make-gc-hide-desc win off-pixbuf w h))])
(cons win r))))))
(define/public (register-collecting-blit x y w h on off on-x on-y off-x off-y)
(let ([on (if (and (zero? on-x)
(zero? on-y)
(= (send on get-width) w)
(= (send on get-height) h))
on
(let ([bm (make-object bitmap% w h)])
(let ([dc (make-object bitmap-dc% on)])
(send dc draw-bitmap-section on 0 0 on-x on-y w h)
(send dc set-bitmap #f)
bm)))])
(let ([pixbuf (bitmap->pixbuf on)])
(atomically
(set! reg-blits (cons (register-one-blit x y w h pixbuf) reg-blits))))))
(let ([fix-size (lambda (on on-x on-y)
(if (and (zero? on-x)
(zero? on-y)
(= (send on get-width) w)
(= (send on get-height) h))
on
(let ([bm (make-object bitmap% w h)])
(let ([dc (make-object bitmap-dc% on)])
(send dc draw-bitmap-section on 0 0 on-x on-y w h)
(send dc set-bitmap #f)
bm))))])
(let ([on (fix-size on on-x on-y)]
[off (fix-size off off-x off-y)])
(let ([on-pixbuf (bitmap->pixbuf on)]
[off-pixbuf (bitmap->pixbuf off)])
(atomically
(set! reg-blits (cons (register-one-blit x y w h on-pixbuf off-pixbuf) reg-blits)))))))
(define/public (unregister-collecting-blits)
(atomically

View File

@ -54,7 +54,7 @@
(define-mz scheme_add_gc_callback (_fun _racket _racket -> _racket))
(define-mz scheme_remove_gc_callback (_fun _racket -> _void))
(define (create-gc-window cwin x y w h pixbuf)
(define (create-gc-window cwin x y w h)
(let ([win (gdk_window_new cwin (make-GdkWindowAttr
""
0
@ -68,16 +68,27 @@
GDK_WA_Y))])
win))
(define (make-draw win pixbuf w h)
(vector 'ptr_ptr_ptr_int_int_int_int_int_int_int_int_int->void
gdk_draw_pixbuf
win #f pixbuf
0 0 0 0 w h
0 0 0))
(define (make-flush)
(vector 'ptr_ptr_ptr->void gdk_display_flush (gdk_display_get_default) #f #f))
(define (make-gc-show-desc win pixbuf w h)
(vector
(vector 'ptr_ptr_ptr->void gdk_window_show win #f #f)
(vector 'ptr_ptr_ptr_int_int_int_int_int_int_int_int_int->void
gdk_draw_pixbuf
win #f pixbuf
0 0 0 0 w h
0 0 0)
(vector 'ptr_ptr_ptr->void gdk_display_flush (gdk_display_get_default) #f #f)))
(make-draw win pixbuf w h)
(make-flush)))
(define (make-gc-hide-desc win)
(define (make-gc-hide-desc win pixbuf w h)
(vector
;; draw the ``off'' bitmap so we can flush immediately
(make-draw win pixbuf w h)
(make-flush)
;; hide the window; it may take a while for the underlying canvas
;; to refresh:
(vector 'ptr_ptr_ptr->void gdk_window_hide win #f #f)))

View File

@ -337,16 +337,15 @@ Registers a ``blit'' to occur when garbage collection starts and
ends. When garbage collection starts, @racket[on] is drawn at
location @racket[x] and @racket[y] within @racket[canvas], if
@racket[canvas] is shown. When garbage collection ends, the drawing
is reverted. The @racket[off], @racket[off-x], and @racket[off-y]
arguments are currently unused, though they were formerly used to
revert the drawing of @racket[on].
is reverted, possibly by drawing the @racket[off] bitmap.
The background behind @racket[on] is unspecified, so @racket[on]
should be a solid image, and the canvas's scale or scrolling is not
applied to the drawing. Only the portion of @racket[on] within
@racket[w] and @racket[h] pixels is used; if @racket[on-x] and
@racket[on-y] are specified, they specify an offset within the bitmap
that is used for drawing.
that is used for drawing, and @racket[off-x] and @racket[off-y]
similarly specify an offset within @racket[off].
The blit is automatically unregistered if @scheme[canvas] becomes
invisible and inaccessible. Multiple registrations can be installed