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