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 g-value-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-g-value-for-type
(gvalue-ptr gtype parse-kind
))
28 (defmethod parse-g-value-for-type :around
(gvalue-ptr gtype parse-kind
)
29 (assert (typep gtype
'(or gtype nil
)))
32 (defmethod parse-g-value-for-type (gvalue-ptr gtype parse-kind
)
33 (if (eq gtype
(g-type-fundamental gtype
))
35 (parse-g-value-for-type gvalue-ptr
(g-type-fundamental gtype
) parse-kind
)))
37 (defun parse-g-value (gvalue &key
(parse-kind :get-property
))
38 "Parses the GValue structure and returns the corresponding Lisp object.
40 @arg[value]{a C pointer to the GValue structure}
41 @return{value contained in the GValue structure. Type of value depends on GValue type}"
42 (let* ((type (g-value-type gvalue
))
43 (fundamental-type (g-type-fundamental type
)))
44 (ev-case fundamental-type
45 ((gtype +g-type-invalid
+) (error "GValue is of invalid type (~A)" (gtype-name type
)))
46 ((gtype +g-type-void
+) nil
)
47 ((gtype +g-type-char
+) (g-value-get-char gvalue
))
48 ((gtype +g-type-uchar
+) (g-value-get-uchar gvalue
))
49 ((gtype +g-type-boolean
+) (g-value-get-boolean gvalue
))
50 ((gtype +g-type-int
+) (g-value-get-int gvalue
))
51 ((gtype +g-type-uint
+) (g-value-get-uint gvalue
))
52 ((gtype +g-type-long
+) (g-value-get-long gvalue
))
53 ((gtype +g-type-ulong
+) (g-value-get-ulong gvalue
))
54 ((gtype +g-type-int64
+) (g-value-get-int64 gvalue
))
55 ((gtype +g-type-uint64
+) (g-value-get-uint64 gvalue
))
56 ((gtype +g-type-enum
+) (parse-g-value-enum gvalue
))
57 ((gtype +g-type-flags
+) (parse-g-value-flags gvalue
))
58 ((gtype +g-type-float
+) (g-value-get-float gvalue
))
59 ((gtype +g-type-double
+) (g-value-get-double gvalue
))
60 ((gtype +g-type-string
+) (g-value-get-string gvalue
))
61 (t (parse-g-value-for-type gvalue type parse-kind
)))))
63 (defmethod parse-g-value-for-type (gvalue-ptr (type (eql (gtype +g-type-pointer
+))) parse-kind
)
64 (declare (ignore parse-kind
))
65 (g-value-get-pointer gvalue-ptr
))
67 (defmethod parse-g-value-for-type (gvalue-ptr (type (eql (gtype +g-type-param
+))) parse-kind
)
68 (declare (ignore parse-kind
))
69 (parse-g-param-spec (g-value-get-param gvalue-ptr
)))
71 (defgeneric set-gvalue-for-type
(gvalue-ptr type value
))
73 (defmethod set-gvalue-for-type :around
(gvalue-ptr type value
)
74 (assert (typep type
'(or gtype null
)))
77 (defmethod set-gvalue-for-type (gvalue-ptr type value
)
78 (if (eq type
(g-type-fundamental type
))
80 (set-gvalue-for-type gvalue-ptr
(g-type-fundamental type
) value
)))
82 (defun set-g-value (gvalue value type
&key zero-g-value unset-g-value
(g-value-init t
))
83 "Assigns the GValue structure @code{gvalue} the value @code{value} of GType @code{type}.
85 @arg[gvalue]{a C pointer to the GValue structure}
86 @arg[value]{a Lisp object that is to be assigned}
87 @arg[type]{a GType that is to be assigned}
88 @arg[zero-g-value]{a boolean specifying whether GValue should be zero-initialized before assigning. See @fun{g-value-zero}}
89 @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}
90 @arg[g-value-init]{a boolean specifying where GValue should be initialized}"
91 (setf type
(gtype type
))
93 (zero-g-value (g-value-zero gvalue
))
94 (unset-g-value (g-value-unset gvalue
)))
95 (when g-value-init
(g-value-init gvalue type
))
96 (let ((fundamental-type (g-type-fundamental type
)))
97 (ev-case fundamental-type
98 ((gtype +g-type-invalid
+) (error "Invalid type (~A)" type
))
99 ((gtype +g-type-void
+) nil
)
100 ((gtype +g-type-char
+) (g-value-set-char gvalue value
))
101 ((gtype +g-type-uchar
+) (g-value-set-uchar gvalue value
))
102 ((gtype +g-type-boolean
+) (g-value-set-boolean gvalue value
))
103 ((gtype +g-type-int
+) (g-value-set-int gvalue value
))
104 ((gtype +g-type-uint
+) (g-value-set-uint gvalue value
))
105 ((gtype +g-type-long
+) (g-value-set-long gvalue value
))
106 ((gtype +g-type-ulong
+) (g-value-set-ulong gvalue value
))
107 ((gtype +g-type-int64
+) (g-value-set-int64 gvalue value
))
108 ((gtype +g-type-uint64
+) (g-value-set-uint64 gvalue value
))
109 ((gtype +g-type-enum
+) (set-gvalue-enum gvalue value
))
110 ((gtype +g-type-flags
+) (set-gvalue-flags gvalue value
))
111 ((gtype +g-type-float
+) (unless (realp value
) (error "~A is not a real number" value
)) (g-value-set-float gvalue
(coerce value
'single-float
)))
112 ((gtype +g-type-double
+) (unless (realp value
) (error "~A is not a real number" value
)) (g-value-set-double gvalue
(coerce value
'double-float
)))
113 ((gtype +g-type-string
+) (g-value-set-string gvalue value
))
114 (t (set-gvalue-for-type gvalue type value
)))))
116 (defmethod set-gvalue-for-type (gvalue-ptr (type (eql (gtype +g-type-pointer
+))) value
)
117 (g-value-set-pointer gvalue-ptr value
))
119 (defmethod set-gvalue-for-type (gvalue-ptr (type (eql (gtype +g-type-param
+))) value
)
120 (declare (ignore gvalue-ptr value
))
121 (error "Setting of GParam is not implemented"))
125 (defvar *registered-enum-types
* (make-hash-table :test
'equal
))
126 (defun register-enum-type (name type
)
127 (setf (gethash name
*registered-enum-types
*) type
))
128 (defun registered-enum-type (name)
129 (gethash name
*registered-enum-types
*))
131 (defun parse-g-value-enum (gvalue)
132 (let* ((g-type (g-value-type gvalue
))
133 (type-name (gtype-name g-type
))
134 (enum-type (registered-enum-type type-name
)))
136 (error "Enum ~A is not registered" type-name
))
137 (convert-from-foreign (g-value-get-enum gvalue
) enum-type
)))
139 (defun set-gvalue-enum (gvalue value
)
140 (let* ((g-type (g-value-type gvalue
))
141 (type-name (gtype-name g-type
))
142 (enum-type (registered-enum-type type-name
)))
144 (error "Enum ~A is not registered" type-name
))
145 (g-value-set-enum gvalue
(convert-to-foreign value enum-type
))))
150 (defvar *registered-flags-types
* (make-hash-table :test
'equal
))
151 (defun register-flags-type (name type
)
152 (setf (gethash name
*registered-flags-types
*) type
))
153 (defun registered-flags-type (name)
154 (gethash name
*registered-flags-types
*))
156 (defun parse-g-value-flags (gvalue)
157 (let* ((g-type (g-value-type gvalue
))
158 (type-name (gtype-name g-type
))
159 (flags-type (registered-flags-type type-name
)))
161 (error "Flags ~A is not registered" type-name
))
162 (convert-from-foreign (g-value-get-flags gvalue
) flags-type
)))
164 (defun set-gvalue-flags (gvalue value
)
165 (let* ((g-type (g-value-type gvalue
))
166 (type-name (gtype-name g-type
))
167 (flags-type (registered-flags-type type-name
)))
169 (error "Flags ~A is not registered" type-name
))
170 (g-value-set-flags gvalue
(convert-to-foreign value flags-type
))))