chiark / gitweb /
Major cleanup of ffi abstraction layer
[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
6baf860c 18;; $Id: gcallback.lisp,v 1.12 2004/11/06 21:39:58 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
6baf860c 38(def-callback closure-callback-marshal (c-call:void
39 (gclosure system-area-pointer)
40 (return-value system-area-pointer)
41 (n-params c-call:unsigned-int)
42 (param-values system-area-pointer)
43 (invocation-hint system-area-pointer)
44 (callback-id c-call:unsigned-int))
831668e8 45 (callback-trampoline callback-id n-params param-values return-value))
c9819f3e 46
6baf860c 47(def-callback %destroy-user-data (c-call:void (id c-call:unsigned-int))
831668e8 48 (destroy-user-data id))
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
67(defun invoke-callback (callback-id type &rest args)
68 (restart-case
69 (apply (find-user-data callback-id) args)
70 (continue nil :report "Return from callback function"
71 (when type
72 (format *query-io* "Enter return value of type ~S: " type)
73 (force-output *query-io*)
74 (eval (read *query-io*))))
75 (re-invoke nil :report "Re-invoke callback function"
76 (apply #'invoke-callback callback-id type args))))
c9819f3e 77
c9819f3e 78
60cfb912 79;;;; Timeouts and idle functions
80
6baf860c 81(def-callback source-callback-marshal (c-call:void (callback-id c-call: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."
6d00d707 163 (let ((callback-id
164 (make-callback-closure
165 (cond
166 ((or (eq object t) (eq object gobject)) function)
167 ((not object)
168 #'(lambda (&rest args) (apply function (cdr args))))
169 (t
170 #'(lambda (&rest args) (apply function object (rest args))))))))
d70890e5 171 (signal-connect-closure gobject signal callback-id :after after)))
dd181a20 172
173
174;;; Message logging
175
176;; TODO: define and signal conditions based on log-level
831668e8 177;(defun log-handler (domain log-level message)
6baf860c 178(def-callback log-handler (c-call:void (domain c-call:c-string)
179 (log-level c-call:int)
180 (message c-call:c-string))
dd181a20 181 (error "~A: ~A" domain message))
182
831668e8 183(setf (extern-alien "log_handler" system-area-pointer) (callback log-handler))