chiark / gitweb /
Small change to %DEFBINDING
[clg] / glib / gcallback.lisp
index ee113878b89c2cefa338687114100f04cbc5684a..ca406e96bab19b1dde486573324d44ea76f96691 100644 (file)
@@ -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.11 2004-11-01 00:08:49 espen Exp $
+;; $Id: gcallback.lisp,v 1.16 2004-12-05 13:54:10 espen Exp $
 
 (in-package "GLIB")
 
@@ -35,14 +35,17 @@ (defun register-callback-function (function)
   (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 
@@ -61,38 +64,52 @@ (defun callback-trampoline (callback-id n-params param-values return-value)
        (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))
+(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
@@ -156,24 +173,48 @@ (defmethod signal-connect ((gobject gobject) signal function &key after object)
  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
 
 ;; 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))))
+
+