- (type-from-number (gvalue-type return-value))))
- (args nil)
- (callback-function (find-user-data callback-id)))
-
- (destructuring-bind (nparams . param-values) params
- (dotimes (n nparams)
- (push (gvalue-get (sap+ param-values (* n +gvalue-size+))) args)))
-
- (labels ((invoke-callback ()
- (restart-case
- (unwind-protect
- (let ((result (apply callback-function (reverse args))))
- (when return-type
- (gvalue-set return-value result))))
-
- (continue nil :report "Return from callback function"
- (when return-type
- (format
- *query-io*
- "Enter return value of type ~S: "
- return-type)
- (force-output *query-io*)
- (gvalue-set return-value (eval (read *query-io*)))))
- (re-invoke nil :report "Re-invoke callback function"
- (invoke-callback)))))
- (invoke-callback))))
-
-(defun after-gc-hook ()
- (setf
- (extern-alien "callback_trampoline" system-area-pointer)
- (make-pointer (kernel:get-lisp-obj-address #'callback-trampoline))
- (extern-alien "destroy_user_data" system-area-pointer)
- (make-pointer (kernel:get-lisp-obj-address #'destroy-user-data))))
-
-(pushnew 'after-gc-hook ext:*after-gc-hooks*)
-(after-gc-hook)
-
+ (gvalue-type return-value)))
+ (args (loop
+ for n from 0 below n-params
+ collect (gvalue-get (sap+ param-values (* n +gvalue-size+))))))
+ (let ((result (apply #'invoke-callback callback-id return-type args)))
+ (when return-type
+ (gvalue-set return-value result)))))
+
+
+(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 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 return-type args))))
+
+
+;;;; Timeouts and idle functions
+
+(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")
+ (interval function &optional (priority +priority-default+)) unsigned-int
+ (priority int)
+ (interval unsigned-int)
+ ((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 +priority-default-idle+)) unsigned-int
+ (priority int)
+ ((callback source-callback-marshal) pointer)
+ ((register-callback-function function) unsigned-long)
+ ((callback %destroy-user-data) pointer))
+
+(defun idle-remove (idle)
+ (source-remove idle))