1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
(ns glimmer-cosmic.ffi
"Raw bindings for libjoltcosmic (`crates/jolt-cosmic/src/lib.rs`).
The node half is libvidya's tree ABI under a `cosmic_` prefix. The loop half
is not: libcosmic owns the main thread, so `run!` blocks there while the
reconciler works from another thread, and its edits are published with
`commit!`.
**Any thread may call anything here except `raw-run`.** The arena sits behind
a mutex; nothing is thread-local.
**Strings returned are borrowed** until the next call of the same family —
jolt copies a `:string` return as it crosses, so holding the value is safe."
(:require [jolt.ffi :as ffi]))
;; --- the loop ----------------------------------------------------------------
;; :blocking releases the calling thread to Chez for the life of the call.
;; Without it, the worker would stall at its first collection waiting on a
;; thread parked inside libcosmic. A :blocking procedure may not take a string,
;; which is why the title is set by a call of its own.
(ffi/defcfn set-title! "cosmic_set_title" [:string] :void)
(ffi/defcfn raw-run "cosmic_run" [:int :int :int] :int {:blocking true})
(ffi/defcfn raw-wait "cosmic_wait" [:int] :int {:blocking true})
(ffi/defcfn wake! "cosmic_wake" [] :void)
(ffi/defcfn quit! "cosmic_quit" [] :void)
(ffi/defcfn raw-should-close "cosmic_should_close" [] :int)
(ffi/defcfn raw-commit "cosmic_tree_commit" [] :int)
;; --- the tree ----------------------------------------------------------------
(ffi/defcfn tree-root "cosmic_tree_root" [] :int)
(ffi/defcfn node-new "cosmic_node_new" [:string] :int)
(ffi/defcfn node-free! "cosmic_node_free" [:int] :void)
(ffi/defcfn raw-node-exists "cosmic_node_exists" [:int] :int)
(ffi/defcfn node-set-str! "cosmic_node_set_str" [:int :string :string] :void)
(ffi/defcfn node-set-num! "cosmic_node_set_num" [:int :string :double] :void)
(ffi/defcfn raw-node-set-bool "cosmic_node_set_bool" [:int :string :int] :void)
(ffi/defcfn node-clear-props! "cosmic_node_clear_props" [:int] :void)
(ffi/defcfn node-tag "cosmic_node_tag" [:int] :string)
(ffi/defcfn node-child-count "cosmic_node_child_count" [:int] :int)
(ffi/defcfn node-child-at "cosmic_node_child_at" [:int :int] :int)
(ffi/defcfn tree-dump "cosmic_tree_dump" [:int] :string)
(ffi/defcfn raw-node-append "cosmic_node_append" [:int :int] :int)
(ffi/defcfn node-remove! "cosmic_node_remove" [:int :int] :void)
(ffi/defcfn raw-node-insert-after "cosmic_node_insert_after" [:int :int :int] :int)
(ffi/defcfn raw-node-replace "cosmic_node_replace" [:int :int :int] :int)
;; --- events ------------------------------------------------------------------
(ffi/defcfn raw-poll-event "cosmic_tree_poll_event" [] :int)
(ffi/defcfn event-node "cosmic_tree_event_node" [] :int)
(ffi/defcfn event-name "cosmic_tree_event_name" [] :string)
(ffi/defcfn event-text "cosmic_tree_event_text" [] :string)
(ffi/defcfn event-num "cosmic_tree_event_num" [] :double)
;; --- the window and the desktop ------------------------------------------------
(ffi/defcfn window-width "cosmic_window_width" [] :int)
(ffi/defcfn window-height "cosmic_window_height" [] :int)
(ffi/defcfn raw-pick-image "cosmic_pick_image" [] :int)
(ffi/defcfn raw-picked-image "cosmic_picked_image" [:string] :int)
(ffi/defcfn raw-clipboard-image-png "cosmic_clipboard_image_png" [:string] :int)
;; --- the int/bool seam -------------------------------------------------------
(def system-mode 0)
(def dark-mode 1)
(def light-mode 2)
(defn run!
"Open the window and block in libcosmic until it closes. Main thread only.
Answers 0 on a clean exit, 1 on an error, 2 if a window already ran in this
process."
[width height title mode]
(set-title! title)
(raw-run width height mode))
(defn wait!
"Block up to `ms` for an event, a `wake!`, or the window closing. True when
an event is waiting."
[ms]
(not (zero? (raw-wait ms))))
(defn commit! [] (not (zero? (raw-commit))))
(defn should-close? [] (not (zero? (raw-should-close))))
(defn node-exists? [node] (not (zero? (raw-node-exists node))))
(defn node-set-bool! [node key value] (raw-node-set-bool node key (if value 1 0)))
(defn node-append! [parent child] (not (zero? (raw-node-append parent child))))
(defn node-insert-after! [parent child sibling]
(not (zero? (raw-node-insert-after parent child sibling))))
(defn node-replace! [parent old new] (not (zero? (raw-node-replace parent old new))))
(defn poll-event! [] (not (zero? (raw-poll-event))))
(defn pick-image! [] (not (zero? (raw-pick-image))))
(defn picked-image! [path] (not (zero? (raw-picked-image path))))
(defn clipboard-image-png! [path] (not (zero? (raw-clipboard-image-png path))))
|