chiark / gitweb /
Added linker flags to alien.so required by Darwin
[clg] / glib / gtype.lisp
CommitLineData
55212af1 1;; Common Lisp bindings for GTK+ v2.x
08cb5756 2;; Copyright 2000-2006 Espen S. Johnsen <espen@users.sf.net>
0d07716f 3;;
55212af1 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:
0d07716f 11;;
55212af1 12;; The above copyright notice and this permission notice shall be
13;; included in all copies or substantial portions of the Software.
0d07716f 14;;
55212af1 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
4b634902 23;; $Id: gtype.lisp,v 1.56 2006/08/30 11:11:03 espen Exp $
0d07716f 24
25(in-package "GLIB")
26
27(use-prefix "g")
28
d1266407 29;; Initialize the glib type system
30(defbinding type-init () nil)
31(type-init)
0d07716f 32
fb9bc912 33(deftype type-number () 'unsigned-long)
0d07716f 34
b4a2c852 35(deftype gtype () 'symbol)
36
4d1fea77 37(define-type-method alien-type ((type gtype))
38 (declare (ignore type))
b4a2c852 39 (alien-type 'type-number))
40
08cb5756 41(define-type-method size-of ((type gtype) &key (inlined t))
42 (assert-inlined type inlined)
b4a2c852 43 (size-of 'type-number))
44
08cb5756 45(define-type-method to-alien-form ((type gtype) gtype &optional copy-p)
46 (declare (ignore type copy-p))
b4a2c852 47 `(find-type-number ,gtype t))
48
08cb5756 49(define-type-method to-alien-function ((type gtype) &optional copy-p)
50 (declare (ignore type copy-p))
b4a2c852 51 #'(lambda (gtype)
52 (find-type-number gtype t)))
53
08cb5756 54(define-type-method from-alien-form ((type gtype) form &key ref)
55 (declare (ignore type ref))
56 `(type-from-number ,form))
b4a2c852 57
08cb5756 58(define-type-method from-alien-function ((type gtype) &key ref)
59 (declare (ignore type ref))
b4a2c852 60 #'(lambda (type-number)
40c346ec 61 (type-from-number type-number)))
b4a2c852 62
08cb5756 63(define-type-method writer-function ((type gtype) &key temp (inlined t))
64 (declare (ignore temp))
65 (assert-inlined type inlined)
b4a2c852 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
08cb5756 70(define-type-method reader-function ((type gtype) &key ref (inlined t))
71 (declare (ignore ref))
72 (assert-inlined type inlined)
b4a2c852 73 (let ((reader (reader-function 'type-number)))
08cb5756 74 #'(lambda (location &optional (offset 0))
40c346ec 75 (type-from-number (funcall reader location offset)))))
b4a2c852 76
77
fc47a022 78(eval-when (:compile-toplevel :load-toplevel :execute)
3a935dfa 79 (defclass type-query (struct)
fc47a022 80 ((type-number :allocation :alien :type type-number)
08cb5756 81 (name :allocation :alien :type (copy-of string))
fc47a022 82 (class-size :allocation :alien :type unsigned-int)
83 (instance-size :allocation :alien :type unsigned-int))
4d1d3921 84 (:metaclass struct-class)))
fc47a022 85
86
b4a2c852 87(defbinding type-query (type) nil
88 ((find-type-number type t) type-number)
08cb5756 89 ((make-instance 'type-query) type-query :in/return))
fc47a022 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))
0d07716f 96
3a935dfa 97(defbinding type-class-ref (type) pointer
98 ((find-type-number type t) type-number))
0d07716f 99
08cb5756 100(defbinding type-class-unref () nil
101 (class pointer))
fc47a022 102
3a935dfa 103(defbinding type-class-peek (type) pointer
104 ((find-type-number type t) type-number))
fc47a022 105
0d07716f 106
08cb5756 107
3a935dfa 108;;;; Mapping between lisp types and glib types
0d07716f 109
dcb31db6 110(defvar *registered-types* ())
111(defvar *registered-type-aliases* ())
0f68f696 112(defvar *registered-static-types* ())
dcb31db6 113(defvar *lisp-type-to-type-number* (make-hash-table))
114(defvar *type-number-to-lisp-type* (make-hash-table))
3a935dfa 115
116(defbinding %type-from-name () type-number
117 (name string))
118
dcb31db6 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
b29e33dd 125(defun type-from-glib-name (name)
126 (type-from-number (type-number-from-glib-name name) t))
127
dcb31db6 128(defun register-type (type id)
08cb5756 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))))
dcb31db6 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*)
e9177b70 155 (mapc #'(lambda (type)
08cb5756 156 (apply #'register-new-type type))
b29e33dd 157 (reverse *registered-static-types*))
dcb31db6 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*
08cb5756 164 #+sbcl *init-hooks*
165 #+clisp custom:*init-hooks*)
dcb31db6 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)
0d07716f 173 (etypecase type
174 (integer type)
dcb31db6 175 (string (type-number-from-glib-name type error-p))
3a935dfa 176 (symbol
dcb31db6 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))))
0d07716f 181
b011356b 182(defun type-from-number (type-number &optional error)
183 (multiple-value-bind (type found)
dcb31db6 184 (gethash type-number *type-number-to-lisp-type*)
e40a19fb 185 (if found
186 type
dcb31db6 187 (let ((name (find-foreign-type-name type-number)))
e40a19fb 188 (cond
f53fad52 189 ((and name (not (= (type-number-from-glib-name name nil) type-number)))
e40a19fb 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)))))))
0d07716f 197
dcb31db6 198(defbinding (find-foreign-type-name "g_type_name") (type) (copy-of string)
3a935dfa 199 ((find-type-number type t) type-number))
200
201(defun type-number-of (object)
202 (find-type-number (type-of object) t))
203
6556dccd 204(eval-when (:compile-toplevel :load-toplevel :execute)
dcb31db6 205 (defvar *type-initializers* ())
206 (defun %find-types-in-library (pathname prefixes ignore)
08cb5756 207 (let ((process
208 (run-program
209 "/usr/bin/nm"
210 #+clisp :arguments
4b634902 211 (list #-darwin"--defined-only" #-darwin"-D" "-g" #+darwin"-f" (namestring (truename pathname)))
08cb5756 212 :output :stream :wait nil)))
6556dccd 213 (unwind-protect
214 (loop
4b634902 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))))
6556dccd 223 while symbol
224 when (and
dcb31db6 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))
6556dccd 234 (not (member symbol ignore :test #'string=)))
235 collect symbol)
08cb5756 236 (#+(or cmu sbcl)process-close
237 #+clisp close
238 process)))))
6556dccd 239
0d07716f 240
80031aba 241(defmacro init-types-in-library (filename &key prefix ignore)
6556dccd 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)
dcb31db6 247 (,(intern name))
248 (pushnew ',(intern name) *type-initializers*)))
6556dccd 249 names))))
250
dcb31db6 251(defun find-type-init-function (type-number)
80031aba 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)))
dcb31db6 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
6556dccd 268
0a77b51f 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
e40a19fb 285 (parent-type type-number)
0a77b51f 286 (name string)
287 (info type-info)
288 (0 unsigned-int))
289
8fbfa684 290(defun register-new-type (type parent &optional foreign-name)
0a77b51f 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
8fbfa684 296 (or foreign-name (default-alien-type-name type))
0a77b51f 297 (make-instance 'type-info :class-size class-size :instance-size instance-size))))
0f68f696 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))))
0a77b51f 302
303
6556dccd 304
305;;;; Metaclass for subclasses of ginstance
306
307(eval-when (:compile-toplevel :load-toplevel :execute)
308 (defclass ginstance-class (proxy-class)
7bab08b9 309 ((gtype :initarg :gtype :initform nil :reader ginstance-class-gtype))))
f53fad52 310
311
d905d6ef 312(defun update-size (class)
313 (let ((type-number (find-type-number class)))
314 (cond
08cb5756 315 ((not (foreign-size-p class))
316 (setf (foreign-size class) (type-instance-size type-number)))
d905d6ef 317 ((and
08cb5756 318 (foreign-size-p class)
319 (not (= (type-instance-size type-number) (foreign-size class))))
d905d6ef 320 (warn "Size mismatch for class ~A" class)))))
321
7ce0497d 322
f53fad52 323(defmethod finalize-inheritance ((class ginstance-class))
08cb5756 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))))
6b716036 342 #+nil
08cb5756 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))
d905d6ef 350
351
352(defmethod shared-initialize ((class ginstance-class) names &rest initargs)
08cb5756 353 (declare (ignore names initargs))
d905d6ef 354 (call-next-method)
355 (when (class-finalized-p class)
356 (update-size class)))
357
b011356b 358
6556dccd 359(defmethod validate-superclass ((class ginstance-class) (super standard-class))
360 (subtypep (class-name super) 'ginstance))
361
0d07716f 362
fc47a022 363;;;; Superclass for wrapping types in the glib type system
0d07716f 364
365(eval-when (:compile-toplevel :load-toplevel :execute)
fc47a022 366 (defclass ginstance (proxy)
7ce0497d 367 (;(class :allocation :alien :type pointer :offset 0)
368 )
369 (:metaclass proxy-class)
370 (:size #.(size-of 'pointer))))
0d07716f 371
08cb5756 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
609ba905 377(defun %type-number-of-ginstance (location)
08cb5756 378 (let ((class (ref-pointer location)))
379 (ref-type-number class)))
0d07716f 380
08cb5756 381(defmethod make-proxy-instance :around ((class ginstance-class) location
382 &rest initargs)
4d1d3921 383 (declare (ignore class))
609ba905 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)))))
08cb5756 390 ;; Note that chancing the class argument should not alter "the
1d06a422 391 ;; ordered set of applicable methods" as specified in the
392 ;; Hyperspec
4d1d3921 393 (if class
1d06a422 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
08cb5756 398(define-type-method from-alien-form ((type ginstance) form &key (ref :copy))
399 (call-next-method type form :ref ref))
0d07716f 400
08cb5756 401(define-type-method from-alien-function ((type ginstance) &key (ref :copy))
402 (call-next-method type :ref ref))
508d13a7 403
0d07716f 404
3a935dfa 405;;;; Registering fundamental types
406
40c346ec 407(register-type 'nil "void")
3a935dfa 408(register-type 'pointer "gpointer")
409(register-type 'char "gchar")
410(register-type 'unsigned-char "guchar")
411(register-type 'boolean "gboolean")
3a935dfa 412(register-type 'int "gint")
0b392a0d 413(register-type-alias 'integer 'int)
dcb31db6 414(register-type-alias 'fixnum 'int)
3a935dfa 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")
b77fe850 420(register-type 'pathname "gchararray")
b011356b 421(register-type 'string "gchararray")
3a935dfa 422
423
e9934f39 424;;;; Introspection of type information
3a935dfa 425
4812615b 426(defvar *derivable-type-info* (make-hash-table))
3a935dfa 427
e9934f39 428(defun register-derivable-type (type id expander &optional dependencies)
3a935dfa 429 (register-type type id)
4812615b 430 (let ((type-number (register-type type id)))
e9934f39 431 (setf
432 (gethash type-number *derivable-type-info*)
433 (list expander dependencies))))
3a935dfa 434
b011356b 435(defun find-type-info (type)
436 (dolist (super (cdr (type-hierarchy type)))
4812615b 437 (let ((info (gethash super *derivable-type-info*)))
b011356b 438 (return-if info))))
439
e9934f39 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)))
3a935dfa 443
08cb5756 444
3a935dfa 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
7858d45e 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
4d1d3921 458 (map-c-vector 'list #'identity array 'type-number length)
7858d45e 459 (deallocate-memory array))))
460
461(defun implements (type)
462 (mapcar #'type-from-number (type-interfaces type)))
463
3a935dfa 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
4d1d3921 481 (map-c-vector
3a935dfa 482 'nil
483 #'(lambda (type-number)
484 (when (or
485 (not prefix)
dcb31db6 486 (string-prefix-p prefix (find-foreign-type-name type-number)))
3a935dfa 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))
4812615b 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*)
3a935dfa 502 type-list))
503
08cb5756 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
6b716036 513;; (type . dependencies). This function will not handle indirect
514;; dependencies and types depending on them selve.
08cb5756 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))))))
3a935dfa 564
565
566(defun expand-type-definitions (prefix &optional args)
dcb31db6 567 (flet ((type-options (type-number)
568 (let ((name (find-foreign-type-name type-number)))
b011356b 569 (cdr (assoc name args :test #'string=)))))
3a935dfa 570
4812615b 571 (let ((type-list
572 (delete-if
573 #'(lambda (type-number)
dcb31db6 574 (let ((name (find-foreign-type-name type-number)))
4812615b 575 (or
576 (getf (type-options type-number) :ignore)
577 (find-if
578 #'(lambda (options)
579 (and
580 (string-prefix-p (first options) name)
17c607d0 581 (getf (cdr options) :ignore-prefix)
582 (not (some
583 #'(lambda (exception)
584 (string= name exception))
585 (getf (cdr options) :except)))))
4812615b 586 args))))
587 (find-types prefix))))
6556dccd 588
4812615b 589 (dolist (type-number type-list)
dcb31db6 590 (let ((name (find-foreign-type-name type-number)))
4812615b 591 (register-type
592 (getf (type-options type-number) :type (default-type-name name))
80031aba 593 (register-type-as type-number))))
6556dccd 594
08cb5756 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))))
e9934f39 606 `(progn
607 ,@(mapcar
6556dccd 608 #'(lambda (pair)
609 (destructuring-bind (type . forward-p) pair
610 (expand-type-definition type forward-p (type-options type))))
611 sorted-type-list)
e9934f39 612 ,@(mapcar
6556dccd 613 #'(lambda (pair)
614 (destructuring-bind (type . forward-p) pair
615 (when forward-p
616 (expand-type-definition type nil (type-options type)))))
e9934f39 617 sorted-type-list))))))
4812615b 618
3a935dfa 619(defmacro define-types-by-introspection (prefix &rest args)
b011356b 620 (expand-type-definitions prefix args))
6556dccd 621
08cb5756 622(defexport define-types-by-introspection (prefix &rest args)
d92bb6e7 623 (list-autoexported-symbols (expand-type-definitions prefix args)))
08cb5756 624
6556dccd 625
626;;;; Initialize all non static types in GObject
627
4b634902 628(init-types-in-library #.(concatenate 'string (pkg-config:pkg-variable "glib-2.0" "libdir") "/libgobject-2.0." asdf:*dso-extension*))