Fixes for Mac OS X
[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
daa10b6d 23;; $Id: gtype.lisp,v 1.56 2006-08-30 11:11:03 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*)
155 (mapc #'(lambda (type)
74821f75 156 (apply #'register-new-type type))
d32cbb7a 157 (reverse *registered-static-types*))
58a1fb1d 158 (mapc #'(lambda (type)
dfa4f314 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
daa10b6d 211 (list #-darwin"--defined-only" #-darwin"-D" "-g" #+darwin"-f" (namestring (truename pathname)))
74821f75 212 :output :stream :wait nil)))
21299acf 213 (unwind-protect
214 (loop
daa10b6d 215 as symbol = (let* ((line (read-line
216 #+(or cmu sbcl)
217 (process-output process)
218 #+clisp process
219 nil))
220 (pos (position #\Space line :from-end t)))
221 (when (and line #+darwin(char= (char line (1- pos)) #\T))
222 (subseq line (1+ pos))))
21299acf 223 while symbol
224 when (and
dfa4f314 225 (> (length symbol) 9)
226 (or
227 (not prefixes)
228 (some #'(lambda (prefix)
229 (and
230 (> (length symbol) (length prefix))
231 (string= prefix symbol :end2 (length prefix))))
232 (mklist prefixes)))
233 (string= "_get_type" symbol :start2 (- (length symbol) 9))
21299acf 234 (not (member symbol ignore :test #'string=)))
235 collect symbol)
74821f75 236 (#+(or cmu sbcl)process-close
237 #+clisp close
238 process)))))
21299acf 239
560af5c5 240
735a29da 241(defmacro init-types-in-library (filename &key prefix ignore)
21299acf 242 (let ((names (%find-types-in-library filename prefix ignore)))
243 `(progn
244 ,@(mapcar #'(lambda (name)
245 `(progn
246 (defbinding (,(intern name) ,name) () type-number)
dfa4f314 247 (,(intern name))
248 (pushnew ',(intern name) *type-initializers*)))
21299acf 249 names))))
250
dfa4f314 251(defun find-type-init-function (type-number)
735a29da 252 (loop
253 for type-init in *type-initializers*
254 when (= type-number (funcall type-init))
255 do (return type-init)))
256
257(defun register-type-as (type-number)
258 (or
259 (find-type-init-function type-number)
260 (find-foreign-type-name type-number)
261 (error "Unknown type-number: ~A" type-number)))
dfa4f314 262
263(defun default-type-init-name (type)
264 (find-symbol (format nil "~A_~A_get_type"
265 (package-prefix *package*)
266 (substitute #\_ #\- (string-downcase type)))))
267
21299acf 268
15cbdefc 269(eval-when (:compile-toplevel :load-toplevel :execute)
270 (defclass type-info (struct)
271 ((class-size :allocation :alien :type (unsigned 16) :initarg :class-size)
272 (base-init :allocation :alien :type pointer)
273 (base-finalize :allocation :alien :type pointer)
274 (class-init :allocation :alien :type pointer)
275 (class-finalize :allocation :alien :type pointer)
276 (class-data :allocation :alien :type pointer)
277 (instance-size :allocation :alien :type (unsigned 16)
278 :initarg :instance-size)
279 (n-preallocs :allocation :alien :type (unsigned 16))
280 (instance-init :allocation :alien :type pointer)
281 (value-table :allocation :alien :type pointer))
282 (:metaclass struct-class)))
283
284(defbinding %type-register-static () type-number
e7dbc3bf 285 (parent-type type-number)
15cbdefc 286 (name string)
287 (info type-info)
288 (0 unsigned-int))
289
92a07e63 290(defun register-new-type (type parent &optional foreign-name)
15cbdefc 291 (let ((parent-info (type-query parent)))
292 (with-slots ((parent-number type-number) class-size instance-size) parent-info
293 (let ((type-number
294 (%type-register-static
295 parent-number
92a07e63 296 (or foreign-name (default-alien-type-name type))
15cbdefc 297 (make-instance 'type-info :class-size class-size :instance-size instance-size))))
44f47f3d 298 (pushnew (list type parent foreign-name) *registered-static-types* :key #'car)
299 (setf (gethash type *lisp-type-to-type-number*) type-number)
300 (setf (gethash type-number *type-number-to-lisp-type*) type)
301 type-number))))
15cbdefc 302
303
21299acf 304
305;;;; Metaclass for subclasses of ginstance
306
307(eval-when (:compile-toplevel :load-toplevel :execute)
308 (defclass ginstance-class (proxy-class)
6497583a 309 ((gtype :initarg :gtype :initform nil :reader ginstance-class-gtype))))
cd859052 310
311
1eaa1bd6 312(defun update-size (class)
313 (let ((type-number (find-type-number class)))
314 (cond
74821f75 315 ((not (foreign-size-p class))
316 (setf (foreign-size class) (type-instance-size type-number)))
1eaa1bd6 317 ((and
74821f75 318 (foreign-size-p class)
319 (not (= (type-instance-size type-number) (foreign-size class))))
1eaa1bd6 320 (warn "Size mismatch for class ~A" class)))))
321
09f6e237 322
cd859052 323(defmethod finalize-inheritance ((class ginstance-class))
74821f75 324 (prog1
325 #+clisp(call-next-method)
326 (let* ((class-name (class-name class))
327 (super (most-specific-proxy-superclass class))
328 (gtype (or
329 (first (ginstance-class-gtype class))
330 (default-alien-type-name class-name)))
331 (type-number
332 (or
333 (find-type-number class-name)
334 (let ((type-number
335 (if (or
336 (symbolp gtype)
337 (type-number-from-glib-name gtype nil))
338 (register-type class-name gtype)
339 (register-new-type class-name (class-name super) gtype))))
340 (type-class-ref type-number)
341 type-number))))
584285fb 342 #+nil
74821f75 343 (when (and
344 (supertype type-number)
345 (not (eq (class-name super) (supertype type-number))))
346 (warn "Super class mismatch between CLOS and GObject for ~A"
347 class-name)))
348 (update-size class))
349 #-clisp(call-next-method))
1eaa1bd6 350
351
352(defmethod shared-initialize ((class ginstance-class) names &rest initargs)
74821f75 353 (declare (ignore names initargs))
1eaa1bd6 354 (call-next-method)
355 (when (class-finalized-p class)
356 (update-size class)))
357
4de90d10 358
21299acf 359(defmethod validate-superclass ((class ginstance-class) (super standard-class))
360 (subtypep (class-name super) 'ginstance))
361
560af5c5 362
93aa67db 363;;;; Superclass for wrapping types in the glib type system
560af5c5 364
365(eval-when (:compile-toplevel :load-toplevel :execute)
93aa67db 366 (defclass ginstance (proxy)
09f6e237 367 (;(class :allocation :alien :type pointer :offset 0)
368 )
369 (:metaclass proxy-class)
370 (:size #.(size-of 'pointer))))
560af5c5 371
74821f75 372(defun ref-type-number (location &optional offset)
373 (declare (ignore location offset)))
374
375(setf (symbol-function 'ref-type-number) (reader-function 'type-number))
376
895c9a9e 377(defun %type-number-of-ginstance (location)
74821f75 378 (let ((class (ref-pointer location)))
379 (ref-type-number class)))
560af5c5 380
74821f75 381(defmethod make-proxy-instance :around ((class ginstance-class) location
382 &rest initargs)
d168bafd 383 (declare (ignore class))
895c9a9e 384 (let ((class (labels ((find-known-class (type-number)
385 (or
386 (find-class (type-from-number type-number) nil)
387 (unless (zerop type-number)
388 (find-known-class (type-parent type-number))))))
389 (find-known-class (%type-number-of-ginstance location)))))
74821f75 390 ;; Note that chancing the class argument should not alter "the
8958fa4a 391 ;; ordered set of applicable methods" as specified in the
392 ;; Hyperspec
d168bafd 393 (if class
8958fa4a 394 (apply #'call-next-method class location initargs)
395 (error "Object at ~A has an unkown type number: ~A"
396 location (%type-number-of-ginstance location)))))
397
74821f75 398(define-type-method from-alien-form ((type ginstance) form &key (ref :copy))
399 (call-next-method type form :ref ref))
560af5c5 400
74821f75 401(define-type-method from-alien-function ((type ginstance) &key (ref :copy))
402 (call-next-method type :ref ref))
9ca5565a 403
560af5c5 404
d4b21b08 405;;;; Registering fundamental types
406
63752532 407(register-type 'nil "void")
d4b21b08 408(register-type 'pointer "gpointer")
409(register-type 'char "gchar")
410(register-type 'unsigned-char "guchar")
411(register-type 'boolean "gboolean")
d4b21b08 412(register-type 'int "gint")
73383a9e 413(register-type-alias 'integer 'int)
dfa4f314 414(register-type-alias 'fixnum 'int)
d4b21b08 415(register-type 'unsigned-int "guint")
416(register-type 'long "glong")
417(register-type 'unsigned-long "gulong")
418(register-type 'single-float "gfloat")
419(register-type 'double-float "gdouble")
a8cb9408 420(register-type 'pathname "gchararray")
4de90d10 421(register-type 'string "gchararray")
d4b21b08 422
423
62f12808 424;;;; Introspection of type information
d4b21b08 425
e77e7713 426(defvar *derivable-type-info* (make-hash-table))
d4b21b08 427
62f12808 428(defun register-derivable-type (type id expander &optional dependencies)
d4b21b08 429 (register-type type id)
e77e7713 430 (let ((type-number (register-type type id)))
62f12808 431 (setf
432 (gethash type-number *derivable-type-info*)
433 (list expander dependencies))))
d4b21b08 434
4de90d10 435(defun find-type-info (type)
436 (dolist (super (cdr (type-hierarchy type)))
e77e7713 437 (let ((info (gethash super *derivable-type-info*)))
4de90d10 438 (return-if info))))
439
62f12808 440(defun expand-type-definition (type forward-p options)
441 (let ((expander (first (find-type-info type))))
442 (funcall expander (find-type-number type t) forward-p options)))
d4b21b08 443
74821f75 444
d4b21b08 445(defbinding type-parent (type) type-number
446 ((find-type-number type t) type-number))
447
448(defun supertype (type)
449 (type-from-number (type-parent type)))
450
337933d8 451(defbinding %type-interfaces (type) pointer
452 ((find-type-number type t) type-number)
453 (n-interfaces unsigned-int :out))
454
455(defun type-interfaces (type)
456 (multiple-value-bind (array length) (%type-interfaces type)
457 (unwind-protect
d168bafd 458 (map-c-vector 'list #'identity array 'type-number length)
337933d8 459 (deallocate-memory array))))
460
461(defun implements (type)
462 (mapcar #'type-from-number (type-interfaces type)))
463
d4b21b08 464(defun type-hierarchy (type)
465 (let ((type-number (find-type-number type t)))
466 (unless (= type-number 0)
467 (cons type-number (type-hierarchy (type-parent type-number))))))
468
469(defbinding (type-is-p "g_type_is_a") (type super) boolean
470 ((find-type-number type) type-number)
471 ((find-type-number super) type-number))
472
473(defbinding %type-children () pointer
474 (type-number type-number)
475 (num-children unsigned-int :out))
476
477(defun map-subtypes (function type &optional prefix)
478 (let ((type-number (find-type-number type t)))
479 (multiple-value-bind (array length) (%type-children type-number)
480 (unwind-protect
d168bafd 481 (map-c-vector
d4b21b08 482 'nil
483 #'(lambda (type-number)
484 (when (or
485 (not prefix)
dfa4f314 486 (string-prefix-p prefix (find-foreign-type-name type-number)))
d4b21b08 487 (funcall function type-number))
488 (map-subtypes function type-number prefix))
489 array 'type-number length)
490 (deallocate-memory array)))))
491
492(defun find-types (prefix)
493 (let ((type-list nil))
e77e7713 494 (maphash
495 #'(lambda (type-number expander)
496 (declare (ignore expander))
497 (map-subtypes
498 #'(lambda (type-number)
499 (pushnew type-number type-list))
500 type-number prefix))
501 *derivable-type-info*)
d4b21b08 502 type-list))
503
74821f75 504(defun find-type-dependencies (type &optional options)
505 (let ((find-dependencies (second (find-type-info type))))
506 (when find-dependencies
507 (remove-duplicates
508 (mapcar #'find-type-number
509 (funcall find-dependencies (find-type-number type t) options))))))
510
511
512;; The argument is a list where each elements is on the form
584285fb 513;; (type . dependencies). This function will not handle indirect
514;; dependencies and types depending on them selve.
74821f75 515(defun sort-types-topologicaly (unsorted)
516 (flet ((depend-p (type1)
517 (find-if #'(lambda (type2)
518 (and
519 ;; If a type depends a subtype it has to be
520 ;; forward defined
521 (not (type-is-p (car type2) (car type1)))
522 (find (car type2) (cdr type1))))
523 unsorted)))
524 (let ((sorted
525 (loop
526 while unsorted
527 nconc (multiple-value-bind (sorted remaining)
528 (delete-collect-if
529 #'(lambda (type)
530 (or (not (cdr type)) (not (depend-p type))))
531 unsorted)
532 (cond
533 ((not sorted)
534 ;; We have a circular dependency which have to
535 ;; be resolved
536 (let ((selected
537 (find-if
538 #'(lambda (type)
539 (every
540 #'(lambda (dep)
541 (or
542 (not (type-is-p (car type) dep))
543 (not (find dep unsorted :key #'car))))
544 (cdr type)))
545 unsorted)))
546 (unless selected
547 (error "Couldn't resolve circular dependency"))
548 (setq unsorted (delete selected unsorted))
549 (list selected)))
550 (t
551 (setq unsorted remaining)
552 sorted))))))
553
554 ;; Mark types which have to be forward defined
555 (loop
556 for tmp on sorted
557 as (type . dependencies) = (first tmp)
558 collect (cons type (and
559 dependencies
560 (find-if #'(lambda (type)
561 (find (car type) dependencies))
562 (rest tmp))
563 t))))))
d4b21b08 564
565
566(defun expand-type-definitions (prefix &optional args)
dfa4f314 567 (flet ((type-options (type-number)
568 (let ((name (find-foreign-type-name type-number)))
4de90d10 569 (cdr (assoc name args :test #'string=)))))
d4b21b08 570
e77e7713 571 (let ((type-list
572 (delete-if
573 #'(lambda (type-number)
dfa4f314 574 (let ((name (find-foreign-type-name type-number)))
e77e7713 575 (or
576 (getf (type-options type-number) :ignore)
577 (find-if
578 #'(lambda (options)
579 (and
580 (string-prefix-p (first options) name)
80a09c29 581 (getf (cdr options) :ignore-prefix)
582 (not (some
583 #'(lambda (exception)
584 (string= name exception))
585 (getf (cdr options) :except)))))
e77e7713 586 args))))
587 (find-types prefix))))
21299acf 588
e77e7713 589 (dolist (type-number type-list)
dfa4f314 590 (let ((name (find-foreign-type-name type-number)))
e77e7713 591 (register-type
592 (getf (type-options type-number) :type (default-type-name name))
735a29da 593 (register-type-as type-number))))
21299acf 594
74821f75 595 ;; This is needed for some unknown reason to get type numbers right
596 (mapc #'find-type-dependencies type-list)
597
598 (let ((sorted-type-list
599 #+clisp (mapcar #'list type-list)
600 #-clisp
601 (sort-types-topologicaly
602 (mapcar
603 #'(lambda (type)
604 (cons type (find-type-dependencies type (type-options type))))
605 type-list))))
62f12808 606 `(progn
607 ,@(mapcar
21299acf 608 #'(lambda (pair)
609 (destructuring-bind (type . forward-p) pair
610 (expand-type-definition type forward-p (type-options type))))
611 sorted-type-list)
62f12808 612 ,@(mapcar
21299acf 613 #'(lambda (pair)
614 (destructuring-bind (type . forward-p) pair
615 (when forward-p
616 (expand-type-definition type nil (type-options type)))))
62f12808 617 sorted-type-list))))))
e77e7713 618
d4b21b08 619(defmacro define-types-by-introspection (prefix &rest args)
4de90d10 620 (expand-type-definitions prefix args))
21299acf 621
74821f75 622(defexport define-types-by-introspection (prefix &rest args)
fbd2b3d9 623 (list-autoexported-symbols (expand-type-definitions prefix args)))
74821f75 624
21299acf 625
626;;;; Initialize all non static types in GObject
627
daa10b6d 628(init-types-in-library #.(concatenate 'string (pkg-config:pkg-variable "glib-2.0" "libdir") "/libgobject-2.0." asdf:*dso-extension*))