X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~mdw/git/clg/blobdiff_plain/110bd96ce6f2ff1aa4f25f899e12a5c3e3125f61..HEAD:/glib/gparam.lisp diff --git a/glib/gparam.lisp b/glib/gparam.lisp index 6b4bf1b..15a9f68 100644 --- a/glib/gparam.lisp +++ b/glib/gparam.lisp @@ -20,7 +20,7 @@ ;; TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE ;; SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -;; $Id: gparam.lisp,v 1.24 2007-06-01 06:18:59 espen Exp $ +;; $Id: gparam.lisp,v 1.27 2008-11-04 03:22:23 espen Exp $ (in-package "GLIB") @@ -34,6 +34,9 @@ (defbinding (size-of-gvalue "size_of_gvalue") () unsigned-int)) (defconstant +gvalue-size+ (size-of-gvalue)) (defconstant +gvalue-value-offset+ (max (size-of 'type-number) (type-alignment '(unsigned-byte 64)))) +(defconstant +gvalue-flags-offset+ + (+ +gvalue-value-offset+ (size-of '(unsigned-byte 64)))) +(defconstant +gvalue-nocopy-contents-flag+ 27) (defbinding (%gvalue-init "g_value_init") () nil (value gvalue) @@ -42,10 +45,10 @@ (defbinding (%gvalue-init "g_value_init") () nil (defbinding (gvalue-unset "g_value_unset") () nil (value gvalue)) -(defun gvalue-init (gvalue type &optional (value nil value-p)) +(defun gvalue-init (gvalue type &optional (value nil value-p) temp-p) (%gvalue-init gvalue (find-type-number type)) (when value-p - (funcall (writer-function type) value gvalue +gvalue-value-offset+))) + (funcall (writer-function type :temp temp-p) value gvalue +gvalue-value-offset+))) (defun gvalue-new (&optional type (value nil value-p)) (let ((gvalue (allocate-memory +gvalue-size+))) @@ -69,10 +72,21 @@ (defun gvalue-type (gvalue) (let ((parent (type-parent type))) (unless (zerop parent) (find-most-specific-known-type parent)))))) - (or - (find-most-specific-known-type (ref-type-number gvalue)) - ;; This will signal an error if the type hierarchy is unknown - (type-from-number (ref-type-number gvalue) t)))) + (let ((type-number (ref-type-number gvalue))) + (unless (zerop type-number) + (or + (find-most-specific-known-type type-number) + ;; This will signal an error if the type hierarchy is unknown + (type-from-number type-number t)))))) + +(let ((flags-reader nil)) + (defun gvalue-static-p (gvalue) + (unless flags-reader + (setf flags-reader (reader-function 'unsigned-int))) + (prog1 + (ldb-test (byte 1 +gvalue-nocopy-contents-flag+) + (funcall flags-reader gvalue +gvalue-flags-offset+)) + (force-output)))) (defun gvalue-get (gvalue) (funcall (reader-function (gvalue-type gvalue)) @@ -83,7 +97,8 @@ (defun gvalue-peek (gvalue) gvalue +gvalue-value-offset+)) (defun gvalue-take (gvalue) - (funcall (reader-function (gvalue-type gvalue) :ref :get) + (funcall (reader-function (gvalue-type gvalue) + :ref (if (gvalue-static-p gvalue) :peek :get)) gvalue +gvalue-value-offset+)) (defun gvalue-set (gvalue value) @@ -97,7 +112,7 @@ (defbinding (gvalue-p "g_type_check_value") () boolean (defmacro with-gvalue ((gvalue &optional type (value nil value-p)) &body body) `(with-memory (,gvalue +gvalue-size+) ,(cond - ((and type value-p) `(gvalue-init ,gvalue ,type ,value)) + ((and type value-p) `(gvalue-init ,gvalue ,type ,value t)) (type `(gvalue-init ,gvalue ,type))) ,@body ,(unless value-p `(gvalue-take ,gvalue))))