1 ;; Common Lisp bindings for GTK+ v2.x
2 ;; Copyright 2000-2006 Espen S. Johnsen <espen@users.sf.net>
4 ;; Permission is hereby granted, free of charge, to any person obtaining
5 ;; a copy of this software and associated documentation files (the
6 ;; "Software"), to deal in the Software without restriction, including
7 ;; without limitation the rights to use, copy, modify, merge, publish,
8 ;; distribute, sublicense, and/or sell copies of the Software, and to
9 ;; permit persons to whom the Software is furnished to do so, subject to
10 ;; the following conditions:
12 ;; The above copyright notice and this permission notice shall be
13 ;; included in all copies or substantial portions of the Software.
15 ;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 ;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 ;; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 ;; IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 ;; CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 ;; TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 ;; SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 ;; $Id: gdk.lisp,v 1.40 2007/06/18 13:41:18 espen Exp $
30 (defbinding (gdk-init "gdk_parse_args") () nil
31 "Initializes the library without opening the display."
40 (defmethod print-object ((display display) stream)
41 (if (and (proxy-valid-p display) (slot-boundp display 'name))
42 (print-unreadable-object (display stream :type t :identity nil)
43 (format stream "~S at 0x~X"
44 (display-name display) (pointer-address (foreign-location display))))
47 (defbinding %display-open () display
48 (display-name (or null string)))
50 (defun display-open (&optional display-name)
52 (%display-open display-name)
53 (error "Opening display failed: ~A" display-name))))
54 (unless (display-get-default)
55 (display-set-default display))
58 (defbinding %display-get-n-screens () int
61 (defbinding %display-get-screen () screen
65 (defun display-screens (&optional (display (display-get-default)))
67 for i from 0 below (%display-get-n-screens display)
68 collect (%display-get-screen display i)))
70 (defbinding display-get-default-screen
71 (&optional (display (display-get-default))) screen
74 (defbinding display-beep (&optional (display (display-get-default))) nil
77 (defbinding display-sync (&optional (display (display-get-default))) nil
80 (defbinding display-flush (&optional (display (display-get-default))) nil
83 (defbinding display-close (&optional (display (display-get-default))) nil
86 (defbinding flush () nil)
88 (defbinding display-get-event
89 (&optional (display (display-get-default))) event
92 (defbinding display-peek-event
93 (&optional (display (display-get-default))) event
96 (defbinding display-put-event
97 (event &optional (display (display-get-default))) event
101 (defbinding (display-connection-number "clg_gdk_connection_number")
102 (&optional (display (display-get-default))) int
105 (defun find-display (name)
107 (display-get-default)
108 (find name (list-displays) :key #'display-name :test #'string=)))
110 (defun ensure-display (display)
112 (null (display-get-default))
114 (string (or (find-display display) (display-open display)))))
119 (defbinding display-get-default () display)
121 (defbinding (display-set-default "gdk_display_manager_set_default_display")
123 ((display-manager) display-manager)
126 (defbinding (list-displays "gdk_display_manager_list_displays") ()
127 (gslist (static display))
128 ((display-manager) display-manager))
130 ;; The only purpose of exporting this is to make it possible for
131 ;; applications to connect to the display-opened signal
132 (defbinding (display-manager "gdk_display_manager_get") () display-manager)
134 (defbinding display-get-core-pointer
135 (&optional (display (display-get-default))) device
139 ;;; Primitive graphics structures (points, rectangles and regions)
141 (defbinding %rectangle-intersect () boolean
146 (defun rectangle-intersect (src1 src2 &optional (dest (make-instance 'rectangle)))
147 "Calculates the intersection of two rectangles. It is allowed for DEST to be the same as either SRC1 or SRC2. DEST is returned if the to rectangles intersect, otherwise NIL"
148 (when (%rectangle-intersect src1 src2 dest)
151 (defbinding rectangle-union (src1 src2 &optional (dest (make-instance 'rectangle))) nil
152 "Calculates the union of two rectangles. The union of rectangles SRC1 and SRC2 is the smallest rectangle which includes both SRC1 and SRC2 within it. It is allowed for DEST to be the same as either SRC1 or SRC2."
155 (dest rectangle :in/return))
157 (defun ensure-rectangle (rectangle)
159 (rectangle rectangle)
160 (vector (make-instance 'rectangle
161 :x (aref rectangle 0) :y (aref rectangle 1)
162 :width (aref rectangle 2) :height (aref rectangle 3)))))
165 (defbinding %region-new () pointer)
167 (defbinding %region-polygon () pointer
168 (points (vector (inlined point)))
170 (fill-rule fill-rule))
172 (defbinding %region-rectangle () pointer
173 (rectangle rectangle))
175 (defbinding %region-copy () pointer
178 (defbinding %region-destroy () nil
181 (defmethod allocate-foreign ((region region) &key rectangle polygon fill-rule)
183 ((and rectangle polygon)
184 (error "Only one of the keyword arguments :RECTANGLE and :POLYGON can be specified"))
185 (rectangle (%region-rectangle (ensure-rectangle rectangle)))
186 (polygon (%region-polygon polygon (length polygon) fill-rule))
189 (defun ensure-region (region)
192 ((or rectangle vector)
193 (make-instance 'region :rectangle (ensure-rectangle region)))
195 (make-instance 'region :polygon region))))
197 (defbinding region-get-clipbox (region &optional (rectangle (make-instance 'rectangle))) nil
199 (rectangle rectangle :in/return))
201 (defbinding %region-get-rectangles () nil
203 (rectangles pointer :out)
204 (n-rectangles int :out))
206 (defun region-get-rectangles (region)
207 "Obtains the area covered by the region as a list of rectangles."
208 (multiple-value-bind (location length) (%region-get-rectangles region)
210 (map-c-vector 'list #'identity location '(inlined rectangle) length :get)
211 (deallocate-memory location))))
213 (defbinding region-empty-p () boolean
216 (defbinding region-equal-p () boolean
220 (defbinding region-point-in-p () boolean
225 (defbinding region-rect-in (region rectangle) overlap-type
227 ((ensure-rectangle rectangle) rectangle))
229 (defbinding region-offset () nil
234 (defbinding region-shrink () nil
239 (defbinding region-intersect (source1 source2) nil
240 ((ensure-region source1) region :in/return)
241 ((ensure-region source2) region))
243 (defbinding region-union (source1 source2) nil
244 ((ensure-region source1) region :in/return)
245 ((ensure-region source2) region))
247 (defbinding region-subtract (source1 source2) nil
248 ((ensure-region source1) region :in/return)
249 ((ensure-region source2) region))
251 (defbinding region-xor (source1 source2) nil
252 ((ensure-region source1) region :in/return)
253 ((ensure-region source2) region))
258 (defbinding (events-pending-p "gdk_events_pending") () boolean)
260 (defbinding event-get () event)
262 (defbinding event-peek () event)
264 (defbinding event-get-graphics-expose () event
267 (defbinding event-put () event
270 ;(defbinding event-handler-set () ...)
272 (defbinding set-show-events () nil
273 (show-events boolean))
275 (defbinding get-show-events () boolean)
278 ;;; Miscellaneous functions
280 (defbinding screen-width () int
283 (defbinding screen-height () int
286 (defbinding screen-width-mm () int
289 (defbinding screen-height-mm () int
293 (defbinding pointer-grab
294 (window &key owner-events events confine-to cursor time) grab-status
296 (owner-events boolean)
298 (confine-to (or null window))
299 (cursor (or null cursor))
300 ((or time 0) (unsigned 32)))
302 (defbinding (pointer-ungrab "gdk_display_pointer_ungrab")
303 (&optional time (display (display-get-default))) nil
305 ((or time 0) (unsigned 32)))
307 (defbinding (pointer-is-grabbed-p "gdk_display_pointer_is_grabbed")
308 (&optional (display (display-get-default))) boolean
311 (defbinding keyboard-grab (window &key owner-events time) grab-status
313 (owner-events boolean)
314 ((or time 0) (unsigned 32)))
316 (defbinding (keyboard-ungrab "gdk_display_keyboard_ungrab")
317 (&optional time (display (display-get-default))) nil
319 ((or time 0) (unsigned 32)))
323 (defbinding atom-intern (atom-name &optional only-if-exists) atom
324 ((string atom-name) string)
325 (only-if-exists boolean))
327 (defbinding atom-name () string
334 (defbinding visual-get-best-depth () int)
336 (defbinding visual-get-best-type () visual-type)
338 (defbinding visual-get-system () visual)
341 (defbinding (%visual-get-best-with-nothing "gdk_visual_get_best") () visual)
343 (defbinding %visual-get-best-with-depth () visual
346 (defbinding %visual-get-best-with-type () visual
349 (defbinding %visual-get-best-with-both () visual
353 (defun visual-get-best (&key depth type)
355 ((and depth type) (%visual-get-best-with-both depth type))
356 (depth (%visual-get-best-with-depth depth))
357 (type (%visual-get-best-with-type type))
358 (t (%visual-get-best-with-nothing))))
360 ;(defbinding query-depths ..)
362 ;(defbinding query-visual-types ..)
364 (defbinding list-visuals () (glist visual))
369 (defbinding window-destroy () nil
372 (defbinding window-at-pointer () window
376 (defbinding window-show () nil
379 (defbinding window-show-unraised () nil
382 (defbinding window-hide () nil
385 (defbinding window-is-visible-p () boolean
388 (defbinding window-is-viewable-p () boolean
391 (defbinding window-withdraw () nil
394 (defbinding window-iconify () nil
397 (defbinding window-deiconify () nil
400 (defbinding window-stick () nil
403 (defbinding window-unstick () nil
406 (defbinding window-maximize () nil
409 (defbinding window-unmaximize () nil
412 (defbinding window-fullscreen () nil
415 (defbinding window-unfullscreen () nil
418 (defbinding window-set-keep-above () nil
422 (defbinding window-set-keep-below () nil
426 (defbinding window-move () nil
431 (defbinding window-resize () nil
436 (defbinding window-move-resize () nil
443 (defbinding window-scroll () nil
448 #?(pkg-exists-p "gtk+-2.0" :atleast-version "2.8.0")
449 (defbinding window-move-region (window region dx dy) nil
451 ((ensure-region region) region)
455 (defbinding window-reparent () nil
461 (defbinding window-clear () nil
464 (defbinding %window-clear-area () nil
466 (x int) (y int) (width int) (height int))
468 (defbinding %window-clear-area-e () nil
470 (x int) (y int) (width int) (height int))
472 (defun window-clear-area (window x y width height &optional expose)
474 (%window-clear-area-e window x y width height)
475 (%window-clear-area window x y width height)))
477 (defbinding window-raise () nil
480 (defbinding window-lower () nil
483 (defbinding window-focus () nil
485 (timestamp unsigned-int))
487 (defbinding window-register-dnd () nil
490 (defbinding window-begin-resize-drag () nil
496 (timestamp unsigned-int))
498 (defbinding window-begin-move-drag () nil
503 (timestamp unsigned-int))
505 ;; Probably not needed
506 ;; (defbinding window-constrain-size () nil ..
508 (defbinding window-begin-paint-region (window region) nil
510 ((ensure-region region) region))
512 (defbinding window-end-paint () nil
515 (defmacro with-window-paint ((window region) &body body)
517 (window-begin-paint-region ,window ,region)
520 (window-end-paint ,window))))
522 ;; TODO: create wrapper function and use gdk_window_invalidate_maybe_recurse
523 ;; if last arg is a function
524 (defbinding window-invalidate-region (window region invalidate-children-p) nil
526 ((ensure-region region) region)
527 (invalidate-children-p boolean))
529 (defbinding window-get-update-area () region
532 (defbinding window-freeze-updates () nil
535 (defbinding window-thaw-updates () nil
538 (defbinding window-process-all-updates () nil)
540 (defbinding window-process-updates () nil
542 (update-children-p boolean))
544 (defbinding window-set-debug-updates () nil
547 (defbinding window-enable-synchronized-configure () nil
550 (defbinding window-configure-finished () nil
553 ;; Deprecated, use gobject user data mechanism
554 (defbinding window-set-user-data () nil
558 (defbinding window-set-override-redirect () nil
560 (override-redirect-p boolean))
562 (defbinding window-set-accept-focus () nil
564 (accept-focus-p boolean))
566 (defbinding window-set-focus-on-map () nil
568 (focus-on-map-p boolean))
571 ; (defbinding window-add-filter () nil
572 ; (defbinding window-remove-filter () nil
574 ;; New code should use window-shape-combine
575 (defbinding window-shape-combine-mask () nil
581 (defbinding %window-shape-combine-region () nil
583 (region (or null region))
587 (defun window-shape-combine (window shape offset-x offset-y)
589 (null (%window-shape-combine-region window nil 0 0))
590 (region (%window-shape-combine-region window shape offset-x offset-y))
591 (bitmap (window-shape-combine-mask window shape offset-x offset-y))))
593 (defbinding window-set-child-shapes () nil
596 (defbinding window-merge-child-shapes () nil
599 #?(pkg-exists-p "gtk+-2.0" :atleast-version "2.10.0")
601 (defbinding %window-input-shape-combine-mask () nil
607 (defbinding %window-input-shape-combine-region () nil
609 (region (or null region))
613 (defun window-input-shape-combine (window shape x y)
615 (null (%window-input-shape-combine-region window nil 0 0))
616 (region (%window-input-shape-combine-region window shape x y))
617 (bitmap (%window-input-shape-combine-mask window shape x y))))
619 (defbinding window-set-child-input-shapes () nil
622 (defbinding window-merge-child-input-shapes () nil
625 (defbinding window-set-static-gravities () boolean
627 (use-static-p boolean))
629 (defbinding window-set-title () nil
633 (defbinding window-set-background () nil
637 (defbinding window-set-back-pixmap (window pixmap &optional parent-relative-p) nil
639 (pixmap (or null pixmap))
640 (parent-relative-p boolean))
642 (defbinding window-set-cursor () nil
644 (cursor (or null cursor)))
646 (defbinding window-get-geometry () nil
654 ;(defbinding window-set-geometry-hints () nil
656 (defbinding window-set-icon-list () nil
658 (icons (glist pixbufs)))
660 (defbinding window-set-skip-taskbar-hint () nil
662 (skip-taskbar-p boolean))
664 (defbinding window-set-skip-pager-hint () nil
666 (skip-pager-p boolean))
668 #?(pkg-exists-p "gtk+-2.0" :atleast-version "2.8.0")
669 (defbinding window-set-urgency-hint () nil
673 (defbinding window-get-position () nil
678 (defbinding window-get-root-origin () nil
683 (defbinding window-get-frame-extents (window &optional (extents (make-instance 'rect))) nil
685 (extents rectangle :in/return))
687 (defbinding window-get-origin () nil ; this may not work as
688 (window window) ; an int is actually returned
692 (defbinding window-get-pointer () window
696 (mask modifier-type :out))
698 ;(defbinding window-set-icon () nil
700 (defbinding window-set-icon-name () nil
704 (defbinding window-set-transient-for () nil
708 (defbinding window-set-role () nil
712 (defbinding %window-get-decorations () boolean
714 (decorations wm-decoration :out))
716 (defun %window-decorations-getter (window)
717 (nth-value 1 (%window-get-decorations window)))
719 (defun %window-decorations-boundp (window)
720 (%window-get-decorations window))
722 (defbinding %window-get-toplevels () (glist window))
724 (defun window-get-toplevels (&optional screen)
726 (error "Not implemented")
727 (%window-get-toplevels)))
729 (defbinding %get-default-root-window () window)
731 (defun get-root-window (&optional display)
733 (error "Not implemented")
734 (%get-default-root-window)))
742 (defbinding drag-status () nil
743 (context drag-context)
745 (time (unsigned 32)))
754 (defbinding rgb-init () nil)
761 (defmethod allocate-foreign ((cursor cursor) &key source mask fg bg
762 (x 0) (y 0) (display (display-get-default)))
764 (keyword (%cursor-new-for-display display source))
765 (pixbuf (%cursor-new-from-pixbuf display source x y))
766 (pixmap (%cursor-new-from-pixmap source mask
767 (or fg (ensure-color #(0.0 0.0 0.0)))
768 (or bg (ensure-color #(1.0 1.0 1.0))) x y))
769 (pathname (%cursor-new-from-pixbuf display (pixbuf-load source) x y))))
771 (defun ensure-cursor (cursor &rest args)
772 (if (typep cursor 'cursor)
774 (apply #'make-instance 'cursor :source cursor args)))
776 (defbinding %cursor-new-for-display () pointer
778 (cursor-type cursor-type))
780 (defbinding %cursor-new-from-pixmap () pointer
787 (defbinding %cursor-new-from-pixbuf () pointer
792 (defbinding %cursor-ref () pointer
795 (defbinding %cursor-unref () nil
801 (defbinding %pixmap-new () pointer
802 (window (or null window))
807 (defmethod allocate-foreign ((pximap pixmap) &key width height depth window)
808 (%pixmap-new window width height depth))
810 (defun pixmap-new (width height depth &key window)
811 (warn "PIXMAP-NEW is deprecated, use (make-instance 'pixmap ...) instead")
812 (make-instance 'pixmap :width width :height height :depth depth :window window))
814 (defbinding %pixmap-colormap-create-from-xpm () pixmap
815 (window (or null window))
816 (colormap (or null colormap))
818 (color (or null color))
821 (defbinding %pixmap-colormap-create-from-xpm-d () pixmap
822 (window (or null window))
823 (colormap (or null colormap))
825 (color (or null color))
826 (data (vector string)))
828 ;; Deprecated, use pixbufs instead
829 (defun pixmap-create (source &key color window colormap)
831 (if (not (or window colormap))
834 (multiple-value-bind (pixmap mask)
836 ((or string pathname)
837 (%pixmap-colormap-create-from-xpm window colormap color source))
839 (%pixmap-colormap-create-from-xpm-d window colormap color source)))
840 (values pixmap mask))))
845 (defbinding colormap-get-system () colormap)
847 (defbinding %color-copy () pointer
850 (defmethod allocate-foreign ((color color) &rest initargs)
851 (declare (ignore color initargs))
852 ;; Color structs are allocated as memory chunks by gdk, and since
853 ;; there is no gdk_color_new we have to use this hack to get a new
855 (with-memory (location #.(foreign-size (find-class 'color)))
856 (%color-copy location)))
858 (defun %scale-value (value)
861 (float (truncate (* value 65535)))))
863 (defmethod initialize-instance ((color color) &key (red 0.0) (green 0.0) (blue 0.0))
865 (with-slots ((%red red) (%green green) (%blue blue)) color
867 %red (%scale-value red)
868 %green (%scale-value green)
869 %blue (%scale-value blue))))
871 (defbinding %color-parse () boolean
873 (color color :in/return))
875 (defun color-parse (spec &optional (color (make-instance 'color)))
876 (multiple-value-bind (succeeded-p color) (%color-parse spec color)
879 (error "Parsing color specification ~S failed." spec))))
881 (defun ensure-color (color)
885 (string (color-parse color))
887 (make-instance 'color
888 :red (svref color 0) :green (svref color 1) :blue (svref color 2)))))
892 ;;; Drawable -- all the draw- functions are deprecated and will be
893 ;;; removed, use cairo for drawing instead.
895 (defbinding drawable-get-size () nil
900 (defbinding (drawable-width "gdk_drawable_get_size") () nil
905 (defbinding (drawable-height "gdk_drawable_get_size") () nil
910 ;; (defbinding drawable-get-clip-region () region
911 ;; (drawable drawable))
913 ;; (defbinding drawable-get-visible-region () region
914 ;; (drawable drawable))
916 (defbinding draw-point () nil
917 (drawable drawable) (gc gc)
920 (defbinding %draw-points () nil
921 (drawable drawable) (gc gc)
925 (defbinding draw-line () nil
926 (drawable drawable) (gc gc)
930 (defbinding draw-pixbuf
931 (drawable gc pixbuf src-x src-y dest-x dest-y &optional
932 width height (dither :none) (x-dither 0) (y-dither 0)) nil
933 (drawable drawable) (gc (or null gc))
935 (src-x int) (src-y int)
936 (dest-x int) (dest-y int)
937 ((or width -1) int) ((or height -1) int)
939 (x-dither int) (y-dither int))
941 (defbinding draw-rectangle () nil
942 (drawable drawable) (gc gc)
945 (width int) (height int))
947 (defbinding draw-arc () nil
948 (drawable drawable) (gc gc)
951 (width int) (height int)
952 (angle1 int) (angle2 int))
954 (defbinding %draw-layout () nil
955 (drawable drawable) (gc gc)
958 (layout pango:layout))
960 (defbinding %draw-layout-with-colors () nil
961 (drawable drawable) (gc gc)
964 (layout pango:layout)
965 (foreground (or null color))
966 (background (or null color)))
968 (defun draw-layout (drawable gc font x y layout &optional foreground background)
969 (if (or foreground background)
970 (%draw-layout-with-colors drawable gc font x y layout foreground background)
971 (%draw-layout drawable gc font x y layout)))
973 (defbinding draw-drawable
974 (drawable gc src src-x src-y dest-x dest-y &optional width height) nil
975 (drawable drawable) (gc gc)
977 (src-x int) (src-y int)
978 (dest-x int) (dest-y int)
979 ((or width -1) int) ((or height -1) int))
981 (defbinding draw-image
982 (drawable gc image src-x src-y dest-x dest-y &optional width height) nil
983 (drawable drawable) (gc gc)
985 (src-x int) (src-y int)
986 (dest-x int) (dest-y int)
987 ((or width -1) int) ((or height -1) int))
989 (defbinding drawable-get-image () image
992 (width int) (height int))
994 (defbinding drawable-copy-to-image
995 (drawable src-x src-y width height &optional image dest-x dest-y) image
997 (image (or null image))
998 (src-x int) (src-y int)
999 ((if image dest-x 0) int)
1000 ((if image dest-y 0) int)
1001 (width int) (height int))
1006 (defbinding keyval-name () string
1007 (keyval unsigned-int))
1009 (defbinding %keyval-from-name () unsigned-int
1012 (defun keyval-from-name (name)
1013 "Returns the keysym value for the given key name or NIL if it is not a valid name."
1014 (let ((keyval (%keyval-from-name name)))
1015 (unless (zerop keyval)
1018 (defbinding keyval-to-upper () unsigned-int
1019 (keyval unsigned-int))
1021 (defbinding keyval-to-lower () unsigned-int
1022 (keyval unsigned-int))
1024 (defbinding (keyval-is-upper-p "gdk_keyval_is_upper") () boolean
1025 (keyval unsigned-int))
1027 (defbinding (keyval-is-lower-p "gdk_keyval_is_lower") () boolean
1028 (keyval unsigned-int))
1030 ;;; Cairo interaction
1032 #?(pkg-exists-p "gtk+-2.0" :atleast-version "2.8.0")
1034 (defbinding cairo-create () cairo:context
1035 (drawable drawable))
1037 (defmacro with-cairo-context ((cr drawable) &body body)
1038 `(let ((,cr (cairo-create ,drawable)))
1041 (invalidate-instance ,cr t))))
1043 (defbinding cairo-set-source-color () nil
1047 (defbinding cairo-set-source-pixbuf () nil
1053 (defbinding cairo-rectangle () nil
1055 (rectangle rectangle))
1057 ;; (defbinding cairo-region () nil
1058 ;; (cr cairo:context)
1061 (defbinding (cairo-surface-get-window "clg_gdk_cairo_surface_get_window") () window
1062 (surface cairo:surface))
1067 ;;; Multi-threading support
1071 (defvar *global-lock* (sb-thread:make-mutex :name "global GDK lock"))
1073 (defun %global-lock-p ()
1074 (eq (car (sb-thread:mutex-value *global-lock*)) sb-thread:*current-thread*))
1076 (defun threads-enter ()
1077 (if (%global-lock-p)
1078 (incf (cdr (sb-thread:mutex-value *global-lock*)))
1079 (sb-thread:get-mutex *global-lock* (cons sb-thread:*current-thread* 0))))
1081 (defun threads-leave (&optional flush-p)
1082 (assert (%global-lock-p))
1084 ((zerop (cdr (sb-thread:mutex-value *global-lock*)))
1087 (sb-thread:release-mutex *global-lock*))
1088 (t (decf (cdr (sb-thread:mutex-value *global-lock*))))))
1090 (define-callback %enter-fn nil ()
1093 (define-callback %leave-fn nil ()
1096 (defbinding threads-set-lock-functions (&optional) nil
1097 (%enter-fn callback)
1098 (%leave-fn callback))
1100 (defmacro with-global-lock (&body body)
1105 (threads-leave t))))
1107 (defun timeout-add-with-lock (interval function &optional (priority +priority-default+))
1108 (timeout-add interval
1110 (with-global-lock (funcall function)))
1113 (defun idle-add-with-lock (function &optional (priority +priority-default-idle+))
1116 (with-global-lock (funcall function)))
1122 (defmacro with-global-lock (&body body)
1125 (defun timeout-add-with-lock (interval function &optional (priority +priority-default+))
1126 (timeout-add interval function priority))
1128 (defun idle-add-with-lock (funcation &optional (priority +priority-default-idle+))
1129 (idle-add function priority)))