(:file "gobject.meta")
(:file "gobject.generating")
(:file "gobject.object-defs")
+ (:file "gobject.cffi-callbacks")
(:file "gobject.foreign-gobject-subclassing")
(:file "gobject.boxed")
--- /dev/null
+(in-package :gobject)
+
+(defun wrap-body-with-boxed-translations (args body)
+ (if (null args)
+ body
+ (let ((arg (first args)))
+ (destructuring-bind (arg-name arg-type) arg
+ (if (and (listp arg-type) (eq 'g-boxed-foreign (first arg-type)))
+ (let ((var (gensym))
+ (cffi-type (cffi::parse-type arg-type)))
+ `((let ((,var ,arg-name)
+ (,arg-name (translate-from-foreign ,arg-name ,cffi-type)))
+ (unwind-protect
+ (progn ,@(wrap-body-with-boxed-translations (rest args) body))
+ (cleanup-translated-object-for-callback ,cffi-type ,arg-name ,var)))))
+ (wrap-body-with-boxed-translations (rest args) body))))))
+
+(defmacro glib-defcallback (name-and-options return-type args &body body)
+ (let* ((c-args (iter (for arg in args)
+ (for (name type) = arg)
+ (if (and (listp type) (eq 'g-boxed-foreign (first type)))
+ (collect `(,name :pointer))
+ (collect arg))))
+ (c-body (wrap-body-with-boxed-translations args body)))
+ `(defcallback ,name-and-options ,return-type ,c-args
+ ,@c-body)))
(make-vtable-description :type-name ,type-name :cstruct-name ',cstruct-name :methods (list ,@(mapcar #'make-load-form (vtable-methods items)))))
,@(iter (for method in (vtable-methods items))
(collect `(defgeneric ,(vtable-method-info-name method) (,@(mapcar #'first (vtable-method-info-args method)))))
- (collect `(defcallback ,(vtable-method-info-callback-name method) ,(vtable-method-info-return-type method)
+ (collect `(glib-defcallback ,(vtable-method-info-callback-name method) ,(vtable-method-info-return-type method)
(,@(vtable-method-info-args method))
(restart-case
(,(vtable-method-info-name method) ,@(mapcar #'first (vtable-method-info-args method)))