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 type-numeric parse-kind
))
28 (defmethod parse-g-value-for-type (gvalue-ptr type-numeric parse-kind
)
29 (if (g-type= type-numeric
(g-type-fundamental type-numeric
))
31 (parse-g-value-for-type gvalue-ptr
(g-type-numeric (g-type-fundamental type-numeric
)) parse-kind
)))
33 (defun parse-g-value (gvalue &key
(parse-kind :get-property
))
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 (g-value-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-g-value-enum gvalue
))
53 (+g-type-flags
+ (parse-g-value-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-g-value-for-type gvalue type parse-kind
)))))
59 (defmethod parse-g-value-for-type (gvalue-ptr (type-numeric (eql +g-type-pointer
+)) parse-kind
)
60 (declare (ignore parse-kind
))
61 (g-value-get-pointer gvalue-ptr
))
63 (defmethod parse-g-value-for-type (gvalue-ptr (type-numeric (eql +g-type-param
+)) parse-kind
)
64 (declare (ignore parse-kind
))
65 (parse-g-param-spec (g-value-get-param gvalue-ptr
)))
67 (defgeneric set-gvalue-for-type
(gvalue-ptr type-numeric value
))
69 (defmethod set-gvalue-for-type (gvalue-ptr type-numeric value
)
70 (if (g-type= type-numeric
(g-type-fundamental type-numeric
))
72 (set-gvalue-for-type gvalue-ptr
(g-type-numeric (g-type-fundamental type-numeric
)) value
)))
74 (defun set-g-value (gvalue value type
&key zero-g-value unset-g-value
(g-value-init t
))
75 "Assigns the GValue structure @code{gvalue} the value @code{value} of GType @code{type}.
77 @arg[gvalue]{a C pointer to the GValue structure}
78 @arg[value]{a Lisp object that is to be assigned}
79 @arg[type]{a GType that is to be assigned}
80 @arg[zero-g-value]{a boolean specifying whether GValue should be zero-initialized before assigning. See @fun{g-value-zero}}
81 @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}
82 @arg[g-value-init]{a boolean specifying where GValue should be initialized}"
83 (setf type
(g-type-numeric type
))
85 (zero-g-value (g-value-zero gvalue
))
86 (unset-g-value (g-value-unset gvalue
)))
87 (when g-value-init
(g-value-init gvalue type
))
88 (let ((fundamental-type (ensure-g-type (g-type-fundamental type
))))
89 (ev-case fundamental-type
90 (+g-type-invalid
+ (error "Invalid type (~A)" type
))
92 (+g-type-char
+ (g-value-set-char gvalue value
))
93 (+g-type-uchar
+ (g-value-set-uchar gvalue value
))
94 (+g-type-boolean
+ (g-value-set-boolean gvalue value
))
95 (+g-type-int
+ (g-value-set-int gvalue value
))
96 (+g-type-uint
+ (g-value-set-uint gvalue value
))
97 (+g-type-long
+ (g-value-set-long gvalue value
))
98 (+g-type-ulong
+ (g-value-set-ulong gvalue value
))
99 (+g-type-int64
+ (g-value-set-int64 gvalue value
))
100 (+g-type-uint64
+ (g-value-set-uint64 gvalue value
))
101 (+g-type-enum
+ (set-gvalue-enum gvalue value
))
102 (+g-type-flags
+ (set-gvalue-flags gvalue value
))
103 (+g-type-float
+ (unless (realp value
) (error "~A is not a real number" value
)) (g-value-set-float gvalue
(coerce value
'single-float
)))
104 (+g-type-double
+ (unless (realp value
) (error "~A is not a real number" value
)) (g-value-set-double gvalue
(coerce value
'double-float
)))
105 (+g-type-string
+ (g-value-set-string gvalue value
))
106 (t (set-gvalue-for-type gvalue type value
)))))
108 (defmethod set-gvalue-for-type (gvalue-ptr (type-numeric (eql +g-type-pointer
+)) value
)
109 (g-value-set-pointer gvalue-ptr value
))
111 (defmethod set-gvalue-for-type (gvalue-ptr (type-numeric (eql +g-type-param
+)) value
)
112 (declare (ignore gvalue-ptr value
))
113 (error "Setting of GParam is not implemented"))
117 (defvar *registered-enum-types
* (make-hash-table :test
'equal
))
118 (defun register-enum-type (name type
)
119 (setf (gethash name
*registered-enum-types
*) type
))
120 (defun registered-enum-type (name)
121 (gethash name
*registered-enum-types
*))
123 (defun parse-g-value-enum (gvalue)
124 (let* ((g-type (g-value-type gvalue
))
125 (type-name (g-type-name g-type
))
126 (enum-type (registered-enum-type type-name
)))
128 (error "Enum ~A is not registered" type-name
))
129 (convert-from-foreign (g-value-get-enum gvalue
) enum-type
)))
131 (defun set-gvalue-enum (gvalue value
)
132 (let* ((g-type (g-value-type gvalue
))
133 (type-name (g-type-name g-type
))
134 (enum-type (registered-enum-type type-name
)))
136 (error "Enum ~A is not registered" type-name
))
137 (g-value-set-enum gvalue
(convert-to-foreign value enum-type
))))
142 (defvar *registered-flags-types
* (make-hash-table :test
'equal
))
143 (defun register-flags-type (name type
)
144 (setf (gethash name
*registered-flags-types
*) type
))
145 (defun registered-flags-type (name)
146 (gethash name
*registered-flags-types
*))
148 (defun parse-g-value-flags (gvalue)
149 (let* ((g-type (g-value-type gvalue
))
150 (type-name (g-type-name g-type
))
151 (flags-type (registered-flags-type type-name
)))
153 (error "Flags ~A is not registered" type-name
))
154 (convert-from-foreign (g-value-get-flags gvalue
) flags-type
)))
156 (defun set-gvalue-flags (gvalue value
)
157 (let* ((g-type (g-value-type gvalue
))
158 (type-name (g-type-name g-type
))
159 (flags-type (registered-flags-type type-name
)))
161 (error "Flags ~A is not registered" type-name
))
162 (g-value-set-flags gvalue
(convert-to-foreign value flags-type
))))