;; License along with this library; if not, write to the Free Software
;; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-;; $Id: gcallback.lisp,v 1.11 2004/11/01 00:08:49 espen Exp $
+;; $Id: gcallback.lisp,v 1.14 2004/11/07 16:04:21 espen Exp $
(in-package "GLIB")
(check-type function (or null symbol function))
(register-user-data function))
-(def-callback closure-callback-marshal
- (void (gclosure system-area-pointer) (return-value system-area-pointer)
- (n-params unsigned-int) (param-values system-area-pointer)
- (invocation-hint system-area-pointer) (callback-id unsigned-int))
+(defcallback closure-callback-marshal (nil
+ (gclosure pointer)
+ (return-value gvalue)
+ (n-params unsigned-int)
+ (param-values pointer)
+ (invocation-hint pointer)
+ (callback-id unsigned-int))
(callback-trampoline callback-id n-params param-values return-value))
-(def-callback %destroy-user-data (void (id unsigned-int))
- (destroy-user-data id))
+(defcallback %destroy-user-data (nil (id unsigned-int))
+ (destroy-user-data id))
(defun make-callback-closure (function)
(callback-closure-new
(gvalue-set return-value result)))))
-(defun invoke-callback (callback-id type &rest args)
+(defun invoke-callback (callback-id return-type &rest args)
(restart-case
(apply (find-user-data callback-id) args)
(continue nil :report "Return from callback function"
- (when type
- (format *query-io* "Enter return value of type ~S: " type)
+ (when return-type
+ (format *query-io* "Enter return value of type ~S: " return-type)
(force-output *query-io*)
(eval (read *query-io*))))
(re-invoke nil :report "Re-invoke callback function"
- (apply #'invoke-callback callback-id type args))))
+ (apply #'invoke-callback callback-id return-type args))))
;;;; Timeouts and idle functions
-(def-callback source-callback-marshal (void (callback-id unsigned-int))
+(defcallback source-callback-marshal (nil (callback-id unsigned-int))
(callback-trampoline callback-id 0 nil (make-pointer 0)))
(defbinding (timeout-add "g_timeout_add_full")
;; TODO: define and signal conditions based on log-level
;(defun log-handler (domain log-level message)
-(def-callback log-handler (void (domain c-string) (log-level int)
- (message c-string))
+(def-callback log-handler (c-call:void (domain c-call:c-string)
+ (log-level c-call:int)
+ (message c-call:c-string))
(error "~A: ~A" domain message))
(setf (extern-alien "log_handler" system-area-pointer) (callback log-handler))
+
+
+;;;; Convenient macros
+
+(defmacro def-callback-marshal (name (return-type &rest args))
+ (let ((names (loop
+ for arg in args
+ collect (if (atom arg) (gensym) (first arg))))
+ (types (loop
+ for arg in args
+ collect (if (atom arg) arg (second arg)))))
+ `(defcallback ,name (,return-type ,@(mapcar #'list names types)
+ (callback-id unsigned-int))
+ (invoke-callback callback-id ',return-type ,@names))))
+
+(defmacro with-callback-function ((id function) &body body)
+ `(let ((,id (register-callback-function ,function)))
+ (unwind-protect
+ (progn ,@body)
+ (destroy-user-data ,id))))
+
+