chiark / gitweb /
Initial revision
[clg] / glib / glib.lisp
1 ;; Common Lisp bindings for GTK+ v1.2.x
2 ;; Copyright (C) 1999 Espen S. Johnsen <espejohn@online.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: glib.lisp,v 1.1 2000-08-14 16:44:31 espen Exp $
19
20
21 (in-package "GLIB")
22 (use-prefix "g")
23
24
25 ;;;; Memory management
26
27 (define-foreign ("g_malloc0" allocate-memory) () pointer
28   (size unsigned-long))
29
30 (define-foreign ("g_realloc" reallocate-memory) () pointer
31   (address pointer)
32   (size unsigned-long))
33
34 (define-foreign ("g_free" deallocate-memory) () nil
35   (address pointer))
36
37 (defun copy-memory (from length &optional (to (allocate-memory length)))
38   (kernel:system-area-copy from 0 to 0 (* 8 length))
39   to)
40
41
42
43 ;;;; Linked list
44
45 (deftype glist () 'pointer)
46 (deftype double-list (type) `(or (null (cons ,type list))))
47
48
49 (define-foreign ("g_list_append" %glist-append) () glist
50   (glist glist)
51   (data unsigned))
52
53 (defmacro glist-append (glist value type-spec)
54   (ecase (first (mklist (translate-type-spec type-spec)))
55     (unsigned `(%glist-append ,glist ,value))
56 ;    (signed `(%glist-append ,glist (signed-to-unsigned ,value)))
57     (system-area-pointer `(%glist-append ,glist (system:sap-int ,value)))))
58
59
60 (defmacro glist-data (glist type-spec)
61   (ecase (first (mklist (translate-type-spec type-spec)))
62     (unsigned `(sap-ref-unsigned ,glist 0))
63     (signed `(sap-ref-signed ,glist 0))
64     (system-area-pointer `(sap-ref-sap ,glist 0))))
65
66
67 (defun glist-next (glist)
68   (unless (null-pointer-p glist)
69     (sap-ref-sap glist +size-of-sap+)))
70  
71   
72 (define-foreign ("g_list_free" glist-free) () nil
73   (glist pointer))
74
75
76 (deftype-method translate-type-spec double-list (type-spec)
77   (declare (ignore type-spec))
78   'system-area-pointer)
79
80 (deftype-method translate-to-alien double-list (type-spec list &optional copy)
81   (declare (ignore copy))
82   (let* ((element-type-spec (second (type-expand-to 'double-list type-spec)))
83          (to-alien (translate-to-alien element-type-spec 'element t)))
84     `(let ((glist (make-pointer 0))) 
85        (dolist (element ,list glist)
86          (setq glist (glist-append glist ,to-alien element-type-spec))))))
87
88 (deftype-method
89     translate-from-alien
90     double-list (type-spec glist &optional (alloc :dynamic))
91   (let ((element-type-spec (second (type-expand-to 'double-list type-spec))))
92     `(let ((glist ,glist)
93            (list nil))
94        (do ((tmp glist (glist-next tmp)))
95            ((null-pointer-p tmp))
96          (push
97           ,(translate-from-alien
98             element-type-spec `(glist-data tmp ,element-type-spec) alloc)
99           list))
100        ,(when (eq alloc :dynamic)
101           '(glist-free glist))
102        (nreverse list))))
103
104 (deftype-method cleanup-alien double-list (type-spec glist &optional copied)
105   (declare (ignore copied))
106   (let* ((element-type-spec (second (type-expand-to 'double-list type-spec)))
107          (alien-type-spec (translate-type-spec element-type-spec)))
108     `(let ((glist ,glist))
109        (unless (null-pointer-p glist)
110          ,(when (eq alien-type-spec 'system-area-pointer)
111             `(do ((tmp glist (glist-next tmp)))
112                  ((null-pointer-p tmp))
113                ,(cleanup-alien element-type-spec '(glist-data tmp) t)))
114          (glist-free glist)))))
115
116
117
118 ;;; Array
119 #|
120 (define-foreign ("g_array_new" %array-new) () garray
121   (zero-terminated boolean)
122   (clear boolean)
123   (element-size unsigned-int))
124
125 (defun array-new (&key zero-terminated clear (element-size 4) initial-contents)
126   (let ((array (%array-new zero-terminated clear element-size)))
127     (when initial-contents
128       (dolist (element initial-contents)
129         (array-append array element)))
130     array))
131
132 (define-foreign ("g_array_free" %array-free) () none
133   (array garray)
134   (free-segment boolean))
135
136 (defun array-free (array &optional free-data (free-segment t))
137   (when free-data
138     (dotimes (i (array-get-size array))
139       (free (array-get-pointer array i))))
140   (%array-free array free-segment))
141
142 (defmacro with-array (binding &body body)
143   (let ((array (gensym)))
144     (destructuring-bind (var &rest args
145                          &key (free-contents nil) (free-segment t)
146                          &allow-other-keys )
147         binding
148       (remf args :free-contents)
149       (remf args :free-segment)
150       `(let* ((,array (array-new ,@args))
151               (,var (array-get-data ,array)))
152          (unwind-protect
153              ,@body
154            (array-free ,array ,free-contents ,free-segment))))))
155
156 ;; cl-gtk.c
157 (define-foreign ("g_array_insert_int" array-insert-int) () garray
158   (array garray)
159   (index unsigned-int)
160   (value int))
161
162 (defun array-insert-value (array index value)
163   (etypecase value
164     (null (array-insert-int array index 0))
165     (integer (array-insert-int array index value))
166     (string (array-insert-int array index (sap-int (gforeign::pointer-to-sap (%strdup value)))))
167     (pointer (array-insert-int array index (sap-int (gforeign::pointer-to-sap value))))))
168
169 (defun array-prepend (array value)
170   (array-insert-value array 0 value))
171
172 (defun array-append (array value)
173   (array-insert-value array (array-get-size array) value))
174
175 ;; cl-gtk.c
176 (define-foreign ("g_array_get_int" array-get-int) () int
177   (array garray)
178   (index unsigned-int))
179
180 (defun array-get-pointer (array index)
181   (gforeign::sap-to-pointer (int-sap (array-get-int array index))))
182
183 ;; cl-gtk.c
184 (define-foreign ("g_array_get_data" array-get-data) () pointer
185   (array garray))
186
187 (define-foreign ("g_array_set_size" array-set-size) () garray
188   (array garray)
189   (size unsigned-int))
190
191 ;; cl-gtk.c
192 (define-foreign ("g_array_get_size" array-get-size) () int
193   (array garray))
194 |#