3 (defun g-value-zero (g-value)
4 "Initializes the GValue in \"unset\" state.
6 @arg[g-value]{a C pointer to the GValue structure}"
8 for i from 0 below (foreign-type-size 'g-value)
9 do (setf (mem-ref g-value :uchar i) 0)))
11 (defun gvalue-type (gvalue)
12 (foreign-slot-value gvalue 'g-value :type))
14 (defmacro ev-case (keyform &body clauses)
15 "Macro that is an analogue of CASE except that it evaluates keyforms"
16 (let ((value (gensym)))
17 `(let ((,value ,keyform))
20 for (key . forms) in clauses
24 `((equalp ,key ,value) ,@forms)))))))
26 (defgeneric parse-gvalue-for-type (gvalue-ptr type-numeric))
28 (defmethod parse-gvalue-for-type (gvalue-ptr type-numeric)
29 (if (= type-numeric (g-type-numeric (g-type-fundamental type-numeric)))
31 (parse-gvalue-for-type gvalue-ptr (g-type-numeric (g-type-fundamental type-numeric)))))
33 (defun parse-gvalue (gvalue)
34 "Parses the GValue structure and returns the corresponding Lisp object.
36 @arg[value]{a C pointer to the GValue structure}
37 @return{value contained in the GValue structure. Type of value depends on GValue type}"
38 (let* ((type (g-type-numeric (gvalue-type gvalue)))
39 (fundamental-type (g-type-numeric (g-type-fundamental type))))
40 (ev-case fundamental-type
41 (+g-type-invalid+ (error "GValue is of invalid type (~A)" (g-type-name type)))
43 (+g-type-char+ (g-value-get-char gvalue))
44 (+g-type-uchar+ (g-value-get-uchar gvalue))
45 (+g-type-boolean+ (g-value-get-boolean gvalue))
46 (+g-type-int+ (g-value-get-int gvalue))
47 (+g-type-uint+ (g-value-get-uint gvalue))
48 (+g-type-long+ (g-value-get-long gvalue))
49 (+g-type-ulong+ (g-value-get-ulong gvalue))
50 (+g-type-int64+ (g-value-get-int64 gvalue))
51 (+g-type-uint64+ (g-value-get-uint64 gvalue))
52 (+g-type-enum+ (parse-gvalue-enum gvalue))
53 (+g-type-flags+ (parse-gvalue-flags gvalue))
54 (+g-type-float+ (g-value-get-float gvalue))
55 (+g-type-double+ (g-value-get-double gvalue))
56 (+g-type-string+ (g-value-get-string gvalue))
57 (t (parse-gvalue-for-type gvalue type)))))
59 (defmethod parse-gvalue-for-type (gvalue-ptr (type-numeric (eql +g-type-pointer+)))
60 (g-value-get-pointer gvalue-ptr))
62 (defmethod parse-gvalue-for-type (gvalue-ptr (type-numeric (eql +g-type-param+)))
63 (parse-g-param-spec (g-value-get-param gvalue-ptr)))
65 (defgeneric set-gvalue-for-type (gvalue-ptr type-numeric value))
67 (defmethod set-gvalue-for-type (gvalue-ptr type-numeric value)
68 (if (= type-numeric (g-type-numeric (g-type-fundamental type-numeric)))
70 (set-gvalue-for-type gvalue-ptr (g-type-numeric (g-type-fundamental type-numeric)) value)))
72 (defun set-g-value (gvalue value type &key zero-g-value unset-g-value (g-value-init t))
73 "Assigns the GValue structure @code{gvalue} the value @code{value} of GType @code{type}.
75 @arg[gvalue]{a C pointer to the GValue structure}
76 @arg[value]{a Lisp object that is to be assigned}
77 @arg[type]{a GType that is to be assigned}
78 @arg[zero-g-value]{a boolean specifying whether GValue should be zero-initialized before assigning. See @fun{g-value-zero}}
79 @arg[unset-g-value]{a boolean specifying whether GValue should be \"unset\" before assigning. See @fun{g-value-unset}. The \"true\" value should not be passed to both @code{zero-g-value} and @code{unset-g-value} arguments}
80 @arg[g-value-init]{a boolean specifying where GValue should be initialized}"
81 (setf type (g-type-numeric type))
83 (zero-g-value (g-value-zero gvalue))
84 (unset-g-value (g-value-unset gvalue)))
85 (when g-value-init (g-value-init gvalue type))
86 (let ((fundamental-type (ensure-g-type (g-type-fundamental type))))
87 (ev-case fundamental-type
88 (+g-type-invalid+ (error "Invalid type (~A)" type))
90 (+g-type-char+ (g-value-set-char gvalue value))
91 (+g-type-uchar+ (g-value-set-uchar gvalue value))
92 (+g-type-boolean+ (g-value-set-boolean gvalue value))
93 (+g-type-int+ (g-value-set-int gvalue value))
94 (+g-type-uint+ (g-value-set-uint gvalue value))
95 (+g-type-long+ (g-value-set-long gvalue value))
96 (+g-type-ulong+ (g-value-set-ulong gvalue value))
97 (+g-type-int64+ (g-value-set-int64 gvalue value))
98 (+g-type-uint64+ (g-value-set-uint64 gvalue value))
99 (+g-type-enum+ (set-gvalue-enum gvalue value))
100 (+g-type-flags+ (set-gvalue-flags gvalue value))
101 (+g-type-float+ (unless (realp value) (error "~A is not a real number" value)) (g-value-set-float gvalue (coerce value 'single-float)))
102 (+g-type-double+ (unless (realp value) (error "~A is not a real number" value)) (g-value-set-double gvalue (coerce value 'double-float)))
103 (+g-type-string+ (g-value-set-string gvalue value))
104 (t (set-gvalue-for-type gvalue type value)))))
106 (defmethod set-gvalue-for-type (gvalue-ptr (type-numeric (eql +g-type-pointer+)) value)
107 (g-value-set-pointer gvalue-ptr value))
109 (defmethod set-gvalue-for-type (gvalue-ptr (type-numeric (eql +g-type-param+)) value)
110 (error "Setting of GParam is not implemented"))
114 (defvar *registered-enum-types* (make-hash-table :test 'equal))
115 (defun register-enum-type (name type)
116 (setf (gethash name *registered-enum-types*) type))
117 (defun registered-enum-type (name)
118 (gethash name *registered-enum-types*))
120 (defun parse-gvalue-enum (gvalue)
121 (let* ((g-type (gvalue-type gvalue))
122 (type-name (g-type-name g-type))
123 (enum-type (registered-enum-type type-name)))
125 (error "Enum ~A is not registered" type-name))
126 (convert-from-foreign (g-value-get-enum gvalue) enum-type)))
128 (defun set-gvalue-enum (gvalue value)
129 (let* ((g-type (gvalue-type gvalue))
130 (type-name (g-type-name g-type))
131 (enum-type (registered-enum-type type-name)))
133 (error "Enum ~A is not registered" type-name))
134 (g-value-set-enum gvalue (convert-to-foreign value enum-type))))
139 (defvar *registered-flags-types* (make-hash-table :test 'equal))
140 (defun register-flags-type (name type)
141 (setf (gethash name *registered-flags-types*) type))
142 (defun registered-flags-type (name)
143 (gethash name *registered-flags-types*))
145 (defun parse-gvalue-flags (gvalue)
146 (let* ((g-type (gvalue-type gvalue))
147 (type-name (g-type-name g-type))
148 (flags-type (registered-flags-type type-name)))
150 (error "Flags ~A is not registered" type-name))
151 (convert-from-foreign (g-value-get-flags gvalue) flags-type)))
153 (defun set-gvalue-flags (gvalue value)
154 (let* ((g-type (gvalue-type gvalue))
155 (type-name (g-type-name g-type))
156 (flags-type (registered-flags-type type-name)))
158 (error "Flags ~A is not registered" type-name))
159 (g-value-set-flags gvalue (convert-to-foreign value flags-type))))
163 (defun parse-gvalue-object (gvalue)
164 (get-g-object-for-pointer (g-value-get-object gvalue)))
166 (defun set-gvalue-object (gvalue value)
167 (g-value-set-object gvalue (if value (pointer value) (null-pointer))))