Improved multithreading support
[clg] / gdk / gdk.lisp
CommitLineData
55212af1 1;; Common Lisp bindings for GTK+ v2.x
1b7d3a82 2;; Copyright 2000-2006 Espen S. Johnsen <espen@users.sf.net>
0d07716f 3;;
55212af1 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:
0d07716f 11;;
55212af1 12;; The above copyright notice and this permission notice shall be
13;; included in all copies or substantial portions of the Software.
0d07716f 14;;
55212af1 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.
22
c2618ad5 23;; $Id: gdk.lisp,v 1.39 2007/06/18 12:23:05 espen Exp $
0d07716f 24
25
26(in-package "GDK")
27
e295d6df 28;;; Initialization
29
30(defbinding (gdk-init "gdk_parse_args") () nil
31 "Initializes the library without opening the display."
32 (nil null)
33 (nil null))
0d07716f 34
0d07716f 35
e295d6df 36
a05a0e59 37;;; Display
e295d6df 38
c25641cb 39#-debug-ref-counting
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))))
45 (call-next-method)))
46
e295d6df 47(defbinding %display-open () display
48 (display-name (or null string)))
49
50(defun display-open (&optional display-name)
c25641cb 51 (let ((display (or
52 (%display-open display-name)
53 (error "Opening display failed: ~A" display-name))))
e295d6df 54 (unless (display-get-default)
55 (display-set-default display))
56 display))
57
a05a0e59 58(defbinding %display-get-n-screens () int
59 (display display))
60
61(defbinding %display-get-screen () screen
62 (display display)
63 (screen-num int))
64
65(defun display-screens (&optional (display (display-get-default)))
66 (loop
67 for i from 0 below (%display-get-n-screens display)
68 collect (%display-get-screen display i)))
69
70(defbinding display-get-default-screen
71 (&optional (display (display-get-default))) screen
72 (display display))
73
74(defbinding display-beep (&optional (display (display-get-default))) nil
75 (display display))
76
77(defbinding display-sync (&optional (display (display-get-default))) nil
78 (display display))
79
80(defbinding display-flush (&optional (display (display-get-default))) nil
81 (display display))
82
83(defbinding display-close (&optional (display (display-get-default))) nil
84 (display display))
85
c2618ad5 86(defbinding flush () nil)
87
a05a0e59 88(defbinding display-get-event
89 (&optional (display (display-get-default))) event
90 (display display))
91
92(defbinding display-peek-event
93 (&optional (display (display-get-default))) event
94 (display display))
95
96(defbinding display-put-event
97 (event &optional (display (display-get-default))) event
98 (display display)
99 (event event))
100
e295d6df 101(defbinding (display-connection-number "clg_gdk_connection_number")
102 (&optional (display (display-get-default))) int
103 (display display))
104
c25641cb 105(defun find-display (name)
c2618ad5 106 (if (not name)
107 (display-get-default)
108 (find name (list-displays) :key #'display-name :test #'string=)))
c25641cb 109
110(defun ensure-display (display)
111 (etypecase display
112 (null (display-get-default))
113 (display display)
c2618ad5 114 (string (or (find-display display) (display-open display)))))
e295d6df 115
a05a0e59 116
117;;; Display manager
118
119(defbinding display-get-default () display)
120
a05a0e59 121(defbinding (display-set-default "gdk_display_manager_set_default_display")
122 (display) nil
123 ((display-manager) display-manager)
124 (display display))
125
c25641cb 126(defbinding (list-displays "gdk_display_manager_list_displays") ()
127 (gslist (static display))
128 ((display-manager) display-manager))
129
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)
133
134(defbinding display-get-core-pointer
135 (&optional (display (display-get-default))) device
136 (display display))
137
a05a0e59 138
09bf47c6 139;;; Primitive graphics structures (points, rectangles and regions)
140
141(defbinding %rectangle-intersect () boolean
142 (src1 rectangle)
143 (src2 rectangle)
144 (dest rectangle))
145
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)
149 dest))
150
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."
153 (src1 rectangle)
154 (src2 rectangle)
155 (dest rectangle :in/return))
156
157(defun ensure-rectangle (rectangle)
158 (etypecase 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)))))
163
164
165(defbinding %region-new () pointer)
166
167(defbinding %region-polygon () pointer
168 (points (vector (inlined point)))
169 (n-points int)
170 (fill-rule fill-rule))
171
172(defbinding %region-rectangle () pointer
173 (rectangle rectangle))
174
175(defbinding %region-copy () pointer
176 (location pointer))
177
178(defbinding %region-destroy () nil
179 (location pointer))
180
181(defmethod allocate-foreign ((region region) &key rectangle polygon fill-rule)
09bf47c6 182 (cond
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))
187 ((%region-new))))
188
189(defun ensure-region (region)
190 (etypecase region
191 (region region)
192 ((or rectangle vector)
3dfaa38d 193 (make-instance 'region :rectangle (ensure-rectangle region)))
194 (list
195 (make-instance 'region :polygon region))))
09bf47c6 196
197(defbinding region-get-clipbox (region &optional (rectangle (make-instance 'rectangle))) nil
198 (region region)
199 (rectangle rectangle :in/return))
200
201(defbinding %region-get-rectangles () nil
202 (region region)
203 (rectangles pointer :out)
204 (n-rectangles int :out))
205
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)
209 (prog1
3dfaa38d 210 (map-c-vector 'list #'identity location '(inlined rectangle) length :get)
09bf47c6 211 (deallocate-memory location))))
212
213(defbinding region-empty-p () boolean
214 (region region))
215
216(defbinding region-equal-p () boolean
217 (region1 region)
218 (region2 region))
219
220(defbinding region-point-in-p () boolean
221 (region region)
222 (x int)
223 (y int))
224
225(defbinding region-rect-in (region rectangle) overlap-type
226 (region region)
227 ((ensure-rectangle rectangle) rectangle))
228
229(defbinding region-offset () nil
230 (region region)
231 (dx int)
232 (dy int))
233
234(defbinding region-shrink () nil
235 (region region)
236 (dx int)
237 (dy int))
238
239(defbinding region-intersect (source1 source2) nil
4f076d2d 240 ((ensure-region source1) region :in/return)
09bf47c6 241 ((ensure-region source2) region))
242
243(defbinding region-union (source1 source2) nil
4f076d2d 244 ((ensure-region source1) region :in/return)
09bf47c6 245 ((ensure-region source2) region))
246
247(defbinding region-subtract (source1 source2) nil
4f076d2d 248 ((ensure-region source1) region :in/return)
09bf47c6 249 ((ensure-region source2) region))
250
251(defbinding region-xor (source1 source2) nil
4f076d2d 252 ((ensure-region source1) region :in/return)
09bf47c6 253 ((ensure-region source2) region))
254
a05a0e59 255
e295d6df 256;;; Events
0d07716f 257
5515cd18 258(defbinding (events-pending-p "gdk_events_pending") () boolean)
0d07716f 259
5515cd18 260(defbinding event-get () event)
0d07716f 261
5515cd18 262(defbinding event-peek () event)
0d07716f 263
5515cd18 264(defbinding event-get-graphics-expose () event
0d07716f 265 (window window))
266
5515cd18 267(defbinding event-put () event
0d07716f 268 (event event))
269
5515cd18 270;(defbinding event-handler-set () ...)
0d07716f 271
5515cd18 272(defbinding set-show-events () nil
0d07716f 273 (show-events boolean))
274
5515cd18 275(defbinding get-show-events () boolean)
0d07716f 276
0d07716f 277
a05a0e59 278;;; Miscellaneous functions
0d07716f 279
6cff1e99 280(defbinding screen-width () int
281 (screen screen))
282
283(defbinding screen-height () int
284 (screen screen))
285
286(defbinding screen-width-mm () int
287 (screen screen))
288
289(defbinding screen-height-mm () int
290 (screen screen))
0d07716f 291
0d07716f 292
a05a0e59 293(defbinding pointer-grab
294 (window &key owner-events events confine-to cursor time) grab-status
0d07716f 295 (window window)
296 (owner-events boolean)
a05a0e59 297 (events event-mask)
0d07716f 298 (confine-to (or null window))
299 (cursor (or null cursor))
4a098e36 300 ((or time 0) (unsigned 32)))
0d07716f 301
a05a0e59 302(defbinding (pointer-ungrab "gdk_display_pointer_ungrab")
4a098e36 303 (&optional time (display (display-get-default))) nil
a05a0e59 304 (display display)
4a098e36 305 ((or time 0) (unsigned 32)))
0d07716f 306
a05a0e59 307(defbinding (pointer-is-grabbed-p "gdk_display_pointer_is_grabbed")
1b7d3a82 308 (&optional (display (display-get-default))) boolean
309 (display display))
a05a0e59 310
311(defbinding keyboard-grab (window &key owner-events time) grab-status
0d07716f 312 (window window)
313 (owner-events boolean)
4a098e36 314 ((or time 0) (unsigned 32)))
0d07716f 315
a05a0e59 316(defbinding (keyboard-ungrab "gdk_display_keyboard_ungrab")
4a098e36 317 (&optional time (display (display-get-default))) nil
a05a0e59 318 (display display)
4a098e36 319 ((or time 0) (unsigned 32)))
0d07716f 320
0d07716f 321
0d07716f 322
596c3078 323(defbinding atom-intern (atom-name &optional only-if-exists) atom
324 ((string atom-name) string)
325 (only-if-exists boolean))
326
327(defbinding atom-name () string
328 (atom atom))
329
0d07716f 330
331
332;;; Visuals
333
5515cd18 334(defbinding visual-get-best-depth () int)
0d07716f 335
5515cd18 336(defbinding visual-get-best-type () visual-type)
0d07716f 337
5515cd18 338(defbinding visual-get-system () visual)
0d07716f 339
340
5515cd18 341(defbinding (%visual-get-best-with-nothing "gdk_visual_get_best") () visual)
0d07716f 342
5515cd18 343(defbinding %visual-get-best-with-depth () visual
0d07716f 344 (depth int))
345
5515cd18 346(defbinding %visual-get-best-with-type () visual
0d07716f 347 (type visual-type))
348
5515cd18 349(defbinding %visual-get-best-with-both () visual
0d07716f 350 (depth int)
351 (type visual-type))
352
353(defun visual-get-best (&key depth type)
354 (cond
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))))
359
5515cd18 360;(defbinding query-depths ..)
0d07716f 361
5515cd18 362;(defbinding query-visual-types ..)
0d07716f 363
5515cd18 364(defbinding list-visuals () (glist visual))
0d07716f 365
366
367;;; Windows
368
5515cd18 369(defbinding window-destroy () nil
0d07716f 370 (window window))
371
64780167 372(defbinding window-at-pointer () window
373 (x int :out)
374 (y int :out))
0d07716f 375
5515cd18 376(defbinding window-show () nil
0d07716f 377 (window window))
378
64780167 379(defbinding window-show-unraised () nil
380 (window window))
381
5515cd18 382(defbinding window-hide () nil
0d07716f 383 (window window))
384
64780167 385(defbinding window-is-visible-p () boolean
386 (window window))
387
388(defbinding window-is-viewable-p () boolean
389 (window window))
390
5515cd18 391(defbinding window-withdraw () nil
0d07716f 392 (window window))
393
64780167 394(defbinding window-iconify () nil
395 (window window))
396
397(defbinding window-deiconify () nil
398 (window window))
399
400(defbinding window-stick () nil
401 (window window))
402
403(defbinding window-unstick () nil
404 (window window))
405
406(defbinding window-maximize () nil
407 (window window))
408
409(defbinding window-unmaximize () nil
410 (window window))
411
412(defbinding window-fullscreen () nil
413 (window window))
414
415(defbinding window-unfullscreen () nil
416 (window window))
417
418(defbinding window-set-keep-above () nil
419 (window window)
420 (setting boolean))
421
422(defbinding window-set-keep-below () nil
423 (window window)
424 (setting boolean))
425
5515cd18 426(defbinding window-move () nil
0d07716f 427 (window window)
428 (x int)
429 (y int))
430
5515cd18 431(defbinding window-resize () nil
0d07716f 432 (window window)
433 (width int)
434 (height int))
435
5515cd18 436(defbinding window-move-resize () nil
0d07716f 437 (window window)
438 (x int)
439 (y int)
440 (width int)
441 (height int))
442
64780167 443(defbinding window-scroll () nil
444 (window window)
445 (dx int)
446 (dy int))
447
3dfaa38d 448#?(pkg-exists-p "gtk+-2.0" :atleast-version "2.8.0")
449(defbinding window-move-region (window region dx dy) nil
450 (window window)
451 ((ensure-region region) region)
452 (dx int)
453 (dy int))
454
5515cd18 455(defbinding window-reparent () nil
0d07716f 456 (window window)
457 (new-parent window)
458 (x int)
459 (y int))
460
5515cd18 461(defbinding window-clear () nil
0d07716f 462 (window window))
463
64780167 464(defbinding %window-clear-area () nil
0d07716f 465 (window window)
466 (x int) (y int) (width int) (height int))
467
64780167 468(defbinding %window-clear-area-e () nil
0d07716f 469 (window window)
470 (x int) (y int) (width int) (height int))
471
472(defun window-clear-area (window x y width height &optional expose)
473 (if expose
64780167 474 (%window-clear-area-e window x y width height)
475 (%window-clear-area window x y width height)))
0d07716f 476
5515cd18 477(defbinding window-raise () nil
0d07716f 478 (window window))
479
5515cd18 480(defbinding window-lower () nil
0d07716f 481 (window window))
482
64780167 483(defbinding window-focus () nil
484 (window window)
485 (timestamp unsigned-int))
486
487(defbinding window-register-dnd () nil
488 (window window))
489
490(defbinding window-begin-resize-drag () nil
491 (window window)
492 (edge window-edge)
493 (button int)
494 (root-x int)
495 (root-y int)
496 (timestamp unsigned-int))
497
498(defbinding window-begin-move-drag () nil
499 (window window)
500 (button int)
501 (root-x int)
502 (root-y int)
503 (timestamp unsigned-int))
504
09bf47c6 505;; Probably not needed
506;; (defbinding window-constrain-size () nil ..
507
508(defbinding window-begin-paint-region (window region) nil
509 (window window)
510 ((ensure-region region) region))
511
512(defbinding window-end-paint () nil
513 (window window))
64780167 514
09bf47c6 515(defmacro with-window-paint ((window region) &body body)
516 `(progn
517 (window-begin-paint-region ,window ,region)
518 (unwind-protect
519 (progn ,@body)
520 (window-end-paint ,window))))
521
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
525 (window window)
526 ((ensure-region region) region)
527 (invalidate-children-p boolean))
528
529(defbinding window-get-update-area () region
530 (window window))
531
532(defbinding window-freeze-updates () nil
533 (window window))
534
535(defbinding window-thaw-updates () nil
536 (window window))
537
538(defbinding window-process-all-updates () nil)
539
540(defbinding window-process-updates () nil
541 (window window)
542 (update-children-p boolean))
543
544(defbinding window-set-debug-updates () nil
545 (enable-p boolean))
546
547(defbinding window-enable-synchronized-configure () nil
548 (window window))
549
550(defbinding window-configure-finished () nil
551 (window window))
552
553;; Deprecated, use gobject user data mechanism
64780167 554(defbinding window-set-user-data () nil
555 (window window)
556 (user-data pointer))
0d07716f 557
5515cd18 558(defbinding window-set-override-redirect () nil
0d07716f 559 (window window)
09bf47c6 560 (override-redirect-p boolean))
0d07716f 561
09bf47c6 562(defbinding window-set-accept-focus () nil
563 (window window)
564 (accept-focus-p boolean))
0d07716f 565
09bf47c6 566(defbinding window-set-focus-on-map () nil
567 (window window)
568 (focus-on-map-p boolean))
569
570;; Added if needed
571; (defbinding window-add-filter () nil
5515cd18 572; (defbinding window-remove-filter () nil
0d07716f 573
09bf47c6 574;; New code should use window-shape-combine
5515cd18 575(defbinding window-shape-combine-mask () nil
0d07716f 576 (window window)
577 (shape-mask bitmap)
578 (offset-x int)
579 (offset-y int))
580
09bf47c6 581(defbinding %window-shape-combine-region () nil
582 (window window)
583 (region (or null region))
584 (offset-x int)
585 (offset-y int))
586
587(defun window-shape-combine (window shape offset-x offset-y)
588 (etypecase shape
3dfaa38d 589 (null (%window-shape-combine-region window nil 0 0))
09bf47c6 590 (region (%window-shape-combine-region window shape offset-x offset-y))
3dfaa38d 591 (bitmap (window-shape-combine-mask window shape offset-x offset-y))))
09bf47c6 592
5515cd18 593(defbinding window-set-child-shapes () nil
0d07716f 594 (window window))
595
5515cd18 596(defbinding window-merge-child-shapes () nil
0d07716f 597 (window window))
598
09bf47c6 599#?(pkg-exists-p "gtk+-2.0" :atleast-version "2.10.0")
600(progn
601 (defbinding %window-input-shape-combine-mask () nil
602 (window window)
603 (shape-mask bitmap)
604 (x int)
605 (y int))
606
607 (defbinding %window-input-shape-combine-region () nil
608 (window window)
609 (region (or null region))
610 (x int)
611 (y int))
612
613 (defun window-input-shape-combine (window shape x y)
614 (etypecase shape
3dfaa38d 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))))
09bf47c6 618
619 (defbinding window-set-child-input-shapes () nil
620 (window window))
621
622 (defbinding window-merge-child-input-shapes () nil
623 (window window)))
0d07716f 624
5515cd18 625(defbinding window-set-static-gravities () boolean
0d07716f 626 (window window)
09bf47c6 627 (use-static-p boolean))
628
629(defbinding window-set-title () nil
630 (window window)
631 (title string))
0d07716f 632
09bf47c6 633(defbinding window-set-background () nil
634 (window window)
635 (color color))
636
637(defbinding window-set-back-pixmap (window pixmap &optional parent-relative-p) nil
638 (window window)
639 (pixmap (or null pixmap))
640 (parent-relative-p boolean))
0d07716f 641
5515cd18 642(defbinding window-set-cursor () nil
0d07716f 643 (window window)
64780167 644 (cursor (or null cursor)))
0d07716f 645
09bf47c6 646(defbinding window-get-geometry () nil
647 (window window)
648 (x int :out)
649 (y int :out)
650 (width int :out)
651 (height int :out)
652 (depth int :out))
653
654;(defbinding window-set-geometry-hints () nil
655
e0c6be61 656(defbinding window-set-icon-list () nil
09bf47c6 657 (window window)
658 (icons (glist pixbufs)))
659
660(defbinding window-set-skip-taskbar-hint () nil
661 (window window)
662 (skip-taskbar-p boolean))
663
664(defbinding window-set-skip-pager-hint () nil
665 (window window)
666 (skip-pager-p boolean))
667
668#?(pkg-exists-p "gtk+-2.0" :atleast-version "2.8.0")
669(defbinding window-set-urgency-hint () nil
670 (window window)
671 (urgent-p boolean))
672
673(defbinding window-get-position () nil
674 (window window)
675 (x int :out)
676 (y int :out))
677
678(defbinding window-get-root-origin () nil
679 (window window)
680 (x int :out)
681 (y int :out))
682
683(defbinding window-get-frame-extents (window &optional (extents (make-instance 'rect))) nil
684 (window window)
685 (extents rectangle :in/return))
686
687(defbinding window-get-origin () nil ; this may not work as
688 (window window) ; an int is actually returned
689 (x int :out)
690 (y int :out))
691
5515cd18 692(defbinding window-get-pointer () window
0d07716f 693 (window window)
694 (x int :out)
695 (y int :out)
696 (mask modifier-type :out))
697
09bf47c6 698;(defbinding window-set-icon () nil
699
700(defbinding window-set-icon-name () nil
701 (window window)
702 (icon-name string))
703
704(defbinding window-set-transient-for () nil
705 (window window)
706 (parent window))
707
708(defbinding window-set-role () nil
709 (window window)
710 (role string))
711
712(defbinding %window-get-decorations () boolean
713 (window window)
714 (decorations wm-decoration :out))
715
716(defun %window-decorations-getter (window)
717 (nth-value 1 (%window-get-decorations window)))
718
719(defun %window-decorations-boundp (window)
720 (%window-get-decorations window))
721
64780167 722(defbinding %window-get-toplevels () (glist window))
723
724(defun window-get-toplevels (&optional screen)
725 (if screen
726 (error "Not implemented")
727 (%window-get-toplevels)))
728
402183fc 729(defbinding %get-default-root-window () window)
0d07716f 730
67824820 731(defun get-root-window (&optional display)
402183fc 732 (if display
733 (error "Not implemented")
734 (%get-default-root-window)))
0d07716f 735
736
64780167 737
738;;; Drag and Drop
739
740;; Destination side
741
742(defbinding drag-status () nil
743 (context drag-context)
744 (action drag-action)
745 (time (unsigned 32)))
746
747
748
749
750
751
0d07716f 752;;
753
5515cd18 754(defbinding rgb-init () nil)
0d07716f 755
756
757
758
759;;; Cursor
760
6091b3e8 761(defmethod allocate-foreign ((cursor cursor) &key source mask fg bg
adc20f66 762 (x 0) (y 0) (display (display-get-default)))
6091b3e8 763 (etypecase source
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))))
770
771(defun ensure-cursor (cursor &rest args)
772 (if (typep cursor 'cursor)
773 cursor
48acc6ae 774 (apply #'make-instance 'cursor :source cursor args)))
64780167 775
776(defbinding %cursor-new-for-display () pointer
777 (display display)
0d07716f 778 (cursor-type cursor-type))
779
64780167 780(defbinding %cursor-new-from-pixmap () pointer
0d07716f 781 (source pixmap)
782 (mask bitmap)
783 (foreground color)
784 (background color)
785 (x int) (y int))
786
64780167 787(defbinding %cursor-new-from-pixbuf () pointer
788 (display display)
789 (pixbuf pixbuf)
790 (x int) (y int))
791
5515cd18 792(defbinding %cursor-ref () pointer
6baf860c 793 (location pointer))
0d07716f 794
5515cd18 795(defbinding %cursor-unref () nil
6baf860c 796 (location pointer))
797
0d07716f 798
0d07716f 799;;; Pixmaps
402183fc 800
dc96fcd4 801(defbinding %pixmap-new () pointer
802 (window (or null window))
0d07716f 803 (width int)
804 (height int)
dc96fcd4 805 (depth int))
806
807(defmethod allocate-foreign ((pximap pixmap) &key width height depth window)
808 (%pixmap-new window width height depth))
809
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))
813
5515cd18 814(defbinding %pixmap-colormap-create-from-xpm () pixmap
0d07716f 815 (window (or null window))
816 (colormap (or null colormap))
817 (mask bitmap :out)
818 (color (or null color))
1b7d3a82 819 (filename pathname))
0d07716f 820
5515cd18 821(defbinding %pixmap-colormap-create-from-xpm-d () pixmap
0d07716f 822 (window (or null window))
823 (colormap (or null colormap))
824 (mask bitmap :out)
825 (color (or null color))
b53669e6 826 (data (vector string)))
0d07716f 827
dc96fcd4 828;; Deprecated, use pixbufs instead
5a66b42b 829(defun pixmap-create (source &key color window colormap)
830 (let ((window
831 (if (not (or window colormap))
832 (get-root-window)
833 window)))
834 (multiple-value-bind (pixmap mask)
b53669e6 835 (etypecase source
5a66b42b 836 ((or string pathname)
1b7d3a82 837 (%pixmap-colormap-create-from-xpm window colormap color source))
b53669e6 838 ((vector string)
839 (%pixmap-colormap-create-from-xpm-d window colormap color source)))
5a66b42b 840 (values pixmap mask))))
402183fc 841
0d07716f 842
0d07716f 843;;; Color
844
dc96fcd4 845(defbinding colormap-get-system () colormap)
846
2e10ba8b 847(defbinding %color-copy () pointer
848 (location pointer))
849
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
854 ;; color chunk
1b7d3a82 855 (with-memory (location #.(foreign-size (find-class 'color)))
2e10ba8b 856 (%color-copy location)))
857
0d07716f 858(defun %scale-value (value)
859 (etypecase value
860 (integer value)
861 (float (truncate (* value 65535)))))
862
1b7d3a82 863(defmethod initialize-instance ((color color) &key (red 0.0) (green 0.0) (blue 0.0))
0d07716f 864 (call-next-method)
865 (with-slots ((%red red) (%green green) (%blue blue)) color
866 (setf
216bc8c3 867 %red (%scale-value red)
868 %green (%scale-value green)
869 %blue (%scale-value blue))))
0d07716f 870
f3f8586a 871(defbinding %color-parse () boolean
2e10ba8b 872 (spec string)
1b7d3a82 873 (color color :in/return))
2e10ba8b 874
f3f8586a 875(defun color-parse (spec &optional (color (make-instance 'color)))
876 (multiple-value-bind (succeeded-p color) (%color-parse spec color)
877 (if succeeded-p
878 color
879 (error "Parsing color specification ~S failed." spec))))
880
0d07716f 881(defun ensure-color (color)
882 (etypecase color
883 (null nil)
884 (color color)
f3f8586a 885 (string (color-parse color))
216bc8c3 886 (vector
2e10ba8b 887 (make-instance 'color
f3f8586a 888 :red (svref color 0) :green (svref color 1) :blue (svref color 2)))))
889
0d07716f 890
891
dc96fcd4 892;;; Drawable -- all the draw- functions are deprecated and will be
1b7d3a82 893;;; removed, use cairo for drawing instead.
64780167 894
895(defbinding drawable-get-size () nil
896 (drawable drawable)
897 (width int :out)
898 (height int :out))
899
900(defbinding (drawable-width "gdk_drawable_get_size") () nil
901 (drawable drawable)
902 (width int :out)
903 (nil null))
904
905(defbinding (drawable-height "gdk_drawable_get_size") () nil
906 (drawable drawable)
907 (nil null)
908 (height int :out))
909
910;; (defbinding drawable-get-clip-region () region
911;; (drawable drawable))
912
913;; (defbinding drawable-get-visible-region () region
914;; (drawable drawable))
915
916(defbinding draw-point () nil
917 (drawable drawable) (gc gc)
918 (x int) (y int))
919
920(defbinding %draw-points () nil
921 (drawable drawable) (gc gc)
922 (points pointer)
923 (n-points int))
924
64780167 925(defbinding draw-line () nil
926 (drawable drawable) (gc gc)
927 (x1 int) (y1 int)
928 (x2 int) (y2 int))
929
64780167 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))
934 (pixbuf pixbuf)
935 (src-x int) (src-y int)
936 (dest-x int) (dest-y int)
937 ((or width -1) int) ((or height -1) int)
938 (dither rgb-dither)
939 (x-dither int) (y-dither int))
940
5515cd18 941(defbinding draw-rectangle () nil
64780167 942 (drawable drawable) (gc gc)
943 (filled boolean)
944 (x int) (y int)
945 (width int) (height int))
946
947(defbinding draw-arc () nil
948 (drawable drawable) (gc gc)
949 (filled boolean)
950 (x int) (y int)
951 (width int) (height int)
952 (angle1 int) (angle2 int))
953
64780167 954(defbinding %draw-layout () nil
955 (drawable drawable) (gc gc)
956 (font pango:font)
957 (x int) (y int)
958 (layout pango:layout))
959
960(defbinding %draw-layout-with-colors () nil
961 (drawable drawable) (gc gc)
962 (font pango:font)
963 (x int) (y int)
964 (layout pango:layout)
965 (foreground (or null color))
966 (background (or null color)))
967
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)))
972
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)
976 (src drawable)
977 (src-x int) (src-y int)
978 (dest-x int) (dest-y int)
979 ((or width -1) int) ((or height -1) int))
980
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)
984 (image image)
985 (src-x int) (src-y int)
986 (dest-x int) (dest-y int)
987 ((or width -1) int) ((or height -1) int))
988
989(defbinding drawable-get-image () image
990 (drawable drawable)
991 (x int) (y int)
992 (width int) (height int))
993
994(defbinding drawable-copy-to-image
995 (drawable src-x src-y width height &optional image dest-x dest-y) image
996 (drawable drawable)
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))
0d07716f 1002
1003
1004;;; Key values
1005
5515cd18 1006(defbinding keyval-name () string
0d07716f 1007 (keyval unsigned-int))
1008
56b0eab3 1009(defbinding %keyval-from-name () unsigned-int
0d07716f 1010 (name string))
1011
56b0eab3 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)
1016 keyval)))
1017
5515cd18 1018(defbinding keyval-to-upper () unsigned-int
0d07716f 1019 (keyval unsigned-int))
1020
596c3078 1021(defbinding keyval-to-lower () unsigned-int
0d07716f 1022 (keyval unsigned-int))
1023
5515cd18 1024(defbinding (keyval-is-upper-p "gdk_keyval_is_upper") () boolean
0d07716f 1025 (keyval unsigned-int))
1026
5515cd18 1027(defbinding (keyval-is-lower-p "gdk_keyval_is_lower") () boolean
0d07716f 1028 (keyval unsigned-int))
1029
78dc8487 1030;;; Cairo interaction
1031
1b7d3a82 1032#?(pkg-exists-p "gtk+-2.0" :atleast-version "2.8.0")
78dc8487 1033(progn
1034 (defbinding cairo-create () cairo:context
1035 (drawable drawable))
1036
10ec8e36 1037 (defmacro with-cairo-context ((cr drawable) &body body)
1038 `(let ((,cr (cairo-create ,drawable)))
1039 (unwind-protect
1040 (progn ,@body)
1b7d3a82 1041 (invalidate-instance ,cr t))))
10ec8e36 1042
78dc8487 1043 (defbinding cairo-set-source-color () nil
1044 (cr cairo:context)
1045 (color color))
1046
1047 (defbinding cairo-set-source-pixbuf () nil
1048 (cr cairo:context)
1049 (pixbuf pixbuf)
1050 (x double-float)
1051 (y double-float))
1052
1053 (defbinding cairo-rectangle () nil
1054 (cr cairo:context)
1055 (rectangle rectangle))
1056
1057;; (defbinding cairo-region () nil
1058;; (cr cairo:context)
1059;; (region region))
d3849f30 1060
0720bb75 1061 (defbinding (cairo-surface-get-window "clg_gdk_cairo_surface_get_window") () window
1062 (surface cairo:surface))
78dc8487 1063)
00a8d921 1064
1065
1b7d3a82 1066
00a8d921 1067;;; Multi-threading support
1068
c2618ad5 1069#+sb-thread
00a8d921 1070(progn
1071 (defvar *global-lock* (sb-thread:make-mutex :name "global GDK lock"))
c2618ad5 1072
1073 (defun %global-lock-p ()
1074 (eq (car (sb-thread:mutex-value *global-lock*)) sb-thread:*current-thread*))
1075
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))))
1080
1081 (defun threads-leave (&optional flush-p)
1082 (assert (%global-lock-p))
1083 (cond
1084 ((zerop (cdr (sb-thread:mutex-value *global-lock*)))
1085 (when flush-p
1086 (flush))
1087 (sb-thread:release-mutex *global-lock*))
1088 (t (decf (cdr (sb-thread:mutex-value *global-lock*))))))
00a8d921 1089
1090 (define-callback %enter-fn nil ()
1091 (threads-enter))
1092
1093 (define-callback %leave-fn nil ()
1094 (threads-leave))
1095
1096 (defbinding threads-set-lock-functions (&optional) nil
1097 (%enter-fn callback)
1098 (%leave-fn callback))
1099
1100 (defmacro with-global-lock (&body body)
1101 `(progn
1102 (threads-enter)
1103 (unwind-protect
c2618ad5 1104 (progn ,@body)
1105 (threads-leave t))))
1106
1107 (defun timeout-add-with-lock (interval function &optional (priority +priority-default+))
1108 (timeout-add interval
1109 #'(lambda ()
1110 (with-global-lock (funcall function)))
1111 priority))
1112
1113 (defun idle-add-with-lock (funcation &optional (priority +priority-default-idle+))
1114 (idle-add
1115 #'(lambda ()
1116 (with-global-lock (funcall function)))
1117 priority)))
1118
1119
1120#-sb-thread
1121(progn
1122 (defmacro with-global-lock (&body body)
1123 `(progn ,@body))
1124
1125 (defun timeout-add-with-lock (interval function &optional (priority +priority-default+))
1126 (timeout-add interval function priority))
1127
1128 (defun idle-add-with-lock (funcation &optional (priority +priority-default-idle+))
1129 (idle-add function priority)))
1130
1131