11 #:*glib-interface-age*
21 #:+g-priority-default+
22 #:+g-priority-high-idle+
23 #:+g-priority-default-idle+
27 "Cl-gtk2-glib is wrapper for @a[http://library.gnome.org/devel/glib/]{GLib}."))
31 (eval-when (:compile-toplevel :load-toplevel :execute)
32 (defvar *initializers-table* (make-hash-table :test 'equalp))
33 (defvar *initializers* nil)
34 (defun register-initializer (key fn)
35 (unless (gethash key *initializers-table*)
36 (setf (gethash key *initializers-table*) t
37 *initializers* (nconc *initializers* (list fn))))))
39 (defun run-initializers ()
40 (iter (for fn in *initializers*)
43 (defmacro at-init ((&rest keys) &body body)
45 Runs the code normally but also schedules the code to be run at image load time.
46 It is used to reinitialize the libraries when the dumped image is loaded. (Works only on SBCL for now)
48 `(progn (register-initializer (list ,@keys ',body) (lambda () ,@body))
51 (eval-when (:compile-toplevel :load-toplevel :execute)
52 (define-foreign-library glib
53 (:unix (:or "libglib-2.0.so.0" "libglib-2.0.so"))
56 (use-foreign-library glib)
58 (eval-when (:compile-toplevel :load-toplevel :execute)
59 (define-foreign-library gthread
60 (:unix (:or "libgthread-2.0.so.0" "libgthread-2.0.so"))
61 (t "libgthread-2.0")))
63 (use-foreign-library gthread)
70 ;; Fundamentals - Basic types
74 ;; TODO: not sure about these: for amd64 they are ok
75 (eval-when (:compile-toplevel :load-toplevel :execute)
77 ((cffi-features:cffi-feature-p :x86-64) (defctype gsize :uint64))
78 ((cffi-features:cffi-feature-p :x86) (defctype gsize :ulong))
79 (t (error "Can not define 'gsize', unknown CPU architecture (known are x86 and x86-64)"))))
81 (defctype gssize :long)
83 (defctype goffset :uint64)
87 ;; Fundamentals - Version information
90 (defcvar (*glib-major-version* "glib_major_version" :read-only t :library glib) :uint)
91 (defcvar (*glib-minor-version* "glib_minor_version" :read-only t :library glib) :uint)
92 (defcvar (*glib-micro-version* "glib_micro_version" :read-only t :library glib) :uint)
93 (defcvar (*glib-binary-age* "glib_binary_age" :read-only t :library glib) :uint)
94 (defcvar (*glib-interface-age* "glib_interface_age" :read-only t :library glib) :uint)
98 ;; Limits of Basic Types, Standard Macros, Type Conversion Macros, Byte Order Macros,
99 ;; Numerical Definitions, Miscellaneous Macros, Atomic operations
102 ;; Core Application Support - The Main Event Loop
104 (defcstruct g-main-loop)
105 (defcstruct g-main-context)
106 (defcstruct g-source)
107 (defcstruct g-source-funcs
112 (closure-callback :pointer)
113 (closure-marshal :pointer))
114 (defcstruct g-source-callback-funcs
121 (defcstruct g-poll-fd
122 (fd :int) ;; TODO: #if defined (G_OS_WIN32) && GLIB_SIZEOF_VOID_P == 8
126 (defcstruct g-time-val
128 (microseconds :long))
130 (defcstruct g-thread)
132 (defcfun (g-main-loop-new "g_main_loop_new" :library glib) (:pointer g-main-loop)
133 (context (:pointer g-main-context))
134 (is-running :boolean))
136 (defcfun (g-main-loop-ref "g_main_loop_ref" :library glib) (:pointer g-main-loop)
137 (loop (:pointer g-main-loop)))
139 (defcfun (g-main-loop-unref "g_main_loop_unref" :library glib) (:pointer g-main-loop)
140 (loop (:pointer g-main-loop)))
142 (defcfun (g-main-loop-run "g_main_loop_run" :library glib) :void
143 (loop (:pointer g-main-loop)))
145 (defcfun (g-main-loop-quit "g_main_loop_quit" :library glib) :void
146 (loop (:pointer g-main-loop)))
148 (defcfun (g-main-loop-is-running "g_main_loop_is_running" :library glib) :boolean
149 (loop (:pointer g-main-loop)))
151 (defcfun (g-main-loop-get-context "g_main_loop_get_context" :library glib) (:pointer g-main-context)
152 (loop (:pointer g-main-loop)))
154 (defconstant +g-priority-high+ -100 "Use this for high priority event sources. It is not used within GLib or GTK+.")
155 (defconstant +g-priority-default+ 0 "Use this for default priority event sources. In GLib this priority is used when adding timeout functions with g_timeout_add(). In GDK this priority is used for events from the X server.")
156 (defconstant +g-priority-high-idle+ 100 "Use this for high priority idle functions. GTK+ uses @variable{+g-priority-high-idle+} + 10 for resizing operations, and @variable{+g-priority-high-idle+} + 20 for redrawing operations. (This is done to ensure that any pending resizes are processed before any pending redraws, so that widgets are not redrawn twice unnecessarily.)")
157 (defconstant +g-priority-default-idle+ 200 "Use this for default priority idle functions. In GLib this priority is used when adding idle functions with g_idle_add().")
158 (defconstant +g-priority-low+ 300 "Use this for very low priority background tasks. It is not used within GLib or GTK+.")
160 (defcfun (g-main-context-new "g_main_context_new" :library glib) (:pointer g-main-context))
162 (defcfun (g-main-context-ref "g_main_context_ref" :library glib) (:pointer g-main-context)
163 (context (:pointer g-main-context)))
165 (defcfun (g-main-context-unref "g_main_context_unref" :library glib) (:pointer g-main-context)
166 (context (:pointer g-main-context)))
168 (defcfun (g-main-context-default "g_main_context_default" :library glib) (:pointer g-main-context))
170 (defcfun (g-main-context-iteration "g_main_context_iteration" :library glib) :boolean
171 (context (:pointer g-main-context))
172 (may-block :boolean))
174 (defcfun (g-main-context-pending "g_main_context_pending" :library glib) :boolean
175 (context (:pointer g-main-context)))
177 (defcfun (g-main-context-find-source-by-id "g_main_context_find_source_by_id" :library glib) (:pointer g-source)
178 (context (:pointer g-main-context))
181 (defcfun (g-main-context-find-source-by-user-data "g_main_context_find_source_by_user_data" :library glib) (:pointer g-source)
182 (context (:pointer g-main-context))
183 (user-data :pointer))
185 (defcfun (g-main-context-find-source-by-funcs-user-data "g_main_context_find_source_by_funcs_user_data" :library glib) (:pointer g-source)
186 (context (:pointer g-main-context))
187 (funcs (:pointer g-source-funcs))
188 (user-data :pointer))
190 (defcfun (g-main-context-wakeup "g_main_context_wakeup" :library glib) :void
191 (context (:pointer g-main-context)))
193 (defcfun (g-main-context-acquire "g_main_context_acquire" :library glib) :boolean
194 (context (:pointer g-main-context)))
196 (defcfun (g-main-context-release "g_main_context_release" :library glib) :void
197 (context (:pointer g-main-context)))
199 (defcfun (g-main-context-is-owner "g_main_context_is_owner" :library glib) :boolean
200 (context (:pointer g-main-context)))
202 (defcfun (g-main-context-wait "g_main_context_wait" :library glib) :boolean
203 (context (:pointer g-main-context))
204 (cond (:pointer g-cond))
205 (mutex (:pointer g-mutex)))
207 (defcfun (g_main_context_prepare "g_main_context_prepare" :library glib) :boolean
208 (context (:pointer g-main-context))
209 (priority-ret (:pointer :int)))
211 (defcfun (g_main_context_query "g_main_context_query" :library glib) :int
212 (context (:pointer g-main-context))
214 (timeout-ret (:pointer :int))
215 (fds-ret (:pointer g-poll-fd))
218 (defcfun (g-main-context-check "g_main_context_check" :library glib) :int
219 (context (:pointer g-main-context))
221 (fds (:pointer g-poll-fd))
224 (defcfun (g-main-context-dispatch "g_main_context_dispatch" :library glib) :void
225 (context (:pointer g-main-context)))
227 (defcfun (g-main-context-set-poll-func "g_main_context_set_poll_func" :library glib) :void
228 (context (:pointer g-main-context))
231 (defcfun (g-main-context-get-poll-func "g_main_context_get_poll_func" :library glib) :pointer
232 (context (:pointer g-main-context)))
234 (defcfun (g-main-context-add-poll "g_main_context_add_poll" :library glib) :void
235 (context (:pointer g-main-context))
236 (fd (:pointer g-poll-fd))
239 (defcfun (g-main-context-remove-poll "g_main_context_remove_poll" :library glib) :void
240 (context (:pointer g-main-context))
241 (fd (:pointer g-poll-fd)))
243 (defcfun (g-main-depth "g_main_depth" :library glib) :int)
245 (defcfun (g-main-current-source "g_main_current_source" :library glib) (:pointer g-source))
247 (defcfun (g-timeout-source-new "g_timeout_source_new" :library glib) (:pointer g-source)
248 (interval-milliseconds :int))
250 (defcfun (g-timeout-source-new-seconds "g_timeout_source_new_seconds" :library glib) (:pointer g-source)
251 (interval-seconds :int))
253 (defcfun (g-timeout-add "g_timeout_add" :library glib) :uint
254 (interval-milliseconds :uint)
258 (defcfun (g-timeout-add-full "g_timeout_add_full" :library glib) :uint
260 (interval-milliseconds :uint)
263 (destroy-notify :pointer))
265 (defcfun (g-timeout-add-seconds "g_timeout_add_seconds" :library glib) :uint
266 (interval-seconds :uint)
270 (defcfun (g-timeout-add-seconds-full "g_timeout_add_seconds_full" :library glib) :uint
272 (interval-seconds :uint)
275 (destroy-notify :pointer))
277 (defcfun (g-idle-source-new "g_idle_source_new" :library glib) (:pointer g-source))
279 (defcfun (g-idle-add "g_idle_add" :library glib) :uint
283 (defcfun (g-idle-add-full "g_idle_add_full" :library glib) :uint
284 "A low-level function for adding callbacks to be called from main loop. Wrapper around g_idle_add_full.
285 Adds a function to be called whenever there are no higher priority events pending. If the function returns FALSE it is automatically removed from the list of event sources and will not be called again.
286 @arg[priority]{an integer specifying the priority. See @variable{+g-priority-default+}, @variable{+g-priority-default-idle+}, @variable{+g-priority-high+}, @variable{+g-priority-high-idle+}, @variable{+g-priority-low+}.}
287 @arg[function]{pointer to callback that will be called. Callback should accept a single pointer argument and return a boolean FALSE if it should be removed}
288 @arg[data]{pointer that will be passed to callback function}
289 @arg[notify]{function that will be called when callback is no more needed. It will receive the @code{data} argument}"
295 (defcfun (g-idle-remove-by-data "g_idle_remove_by_data" :library glib) :boolean
298 ;(defctype g-pid :int) ;;TODO: might work on amd64 linux, but on others
300 ;; Omitted GPid, g_child_add_watch, g_child_add_watch_full
302 (defcfun (g-source-new "g_source_new" :library glib) (:pointer g-source)
303 (source-funcs (:pointer g-source-funcs))
306 (defcfun (g-source-ref "g_source_ref" :library glib) (:pointer g-source)
307 (source (:pointer g-source)))
309 (defcfun (g-source-unref "g_source_unref" :library glib) :void
310 (source (:pointer g-source)))
312 (defcfun (g-source-set-funcs "g_source_set_funcs" :library glib) :void
313 (source (:pointer g-source))
314 (funcs (:pointer g-source-funcs)))
316 (defcfun (g-source-attach "g_source_attach" :library glib) :uint
317 (source (:pointer g-source))
318 (context (:pointer g-main-context)))
320 (defcfun (g-source-destroy "g_source_destroy" :library glib) :void
321 (source (:pointer g-source)))
323 (defcfun (g-source-is-destroyed "g_source_is_destroyed" :library glib) :boolean
324 (source (:pointer g-source)))
326 (defcfun (g-source-set-priority "g_source_set_priority" :library glib) :void
327 (source (:pointer g-source))
330 (defcfun (g-source-get-priority "g_source_get_priority" :library glib) :int
331 (source (:pointer g-source)))
333 (defcfun (g-source-set-can-recurse "g_source_set_can_recurse" :library glib) :void
334 (source (:pointer g-source))
335 (can-recurse :boolean))
337 (defcfun (g-source-get-can-recurse "g_source_get_can_recurse" :library glib) :boolean
338 (source (:pointer g-source)))
340 (defcfun (g-source-get-id "g_source_get_id" :library glib) :uint
341 (source (:pointer g-source)))
343 (defcfun (g-source-get-context "g_source_get_context" :library glib) (:pointer g-main-context)
344 (source (:pointer g-source)))
346 (defcfun (g-source-set-callback "g_source_set_callback" :library glib) :void
347 (source (:pointer g-source))
352 (defcfun (g-source-add-poll "g_source_add_poll" :library glib) :void
353 (source (:pointer g-source))
354 (fd (:pointer g-poll-fd)))
356 (defcfun (g-source-remove-poll "g_source_remove_poll" :library glib) :void
357 (source (:pointer g-source))
358 (fd (:pointer g-poll-fd)))
360 (defcfun (g-source-get-current-time "g_source_get_current_time" :library glib) :void
361 (source (:pointer g-source))
362 (timeval-ret (:pointer g-time-val)))
364 (defcfun (g-source-remove "g_source_remove" :library glib) :boolean
367 (defcfun (g-source-remove-by-funcs-user-data "g_source_remove_by_funcs_user_data" :library glib) :boolean
368 (funcs (:pointer g-source-funcs))
371 (defcfun (g-source-remove-by-user-data "g_source_remove_by_user_data" :library glib) :boolean
375 ;; Core Application Support - Threads
378 (defcenum g-thread-error
379 :g-thread-error-again)
381 ;omitted: struct GThreadFunctions
383 (defcfun (g-thread-init "g_thread_init") :void
386 (defvar *threads-initialized-p* nil)
389 (unless *threads-initialized-p*
390 (g-thread-init (null-pointer))
391 (setf *threads-initialized-p* t)))
393 (defcenum g-thread-priority
394 :g-thread-priority-low
395 :g-thread-priority-normal
396 :g-thread-priority-hight
397 :g-thread-priority-urgent)
399 ;omitted: g_thread_create, g_thread_create_full, g_thread_yield, g_thread_exit, g_thread_foreach
401 (defcfun (g-thread-self "g_thread_self" :library glib) (:pointer g-thread))
403 (defcfun (g-thread-join "g_thread_join" :library glib) :pointer
404 (thread (:pointer g-thread)))
406 (defcfun (g-thread-priority "g_thread_set_priority" :library glib) :void
407 (thread (:pointer g-thread))
408 (priority g-thread-priority))
410 ;;;; TODO: Commented g_mutex_*, g_cond* because they are not functions, but called through dispatch table
412 ;; (defcfun (g-mutex-new "g_mutex_new" :library glib) (:pointer g-mutex))
414 ;; (defcfun (g-mutex-lock "g_mutex_lock" :library glib) :void
415 ;; (mutex (:pointer g-mutex)))
417 ;; (defcfun (g-mutex-try-lock "g_mutex_trylock" :library glib) :boolean
418 ;; (mutex (:pointer g-mutex)))
420 ;; (defcfun (g-mutex-free "g_mutex_free" :library glib) :void
421 ;; (mutex (:pointer g-mutex)))
423 ;omitted: GStaticMutex, GStaticRWLock stuff
425 ;; (defcfun (g-cond-new "g_cond_new" :library glib) (:pointer g-cond))
427 ;; (defcfun (g-cond-signal "g_cond_signal" :library glib) :void
428 ;; (cond (:pointer g-cond)))
430 ;; (defcfun (g-cond-broadcast "g_cond_broadcast" :library glib) :void
431 ;; (cond (:pointer g-cond)))
433 ;; (defcfun (g-cond-wait "g_cond_wait" :library glib) :void
434 ;; (cond (:pointer g-cond))
435 ;; (mutex (:pointer g-mutex)))
437 ;; (defcfun (g-cond-timed-wait "g_cond_timed_wait" :library glib) :boolean
438 ;; (cond (:pointer g-cond))
439 ;; (mutex (:pointer g-mutex))
440 ;; (abs-time (:pointer g-time-val)))
442 ;; (defcfun (g-cond-free "g_cond_free" :library glib) :void
443 ;; (cond (:pointer g-cond)))
445 ;omitted: GPrivate, GOnce stuff
447 ;omitted: Thread pools, Asynchronous queues, Dynamic Loading of Modules,
448 ; Memory Allocation, IO Channels, Error Reporting, Message Output and Debugging Functions, Message Logging
450 (defcfun g-free :void
451 "@arg[ptr]{pointer previously obtained with @fun{g-malloc} or with g_malloc C function}
452 Frees the pointer by calling g_free on it."
455 (defcfun (g-malloc "g_malloc0") :pointer
456 "@arg[n-bytes]{an integer}
457 @return{pointer to beginning of allocated memory}
458 Allocates the specified number of bytes in memory. Calls g_malloc.
462 (defcfun g-strdup :pointer
463 "@arg[str]{a @class{string}}
464 @return{foreign pointer to new string}
465 Allocates a new string that is equal to @code{str}. Use @fun{g-free} to free it."
466 (str (:string :free-to-foreign t)))
468 ;omitted all GLib Utilites
469 ;TODO: omitted Date and Time Functions