chiark / gitweb /
Added statusbar example
[clg] / glib / gcallback.lisp
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
18 ;; $Id: gcallback.lisp,v 1.11 2004-11-01 00:08:49 espen Exp $
19
20 (in-package "GLIB")
21
22 (use-prefix "g")
23
24
25 ;;;; Callback mechanism
26
27 (deftype gclosure () 'pointer)
28
29 (defbinding (callback-closure-new "clg_callback_closure_new") () gclosure
30   (callback-id unsigned-int) 
31   (callback pointer)
32   (destroy-notify pointer))
33
34 (defun register-callback-function (function)
35   (check-type function (or null symbol function))
36   (register-user-data function))
37
38 (def-callback closure-callback-marshal
39     (void (gclosure system-area-pointer) (return-value system-area-pointer)
40           (n-params unsigned-int) (param-values system-area-pointer)
41           (invocation-hint system-area-pointer) (callback-id unsigned-int))
42   (callback-trampoline callback-id n-params param-values return-value))
43
44 (def-callback %destroy-user-data (void (id unsigned-int))
45   (destroy-user-data id)) 
46  
47 (defun make-callback-closure (function)
48   (callback-closure-new 
49    (register-callback-function function)
50    (callback closure-callback-marshal) (callback %destroy-user-data)))
51
52
53 (defun callback-trampoline (callback-id n-params param-values return-value)
54   (let* ((return-type (unless (null-pointer-p return-value)
55                         (gvalue-type return-value)))
56          (args (loop
57                 for n from 0 below n-params
58                 collect (gvalue-get (sap+ param-values (* n +gvalue-size+))))))
59     (let ((result (apply #'invoke-callback callback-id return-type args)))
60       (when return-type
61         (gvalue-set return-value result)))))
62
63
64 (defun invoke-callback (callback-id type &rest args)
65   (restart-case
66       (apply (find-user-data callback-id) args)
67     (continue nil :report "Return from callback function"
68               (when type
69                 (format *query-io* "Enter return value of type ~S: " type)
70                 (force-output *query-io*)
71                 (eval (read *query-io*))))
72     (re-invoke nil :report "Re-invoke callback function"
73                (apply #'invoke-callback callback-id type args))))
74
75
76 ;;;; Timeouts and idle functions
77
78 (def-callback source-callback-marshal (void (callback-id unsigned-int))
79   (callback-trampoline callback-id 0 nil (make-pointer 0)))
80
81 (defbinding (timeout-add "g_timeout_add_full")
82     (function interval &optional (priority 0)) unsigned-int 
83   (priority int)
84   (interval unsigned-int)
85   (*source-callback-marshal* pointer)
86   ((register-callback-function function) unsigned-long)
87   ((callback %destroy-user-data) pointer))
88
89 (defbinding (idle-add "g_idle_add_full")
90     (function &optional (priority 0)) unsigned-int 
91   (priority int)
92   (*source-callback-marshal* pointer)
93   ((register-callback-function function) unsigned-long)
94   ((callback %destroy-user-data) pointer))
95
96
97
98 ;;;; Signals
99
100 (defbinding signal-lookup (name itype) unsigned-int
101   ((signal-name-to-string name) string)
102   (itype type-number))
103
104 (defbinding signal-name () string
105   (signal-id unsigned-int))
106
107 (defun ensure-signal-id (signal-id instance)
108   (etypecase signal-id
109     (integer signal-id)
110     (string (signal-lookup signal-id (type-number-of instance)))
111     (symbol (signal-lookup signal-id (type-number-of instance)))))
112   
113 (defbinding signal-stop-emission (instance signal-id) nil
114   (instance ginstance)
115   ((ensure-signal-id signal-id instance) unsigned-int))
116
117 ; (defbinding (signal-add-emisson-hook "g_signal_add_emission_hook_full")
118 ;     () unsigned-int
119 ;   (signal-id unsigned-int)
120 ;   (closure gclosure))
121
122 ; (defbinding signal-remove-emisson-hook () nil
123 ;   (signal-id unsigned-int)
124 ;   (hook-id unsigned-int))
125
126 (defbinding (signal-has-handler-pending-p "g_signal_has_handler_pending")
127     (instance signal-id &key detail blocked) boolean
128   (instance ginstance)
129   ((ensure-signal-id signal-id instance) unsigned-int)
130   ((or detail 0) quark)
131   (blocked boolean))
132     
133 (defbinding (signal-connect-closure "g_signal_connect_closure_by_id")
134     (instance signal-id closure &key detail after) unsigned-int
135   (instance ginstance)
136   ((ensure-signal-id signal-id instance) unsigned-int)
137   ((or detail 0) quark)
138   (closure gclosure)
139   (after boolean))
140
141 (defbinding signal-handler-block () nil
142   (instance ginstance)
143   (handler unsigned-int))
144
145 (defbinding signal-handler-unblock () nil
146   (instance ginstance)
147   (handler unsigned-int))
148
149 (defbinding signal-handler-disconnect () nil
150   (instance ginstance)
151   (handler unsigned-int))
152
153
154 (defmethod signal-connect ((gobject gobject) signal function &key after object)
155 "Connects a callback function to a signal for a particular object. If :OBJECT 
156  is T, the object connected to is passed as the first argument to the callback 
157  function, or if :OBJECT is any other non NIL value, it is passed as the first 
158  argument instead. If :AFTER is non NIL, the handler will be called after the 
159  default handler of the signal."
160   (let ((callback-id
161          (make-callback-closure
162           (cond
163            ((or (eq object t) (eq object gobject)) function)
164            ((not object)
165             #'(lambda (&rest args) (apply function (cdr args))))
166            (t
167             #'(lambda (&rest args) (apply function object (rest args))))))))
168     (signal-connect-closure gobject signal callback-id :after after)))
169
170
171 ;;; Message logging
172
173 ;; TODO: define and signal conditions based on log-level
174 ;(defun log-handler (domain log-level message)
175 (def-callback log-handler (void (domain c-string) (log-level int) 
176                                 (message c-string))
177   (error "~A: ~A" domain message))
178
179 (setf (extern-alien "log_handler" system-area-pointer) (callback log-handler))