chiark / gitweb /
Return a more robust warning when we try to define a type with a
[clg] / glib / gparam.lisp
index 05ccca1f4547fb675a63794ab5138eee5892a47e..15a9f68012b39c9928cd94c0bd538d98a527b1ef 100644 (file)
@@ -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.21 2006-04-25 22:12:48 espen Exp $
+;; $Id: gparam.lisp,v 1.27 2008-11-04 03:22:23 espen Exp $
 
 (in-package "GLIB")
 
@@ -32,7 +32,11 @@ (eval-when (:compile-toplevel :load-toplevel :execute)
   (defbinding (size-of-gvalue "size_of_gvalue") () unsigned-int))
 
 (defconstant +gvalue-size+ (size-of-gvalue))
-(defconstant +gvalue-value-offset+ (size-of 'type-number))
+(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)
@@ -41,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+)))
@@ -60,7 +64,29 @@ (defun gvalue-free (gvalue &optional (unset-p t))
     (deallocate-memory gvalue)))
 
 (defun gvalue-type (gvalue)
-  (type-from-number (ref-type-number gvalue)))
+  ;; We need to search for the for the most specific known type
+  ;; because internal types, unknown to Lisp, may be passed in GValues
+  (labels ((find-most-specific-known-type (type)
+            (or 
+             (type-from-number type)
+             (let ((parent (type-parent type)))
+               (unless (zerop parent)
+                 (find-most-specific-known-type parent))))))
+    (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))
@@ -71,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)
@@ -85,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))))