chiark / gitweb /
Bug fix
[clg] / glib / gtype.lisp
CommitLineData
112ac1d3 1;; Common Lisp bindings for GTK+ v2.x
74821f75 2;; Copyright 2000-2006 Espen S. Johnsen <espen@users.sf.net>
560af5c5 3;;
112ac1d3 4;; Permission is hereby granted, free of charge, to any person obtaining
5;; a copy of this software and associated documentation files (the
6;; "Software"), to deal in the Software without restriction, including
7;; without limitation the rights to use, copy, modify, merge, publish,
8;; distribute, sublicense, and/or sell copies of the Software, and to
9;; permit persons to whom the Software is furnished to do so, subject to
10;; the following conditions:
560af5c5 11;;
112ac1d3 12;; The above copyright notice and this permission notice shall be
13;; included in all copies or substantial portions of the Software.
560af5c5 14;;
112ac1d3 15;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17;; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18;; IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19;; CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20;; TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21;; SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
d32cbb7a 23;; $Id: gtype.lisp,v 1.55 2006-08-25 10:37:33 espen Exp $
560af5c5 24
25(in-package "GLIB")
26
27(use-prefix "g")
28
e0349dbd 29;; Initialize the glib type system
30(defbinding type-init () nil)
31(type-init)
560af5c5 32
42e68ad2 33(deftype type-number () 'unsigned-long)
560af5c5 34
e74cfcab 35(deftype gtype () 'symbol)
36
75689fea 37(define-type-method alien-type ((type gtype))
38 (declare (ignore type))
e74cfcab 39 (alien-type 'type-number))
40
74821f75 41(define-type-method size-of ((type gtype) &key (inlined t))
42 (assert-inlined type inlined)
e74cfcab 43 (size-of 'type-number))
44
74821f75 45(define-type-method to-alien-form ((type gtype) gtype &optional copy-p)
46 (declare (ignore type copy-p))
e74cfcab 47 `(find-type-number ,gtype t))
48
74821f75 49(define-type-method to-alien-function ((type gtype) &optional copy-p)
50 (declare (ignore type copy-p))
e74cfcab 51 #'(lambda (gtype)
52 (find-type-number gtype t)))
53
74821f75 54(define-type-method from-alien-form ((type gtype) form &key ref)
55 (declare (ignore type ref))
56 `(type-from-number ,form))
e74cfcab 57
74821f75 58(define-type-method from-alien-function ((type gtype) &key ref)
59 (declare (ignore type ref))
e74cfcab 60 #'(lambda (type-number)
63752532 61 (type-from-number type-number)))
e74cfcab 62
74821f75 63(define-type-method writer-function ((type gtype) &key temp (inlined t))
64 (declare (ignore temp))
65 (assert-inlined type inlined)
e74cfcab 66 (let ((writer (writer-function 'type-number)))
67 #'(lambda (gtype location &optional (offset 0))
68 (funcall writer (find-type-number gtype t) location offset))))
69
74821f75 70(define-type-method reader-function ((type gtype) &key ref (inlined t))
71 (declare (ignore ref))
72 (assert-inlined type inlined)
e74cfcab 73 (let ((reader (reader-function 'type-number)))
74821f75 74 #'(lambda (location &optional (offset 0))
63752532 75 (type-from-number (funcall reader location offset)))))
e74cfcab 76
77
93aa67db 78(eval-when (:compile-toplevel :load-toplevel :execute)
d4b21b08 79 (defclass type-query (struct)
93aa67db 80 ((type-number :allocation :alien :type type-number)
74821f75 81 (name :allocation :alien :type (copy-of string))
93aa67db 82 (class-size :allocation :alien :type unsigned-int)
83 (instance-size :allocation :alien :type unsigned-int))
d168bafd 84 (:metaclass struct-class)))
93aa67db 85
86
e74cfcab 87(defbinding type-query (type) nil
88 ((find-type-number type t) type-number)
74821f75 89 ((make-instance 'type-query) type-query :in/return))
93aa67db 90
91(defun type-instance-size (type)
92 (slot-value (type-query type) 'instance-size))
93
94(defun type-class-size (type)
95 (slot-value (type-query type) 'class-size))
560af5c5 96
d4b21b08 97(defbinding type-class-ref (type) pointer
98 ((find-type-number type t) type-number))
560af5c5 99
74821f75 100(defbinding type-class-unref () nil
101 (class pointer))
93aa67db 102
d4b21b08 103(defbinding type-class-peek (type) pointer
104 ((find-type-number type t) type-number))
93aa67db 105
560af5c5 106
74821f75 107
d4b21b08 108;;;; Mapping between lisp types and glib types
560af5c5 109
dfa4f314 110(defvar *registered-types* ())
111(defvar *registered-type-aliases* ())
44f47f3d 112(defvar *registered-static-types* ())
dfa4f314 113(defvar *lisp-type-to-type-number* (make-hash-table))
114(defvar *type-number-to-lisp-type* (make-hash-table))
d4b21b08 115
116(defbinding %type-from-name () type-number
117 (name string))
118
dfa4f314 119(defun type-number-from-glib-name (name &optional (error-p t))
120 (let ((type-number (%type-from-name name)))
121 (cond
122 ((not (zerop type-number)) type-number)
123 (error-p (error "Invalid gtype name: ~A" name)))))
124
d32cbb7a 125(defun type-from-glib-name (name)
126 (type-from-number (type-number-from-glib-name name) t))
127
dfa4f314 128(defun register-type (type id)
74821f75 129 (cond
130 ((find-type-number type))
131 ((not id) (warn "Can't register type with no foreign id: ~A" type))
132 (t
133 (pushnew (cons type id) *registered-types* :key #'car)
134 (let ((type-number
135 (typecase id
136 (string (type-number-from-glib-name id))
137 (symbol (funcall id)))))
138 (setf (gethash type *lisp-type-to-type-number*) type-number)
139 (setf (gethash type-number *type-number-to-lisp-type*) type)
140 type-number))))
dfa4f314 141
142(defun register-type-alias (type alias)
143 (pushnew (cons type alias) *registered-type-aliases* :key #'car)
144 (setf
145 (gethash type *lisp-type-to-type-number*)
146 (find-type-number alias t)))
147
148(defun reinitialize-all-types ()
149 (clrhash *lisp-type-to-type-number*)
150 (clrhash *type-number-to-lisp-type*)
151 (type-init) ; initialize the glib type system
152 (mapc #'(lambda (type)
153 (register-type (car type) (cdr type)))
154 *registered-types*)
58a1fb1d 155 (mapc #'(lambda (type)
74821f75 156 (apply #'register-new-type type))
d32cbb7a 157 (reverse *registered-static-types*))
dfa4f314 158 (mapc #'(lambda (type)
159 (register-type-alias (car type) (cdr type)))
160 *registered-type-aliases*))
161
162(pushnew 'reinitialize-all-types
163 #+cmu *after-save-initializations*
74821f75 164 #+sbcl *init-hooks*
165 #+clisp custom:*init-hooks*)
dfa4f314 166
167#+cmu
168(pushnew 'system::reinitialize-global-table ; we shouldn't have to do this?
169 *after-save-initializations*)
170
171
172(defun find-type-number (type &optional error-p)
560af5c5 173 (etypecase type
174 (integer type)
dfa4f314 175 (string (type-number-from-glib-name type error-p))
d4b21b08 176 (symbol
dfa4f314 177 (or
178 (gethash type *lisp-type-to-type-number*)
179 (and error-p (error "Type not registered: ~A" type))))
180 (class (find-type-number (class-name type) error-p))))
560af5c5 181
4de90d10 182(defun type-from-number (type-number &optional error)
183 (multiple-value-bind (type found)
dfa4f314 184 (gethash type-number *type-number-to-lisp-type*)
e7dbc3bf 185 (if found
186 type
dfa4f314 187 (let ((name (find-foreign-type-name type-number)))
e7dbc3bf 188 (cond
cd859052 189 ((and name (not (= (type-number-from-glib-name name nil) type-number)))
e7dbc3bf 190 ;; This is a hack because GdkEvent seems to be registered
191 ;; multiple times
192 (type-from-number (type-number-from-glib-name name)))
193 ((and error name)
194 (error "Type number not registered: ~A (~A)" type-number name))
195 ((and error)
196 (error "Invalid type number: ~A" type-number)))))))
560af5c5 197
dfa4f314 198(defbinding (find-foreign-type-name "g_type_name") (type) (copy-of string)
d4b21b08 199 ((find-type-number type t) type-number))
200
201(defun type-number-of (object)
202 (find-type-number (type-of object) t))
203
21299acf 204(eval-when (:compile-toplevel :load-toplevel :execute)
dfa4f314 205 (defvar *type-initializers* ())
206 (defun %find-types-in-library (pathname prefixes ignore)
74821f75 207 (let ((process
208 (run-program
209 "/usr/bin/nm"
210 #+clisp :arguments
211 (list "--defined-only" "-D" (namestring (truename pathname)))
212 :output :stream :wait nil)))
21299acf 213 (unwind-protect
214 (loop
74821f75 215 as symbol = (let ((line (read-line
216 #+(or cmu sbcl)
217 (process-output process)
218 #+clisp process
219 nil)))
42e68ad2 220 (when line
221 (subseq line (1+ (position #\Space line :from-end t)))))
21299acf 222 while symbol
223 when (and
dfa4f314 224 (> (length symbol) 9)
225 (or
226 (not prefixes)
227 (some #'(lambda (prefix)
228 (and
229 (> (length symbol) (length prefix))
230 (string= prefix symbol :end2 (length prefix))))
231 (mklist prefixes)))
232 (string= "_get_type" symbol :start2 (- (length symbol) 9))
21299acf 233 (not (member symbol ignore :test #'string=)))
234 collect symbol)
74821f75 235 (#+(or cmu sbcl)process-close
236 #+clisp close
237 process)))))
21299acf 238
560af5c5 239
735a29da 240(defmacro init-types-in-library (filename &key prefix ignore)
21299acf 241 (let ((names (%find-types-in-library filename prefix ignore)))
242 `(progn
243 ,@(mapcar #'(lambda (name)
244 `(progn
245 (defbinding (,(intern name) ,name) () type-number)
dfa4f314 246 (,(intern name))
247 (pushnew ',(intern name) *type-initializers*)))
21299acf 248 names))))
249
dfa4f314 250(defun find-type-init-function (type-number)
735a29da 251 (loop
252 for type-init in *type-initializers*
253 when (= type-number (funcall type-init))
254 do (return type-init)))
255
256(defun register-type-as (type-number)
257 (or
258 (find-type-init-function type-number)
259 (find-foreign-type-name type-number)
260 (error "Unknown type-number: ~A" type-number)))
dfa4f314 261
262(defun default-type-init-name (type)
263 (find-symbol (format nil "~A_~A_get_type"
264 (package-prefix *package*)
265 (substitute #\_ #\- (string-downcase type)))))
266
21299acf 267
15cbdefc 268(eval-when (:compile-toplevel :load-toplevel :execute)
269 (defclass type-info (struct)
270 ((class-size :allocation :alien :type (unsigned 16) :initarg :class-size)
271 (base-init :allocation :alien :type pointer)
272 (base-finalize :allocation :alien :type pointer)
273 (class-init :allocation :alien :type pointer)
274 (class-finalize :allocation :alien :type pointer)
275 (class-data :allocation :alien :type pointer)
276 (instance-size :allocation :alien :type (unsigned 16)
277 :initarg :instance-size)
278 (n-preallocs :allocation :alien :type (unsigned 16))
279 (instance-init :allocation :alien :type pointer)
280 (value-table :allocation :alien :type pointer))
281 (:metaclass struct-class)))
282
283(defbinding %type-register-static () type-number
e7dbc3bf 284 (parent-type type-number)
15cbdefc 285 (name string)
286 (info type-info)
287 (0 unsigned-int))
288
92a07e63 289(defun register-new-type (type parent &optional foreign-name)
15cbdefc 290 (let ((parent-info (type-query parent)))
291 (with-slots ((parent-number type-number) class-size instance-size) parent-info
292 (let ((type-number
293 (%type-register-static
294 parent-number
92a07e63 295 (or foreign-name (default-alien-type-name type))
15cbdefc 296 (make-instance 'type-info :class-size class-size :instance-size instance-size))))
44f47f3d 297 (pushnew (list type parent foreign-name) *registered-static-types* :key #'car)
298 (setf (gethash type *lisp-type-to-type-number*) type-number)
299 (setf (gethash type-number *type-number-to-lisp-type*) type)
300 type-number))))
15cbdefc 301
302
21299acf 303
304;;;; Metaclass for subclasses of ginstance
305
306(eval-when (:compile-toplevel :load-toplevel :execute)
307 (defclass ginstance-class (proxy-class)
6497583a 308 ((gtype :initarg :gtype :initform nil :reader ginstance-class-gtype))))
cd859052 309
310
1eaa1bd6 311(defun update-size (class)
312 (let ((type-number (find-type-number class)))
313 (cond
74821f75 314 ((not (foreign-size-p class))
315 (setf (foreign-size class) (type-instance-size type-number)))
1eaa1bd6 316 ((and
74821f75 317 (foreign-size-p class)
318 (not (= (type-instance-size type-number) (foreign-size class))))
1eaa1bd6 319 (warn "Size mismatch for class ~A" class)))))
320
09f6e237 321
cd859052 322(defmethod finalize-inheritance ((class ginstance-class))
74821f75 323 (prog1
324 #+clisp(call-next-method)
325 (let* ((class-name (class-name class))
326 (super (most-specific-proxy-superclass class))
327 (gtype (or
328 (first (ginstance-class-gtype class))
329 (default-alien-type-name class-name)))
330 (type-number
331 (or
332 (find-type-number class-name)
333 (let ((type-number
334 (if (or
335 (symbolp gtype)
336 (type-number-from-glib-name gtype nil))
337 (register-type class-name gtype)
338 (register-new-type class-name (class-name super) gtype))))
339 (type-class-ref type-number)
340 type-number))))
584285fb 341 #+nil
74821f75 342 (when (and
343 (supertype type-number)
344 (not (eq (class-name super) (supertype type-number))))
345 (warn "Super class mismatch between CLOS and GObject for ~A"
346 class-name)))
347 (update-size class))
348 #-clisp(call-next-method))
1eaa1bd6 349
350
351(defmethod shared-initialize ((class ginstance-class) names &rest initargs)
74821f75 352 (declare (ignore names initargs))
1eaa1bd6 353 (call-next-method)
354 (when (class-finalized-p class)
355 (update-size class)))
356
4de90d10 357
21299acf 358(defmethod validate-superclass ((class ginstance-class) (super standard-class))
359 (subtypep (class-name super) 'ginstance))
360
560af5c5 361
93aa67db 362;;;; Superclass for wrapping types in the glib type system
560af5c5 363
364(eval-when (:compile-toplevel :load-toplevel :execute)
93aa67db 365 (defclass ginstance (proxy)
09f6e237 366 (;(class :allocation :alien :type pointer :offset 0)
367 )
368 (:metaclass proxy-class)
369 (:size #.(size-of 'pointer))))
560af5c5 370
74821f75 371(defun ref-type-number (location &optional offset)
372 (declare (ignore location offset)))
373
374(setf (symbol-function 'ref-type-number) (reader-function 'type-number))
375
895c9a9e 376(defun %type-number-of-ginstance (location)
74821f75 377 (let ((class (ref-pointer location)))
378 (ref-type-number class)))
560af5c5 379
74821f75 380(defmethod make-proxy-instance :around ((class ginstance-class) location
381 &rest initargs)
d168bafd 382 (declare (ignore class))
895c9a9e 383 (let ((class (labels ((find-known-class (type-number)
384 (or
385 (find-class (type-from-number type-number) nil)
386 (unless (zerop type-number)
387 (find-known-class (type-parent type-number))))))
388 (find-known-class (%type-number-of-ginstance location)))))
74821f75 389 ;; Note that chancing the class argument should not alter "the
8958fa4a 390 ;; ordered set of applicable methods" as specified in the
391 ;; Hyperspec
d168bafd 392 (if class
8958fa4a 393 (apply #'call-next-method class location initargs)
394 (error "Object at ~A has an unkown type number: ~A"
395 location (%type-number-of-ginstance location)))))
396
74821f75 397(define-type-method from-alien-form ((type ginstance) form &key (ref :copy))
398 (call-next-method type form :ref ref))
560af5c5 399
74821f75 400(define-type-method from-alien-function ((type ginstance) &key (ref :copy))
401 (call-next-method type :ref ref))
9ca5565a 402
560af5c5 403
d4b21b08 404;;;; Registering fundamental types
405
63752532 406(register-type 'nil "void")
d4b21b08 407(register-type 'pointer "gpointer")
408(register-type 'char "gchar")
409(register-type 'unsigned-char "guchar")
410(register-type 'boolean "gboolean")
d4b21b08 411(register-type 'int "gint")
73383a9e 412(register-type-alias 'integer 'int)
dfa4f314 413(register-type-alias 'fixnum 'int)
d4b21b08 414(register-type 'unsigned-int "guint")
415(register-type 'long "glong")
416(register-type 'unsigned-long "gulong")
417(register-type 'single-float "gfloat")
418(register-type 'double-float "gdouble")
a8cb9408 419(register-type 'pathname "gchararray")
4de90d10 420(register-type 'string "gchararray")
d4b21b08 421
422
62f12808 423;;;; Introspection of type information
d4b21b08 424
e77e7713 425(defvar *derivable-type-info* (make-hash-table))
d4b21b08 426
62f12808 427(defun register-derivable-type (type id expander &optional dependencies)
d4b21b08 428 (register-type type id)
e77e7713 429 (let ((type-number (register-type type id)))
62f12808 430 (setf
431 (gethash type-number *derivable-type-info*)
432 (list expander dependencies))))
d4b21b08 433
4de90d10 434(defun find-type-info (type)
435 (dolist (super (cdr (type-hierarchy type)))
e77e7713 436 (let ((info (gethash super *derivable-type-info*)))
4de90d10 437 (return-if info))))
438
62f12808 439(defun expand-type-definition (type forward-p options)
440 (let ((expander (first (find-type-info type))))
441 (funcall expander (find-type-number type t) forward-p options)))
d4b21b08 442
74821f75 443
d4b21b08 444(defbinding type-parent (type) type-number
445 ((find-type-number type t) type-number))
446
447(defun supertype (type)
448 (type-from-number (type-parent type)))
449
337933d8 450(defbinding %type-interfaces (type) pointer
451 ((find-type-number type t) type-number)
452 (n-interfaces unsigned-int :out))
453
454(defun type-interfaces (type)
455 (multiple-value-bind (array length) (%type-interfaces type)
456 (unwind-protect
d168bafd 457 (map-c-vector 'list #'identity array 'type-number length)
337933d8 458 (deallocate-memory array))))
459
460(defun implements (type)
461 (mapcar #'type-from-number (type-interfaces type)))
462
d4b21b08 463(defun type-hierarchy (type)
464 (let ((type-number (find-type-number type t)))
465 (unless (= type-number 0)
466 (cons type-number (type-hierarchy (type-parent type-number))))))
467
468(defbinding (type-is-p "g_type_is_a") (type super) boolean
469 ((find-type-number type) type-number)
470 ((find-type-number super) type-number))
471
472(defbinding %type-children () pointer
473 (type-number type-number)
474 (num-children unsigned-int :out))
475
476(defun map-subtypes (function type &optional prefix)
477 (let ((type-number (find-type-number type t)))
478 (multiple-value-bind (array length) (%type-children type-number)
479 (unwind-protect
d168bafd 480 (map-c-vector
d4b21b08 481 'nil
482 #'(lambda (type-number)
483 (when (or
484 (not prefix)
dfa4f314 485 (string-prefix-p prefix (find-foreign-type-name type-number)))
d4b21b08 486 (funcall function type-number))
487 (map-subtypes function type-number prefix))
488 array 'type-number length)
489 (deallocate-memory array)))))
490
491(defun find-types (prefix)
492 (let ((type-list nil))
e77e7713 493 (maphash
494 #'(lambda (type-number expander)
495 (declare (ignore expander))
496 (map-subtypes
497 #'(lambda (type-number)
498 (pushnew type-number type-list))
499 type-number prefix))
500 *derivable-type-info*)
d4b21b08 501 type-list))
502
74821f75 503(defun find-type-dependencies (type &optional options)
504 (let ((find-dependencies (second (find-type-info type))))
505 (when find-dependencies
506 (remove-duplicates
507 (mapcar #'find-type-number
508 (funcall find-dependencies (find-type-number type t) options))))))
509
510
511;; The argument is a list where each elements is on the form
584285fb 512;; (type . dependencies). This function will not handle indirect
513;; dependencies and types depending on them selve.
74821f75 514(defun sort-types-topologicaly (unsorted)
515 (flet ((depend-p (type1)
516 (find-if #'(lambda (type2)
517 (and
518 ;; If a type depends a subtype it has to be
519 ;; forward defined
520 (not (type-is-p (car type2) (car type1)))
521 (find (car type2) (cdr type1))))
522 unsorted)))
523 (let ((sorted
524 (loop
525 while unsorted
526 nconc (multiple-value-bind (sorted remaining)
527 (delete-collect-if
528 #'(lambda (type)
529 (or (not (cdr type)) (not (depend-p type))))
530 unsorted)
531 (cond
532 ((not sorted)
533 ;; We have a circular dependency which have to
534 ;; be resolved
535 (let ((selected
536 (find-if
537 #'(lambda (type)
538 (every
539 #'(lambda (dep)
540 (or
541 (not (type-is-p (car type) dep))
542 (not (find dep unsorted :key #'car))))
543 (cdr type)))
544 unsorted)))
545 (unless selected
546 (error "Couldn't resolve circular dependency"))
547 (setq unsorted (delete selected unsorted))
548 (list selected)))
549 (t
550 (setq unsorted remaining)
551 sorted))))))
552
553 ;; Mark types which have to be forward defined
554 (loop
555 for tmp on sorted
556 as (type . dependencies) = (first tmp)
557 collect (cons type (and
558 dependencies
559 (find-if #'(lambda (type)
560 (find (car type) dependencies))
561 (rest tmp))
562 t))))))
d4b21b08 563
564
565(defun expand-type-definitions (prefix &optional args)
dfa4f314 566 (flet ((type-options (type-number)
567 (let ((name (find-foreign-type-name type-number)))
4de90d10 568 (cdr (assoc name args :test #'string=)))))
d4b21b08 569
e77e7713 570 (let ((type-list
571 (delete-if
572 #'(lambda (type-number)
dfa4f314 573 (let ((name (find-foreign-type-name type-number)))
e77e7713 574 (or
575 (getf (type-options type-number) :ignore)
576 (find-if
577 #'(lambda (options)
578 (and
579 (string-prefix-p (first options) name)
80a09c29 580 (getf (cdr options) :ignore-prefix)
581 (not (some
582 #'(lambda (exception)
583 (string= name exception))
584 (getf (cdr options) :except)))))
e77e7713 585 args))))
586 (find-types prefix))))
21299acf 587
e77e7713 588 (dolist (type-number type-list)
dfa4f314 589 (let ((name (find-foreign-type-name type-number)))
e77e7713 590 (register-type
591 (getf (type-options type-number) :type (default-type-name name))
735a29da 592 (register-type-as type-number))))
21299acf 593
74821f75 594 ;; This is needed for some unknown reason to get type numbers right
595 (mapc #'find-type-dependencies type-list)
596
597 (let ((sorted-type-list
598 #+clisp (mapcar #'list type-list)
599 #-clisp
600 (sort-types-topologicaly
601 (mapcar
602 #'(lambda (type)
603 (cons type (find-type-dependencies type (type-options type))))
604 type-list))))
62f12808 605 `(progn
606 ,@(mapcar
21299acf 607 #'(lambda (pair)
608 (destructuring-bind (type . forward-p) pair
609 (expand-type-definition type forward-p (type-options type))))
610 sorted-type-list)
62f12808 611 ,@(mapcar
21299acf 612 #'(lambda (pair)
613 (destructuring-bind (type . forward-p) pair
614 (when forward-p
615 (expand-type-definition type nil (type-options type)))))
62f12808 616 sorted-type-list))))))
e77e7713 617
d4b21b08 618(defmacro define-types-by-introspection (prefix &rest args)
4de90d10 619 (expand-type-definitions prefix args))
21299acf 620
74821f75 621(defexport define-types-by-introspection (prefix &rest args)
fbd2b3d9 622 (list-autoexported-symbols (expand-type-definitions prefix args)))
74821f75 623
21299acf 624
625;;;; Initialize all non static types in GObject
626
627(init-types-in-library #.(concatenate 'string (pkg-config:pkg-variable "glib-2.0" "libdir") "/libgobject-2.0.so"))