chiark / gitweb /
Added expander demo
[clg] / glib / gcallback.lisp
CommitLineData
c9819f3e 1;; Common Lisp bindings for GTK+ v2.0
2;; Copyright (C) 2000 Espen S. Johnsen <esj@stud.cs.uit.no>
3;;
4;; This library is free software; you can redistribute it and/or
5;; modify it under the terms of the GNU Lesser General Public
6;; License as published by the Free Software Foundation; either
7;; version 2 of the License, or (at your option) any later version.
8;;
9;; This library is distributed in the hope that it will be useful,
10;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12;; Lesser General Public License for more details.
13;;
14;; You should have received a copy of the GNU Lesser General Public
15;; License along with this library; if not, write to the Free Software
16;; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
ff378415 18;; $Id: gcallback.lisp,v 1.15 2004/12/04 00:29:57 espen Exp $
c9819f3e 19
20(in-package "GLIB")
21
22(use-prefix "g")
23
24
831668e8 25;;;; Callback mechanism
c9819f3e 26
27(deftype gclosure () 'pointer)
28
831668e8 29(defbinding (callback-closure-new "clg_callback_closure_new") () gclosure
30 (callback-id unsigned-int)
31 (callback pointer)
32 (destroy-notify pointer))
c9819f3e 33
60cfb912 34(defun register-callback-function (function)
35 (check-type function (or null symbol function))
36 (register-user-data function))
c9819f3e 37
7bde5a67 38(defcallback closure-callback-marshal (nil
39 (gclosure pointer)
40 (return-value gvalue)
41 (n-params unsigned-int)
42 (param-values pointer)
43 (invocation-hint pointer)
44 (callback-id unsigned-int))
831668e8 45 (callback-trampoline callback-id n-params param-values return-value))
c9819f3e 46
7bde5a67 47(defcallback %destroy-user-data (nil (id unsigned-int))
48 (destroy-user-data id))
831668e8 49
50(defun make-callback-closure (function)
51 (callback-closure-new
52 (register-callback-function function)
53 (callback closure-callback-marshal) (callback %destroy-user-data)))
c9819f3e 54
c9819f3e 55
831668e8 56(defun callback-trampoline (callback-id n-params param-values return-value)
c9819f3e 57 (let* ((return-type (unless (null-pointer-p return-value)
60cfb912 58 (gvalue-type return-value)))
831668e8 59 (args (loop
60 for n from 0 below n-params
61 collect (gvalue-get (sap+ param-values (* n +gvalue-size+))))))
62 (let ((result (apply #'invoke-callback callback-id return-type args)))
63 (when return-type
64 (gvalue-set return-value result)))))
65
66
7bde5a67 67(defun invoke-callback (callback-id return-type &rest args)
831668e8 68 (restart-case
69 (apply (find-user-data callback-id) args)
70 (continue nil :report "Return from callback function"
7bde5a67 71 (when return-type
72 (format *query-io* "Enter return value of type ~S: " return-type)
831668e8 73 (force-output *query-io*)
74 (eval (read *query-io*))))
75 (re-invoke nil :report "Re-invoke callback function"
7bde5a67 76 (apply #'invoke-callback callback-id return-type args))))
c9819f3e 77
c9819f3e 78
60cfb912 79;;;; Timeouts and idle functions
80
7bde5a67 81(defcallback source-callback-marshal (nil (callback-id unsigned-int))
831668e8 82 (callback-trampoline callback-id 0 nil (make-pointer 0)))
60cfb912 83
84(defbinding (timeout-add "g_timeout_add_full")
85 (function interval &optional (priority 0)) unsigned-int
86 (priority int)
87 (interval unsigned-int)
88 (*source-callback-marshal* pointer)
89 ((register-callback-function function) unsigned-long)
831668e8 90 ((callback %destroy-user-data) pointer))
60cfb912 91
92(defbinding (idle-add "g_idle_add_full")
93 (function &optional (priority 0)) unsigned-int
94 (priority int)
95 (*source-callback-marshal* pointer)
96 ((register-callback-function function) unsigned-long)
831668e8 97 ((callback %destroy-user-data) pointer))
60cfb912 98
99
c9819f3e 100
101;;;; Signals
102
3f4249c7 103(defbinding signal-lookup (name itype) unsigned-int
c9819f3e 104 ((signal-name-to-string name) string)
105 (itype type-number))
106
3f4249c7 107(defbinding signal-name () string
c9819f3e 108 (signal-id unsigned-int))
109
7eec806d 110(defun ensure-signal-id (signal-id instance)
c9819f3e 111 (etypecase signal-id
112 (integer signal-id)
113 (string (signal-lookup signal-id (type-number-of instance)))
114 (symbol (signal-lookup signal-id (type-number-of instance)))))
115
3f4249c7 116(defbinding signal-stop-emission (instance signal-id) nil
c9819f3e 117 (instance ginstance)
7eec806d 118 ((ensure-signal-id signal-id instance) unsigned-int))
c9819f3e 119
3f4249c7 120; (defbinding (signal-add-emisson-hook "g_signal_add_emission_hook_full")
c9819f3e 121; () unsigned-int
122; (signal-id unsigned-int)
123; (closure gclosure))
124
3f4249c7 125; (defbinding signal-remove-emisson-hook () nil
c9819f3e 126; (signal-id unsigned-int)
127; (hook-id unsigned-int))
128
3f4249c7 129(defbinding (signal-has-handler-pending-p "g_signal_has_handler_pending")
c9819f3e 130 (instance signal-id &key detail blocked) boolean
131 (instance ginstance)
7eec806d 132 ((ensure-signal-id signal-id instance) unsigned-int)
c9819f3e 133 ((or detail 0) quark)
134 (blocked boolean))
135
3f4249c7 136(defbinding (signal-connect-closure "g_signal_connect_closure_by_id")
c9819f3e 137 (instance signal-id closure &key detail after) unsigned-int
138 (instance ginstance)
7eec806d 139 ((ensure-signal-id signal-id instance) unsigned-int)
c9819f3e 140 ((or detail 0) quark)
141 (closure gclosure)
142 (after boolean))
143
3f4249c7 144(defbinding signal-handler-block () nil
c9819f3e 145 (instance ginstance)
146 (handler unsigned-int))
147
3f4249c7 148(defbinding signal-handler-unblock () nil
c9819f3e 149 (instance ginstance)
150 (handler unsigned-int))
151
3f4249c7 152(defbinding signal-handler-disconnect () nil
c9819f3e 153 (instance ginstance)
154 (handler unsigned-int))
155
156
6d00d707 157(defmethod signal-connect ((gobject gobject) signal function &key after object)
935a783c 158"Connects a callback function to a signal for a particular object. If :OBJECT
159 is T, the object connected to is passed as the first argument to the callback
160 function, or if :OBJECT is any other non NIL value, it is passed as the first
161 argument instead. If :AFTER is non NIL, the handler will be called after the
162 default handler of the signal."
ff378415 163 (when function
164 (let ((callback-id
165 (make-callback-closure
166 (cond
167 ((or (eq object t) (eq object gobject)) function)
168 ((not object)
169 #'(lambda (&rest args) (apply function (cdr args))))
170 (t
171 #'(lambda (&rest args) (apply function object (rest args))))))))
172 (signal-connect-closure gobject signal callback-id :after after))))
dd181a20 173
174
175;;; Message logging
176
177;; TODO: define and signal conditions based on log-level
831668e8 178;(defun log-handler (domain log-level message)
6baf860c 179(def-callback log-handler (c-call:void (domain c-call:c-string)
180 (log-level c-call:int)
181 (message c-call:c-string))
dd181a20 182 (error "~A: ~A" domain message))
183
831668e8 184(setf (extern-alien "log_handler" system-area-pointer) (callback log-handler))
11e1e57c 185
186
187;;;; Convenient macros
188
189(defmacro def-callback-marshal (name (return-type &rest args))
190 (let ((names (loop
191 for arg in args
192 collect (if (atom arg) (gensym) (first arg))))
193 (types (loop
194 for arg in args
195 collect (if (atom arg) arg (second arg)))))
196 `(defcallback ,name (,return-type ,@(mapcar #'list names types)
197 (callback-id unsigned-int))
198 (invoke-callback callback-id ',return-type ,@names))))
199
200(defmacro with-callback-function ((id function) &body body)
201 `(let ((,id (register-callback-function ,function)))
202 (unwind-protect
203 (progn ,@body)
204 (destroy-user-data ,id))))
205
206