Typo.
[cl-gtk2.git] / glib / glib.lisp
1 (defpackage :glib
2   (:use :cl :cffi :iter)
3   (:export #:at-init
4            #:gsize
5            #:gssize
6            #:goffset
7            #:*glib-major-version*
8            #:*glib-minor-version*
9            #:*glib-micro-version*
10            #:*glib-binary-age*
11            #:*glib-interface-age*
12            #:g-free
13            #:glist
14            #:gstrv
15            #:g-malloc
16            #:g-strdup
17            #:g-string
18            #:gslist
19            #:g-quark
20            #:+g-priority-high+
21            #:+g-priority-default+
22            #:+g-priority-high-idle+
23            #:+g-priority-default-idle+
24            #:+g-priority-low+
25            #:g-idle-add-full
26            #:g-idle-add
27            #:g-timeout-add-full
28            #:g-source-remove
29            #:at-finalize
30            #:with-g-error
31            #:with-catching-to-g-error
32            #:g-error-condition
33            #:g-error-condition-domain
34            #:g-error-condition-code
35            #:g-error-condition-message
36            #:g-spawn-flags
37            #:push-library-version-features
38            #:foreign-library-minimum-version-mismatch
39            #:require-library-version)
40   (:documentation
41    "Cl-gtk2-glib is wrapper for @a[http://library.gnome.org/devel/glib/]{GLib}."))
42
43 (in-package :glib)
44
45 (eval-when (:compile-toplevel :load-toplevel :execute)
46   (defvar *initializers-table* (make-hash-table :test 'equalp))
47   (defvar *initializers* nil)
48   (defun register-initializer (key fn)
49     (unless (gethash key *initializers-table*)
50       (setf (gethash key *initializers-table*) t
51             *initializers* (nconc *initializers* (list fn)))))
52   (defvar *finalizers-table* (make-hash-table :test 'equalp))
53   (defvar *finalizers* nil)
54   (defun register-finalizer (key fn)
55     (unless (gethash key *finalizers-table*)
56       (setf (gethash key *finalizers-table*) t
57             *finalizers* (nconc *finalizers* (list fn))))))
58
59 (defun run-initializers ()
60   (iter (for fn in *initializers*)
61         (funcall fn)))
62
63 (defun run-finalizers ()
64   (iter (for fn in *finalizers*)
65         (funcall fn)))
66
67 #+sbcl
68 (pushnew 'run-initializers sb-ext:*init-hooks*)
69 #+openmcl
70 (pushnew 'run-initializers ccl:*restore-lisp-functions*)
71
72 #+sbcl
73 (pushnew 'run-finalizers sb-ext:*save-hooks*)
74 #+openmcl
75 (pushnew 'run-finalizers ccl:*save-exit-functions*)
76
77 (defmacro at-init ((&rest keys) &body body)
78   "
79 @arg[keys]{list of expression}
80 @arg[body]{the code}
81 Runs the code normally but also schedules the code to be run at image load time.
82 It is used to reinitialize the libraries when the dumped image is loaded. (Works only on SBCL for now).
83
84 At-init form may be called multiple times. The same code from should not be run multiple times at initialization time (in best case, this will only slow down initialization, in worst case, the code may crash). To ensure this, every @code{at-init} expression is added to hash-table with the @code{body} and @code{keys} as a composite key. This ensures that the same code is only executed once (once on the same set of parameters).
85
86 Example:
87 @begin{pre}
88 \(defmethod initialize-instance :after ((class gobject-class) &key &allow-other-keys)
89   (register-object-type (gobject-class-g-type-name class) (class-name class))
90   (at-init (class) (initialize-gobject-class-g-type class)))
91 @end{pre}
92
93 In this example, for every @code{class}, @code{(initialize-gobject-class-g-type class)} will be called only once.
94 "
95   `(progn (register-initializer (list ,@keys ',body) (lambda () ,@body))
96           ,@body))
97
98 (defmacro at-finalize ((&rest keys) &body body)
99   `(register-finalizer (list ,@keys ',body) (lambda () ,@body)))
100
101 (at-init ()
102   (eval-when (:compile-toplevel :load-toplevel :execute)
103     (define-foreign-library glib
104       ((:and :unix (:not :darwin)) (:or "libglib-2.0.so.0" "libglib-2.0.so"))
105       (:darwin (:or "libglib-2.0.0.dylib" "libglib-2.0.dylib"))
106       (:windows "libglib-2.0-0.dll")
107       (t (:default "libglib-2.0"))))
108   (eval-when (:compile-toplevel :load-toplevel :execute)
109     (define-foreign-library gthread
110       ((:and :unix (:not :darwin))  (:or "libgthread-2.0.so.0"  "libgthread-2.0.so"))
111       (:darwin (:or "libgthread-2.0.0.dylib"  "libgthread-2.0.dylib"))
112       (:windows "libgthread-2.0-0.dll")
113       (t "libgthread-2.0")))
114
115   (use-foreign-library glib)
116   (use-foreign-library gthread))
117
118 (defmacro push-library-version-features (library-name major-version-var minor-version-var &body versions)
119   `(eval-when (:load-toplevel :execute)
120      ,@(iter (for (major minor) on versions by #'cddr)
121              (collect
122                  `(when (or (and (= ,major-version-var ,major) (>= ,minor-version-var ,minor))
123                             (> ,major-version-var ,major))
124                     (pushnew ,(intern (format nil "~A-~A.~A" (string library-name) major minor) (find-package :keyword)) *features*))))))
125
126 (define-condition foreign-library-minimum-version-mismatch (error)
127   ((library :initarg :library :reader .library)
128    (minimum-version :initarg :minimum-version :reader .minimum-version)
129    (actual-version :initarg :actual-version :reader .actual-version))
130   (:report (lambda (c s)
131              (format s "Library ~A has too old version: it is ~A but required to be at least ~A"
132                      (.library c)
133                      (.actual-version c)
134                      (.minimum-version c)))))
135
136 (defun require-library-version (library min-major-version min-minor-version major-version minor-version)
137   (unless (or (> major-version min-major-version)
138               (and (= major-version min-major-version)
139                    (>= minor-version min-minor-version)))
140     (restart-case
141         (error 'foreign-library-minimum-version-mismatch
142                :library library
143                :minimum-version (format nil "~A.~A" min-major-version min-minor-version)
144                :actual-version (format nil "~A.~A" major-version minor-version))
145       (ignore () :report "Ignore version requirement" nil))))
146
147 ;;
148 ;; Glib Fundamentals
149 ;;
150
151 ;;
152 ;; Fundamentals - Basic types
153 ;;
154
155
156 ;; TODO: not sure about these: for amd64 they are ok
157 (eval-when (:compile-toplevel :load-toplevel :execute)
158   (cond
159     ((cffi-features:cffi-feature-p :x86-64) (defctype gsize :uint64))
160     ((cffi-features:cffi-feature-p :x86) (defctype gsize :ulong))
161     ((cffi-features:cffi-feature-p :ppc32) (defctype gsize :uint32))
162     ((cffi-features:cffi-feature-p :ppc64) (defctype gsize :uint64))
163     (t (error "Can not define 'gsize', unknown CPU architecture (known are x86 and x86-64)"))))
164
165 (defctype gssize :long)
166
167 (defctype goffset :uint64)
168
169
170 ;;
171 ;; Fundamentals - Version information
172 ;;
173
174 (defcvar (*glib-major-version* "glib_major_version" :read-only t :library glib) :uint)
175 (defcvar (*glib-minor-version* "glib_minor_version" :read-only t :library glib) :uint)
176 (defcvar (*glib-micro-version* "glib_micro_version" :read-only t :library glib) :uint)
177 (defcvar (*glib-binary-age* "glib_binary_age" :read-only t :library glib) :uint)
178 (defcvar (*glib-interface-age* "glib_interface_age" :read-only t :library glib) :uint)
179
180 (push-library-version-features glib *glib-major-version* *glib-micro-version*
181   2 2
182   2 4
183   2 6
184   2 8
185   2 10
186   2 12
187   2 14
188   2 16
189   2 18
190   2 20
191   2 22)
192
193 (require-library-version "Glib" 2 20 *glib-major-version* *glib-minor-version*)
194
195 ;;
196 ;; Omitted:
197 ;; Limits of Basic Types, Standard Macros, Type Conversion Macros, Byte Order Macros, 
198 ;; Numerical Definitions, Miscellaneous Macros, Atomic operations
199 ;;
200
201 ;; Core Application Support - The Main Event Loop
202
203 (defcstruct g-main-loop)
204 (defctype g-main-loop (:struct g-main-loop))
205 (defcstruct g-main-context)
206 (defctype g-main-context (:struct g-main-context))
207 (defcstruct g-source)
208 (defctype g-source (:struct g-source))
209 (defcstruct g-source-funcs
210   (prepare :pointer)
211   (check :pointer)
212   (dispatch :pointer)
213   (finalize :pointer)
214   (closure-callback :pointer)
215   (closure-marshal :pointer))
216 (defctype g-source-funcs (:struct g-source-funcs))
217 (defcstruct g-source-callback-funcs
218   (ref :pointer)
219   (unref :pointer)
220   (get :pointer))
221 (defctype g-source-callback-funcs (:struct g-source-callback-funcs))
222 (defcstruct g-cond)
223 (defctype g-cond (:struct g-cond))
224 (defcstruct g-mutex)
225 (defctype g-mutex (:struct g-mutex))
226
227 (defcstruct g-poll-fd
228   (fd :int) ;; TODO: #if defined (G_OS_WIN32) && GLIB_SIZEOF_VOID_P == 8
229   (events :ushort)
230   (revent :ushort))
231 (defctype g-poll-fd (:struct g-poll-fd))
232
233 (defcstruct g-time-val
234   (seconds :long)
235   (microseconds :long))
236 (defctype g-time-val (:struct g-time-val))
237
238 (defcstruct g-thread)
239 (defctype g-thread (:struct g-thread))
240
241 (defcfun (g-main-loop-new "g_main_loop_new" :library glib) (:pointer g-main-loop)
242   (context (:pointer g-main-context))
243   (is-running :boolean))
244
245 (defcfun (g-main-loop-ref "g_main_loop_ref" :library glib) (:pointer g-main-loop)
246   (loop (:pointer g-main-loop)))
247
248 (defcfun (g-main-loop-unref "g_main_loop_unref" :library glib) (:pointer g-main-loop)
249   (loop (:pointer g-main-loop)))
250
251 (defcfun (g-main-loop-run "g_main_loop_run" :library glib) :void
252   (loop (:pointer g-main-loop)))
253
254 (defcfun (g-main-loop-quit "g_main_loop_quit" :library glib) :void
255   (loop (:pointer g-main-loop)))
256
257 (defcfun (g-main-loop-is-running "g_main_loop_is_running" :library glib) :boolean
258   (loop (:pointer g-main-loop)))
259
260 (defcfun (g-main-loop-get-context "g_main_loop_get_context" :library glib) (:pointer g-main-context)
261   (loop (:pointer g-main-loop)))
262
263 (defconstant +g-priority-high+ -100 "Use this for high priority event sources. It is not used within GLib or GTK+.")
264 (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.")
265 (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.)")
266 (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().")
267 (defconstant +g-priority-low+ 300 "Use this for very low priority background tasks. It is not used within GLib or GTK+.")
268
269 (defcfun (g-main-context-new "g_main_context_new" :library glib) (:pointer g-main-context))
270
271 (defcfun (g-main-context-ref "g_main_context_ref" :library glib) (:pointer g-main-context)
272   (context (:pointer g-main-context)))
273
274 (defcfun (g-main-context-unref "g_main_context_unref" :library glib) (:pointer g-main-context)
275   (context (:pointer g-main-context)))
276
277 (defcfun (g-main-context-default "g_main_context_default" :library glib) (:pointer g-main-context))
278
279 (defcfun (g-main-context-iteration "g_main_context_iteration" :library glib) :boolean
280   (context (:pointer g-main-context))
281   (may-block :boolean))
282
283 (defcfun (g-main-context-pending "g_main_context_pending" :library glib) :boolean
284   (context (:pointer g-main-context)))
285
286 (defcfun (g-main-context-find-source-by-id "g_main_context_find_source_by_id" :library glib) (:pointer g-source)
287   (context (:pointer g-main-context))
288   (source-id :uint))
289
290 (defcfun (g-main-context-find-source-by-user-data "g_main_context_find_source_by_user_data" :library glib) (:pointer g-source)
291   (context (:pointer g-main-context))
292   (user-data :pointer))
293
294 (defcfun (g-main-context-find-source-by-funcs-user-data "g_main_context_find_source_by_funcs_user_data" :library glib) (:pointer g-source)
295   (context (:pointer g-main-context))
296   (funcs (:pointer g-source-funcs))
297   (user-data :pointer))
298
299 (defcfun (g-main-context-wakeup "g_main_context_wakeup" :library glib) :void
300   (context (:pointer g-main-context)))
301
302 (defcfun (g-main-context-acquire "g_main_context_acquire" :library glib) :boolean
303   (context (:pointer g-main-context)))
304
305 (defcfun (g-main-context-release "g_main_context_release" :library glib) :void
306   (context (:pointer g-main-context)))
307
308 (defcfun (g-main-context-is-owner "g_main_context_is_owner" :library glib) :boolean
309   (context (:pointer g-main-context)))
310
311 (defcfun (g-main-context-wait "g_main_context_wait" :library glib) :boolean
312   (context (:pointer g-main-context))
313   (cond (:pointer g-cond))
314   (mutex (:pointer g-mutex)))
315
316 (defcfun (g_main_context_prepare "g_main_context_prepare" :library glib) :boolean
317   (context (:pointer g-main-context))
318   (priority-ret (:pointer :int)))
319
320 (defcfun (g_main_context_query "g_main_context_query" :library glib) :int
321   (context (:pointer g-main-context))
322   (max-priority :int)
323   (timeout-ret (:pointer :int))
324   (fds-ret (:pointer g-poll-fd))
325   (n-dfs :int))
326
327 (defcfun (g-main-context-check "g_main_context_check" :library glib) :int
328   (context (:pointer g-main-context))
329   (max-priority :int)
330   (fds (:pointer g-poll-fd))
331   (n-fds :int))
332
333 (defcfun (g-main-context-dispatch "g_main_context_dispatch" :library glib) :void
334   (context (:pointer g-main-context)))
335
336 (defcfun (g-main-context-set-poll-func "g_main_context_set_poll_func" :library glib) :void
337   (context (:pointer g-main-context))
338   (func :pointer))
339
340 (defcfun (g-main-context-get-poll-func "g_main_context_get_poll_func" :library glib) :pointer
341   (context (:pointer g-main-context)))
342
343 (defcfun (g-main-context-add-poll "g_main_context_add_poll" :library glib) :void
344   (context (:pointer g-main-context))
345   (fd (:pointer g-poll-fd))
346   (priority :int))
347
348 (defcfun (g-main-context-remove-poll "g_main_context_remove_poll" :library glib) :void
349   (context (:pointer g-main-context))
350   (fd (:pointer g-poll-fd)))
351
352 (defcfun (g-main-depth "g_main_depth" :library glib) :int)
353
354 (defcfun (g-main-current-source "g_main_current_source" :library glib) (:pointer g-source))
355
356 (defcfun (g-timeout-source-new "g_timeout_source_new" :library glib) (:pointer g-source)
357   (interval-milliseconds :int))
358
359 (defcfun (g-timeout-source-new-seconds "g_timeout_source_new_seconds" :library glib) (:pointer g-source)
360   (interval-seconds :int))
361
362 (defcfun (g-timeout-add "g_timeout_add" :library glib) :uint
363   (interval-milliseconds :uint)
364   (function :pointer)
365   (data :pointer))
366
367 (defcfun (g-timeout-add-full "g_timeout_add_full" :library glib) :uint
368   (priority :int)
369   (interval-milliseconds :uint)
370   (function :pointer)
371   (data :pointer)
372   (destroy-notify :pointer))
373
374 (defcfun (g-timeout-add-seconds "g_timeout_add_seconds" :library glib) :uint
375   (interval-seconds :uint)
376   (function :pointer)
377   (data :pointer))
378
379 (defcfun (g-timeout-add-seconds-full "g_timeout_add_seconds_full" :library glib) :uint
380   (priority :int)
381   (interval-seconds :uint)
382   (function :pointer)
383   (data :pointer)
384   (destroy-notify :pointer))
385
386 (defcfun (g-idle-source-new "g_idle_source_new" :library glib) (:pointer g-source))
387
388 (defcfun (g-idle-add "g_idle_add" :library glib) :uint
389   (function :pointer)
390   (data :pointer))
391
392 (defcfun (g-idle-add-full "g_idle_add_full" :library glib) :uint
393   "A low-level function for adding callbacks to be called from main loop. Wrapper around g_idle_add_full.
394 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.
395 @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+}.}
396 @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}
397 @arg[data]{pointer that will be passed to callback function}
398 @arg[notify]{function that will be called when callback is no more needed. It will receive the @code{data} argument}"
399   (priority :uint)
400   (function :pointer)
401   (data :pointer)
402   (notify :pointer))
403
404 (defcfun (g-idle-remove-by-data "g_idle_remove_by_data" :library glib) :boolean
405   (data :pointer))
406
407 ;(defctype g-pid :int) ;;TODO: might work on amd64 linux, but on others
408
409 ;; Omitted GPid, g_child_add_watch, g_child_add_watch_full
410
411 (defcfun (g-source-new "g_source_new" :library glib) (:pointer g-source)
412   (source-funcs (:pointer g-source-funcs))
413   (struct-size :uint))
414
415 (defcfun (g-source-ref "g_source_ref" :library glib) (:pointer g-source)
416   (source (:pointer g-source)))
417
418 (defcfun (g-source-unref "g_source_unref" :library glib) :void
419   (source (:pointer g-source)))
420
421 (defcfun (g-source-set-funcs "g_source_set_funcs" :library glib) :void
422   (source (:pointer g-source))
423   (funcs (:pointer g-source-funcs)))
424
425 (defcfun (g-source-attach "g_source_attach" :library glib) :uint
426   (source (:pointer g-source))
427   (context (:pointer g-main-context)))
428
429 (defcfun (g-source-destroy "g_source_destroy" :library glib) :void
430   (source (:pointer g-source)))
431
432 (defcfun (g-source-is-destroyed "g_source_is_destroyed" :library glib) :boolean
433   (source (:pointer g-source)))
434
435 (defcfun (g-source-set-priority "g_source_set_priority" :library glib) :void
436   (source (:pointer g-source))
437   (priority :int))
438
439 (defcfun (g-source-get-priority "g_source_get_priority" :library glib) :int
440   (source (:pointer g-source)))
441
442 (defcfun (g-source-set-can-recurse "g_source_set_can_recurse" :library glib) :void
443   (source (:pointer g-source))
444   (can-recurse :boolean))
445
446 (defcfun (g-source-get-can-recurse "g_source_get_can_recurse" :library glib) :boolean
447   (source (:pointer g-source)))
448
449 (defcfun (g-source-get-id "g_source_get_id" :library glib) :uint
450   (source (:pointer g-source)))
451
452 (defcfun (g-source-get-context "g_source_get_context" :library glib) (:pointer g-main-context)
453   (source (:pointer g-source)))
454
455 (defcfun (g-source-set-callback "g_source_set_callback" :library glib) :void
456   (source (:pointer g-source))
457   (func :pointer)
458   (data :pointer)
459   (notify :pointer))
460
461 (defcfun (g-source-add-poll "g_source_add_poll" :library glib) :void
462   (source (:pointer g-source))
463   (fd (:pointer g-poll-fd)))
464
465 (defcfun (g-source-remove-poll "g_source_remove_poll" :library glib) :void
466   (source (:pointer g-source))
467   (fd (:pointer g-poll-fd)))
468
469 (defcfun (g-source-get-current-time "g_source_get_current_time" :library glib) :void
470   (source (:pointer g-source))
471   (timeval-ret (:pointer g-time-val)))
472
473 (defcfun (g-source-remove "g_source_remove" :library glib) :boolean
474   (id :uint))
475
476 (defcfun (g-source-remove-by-funcs-user-data "g_source_remove_by_funcs_user_data" :library glib) :boolean
477   (funcs (:pointer g-source-funcs))
478   (data :pointer))
479
480 (defcfun (g-source-remove-by-user-data "g_source_remove_by_user_data" :library glib) :boolean
481   (data :pointer))
482
483 ;;
484 ;; Core Application Support - Threads
485 ;;
486
487 (defcenum g-thread-error
488   :g-thread-error-again)
489
490 ;omitted: struct GThreadFunctions
491
492 (defcfun (g-thread-init "g_thread_init") :void
493   (vtable :pointer))
494
495 (defcfun g-thread-get-initialized :boolean)
496
497 (at-init ()
498   (unless (g-thread-get-initialized)
499     (g-thread-init (null-pointer))))
500
501 (defcenum g-thread-priority
502   :g-thread-priority-low
503   :g-thread-priority-normal
504   :g-thread-priority-hight
505   :g-thread-priority-urgent)
506
507 ;omitted: g_thread_create, g_thread_create_full, g_thread_yield, g_thread_exit, g_thread_foreach
508
509 (defcfun (g-thread-self "g_thread_self" :library glib) (:pointer g-thread))
510
511 (defcfun (g-thread-join "g_thread_join" :library glib) :pointer
512   (thread (:pointer g-thread)))
513
514 (defcfun (g-thread-priority "g_thread_set_priority" :library glib) :void
515   (thread (:pointer g-thread))
516   (priority g-thread-priority))
517
518 ;;;; TODO: Commented g_mutex_*, g_cond* because they are not functions, but called through dispatch table
519
520 ;; (defcfun (g-mutex-new "g_mutex_new" :library glib) (:pointer g-mutex))
521
522 ;; (defcfun (g-mutex-lock "g_mutex_lock" :library glib) :void
523 ;;   (mutex (:pointer g-mutex)))
524
525 ;; (defcfun (g-mutex-try-lock "g_mutex_trylock" :library glib) :boolean
526 ;;   (mutex (:pointer g-mutex)))
527
528 ;; (defcfun (g-mutex-free "g_mutex_free" :library glib) :void
529 ;;   (mutex (:pointer g-mutex)))
530
531 ;omitted: GStaticMutex, GStaticRWLock stuff
532
533 ;; (defcfun (g-cond-new "g_cond_new" :library glib) (:pointer g-cond))
534
535 ;; (defcfun (g-cond-signal "g_cond_signal" :library glib) :void
536 ;;   (cond (:pointer g-cond)))
537
538 ;; (defcfun (g-cond-broadcast "g_cond_broadcast" :library glib) :void
539 ;;   (cond (:pointer g-cond)))
540
541 ;; (defcfun (g-cond-wait "g_cond_wait" :library glib) :void
542 ;;   (cond (:pointer g-cond))
543 ;;   (mutex (:pointer g-mutex)))
544
545 ;; (defcfun (g-cond-timed-wait "g_cond_timed_wait" :library glib) :boolean
546 ;;   (cond (:pointer g-cond))
547 ;;   (mutex (:pointer g-mutex))
548 ;;   (abs-time (:pointer g-time-val)))
549
550 ;; (defcfun (g-cond-free "g_cond_free" :library glib) :void
551 ;;   (cond (:pointer g-cond)))
552
553 ;omitted: GPrivate, GOnce stuff
554
555 ;omitted: Thread pools, Asynchronous queues, Dynamic Loading of Modules,
556 ; Memory Allocation, IO Channels, Error Reporting, Message Output and Debugging  Functions, Message Logging
557
558 (defcfun g-free :void
559   "@arg[ptr]{pointer previously obtained with @fun{g-malloc} or with g_malloc C function}
560 Frees the pointer by calling g_free on it."
561   (ptr :pointer))
562
563 (defcfun (g-malloc "g_malloc0") :pointer
564   "@arg[n-bytes]{an integer}
565 @return{pointer to beginning of allocated memory}
566 Allocates the specified number of bytes in memory. Calls g_malloc.
567 @see{g-free}"
568   (n-bytes gsize))
569
570 (defcfun g-strdup :pointer
571   "@arg[str]{a @class{string}}
572 @return{foreign pointer to new string}
573 Allocates a new string that is equal to @code{str}. Use @fun{g-free} to free it."
574   (str (:string :free-to-foreign t)))
575
576 ;omitted all GLib Utilites
577
578 (defbitfield g-spawn-flags
579   :leave-descriptors-open :do-not-reap-child :search-path :stdout-to-dev-null :stderr-to-dev-null
580   :child-inherits-stdin :file-and-argv-zero)
581
582 ;TODO: omitted Date and Time Functions