X-Git-Url: https://git.distorted.org.uk/~mdw/clg/blobdiff_plain/9adccb27da69b60d058aa37867d55ea20ecf97ca..1ff84b0665062c842c5eb53c91d69c68249c87b5:/glib/gcallback.lisp diff --git a/glib/gcallback.lisp b/glib/gcallback.lisp index 520d7a8..ca406e9 100644 --- a/glib/gcallback.lisp +++ b/glib/gcallback.lisp @@ -15,7 +15,7 @@ ;; 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.12 2004-11-06 21:39:58 espen Exp $ +;; $Id: gcallback.lisp,v 1.16 2004-12-05 13:54:10 espen Exp $ (in-package "GLIB") @@ -35,17 +35,17 @@ (check-type function (or null symbol function)) (register-user-data function)) -(def-callback closure-callback-marshal (c-call:void - (gclosure system-area-pointer) - (return-value system-area-pointer) - (n-params c-call:unsigned-int) - (param-values system-area-pointer) - (invocation-hint system-area-pointer) - (callback-id c-call: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 (c-call:void (id c-call: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 @@ -64,38 +64,52 @@ (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 (c-call:void (callback-id c-call:unsigned-int)) +(defconstant +priority-high+ -100) +(defconstant +priority-default+ 0) +(defconstant +priority-high-idle+ 100) +(defconstant +priority-default-idle+ 200) +(defconstant +priority-low+ 300) + +(defbinding source-remove () boolean + (tag 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") - (function interval &optional (priority 0)) unsigned-int + (interval function &optional (priority +priority-default+)) unsigned-int (priority int) (interval unsigned-int) - (*source-callback-marshal* pointer) + ((callback source-callback-marshal) pointer) ((register-callback-function function) unsigned-long) ((callback %destroy-user-data) pointer)) +(defun timeout-remove (timeout) + (source-remove timeout)) + (defbinding (idle-add "g_idle_add_full") - (function &optional (priority 0)) unsigned-int + (function &optional (priority +priority-default-idle+)) unsigned-int (priority int) - (*source-callback-marshal* pointer) + ((callback source-callback-marshal) pointer) ((register-callback-function function) unsigned-long) ((callback %destroy-user-data) pointer)) +(defun idle-remove (idle) + (source-remove idle)) ;;;; Signals @@ -159,16 +173,17 @@ is T, the object connected to is passed as the first argument to the callback function, or if :OBJECT is any other non NIL value, it is passed as the first argument instead. If :AFTER is non NIL, the handler will be called after the - default handler of the signal." - (let ((callback-id - (make-callback-closure - (cond - ((or (eq object t) (eq object gobject)) function) - ((not object) - #'(lambda (&rest args) (apply function (cdr args)))) - (t - #'(lambda (&rest args) (apply function object (rest args)))))))) - (signal-connect-closure gobject signal callback-id :after after))) + default handler for the signal." + (when function + (let ((callback-id + (make-callback-closure + (cond + ((or (eq object t) (eq object gobject)) function) + ((not object) + #'(lambda (&rest args) (apply function (cdr args)))) + (t + #'(lambda (&rest args) (apply function object (rest args)))))))) + (signal-connect-closure gobject signal callback-id :after after)))) ;;; Message logging @@ -181,3 +196,25 @@ (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)))) + +