
Remove a misguided attempt to improve finaliation while making GTK+ 3 changes, although this change affected only GTK+ 2.
183 lines
5.1 KiB
Racket
183 lines
5.1 KiB
Racket
#lang racket/base
|
|
(require ffi/unsafe
|
|
ffi/unsafe/define
|
|
racket/draw/unsafe/cairo
|
|
racket/class
|
|
"utils.rkt"
|
|
"types.rkt"
|
|
"window.rkt"
|
|
"pixbuf.rkt"
|
|
"x11.rkt")
|
|
|
|
(provide
|
|
(protect-out scheme_add_gc_callback
|
|
scheme_remove_gc_callback
|
|
create-gc-window
|
|
free-gc-window
|
|
make-gc-show-desc
|
|
make-gc-hide-desc
|
|
bitmap->gc-bitmap))
|
|
|
|
;; Gtk2, only:
|
|
(define-cstruct _GdkWindowAttr
|
|
([title _string]
|
|
[event_mask _int]
|
|
[x _int]
|
|
[y _int]
|
|
[width _int]
|
|
[height _int]
|
|
[wclass _int] ; GDK_INPUT_OUTPUT
|
|
[visual _pointer]
|
|
[colormap _pointer] ; this field is absent in Gtk3
|
|
[window_type _int] ; GDK_WINDOW_CHILD
|
|
[cursor _pointer]
|
|
[wmclass_name _string]
|
|
[wmclass_class _string]
|
|
[override_redirect _gboolean]
|
|
[type_hint _int]))
|
|
|
|
(define << arithmetic-shift)
|
|
|
|
(define GDK_WA_TITLE (1 . << . 1))
|
|
(define GDK_WA_X (1 . << . 2))
|
|
(define GDK_WA_Y (1 . << . 3))
|
|
(define GDK_WA_CURSOR (1 . << . 4))
|
|
(define GDK_WA_COLORMAP (1 . << . 5))
|
|
(define GDK_WA_VISUAL (1 . << . 6))
|
|
(define GDK_WA_WMCLASS (1 . << . 7))
|
|
(define GDK_WA_NOREDIR (1 . << . 8))
|
|
(define GDK_WA_TYPE_HINT (1 . << . 9))
|
|
|
|
(define GDK_INPUT_OUTPUT 0)
|
|
|
|
(define GDK_WINDOW_CHILD 2)
|
|
|
|
(define-gdk gdk_window_new (_fun _GdkWindow _GdkWindowAttr-pointer _uint -> _GdkWindow))
|
|
|
|
(define-gdk gdk_window_show _fpointer)
|
|
(define-gdk gdk_window_hide _fpointer)
|
|
(define-gdk gdk_display_flush _fpointer)
|
|
|
|
;; Gtk2
|
|
(define-gdk gdk_draw_pixbuf _fpointer
|
|
#:make-fail make-not-available)
|
|
|
|
(define-mz scheme_add_gc_callback (_fun _racket _racket -> _racket))
|
|
(define-mz scheme_remove_gc_callback (_fun _racket -> _void))
|
|
|
|
(define-x11 XSetWindowBackgroundPixmap _fpointer #:fail (lambda () #f))
|
|
(define-x11 XMapRaised _fpointer #:fail (lambda () #f))
|
|
(define-x11 XUnmapWindow _fpointer #:fail (lambda () #f))
|
|
|
|
(define (bitmap->gc-bitmap bm client-gtk)
|
|
(cond
|
|
[gtk3?
|
|
; Generate an X11 Pixmap
|
|
(define gwin (widget-window client-gtk))
|
|
(define display (gdk_x11_display_get_xdisplay (gdk_window_get_display gwin)))
|
|
(define sf (->screen (gtk_widget_get_scale_factor client-gtk)))
|
|
(define w (send bm get-width))
|
|
(define h (send bm get-height))
|
|
(define bms (send bm get-backing-scale))
|
|
(define cw (inexact->exact (ceiling (* sf w))))
|
|
(define ch (inexact->exact (ceiling (* sf h))))
|
|
(define visual (gdk_window_get_visual gwin))
|
|
(define pixmap (XCreatePixmap display
|
|
(gdk_x11_window_get_xid gwin)
|
|
cw ch
|
|
(gdk_visual_get_depth visual)))
|
|
(define s (cairo_xlib_surface_create display
|
|
(cast pixmap _pointer _ulong)
|
|
(gdk_x11_visual_get_xvisual visual)
|
|
cw ch))
|
|
(define cr (cairo_create s))
|
|
(define pat (cairo_pattern_create_for_surface (send bm get-handle)))
|
|
(cairo_pattern_set_matrix pat (make-cairo_matrix_t (/ bms sf) 0.0
|
|
0.0 (/ bms sf)
|
|
0.0 0.0))
|
|
(cairo_set_source cr pat)
|
|
(cairo_pattern_destroy pat)
|
|
(cairo_rectangle cr 0 0 cw ch)
|
|
(cairo_fill cr)
|
|
(cairo_destroy cr)
|
|
(cairo_surface_destroy s)
|
|
pixmap]
|
|
[else
|
|
;; Generate a Gdk Pixbuf
|
|
(bitmap->pixbuf bm (->screen 1.0))]))
|
|
|
|
(define (create-gc-window client-gtk x y w h)
|
|
(define cwin (widget-window client-gtk))
|
|
(cond
|
|
[gtk3?
|
|
;; Work at the level of X11 to change the screen without an event loop
|
|
(define display (gdk_x11_display_get_xdisplay (gdk_window_get_display cwin)))
|
|
(define s (gtk_widget_get_scale_factor client-gtk))
|
|
(cons display
|
|
(XCreateSimpleWindow display
|
|
(gdk_x11_window_get_xid cwin)
|
|
(* s x) (* s y) (* s w) (* s h) 0 0 0))]
|
|
[else
|
|
(gdk_window_new cwin (make-GdkWindowAttr
|
|
""
|
|
0
|
|
x y w h
|
|
GDK_INPUT_OUTPUT
|
|
#f #f
|
|
GDK_WINDOW_CHILD
|
|
#f
|
|
"" "" #f 0)
|
|
(bitwise-ior GDK_WA_X
|
|
GDK_WA_Y))]))
|
|
|
|
(define (free-gc-window win)
|
|
(cond
|
|
[gtk3? (XDestroyWindow (car win) (cdr win))]
|
|
[else (g_object_unref win)]))
|
|
|
|
(define (make-draw win gc-bitmap w h)
|
|
(cond
|
|
[gtk3? (vector 'ptr_ptr_ptr->void
|
|
XSetWindowBackgroundPixmap
|
|
(car win)
|
|
(cdr win)
|
|
gc-bitmap)]
|
|
[else (vector 'ptr_ptr_ptr_int_int_int_int_int_int_int_int_int->void
|
|
gdk_draw_pixbuf
|
|
win #f gc-bitmap
|
|
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 gc-bitmap w h)
|
|
(cond
|
|
[gtk3? (vector
|
|
(make-draw win gc-bitmap w h)
|
|
(vector 'ptr_ptr_ptr->void
|
|
XMapRaised
|
|
(car win)
|
|
(cdr win)
|
|
#f)
|
|
(make-flush))]
|
|
[else (vector
|
|
(vector 'ptr_ptr_ptr->void gdk_window_show win #f #f)
|
|
(make-draw win gc-bitmap w h)
|
|
(make-flush))]))
|
|
|
|
(define (make-gc-hide-desc win gc-bitmap w h)
|
|
(vector
|
|
;; draw the ``off'' bitmap so we can flush immediately
|
|
(make-draw win gc-bitmap w h)
|
|
(make-flush)
|
|
;; hide the window; it may take a while for the underlying canvas
|
|
;; to refresh:
|
|
(if gtk3?
|
|
(vector 'ptr_ptr_ptr->void
|
|
XUnmapWindow
|
|
(car win)
|
|
(cast (cdr win) _Window _pointer)
|
|
#f)
|
|
(vector 'ptr_ptr_ptr->void gdk_window_hide win #f #f))))
|