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.37 2007/05/10 16:58:45 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 display-get-event
87 (&optional (display (display-get-default))) event
90 (defbinding display-peek-event
91 (&optional (display (display-get-default))) event
94 (defbinding display-put-event
95 (event &optional (display (display-get-default))) event
99 (defbinding (display-connection-number "clg_gdk_connection_number")
100 (&optional (display (display-get-default))) int
103 (defun find-display (name)
104 (find name (list-displays) :key #'display-name :test #'string=))
106 (defun ensure-display (display)
108 (null (display-get-default))
112 (find display (list-displays) :key #'display-name :test #'string=)
113 (display-open display)))))
118 (defbinding display-get-default () display)
120 (defbinding (display-set-default "gdk_display_manager_set_default_display")
122 ((display-manager) display-manager)
125 (defbinding (list-displays "gdk_display_manager_list_displays") ()
126 (gslist (static display))
127 ((display-manager) display-manager))
129 ;; The only purpose of exporting this is to make it possible for
130 ;; applications to connect to the display-opened signal
131 (defbinding (display-manager "gdk_display_manager_get") () display-manager)
133 (defbinding display-get-core-pointer
134 (&optional (display (display-get-default))) device
138 ;;; Primitive graphics structures (points, rectangles and regions)
140 (defbinding %rectangle-intersect () boolean
145 (defun rectangle-intersect (src1 src2 &optional (dest (make-instance 'rectangle)))
146 "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"
147 (when (%rectangle-intersect src1 src2 dest)
150 (defbinding rectangle-union (src1 src2 &optional (dest (make-instance 'rectangle))) nil
151 "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."
154 (dest rectangle :in/return))
156 (defun ensure-rectangle (rectangle)
158 (rectangle rectangle)
159 (vector (make-instance 'rectangle
160 :x (aref rectangle 0) :y (aref rectangle 1)
161 :width (aref rectangle 2) :height (aref rectangle 3)))))
164 (defbinding %region-new () pointer)
166 (defbinding %region-polygon () pointer
167 (points (vector (inlined point)))
169 (fill-rule fill-rule))
171 (defbinding %region-rectangle () pointer
172 (rectangle rectangle))
174 (defbinding %region-copy () pointer
177 (defbinding %region-destroy () nil
180 (defmethod allocate-foreign ((region region) &key rectangle polygon fill-rule)
182 ((and rectangle polygon)
183 (error "Only one of the keyword arguments :RECTANGLE and :POLYGON can be specified"))
184 (rectangle (%region-rectangle (ensure-rectangle rectangle)))
185 (polygon (%region-polygon polygon (length polygon) fill-rule))
188 (defun ensure-region (region)
191 ((or rectangle vector)
192 (make-instance 'region :rectangle (ensure-rectangle region)))
194 (make-instance 'region :polygon region))))
196 (defbinding region-get-clipbox (region &optional (rectangle (make-instance 'rectangle))) nil
198 (rectangle rectangle :in/return))
200 (defbinding %region-get-rectangles () nil
202 (rectangles pointer :out)
203 (n-rectangles int :out))
205 (defun region-get-rectangles (region)
206 "Obtains the area covered by the region as a list of rectangles."
207 (multiple-value-bind (location length) (%region-get-rectangles region)
209 (map-c-vector 'list #'identity location '(inlined rectangle) length :get)
210 (deallocate-memory location))))
212 (defbinding region-empty-p () boolean
215 (defbinding region-equal-p () boolean
219 (defbinding region-point-in-p () boolean
224 (defbinding region-rect-in (region rectangle) overlap-type
226 ((ensure-rectangle rectangle) rectangle))
228 (defbinding region-offset () nil
233 (defbinding region-shrink () nil
238 (defbinding region-intersect (source1 source2) nil
239 ((ensure-region source1) region :in/return)
240 ((ensure-region source2) region))
242 (defbinding region-union (source1 source2) nil
243 ((ensure-region source1) region :in/return)
244 ((ensure-region source2) region))
246 (defbinding region-subtract (source1 source2) nil
247 ((ensure-region source1) region :in/return)
248 ((ensure-region source2) region))
250 (defbinding region-xor (source1 source2) nil
251 ((ensure-region source1) region :in/return)
252 ((ensure-region source2) region))
257 (defbinding (events-pending-p "gdk_events_pending") () boolean)
259 (defbinding event-get () event)
261 (defbinding event-peek () event)
263 (defbinding event-get-graphics-expose () event
266 (defbinding event-put () event
269 ;(defbinding event-handler-set () ...)
271 (defbinding set-show-events () nil
272 (show-events boolean))
274 (defbinding get-show-events () boolean)
277 ;;; Miscellaneous functions
279 (defbinding screen-width () int
282 (defbinding screen-height () int
285 (defbinding screen-width-mm () int
288 (defbinding screen-height-mm () int
292 (defbinding pointer-grab
293 (window &key owner-events events confine-to cursor time) grab-status
295 (owner-events boolean)
297 (confine-to (or null window))
298 (cursor (or null cursor))
299 ((or time 0) (unsigned 32)))
301 (defbinding (pointer-ungrab "gdk_display_pointer_ungrab")
302 (&optional time (display (display-get-default))) nil
304 ((or time 0) (unsigned 32)))
306 (defbinding (pointer-is-grabbed-p "gdk_display_pointer_is_grabbed")
307 (&optional (display (display-get-default))) boolean
310 (defbinding keyboard-grab (window &key owner-events time) grab-status
312 (owner-events boolean)
313 ((or time 0) (unsigned 32)))
315 (defbinding (keyboard-ungrab "gdk_display_keyboard_ungrab")
316 (&optional time (display (display-get-default))) nil
318 ((or time 0) (unsigned 32)))
322 (defbinding atom-intern (atom-name &optional only-if-exists) atom
323 ((string atom-name) string)
324 (only-if-exists boolean))
326 (defbinding atom-name () string
333 (defbinding visual-get-best-depth () int)
335 (defbinding visual-get-best-type () visual-type)
337 (defbinding visual-get-system () visual)
340 (defbinding (%visual-get-best-with-nothing "gdk_visual_get_best") () visual)
342 (defbinding %visual-get-best-with-depth () visual
345 (defbinding %visual-get-best-with-type () visual
348 (defbinding %visual-get-best-with-both () visual
352 (defun visual-get-best (&key depth type)
354 ((and depth type) (%visual-get-best-with-both depth type))
355 (depth (%visual-get-best-with-depth depth))
356 (type (%visual-get-best-with-type type))
357 (t (%visual-get-best-with-nothing))))
359 ;(defbinding query-depths ..)
361 ;(defbinding query-visual-types ..)
363 (defbinding list-visuals () (glist visual))
368 (defbinding window-destroy () nil
371 (defbinding window-at-pointer () window
375 (defbinding window-show () nil
378 (defbinding window-show-unraised () nil
381 (defbinding window-hide () nil
384 (defbinding window-is-visible-p () boolean
387 (defbinding window-is-viewable-p () boolean
390 (defbinding window-withdraw () nil
393 (defbinding window-iconify () nil
396 (defbinding window-deiconify () nil
399 (defbinding window-stick () nil
402 (defbinding window-unstick () nil
405 (defbinding window-maximize () nil
408 (defbinding window-unmaximize () nil
411 (defbinding window-fullscreen () nil
414 (defbinding window-unfullscreen () nil
417 (defbinding window-set-keep-above () nil
421 (defbinding window-set-keep-below () nil
425 (defbinding window-move () nil
430 (defbinding window-resize () nil
435 (defbinding window-move-resize () nil
442 (defbinding window-scroll () nil
447 #?(pkg-exists-p "gtk+-2.0" :atleast-version "2.8.0")
448 (defbinding window-move-region (window region dx dy) nil
450 ((ensure-region region) region)
454 (defbinding window-reparent () nil
460 (defbinding window-clear () nil
463 (defbinding %window-clear-area () nil
465 (x int) (y int) (width int) (height int))
467 (defbinding %window-clear-area-e () nil
469 (x int) (y int) (width int) (height int))
471 (defun window-clear-area (window x y width height &optional expose)
473 (%window-clear-area-e window x y width height)
474 (%window-clear-area window x y width height)))
476 (defbinding window-raise () nil
479 (defbinding window-lower () nil
482 (defbinding window-focus () nil
484 (timestamp unsigned-int))
486 (defbinding window-register-dnd () nil
489 (defbinding window-begin-resize-drag () nil
495 (timestamp unsigned-int))
497 (defbinding window-begin-move-drag () nil
502 (timestamp unsigned-int))
504 ;; Probably not needed
505 ;; (defbinding window-constrain-size () nil ..
507 (defbinding window-begin-paint-region (window region) nil
509 ((ensure-region region) region))
511 (defbinding window-end-paint () nil
514 (defmacro with-window-paint ((window region) &body body)
516 (window-begin-paint-region ,window ,region)
519 (window-end-paint ,window))))
521 ;; TODO: create wrapper function and use gdk_window_invalidate_maybe_recurse
522 ;; if last arg is a function
523 (defbinding window-invalidate-region (window region invalidate-children-p) nil
525 ((ensure-region region) region)
526 (invalidate-children-p boolean))
528 (defbinding window-get-update-area () region
531 (defbinding window-freeze-updates () nil
534 (defbinding window-thaw-updates () nil
537 (defbinding window-process-all-updates () nil)
539 (defbinding window-process-updates () nil
541 (update-children-p boolean))
543 (defbinding window-set-debug-updates () nil
546 (defbinding window-enable-synchronized-configure () nil
549 (defbinding window-configure-finished () nil
552 ;; Deprecated, use gobject user data mechanism
553 (defbinding window-set-user-data () nil
557 (defbinding window-set-override-redirect () nil
559 (override-redirect-p boolean))
561 (defbinding window-set-accept-focus () nil
563 (accept-focus-p boolean))
565 (defbinding window-set-focus-on-map () nil
567 (focus-on-map-p boolean))
570 ; (defbinding window-add-filter () nil
571 ; (defbinding window-remove-filter () nil
573 ;; New code should use window-shape-combine
574 (defbinding window-shape-combine-mask () nil
580 (defbinding %window-shape-combine-region () nil
582 (region (or null region))
586 (defun window-shape-combine (window shape offset-x offset-y)
588 (null (%window-shape-combine-region window nil 0 0))
589 (region (%window-shape-combine-region window shape offset-x offset-y))
590 (bitmap (window-shape-combine-mask window shape offset-x offset-y))))
592 (defbinding window-set-child-shapes () nil
595 (defbinding window-merge-child-shapes () nil
598 #?(pkg-exists-p "gtk+-2.0" :atleast-version "2.10.0")
600 (defbinding %window-input-shape-combine-mask () nil
606 (defbinding %window-input-shape-combine-region () nil
608 (region (or null region))
612 (defun window-input-shape-combine (window shape x y)
614 (null (%window-input-shape-combine-region window nil 0 0))
615 (region (%window-input-shape-combine-region window shape x y))
616 (bitmap (%window-input-shape-combine-mask window shape x y))))
618 (defbinding window-set-child-input-shapes () nil
621 (defbinding window-merge-child-input-shapes () nil
624 (defbinding window-set-static-gravities () boolean
626 (use-static-p boolean))
628 (defbinding window-set-title () nil
632 (defbinding window-set-background () nil
636 (defbinding window-set-back-pixmap (window pixmap &optional parent-relative-p) nil
638 (pixmap (or null pixmap))
639 (parent-relative-p boolean))
641 (defbinding window-set-cursor () nil
643 (cursor (or null cursor)))
645 (defbinding window-get-geometry () nil
653 ;(defbinding window-set-geometry-hints () nil
655 (defbinding window-set-icon-list () nil
657 (icons (glist pixbufs)))
659 (defbinding window-set-skip-taskbar-hint () nil
661 (skip-taskbar-p boolean))
663 (defbinding window-set-skip-pager-hint () nil
665 (skip-pager-p boolean))
667 #?(pkg-exists-p "gtk+-2.0" :atleast-version "2.8.0")
668 (defbinding window-set-urgency-hint () nil
672 (defbinding window-get-position () nil
677 (defbinding window-get-root-origin () nil
682 (defbinding window-get-frame-extents (window &optional (extents (make-instance 'rect))) nil
684 (extents rectangle :in/return))
686 (defbinding window-get-origin () nil ; this may not work as
687 (window window) ; an int is actually returned
691 (defbinding window-get-pointer () window
695 (mask modifier-type :out))
697 ;(defbinding window-set-icon () nil
699 (defbinding window-set-icon-name () nil
703 (defbinding window-set-transient-for () nil
707 (defbinding window-set-role () nil
711 (defbinding %window-get-decorations () boolean
713 (decorations wm-decoration :out))
715 (defun %window-decorations-getter (window)
716 (nth-value 1 (%window-get-decorations window)))
718 (defun %window-decorations-boundp (window)
719 (%window-get-decorations window))
721 (defbinding %window-get-toplevels () (glist window))
723 (defun window-get-toplevels (&optional screen)
725 (error "Not implemented")
726 (%window-get-toplevels)))
728 (defbinding %get-default-root-window () window)
730 (defun get-root-window (&optional display)
732 (error "Not implemented")
733 (%get-default-root-window)))
741 (defbinding drag-status () nil
742 (context drag-context)
744 (time (unsigned 32)))
753 (defbinding rgb-init () nil)
760 (defmethod allocate-foreign ((cursor cursor) &key source mask fg bg
761 (x 0) (y 0) (display (display-get-default)))
763 (keyword (%cursor-new-for-display display source))
764 (pixbuf (%cursor-new-from-pixbuf display source x y))
765 (pixmap (%cursor-new-from-pixmap source mask
766 (or fg (ensure-color #(0.0 0.0 0.0)))
767 (or bg (ensure-color #(1.0 1.0 1.0))) x y))
768 (pathname (%cursor-new-from-pixbuf display (pixbuf-load source) x y))))
770 (defun ensure-cursor (cursor &rest args)
771 (if (typep cursor 'cursor)
773 (apply #'make-instance 'cursor :source cursor args)))
775 (defbinding %cursor-new-for-display () pointer
777 (cursor-type cursor-type))
779 (defbinding %cursor-new-from-pixmap () pointer
786 (defbinding %cursor-new-from-pixbuf () pointer
791 (defbinding %cursor-ref () pointer
794 (defbinding %cursor-unref () nil
800 (defbinding %pixmap-new () pointer
801 (window (or null window))
806 (defmethod allocate-foreign ((pximap pixmap) &key width height depth window)
807 (%pixmap-new window width height depth))
809 (defun pixmap-new (width height depth &key window)
810 (warn "PIXMAP-NEW is deprecated, use (make-instance 'pixmap ...) instead")
811 (make-instance 'pixmap :width width :height height :depth depth :window window))
813 (defbinding %pixmap-colormap-create-from-xpm () pixmap
814 (window (or null window))
815 (colormap (or null colormap))
817 (color (or null color))
820 (defbinding %pixmap-colormap-create-from-xpm-d () pixmap
821 (window (or null window))
822 (colormap (or null colormap))
824 (color (or null color))
825 (data (vector string)))
827 ;; Deprecated, use pixbufs instead
828 (defun pixmap-create (source &key color window colormap)
830 (if (not (or window colormap))
833 (multiple-value-bind (pixmap mask)
835 ((or string pathname)
836 (%pixmap-colormap-create-from-xpm window colormap color source))
838 (%pixmap-colormap-create-from-xpm-d window colormap color source)))
839 (values pixmap mask))))
844 (defbinding colormap-get-system () colormap)
846 (defbinding %color-copy () pointer
849 (defmethod allocate-foreign ((color color) &rest initargs)
850 (declare (ignore color initargs))
851 ;; Color structs are allocated as memory chunks by gdk, and since
852 ;; there is no gdk_color_new we have to use this hack to get a new
854 (with-memory (location #.(foreign-size (find-class 'color)))
855 (%color-copy location)))
857 (defun %scale-value (value)
860 (float (truncate (* value 65535)))))
862 (defmethod initialize-instance ((color color) &key (red 0.0) (green 0.0) (blue 0.0))
864 (with-slots ((%red red) (%green green) (%blue blue)) color
866 %red (%scale-value red)
867 %green (%scale-value green)
868 %blue (%scale-value blue))))
870 (defbinding %color-parse () boolean
872 (color color :in/return))
874 (defun color-parse (spec &optional (color (make-instance 'color)))
875 (multiple-value-bind (succeeded-p color) (%color-parse spec color)
878 (error "Parsing color specification ~S failed." spec))))
880 (defun ensure-color (color)
884 (string (color-parse color))
886 (make-instance 'color
887 :red (svref color 0) :green (svref color 1) :blue (svref color 2)))))
891 ;;; Drawable -- all the draw- functions are deprecated and will be
892 ;;; removed, use cairo for drawing instead.
894 (defbinding drawable-get-size () nil
899 (defbinding (drawable-width "gdk_drawable_get_size") () nil
904 (defbinding (drawable-height "gdk_drawable_get_size") () nil
909 ;; (defbinding drawable-get-clip-region () region
910 ;; (drawable drawable))
912 ;; (defbinding drawable-get-visible-region () region
913 ;; (drawable drawable))
915 (defbinding draw-point () nil
916 (drawable drawable) (gc gc)
919 (defbinding %draw-points () nil
920 (drawable drawable) (gc gc)
924 (defbinding draw-line () nil
925 (drawable drawable) (gc gc)
929 (defbinding draw-pixbuf
930 (drawable gc pixbuf src-x src-y dest-x dest-y &optional
931 width height (dither :none) (x-dither 0) (y-dither 0)) nil
932 (drawable drawable) (gc (or null gc))
934 (src-x int) (src-y int)
935 (dest-x int) (dest-y int)
936 ((or width -1) int) ((or height -1) int)
938 (x-dither int) (y-dither int))
940 (defbinding draw-rectangle () nil
941 (drawable drawable) (gc gc)
944 (width int) (height int))
946 (defbinding draw-arc () nil
947 (drawable drawable) (gc gc)
950 (width int) (height int)
951 (angle1 int) (angle2 int))
953 (defbinding %draw-layout () nil
954 (drawable drawable) (gc gc)
957 (layout pango:layout))
959 (defbinding %draw-layout-with-colors () nil
960 (drawable drawable) (gc gc)
963 (layout pango:layout)
964 (foreground (or null color))
965 (background (or null color)))
967 (defun draw-layout (drawable gc font x y layout &optional foreground background)
968 (if (or foreground background)
969 (%draw-layout-with-colors drawable gc font x y layout foreground background)
970 (%draw-layout drawable gc font x y layout)))
972 (defbinding draw-drawable
973 (drawable gc src src-x src-y dest-x dest-y &optional width height) nil
974 (drawable drawable) (gc gc)
976 (src-x int) (src-y int)
977 (dest-x int) (dest-y int)
978 ((or width -1) int) ((or height -1) int))
980 (defbinding draw-image
981 (drawable gc image src-x src-y dest-x dest-y &optional width height) nil
982 (drawable drawable) (gc gc)
984 (src-x int) (src-y int)
985 (dest-x int) (dest-y int)
986 ((or width -1) int) ((or height -1) int))
988 (defbinding drawable-get-image () image
991 (width int) (height int))
993 (defbinding drawable-copy-to-image
994 (drawable src-x src-y width height &optional image dest-x dest-y) image
996 (image (or null image))
997 (src-x int) (src-y int)
998 ((if image dest-x 0) int)
999 ((if image dest-y 0) int)
1000 (width int) (height int))
1005 (defbinding keyval-name () string
1006 (keyval unsigned-int))
1008 (defbinding %keyval-from-name () unsigned-int
1011 (defun keyval-from-name (name)
1012 "Returns the keysym value for the given key name or NIL if it is not a valid name."
1013 (let ((keyval (%keyval-from-name name)))
1014 (unless (zerop keyval)
1017 (defbinding keyval-to-upper () unsigned-int
1018 (keyval unsigned-int))
1020 (defbinding keyval-to-lower () unsigned-int
1021 (keyval unsigned-int))
1023 (defbinding (keyval-is-upper-p "gdk_keyval_is_upper") () boolean
1024 (keyval unsigned-int))
1026 (defbinding (keyval-is-lower-p "gdk_keyval_is_lower") () boolean
1027 (keyval unsigned-int))
1029 ;;; Cairo interaction
1031 #?(pkg-exists-p "gtk+-2.0" :atleast-version "2.8.0")
1033 (defbinding cairo-create () cairo:context
1034 (drawable drawable))
1036 (defmacro with-cairo-context ((cr drawable) &body body)
1037 `(let ((,cr (cairo-create ,drawable)))
1040 (invalidate-instance ,cr t))))
1042 (defbinding cairo-set-source-color () nil
1046 (defbinding cairo-set-source-pixbuf () nil
1052 (defbinding cairo-rectangle () nil
1054 (rectangle rectangle))
1056 ;; (defbinding cairo-region () nil
1057 ;; (cr cairo:context)
1060 (defbinding (cairo-xlib-surface-get-window
1061 "clg_gdk_cairo_xlib_surface_get_window") () window
1062 (surface cairo:xlib-surface))
1067 ;;; Multi-threading support
1071 (defvar *global-lock* (sb-thread:make-mutex :name "global GDK lock"))
1072 (let ((recursive-level 0))
1073 (defun threads-enter ()
1074 (if (eq (sb-thread:mutex-value *global-lock*) sb-thread:*current-thread*)
1075 (incf recursive-level)
1076 (sb-thread:get-mutex *global-lock*)))
1078 (defun threads-leave (&optional flush-p)
1080 ((zerop recursive-level)
1083 (sb-thread:release-mutex *global-lock*))
1084 (t (decf recursive-level)))))
1086 (define-callback %enter-fn nil ()
1089 (define-callback %leave-fn nil ()
1092 (defbinding threads-set-lock-functions (&optional) nil
1093 (%enter-fn callback)
1094 (%leave-fn callback))
1096 (defmacro with-global-lock (&body body)
1101 (threads-leave t)))))