fix some issues with freeing Xft/fontconfig resources.
Remaining problem: - XftFontsetDestroy() calls free() for each XftPattern stored in the Fontset. XftPatterns created by MAKE-XFT-PATTERN get their own finalizer, thus if added to the fontset, there might be two calls to free() for that object. That needs fixing.
This commit is contained in:
parent
6ae8950d98
commit
afb80004d6
|
@ -37,6 +37,7 @@ EXTRA_DIST = \
|
||||||
scheme/libs/xpm.scm \
|
scheme/libs/xpm.scm \
|
||||||
scheme/libs/xft.scm \
|
scheme/libs/xft.scm \
|
||||||
scheme/libs/xrender.scm \
|
scheme/libs/xrender.scm \
|
||||||
|
scheme/libs/weak-list.scm \
|
||||||
scheme/xt/widget-type.scm \
|
scheme/xt/widget-type.scm \
|
||||||
scheme/xt/widget.scm \
|
scheme/xt/widget.scm \
|
||||||
scheme/xt/resource-types.scm
|
scheme/xt/resource-types.scm
|
||||||
|
|
|
@ -116,3 +116,11 @@
|
||||||
set-xrendercolor-green!
|
set-xrendercolor-green!
|
||||||
set-xrendercolor-blue!
|
set-xrendercolor-blue!
|
||||||
set-xrendercolor-alpha!))
|
set-xrendercolor-alpha!))
|
||||||
|
|
||||||
|
(define-interface weak-table-interface
|
||||||
|
(export
|
||||||
|
make-value-weak-table
|
||||||
|
weak-table?
|
||||||
|
add-to-weak-table!
|
||||||
|
remove-from-weak-table!
|
||||||
|
lookup-in-weak-table))
|
||||||
|
|
|
@ -13,7 +13,9 @@
|
||||||
define-record-types
|
define-record-types
|
||||||
finite-types
|
finite-types
|
||||||
srfi-1
|
srfi-1
|
||||||
external-calls)
|
external-calls
|
||||||
|
weak-table
|
||||||
|
weak)
|
||||||
(files xft))
|
(files xft))
|
||||||
|
|
||||||
(define-structure xrender xrender-interface
|
(define-structure xrender xrender-interface
|
||||||
|
@ -21,4 +23,10 @@
|
||||||
define-record-types
|
define-record-types
|
||||||
external-calls)
|
external-calls)
|
||||||
(files xrender))
|
(files xrender))
|
||||||
|
|
||||||
|
(define-structure weak-table weak-table-interface
|
||||||
|
(open scheme
|
||||||
|
srfi-9
|
||||||
|
general-tables
|
||||||
|
weak)
|
||||||
|
(files weak-table))
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
;;; weak table with weak values
|
||||||
|
|
||||||
|
(define-record-type weak-table
|
||||||
|
(really-make-weak-table table)
|
||||||
|
weak-table?
|
||||||
|
(table weak-table-table))
|
||||||
|
|
||||||
|
(define (make-value-weak-table)
|
||||||
|
(really-make-weak-table (make-integer-table)))
|
||||||
|
|
||||||
|
(define (add-to-weak-table! table address object)
|
||||||
|
(table-set! (weak-table-table table)
|
||||||
|
address
|
||||||
|
(make-weak-pointer object)))
|
||||||
|
|
||||||
|
(define (remove-from-weak-table! table address)
|
||||||
|
(table-set! (weak-table-table table)
|
||||||
|
address #f))
|
||||||
|
|
||||||
|
(define (lookup-in-weak-table table address)
|
||||||
|
(cond
|
||||||
|
((table-ref (weak-table-table table) address)
|
||||||
|
=> weak-pointer-ref)
|
||||||
|
(else #f)))
|
|
@ -1,4 +1,42 @@
|
||||||
|
|
||||||
|
;; *object-table* maps each Xft object (identified by its memory
|
||||||
|
;; address) to the correspoding Scheme object. This avoids situations
|
||||||
|
;; where we have two pointer Scheme objects for one Xft object. In
|
||||||
|
;; these situations we would call the finalizer (Xft free() operation)
|
||||||
|
;; on twice on the same object. This may crash the system, or, at
|
||||||
|
;; least print bogus error messages.
|
||||||
|
;; Key is an integer (memory address of the Xft structure), value a
|
||||||
|
;; weak pointer to the Scheme object.
|
||||||
|
|
||||||
|
(define *freed-objects* '())
|
||||||
|
|
||||||
|
(define *object-table*
|
||||||
|
(make-value-weak-table))
|
||||||
|
|
||||||
|
(define (register-xft-pointer! pointer object)
|
||||||
|
(add-to-weak-table! *object-table* pointer object))
|
||||||
|
|
||||||
|
(define (unregister-xft-pointer! pointer)
|
||||||
|
(remove-from-weak-table! *object-table* pointer))
|
||||||
|
|
||||||
|
(define (lookup-xft-pointer pointer)
|
||||||
|
(lookup-in-weak-table *object-table* pointer))
|
||||||
|
|
||||||
|
;; Be careful about sequence in which we call the finalizers on Xft
|
||||||
|
;; objects. There are some dependencies which impose constraints on
|
||||||
|
;; the sequence we can call the finalizers. Ok, maybe I'm a bit
|
||||||
|
;; paranoid about that.
|
||||||
|
|
||||||
|
(define (cons-weak obj list)
|
||||||
|
(cons (make-weak-pointer obj) list))
|
||||||
|
|
||||||
|
(define (filter-collected list)
|
||||||
|
(filter (lambda (weak-pointer)
|
||||||
|
(not (weak-pointer-ref weak-pointer)))
|
||||||
|
list))
|
||||||
|
|
||||||
|
;; types
|
||||||
|
|
||||||
(define-record-type xft-pattern :xft-pattern
|
(define-record-type xft-pattern :xft-pattern
|
||||||
(really-make-xft-pattern c-pointer)
|
(really-make-xft-pattern c-pointer)
|
||||||
xft-pattern?
|
xft-pattern?
|
||||||
|
@ -40,10 +78,10 @@
|
||||||
(define-exported-binding "xft-objectset" :xft-objectset)
|
(define-exported-binding "xft-objectset" :xft-objectset)
|
||||||
|
|
||||||
(define-record-type xft-fontset :xft-fontset
|
(define-record-type xft-fontset :xft-fontset
|
||||||
(really-make-xft-fontset c-pointer patterns)
|
(really-make-xft-fontset c-pointer dependencies)
|
||||||
xft-fontset?
|
xft-fontset?
|
||||||
(c-pointer xft-fontset-c-pointer)
|
(c-pointer xft-fontset-c-pointer)
|
||||||
(patterns xft-fontset-patterns set-xft-fontset-patterns!))
|
(dependencies xft-fontset-dependencies set-xft-fontset-dependencies!))
|
||||||
|
|
||||||
(define-exported-binding "xft-fontset" :xft-fontset)
|
(define-exported-binding "xft-fontset" :xft-fontset)
|
||||||
|
|
||||||
|
@ -174,17 +212,76 @@
|
||||||
(else
|
(else
|
||||||
(error "scx: internal error. Could not map rgba id to finite type"))))))
|
(error "scx: internal error. Could not map rgba id to finite type"))))))
|
||||||
|
|
||||||
;;; add finalizers
|
(define (xft-pattern-finalizer pattern)
|
||||||
|
(if (member (xft-pattern-c-pointer pattern) *freed-objects*)
|
||||||
|
(error "free() called twice on" pattern)
|
||||||
|
(set! *freed-objects* (cons (xft-pattern-c-pointer pattern) *freed-objects*)))
|
||||||
|
(unregister-xft-pointer! (xft-pattern-c-pointer pattern))
|
||||||
|
(xft-pattern-destroy pattern))
|
||||||
|
|
||||||
|
(define (xft-color-finalizer color)
|
||||||
|
(if (member (xft-color-c-pointer color) *freed-objects*)
|
||||||
|
(error "free() called twice on" color)
|
||||||
|
(set! *freed-objects* (cons (xft-color-c-pointer color) *freed-objects*)))
|
||||||
|
(unregister-xft-pointer! (xft-color-c-pointer color))
|
||||||
|
(xft-color-free (xft-color-display color)
|
||||||
|
(xft-color-visual color)
|
||||||
|
(xft-color-colormap color)
|
||||||
|
color))
|
||||||
|
|
||||||
|
(define (xft-draw-finalizer draw)
|
||||||
|
(if (member (xft-draw-c-pointer draw) *freed-objects*)
|
||||||
|
(error "free() called twice on" draw)
|
||||||
|
(set! *freed-objects* (cons (xft-draw-c-pointer draw) *freed-objects*)))
|
||||||
|
(unregister-xft-pointer! (xft-draw-c-pointer draw))
|
||||||
|
(xft-draw-destroy draw))
|
||||||
|
|
||||||
|
(define (xft-objectset-finalizer objectset)
|
||||||
|
(if (member (xft-objectset-c-pointer objectset) *freed-objects*)
|
||||||
|
(error "free() called twice on" objectset)
|
||||||
|
(set! *freed-objects* (cons (xft-objectset-c-pointer objectset) *freed-objects*)))
|
||||||
|
(unregister-xft-pointer! (xft-objectset-c-pointer objectset))
|
||||||
|
(xft-objectset-destroy objectset))
|
||||||
|
|
||||||
|
(define (xft-fontset-finalizer fontset)
|
||||||
|
(cond
|
||||||
|
((null? (xft-fontset-dependencies fontset))
|
||||||
|
(add-finalizer! fontset xft-fontset-freeing-finalizer))
|
||||||
|
(else
|
||||||
|
(set-xft-fontset-dependencies!
|
||||||
|
fontset (filter-collected (xft-fontset-dependencies fontset)))
|
||||||
|
(add-finalizer! fontset xft-fontset-finalizer))))
|
||||||
|
|
||||||
|
(define (xft-fontset-freeing-finalizer fontset)
|
||||||
|
(if (member (xft-fontset-c-pointer fontset) *freed-objects*)
|
||||||
|
(error "free() called twice on" fontset)
|
||||||
|
(set! *freed-objects* (cons (xft-fontset-c-pointer fontset) *freed-objects*)))
|
||||||
|
(unregister-xft-pointer! (xft-fontset-c-pointer fontset))
|
||||||
|
(xft-fontset-destroy fontset))
|
||||||
|
|
||||||
|
(define (xft-font-finalizer font)
|
||||||
|
(if (member (xft-font-c-pointer font) *freed-objects*)
|
||||||
|
(error "free() called twice on" font)
|
||||||
|
(set! *freed-objects* (cons (xft-font-c-pointer font) *freed-objects*)))
|
||||||
|
(unregister-xft-pointer! (xft-font-c-pointer font))
|
||||||
|
(xft-font-close-internal font))
|
||||||
|
|
||||||
(define (make-xft-pattern)
|
(define (make-xft-pattern)
|
||||||
(let ((pattern (xft-pattern-create)))
|
(let ((pattern (xft-pattern-create)))
|
||||||
(add-finalizer! pattern xft-pattern-destroy)
|
(or (lookup-xft-pointer (xft-pattern-c-pointer pattern))
|
||||||
pattern))
|
(begin
|
||||||
|
(register-xft-pointer! (xft-pattern-c-pointer pattern) pattern)
|
||||||
|
(add-finalizer! pattern xft-pattern-finalizer)
|
||||||
|
pattern))))
|
||||||
|
|
||||||
(define (xft-pattern-duplicate pattern)
|
(define (xft-pattern-duplicate pattern)
|
||||||
(let ((copy (xft-pattern-duplicate-internal pattern)))
|
(let* ((copy (xft-pattern-duplicate-internal pattern))
|
||||||
(add-finalizer! copy xft-pattern-destroy)
|
(pointer (xft-pattern-c-pointer copy)))
|
||||||
copy))
|
(or (lookup-xft-pointer pointer)
|
||||||
|
(begin
|
||||||
|
(register-xft-pointer! pointer copy)
|
||||||
|
(add-finalizer! copy xft-pattern-finalizer)
|
||||||
|
copy))))
|
||||||
|
|
||||||
(define (xft-pattern-get pattern object id)
|
(define (xft-pattern-get pattern object id)
|
||||||
(let ((object-id (xft-pattern-object-id object)))
|
(let ((object-id (xft-pattern-object-id object)))
|
||||||
|
@ -230,43 +327,65 @@
|
||||||
(apply values
|
(apply values
|
||||||
(xft-font-match-internal display screen-number pattern))))
|
(xft-font-match-internal display screen-number pattern))))
|
||||||
(lambda (result pattern)
|
(lambda (result pattern)
|
||||||
(add-finalizer! pattern xft-pattern-destroy)
|
(let ((pointer (xft-pattern-c-pointer pattern)))
|
||||||
(values result pattern))))
|
(cond
|
||||||
|
((lookup-xft-pointer pointer)
|
||||||
(define (xft-font-close font)
|
=> (lambda (obj) (values result obj)))
|
||||||
(xft-font-close (xft-font-display font) font))
|
(else
|
||||||
|
(register-xft-pointer! (xft-pattern-c-pointer pattern) pattern)
|
||||||
|
(add-finalizer! pattern xft-pattern-finalizer)
|
||||||
|
(values result pattern)))))))
|
||||||
|
|
||||||
(define (xft-font-open-pattern display pattern)
|
(define (xft-font-open-pattern display pattern)
|
||||||
(let ((font (xft-font-open-pattern-internal display pattern)))
|
(let ((font (xft-font-open-pattern-internal display pattern)))
|
||||||
(if font (add-finalizer! font xft-font-close))
|
(or (lookup-xft-pointer (xft-font-c-pointer font))
|
||||||
font))
|
(begin
|
||||||
|
(register-xft-pointer! (xft-font-c-pointer font) font)
|
||||||
|
(add-finalizer! font xft-font-finalizer)
|
||||||
|
font))))
|
||||||
|
|
||||||
(define (xft-font-open-name display screen name)
|
(define (xft-font-open-name display screen name)
|
||||||
(let* ((screen-number (screen:number screen))
|
(let* ((screen-number (screen:number screen))
|
||||||
(font (xft-font-open-name-internal display screen-number name)))
|
(font (xft-font-open-name-internal display screen-number name)))
|
||||||
(if font (add-finalizer! font xft-font-close))
|
(or (lookup-xft-pointer (xft-font-c-pointer font))
|
||||||
font))
|
(begin
|
||||||
|
(register-xft-pointer! (xft-font-c-pointer font) font)
|
||||||
|
(add-finalizer! font xft-font-finalizer)
|
||||||
|
font))))
|
||||||
|
|
||||||
(define (xft-font-open-xlfd display screen name)
|
(define (xft-font-open-xlfd display screen name)
|
||||||
(let* ((screen-numer (screen:number screen))
|
(let* ((screen-numer (screen:number screen))
|
||||||
(font (xft-font-open-xlfd-internal display screen-numer name)))
|
(font (xft-font-open-xlfd-internal display screen-numer name)))
|
||||||
(if font (add-finalizer! font xft-font-close))
|
(or (lookup-xft-pointer (xft-font-c-pointer font) font)
|
||||||
font))
|
(begin
|
||||||
|
(register-xft-pointer! (xft-font-c-pointer font) font)
|
||||||
|
(add-finalizer! font xft-font-finalizer)
|
||||||
|
font))))
|
||||||
|
|
||||||
(define (make-xft-draw display drawable visual colormap)
|
(define (make-xft-draw display drawable visual colormap)
|
||||||
(let ((draw (xft-draw-create-internal display drawable visual colormap)))
|
(let ((draw (xft-draw-create-internal display drawable visual colormap)))
|
||||||
(add-finalizer! draw xft-draw-destroy)
|
(or (lookup-xft-pointer (xft-draw-c-pointer draw))
|
||||||
draw))
|
(begin
|
||||||
|
(register-xft-pointer! (xft-draw-c-pointer draw) draw)
|
||||||
|
(add-finalizer! draw xft-draw-finalizer)
|
||||||
|
draw))))
|
||||||
|
|
||||||
(define (make-xft-draw-bitmap display drawable)
|
(define (make-xft-draw-bitmap display drawable)
|
||||||
(let ((draw (xft-draw-create-bitmap-internal display drawable)))
|
(let ((draw (xft-draw-create-bitmap-internal display drawable)))
|
||||||
(add-finalizer! draw xft-draw-destroy)
|
(or (lookup-xft-pointer (xft-draw-c-pointer draw))
|
||||||
draw))
|
(begin
|
||||||
|
(register-xft-pointer! (xft-draw-c-pointer draw) draw)
|
||||||
|
(add-finalizer! draw xft-draw-finalizer)
|
||||||
|
draw))))
|
||||||
|
|
||||||
(define (make-xft-objectset)
|
(define (make-xft-objectset)
|
||||||
(let ((objectset (xft-objectset-create)))
|
(let ((objectset (xft-objectset-create)))
|
||||||
(add-finalizer! objectset xft-objectset-destroy)
|
(or (lookup-xft-pointer (xft-objectset-c-pointer objectset))
|
||||||
objectset))
|
(begin
|
||||||
|
(register-xft-pointer! (xft-objectset-c-pointer objectset)
|
||||||
|
objectset)
|
||||||
|
(add-finalizer! objectset xft-objectset-finalizer)
|
||||||
|
objectset))))
|
||||||
|
|
||||||
(define (xft-objectset-add objectset pattern-object)
|
(define (xft-objectset-add objectset pattern-object)
|
||||||
(xft-objectset-add-internal
|
(xft-objectset-add-internal
|
||||||
|
@ -274,46 +393,59 @@
|
||||||
|
|
||||||
(define (xft-draw-display draw)
|
(define (xft-draw-display draw)
|
||||||
(let ((display (xft-draw-display-internal draw)))
|
(let ((display (xft-draw-display-internal draw)))
|
||||||
(if display
|
(or display
|
||||||
display
|
|
||||||
(error "XftDrawDisplay() unavailable in this version of Xft"))))
|
(error "XftDrawDisplay() unavailable in this version of Xft"))))
|
||||||
|
|
||||||
(define (xft-draw-drawable draw)
|
(define (xft-draw-drawable draw)
|
||||||
(let ((drawable (xft-draw-drawable-internal draw)))
|
(let ((drawable (xft-draw-drawable-internal draw)))
|
||||||
(if drawable
|
(or drawable
|
||||||
drawable
|
|
||||||
(error "XftDrawDrawable() unavailable in this version of Xft"))))
|
(error "XftDrawDrawable() unavailable in this version of Xft"))))
|
||||||
|
|
||||||
(define (xft-draw-colormap draw)
|
(define (xft-draw-colormap draw)
|
||||||
(let ((colormap (xft-draw-colormap-internal draw)))
|
(let ((colormap (xft-draw-colormap-internal draw)))
|
||||||
(if colormap
|
(or colormap
|
||||||
colormap
|
|
||||||
(error "XftDrawColormap() unavailable in this version of Xft"))))
|
(error "XftDrawColormap() unavailable in this version of Xft"))))
|
||||||
|
|
||||||
(define (xft-draw-visual draw)
|
(define (xft-draw-visual draw)
|
||||||
(let ((visual (xft-draw-visual-internal draw)))
|
(let ((visual (xft-draw-visual-internal draw)))
|
||||||
(if visual
|
(or visual
|
||||||
visual
|
|
||||||
(error "XftDrawVisual() unavailable in this version of Xft"))))
|
(error "XftDrawVisual() unavailable in this version of Xft"))))
|
||||||
|
|
||||||
(define (xft-list-fonts-pattern-objects display screen pattern objectset)
|
(define (xft-list-fonts-pattern-objects display screen pattern objectset)
|
||||||
(let* ((screen-number (screen:number screen))
|
(let* ((screen-number (screen:number screen))
|
||||||
(fontset (xft-list-fonts-pattern-objects-internal
|
(fontset (xft-list-fonts-pattern-objects-internal
|
||||||
display screen-number pattern objectset)))
|
display screen-number pattern objectset)))
|
||||||
(add-finalizer! fontset xft-fontset-destroy)
|
(or (lookup-xft-pointer (xft-fontset-c-pointer fontset))
|
||||||
fontset))
|
(begin
|
||||||
|
(register-xft-pointer! (xft-fontset-c-pointer fontset) fontset)
|
||||||
|
(set-xft-fontset-dependencies! fontset '())
|
||||||
|
(add-finalizer! fontset xft-fontset-finalizer)
|
||||||
|
fontset))))
|
||||||
|
|
||||||
(define (make-xft-fontset)
|
(define (make-xft-fontset)
|
||||||
(let ((fontset (xft-fontset-create)))
|
(let ((fontset (xft-fontset-create)))
|
||||||
(set-xft-fontset-patterns! fontset '())
|
(or (lookup-xft-pointer (xft-fontset-c-pointer fontset))
|
||||||
(add-finalizer! fontset xft-fontset-create)
|
(begin
|
||||||
fontset))
|
(register-xft-pointer! (xft-fontset-c-pointer fontset) fontset)
|
||||||
|
(set-xft-fontset-dependencies! fontset '())
|
||||||
|
(add-finalizer! fontset xft-fontset-finalizer)
|
||||||
|
fontset))))
|
||||||
|
|
||||||
(define (xft-fontset-add fontset pattern)
|
(define (xft-fontset-add fontset pattern)
|
||||||
(set-xft-fontset-patterns!
|
(set-xft-fontset-dependencies!
|
||||||
fontset (lset-adjoin eq? pattern (xft-fontset-patterns fontset)))
|
fontset (cons-weak pattern (xft-fontset-dependencies fontset)))
|
||||||
(xft-fontset-add-internal fontset pattern))
|
(xft-fontset-add-internal fontset pattern))
|
||||||
|
|
||||||
|
(define (xft-fontset-ref fontset index)
|
||||||
|
(let ((pattern (xft-fontset-ref-internal fontset index)))
|
||||||
|
(or (lookup-xft-pointer (xft-pattern-c-pointer pattern))
|
||||||
|
(begin
|
||||||
|
(register-xft-pointer! (xft-pattern-c-pointer pattern) pattern)
|
||||||
|
(set-xft-fontset-dependencies!
|
||||||
|
fontset (cons-weak pattern (xft-fontset-dependencies fontset)))
|
||||||
|
;(add-finalizer! pattern xft-pattern-finalizer)
|
||||||
|
pattern))))
|
||||||
|
|
||||||
(define (xft-color-alloc-name display visual colormap name)
|
(define (xft-color-alloc-name display visual colormap name)
|
||||||
(call-with-values
|
(call-with-values
|
||||||
(lambda ()
|
(lambda ()
|
||||||
|
@ -342,12 +474,6 @@
|
||||||
(add-finalizer! color xft-color-finalizer)
|
(add-finalizer! color xft-color-finalizer)
|
||||||
color)))
|
color)))
|
||||||
|
|
||||||
(define (xft-color-finalizer color)
|
|
||||||
(xft-color-free (xft-color-display color)
|
|
||||||
(xft-color-visual color)
|
|
||||||
(xft-color-colormap color)
|
|
||||||
color))
|
|
||||||
|
|
||||||
(define (xft-default-substitute display screen pattern)
|
(define (xft-default-substitute display screen pattern)
|
||||||
(xft-default-substitute-internal display (screen:number screen) pattern))
|
(xft-default-substitute-internal display (screen:number screen) pattern))
|
||||||
|
|
||||||
|
@ -391,7 +517,7 @@
|
||||||
"scx_XftPatternCreate")
|
"scx_XftPatternCreate")
|
||||||
|
|
||||||
(import-lambda-definition xft-pattern-destroy
|
(import-lambda-definition xft-pattern-destroy
|
||||||
()
|
(pattern)
|
||||||
"scx_XftPatternDestroy")
|
"scx_XftPatternDestroy")
|
||||||
|
|
||||||
(import-lambda-definition xft-pattern-duplicate-internal
|
(import-lambda-definition xft-pattern-duplicate-internal
|
||||||
|
@ -550,6 +676,6 @@
|
||||||
(fontset)
|
(fontset)
|
||||||
"scx_xftfontset_count_get")
|
"scx_xftfontset_count_get")
|
||||||
|
|
||||||
(import-lambda-definition xft-fontset-ref
|
(import-lambda-definition xft-fontset-ref-internal
|
||||||
(fontset index)
|
(fontset index)
|
||||||
"scx_xftfontset_pattern_ref")
|
"scx_xftfontset_pattern_ref")
|
||||||
|
|
Loading…
Reference in New Issue