| 1 | // The C surface of crates/mobile; see its lib.rs and library.rs for each call's contract. |
| 2 | #pragma once |
| 3 | |
| 4 | #include <stdbool.h> |
| 5 | #include <stddef.h> |
| 6 | #include <stdint.h> |
| 7 | |
| 8 | typedef struct Library Library; |
| 9 | typedef struct Share Share; |
| 10 | typedef struct Section Section; |
| 11 | typedef struct View View; |
| 12 | |
| 13 | void sb_string_free(char *text); |
| 14 | |
| 15 | bool sb_crash_start(const char *path, const char *build, const char *system); |
| 16 | const char *sb_crash_address(void); |
| 17 | char *sb_crash_report(void); |
| 18 | void sb_crash_forget(void); |
| 19 | |
| 20 | typedef void (*sb_coordinator)(const char *path, bool write, void (*body)(void *), void *context); |
| 21 | void sb_set_coordinator(sb_coordinator coordinator); |
| 22 | void sb_set_sync_wake(void (*wake)(void)); |
| 23 | typedef void (*sb_versions)(const char *path, void (*found)(void *, const char *id, const char *device), void *context); |
| 24 | typedef bool (*sb_retire)(const char *path, const char *id, bool keep); |
| 25 | void sb_set_versions(sb_versions versions, sb_retire retire); |
| 26 | char *sb_tags(void); |
| 27 | char *sb_pens(uint32_t section); |
| 28 | bool sb_tag_icon(uint16_t shape, bool checked, uint32_t pixels, uint8_t *rgba); |
| 29 | |
| 30 | // A document provider, as Android's ContentResolver reaches picked documents by URI. Each call |
| 31 | // returns 0, or 1 while the provider can't be reached, 2 once the grant is revoked, 3 for a |
| 32 | // document gone, anything else for another failure; size and modified (ms since 1970) are -1 |
| 33 | // where unknown. Every field is required. Calls come concurrently from the caller's thread, the |
| 34 | // background sync thread and each section's worker, and the host attaches those threads to its |
| 35 | // runtime (the JVM) itself; callbacks run only within the call that takes them. Ids and names |
| 36 | // passed either way are non-null. |
| 37 | typedef void (*sb_document_found)(void *context, const char *id, const char *name, bool directory, int64_t size, |
| 38 | int64_t modified, bool writable); |
| 39 | typedef struct sb_provider { |
| 40 | int32_t (*document)(const char *id, sb_document_found found, void *context); |
| 41 | int32_t (*children)(const char *id, sb_document_found found, void *context); |
| 42 | // mode is "r", "rw", "wt" or "w"; fd is a duplicate Snowbound owns and closes, handle the descriptor |
| 43 | // the host keeps open: detachFd would end the channel checkError reads. A nonzero status |
| 44 | // sets neither; a negative fd with status 0 has its handle closed. |
| 45 | int32_t (*open)(const char *id, const char *mode, int32_t *fd, uint64_t *handle); |
| 46 | // Once fd is closed: the provider's error (checkError), then the host's close. |
| 47 | int32_t (*close)(uint64_t handle); |
| 48 | int32_t (*rename)(const char *id, const char *name, void (*renamed)(void *context, const char *id), void *context); |
| 49 | } sb_provider; |
| 50 | void sb_set_provider(const sb_provider *provider); |
| 51 | |
| 52 | const Library *sb_library_open(const char *path, const char *cache, bool local, char **error); |
| 53 | const Library *sb_library_provider(const char *root, bool folder, bool local, const char *device, const char *cache, |
| 54 | char **error); |
| 55 | const Library *sb_library_server(const char *address, const char *share, const char *user, const char *password, |
| 56 | const char *domain, const char *root, const char *cache, char **error); |
| 57 | // Callback/token live until the blocking join returns; false cancels, approving reports host approval. |
| 58 | typedef bool (*sb_join_wait)(uintptr_t token, bool approving); |
| 59 | // Private credential/refusal JSON; persist credential before hosted open, then free with sb_string_free. |
| 60 | char *sb_live_join(const char *author, const char *device, const char *code, const char *password, |
| 61 | const char *relay, bool local_network, sb_join_wait waiting, uintptr_t token); |
| 62 | // Null relay disables relay, false local_network disables LAN; offline guards cached edits before first watch. |
| 63 | const Library *sb_library_hosted(const char *credential, const char *author, const char *device, |
| 64 | const char *relay, bool local_network, bool offline, const char *cache, char **error); |
| 65 | char *sb_library_live_status(const Library *library); |
| 66 | bool sb_notebook_create(const char *path, const char *cache, const char *author, const char *date, const char *time, |
| 67 | char **error); |
| 68 | bool sb_notebook_moved(const char *cache, const char *from, const char *to, char **error); |
| 69 | char *sb_library_sections(const Library *library); |
| 70 | int32_t sb_library_color(const Library *library); |
| 71 | char *sb_library_new_section(const Library *library, const char *folder, const char *name, const char *author, |
| 72 | const char *date, const char *time); |
| 73 | char *sb_library_move_page(const Library *library, const char *from, const char *id, const char *to, const char *before, |
| 74 | uint32_t level, const char *discard, const char *author, const char *date, const char *time); |
| 75 | char *sb_library_place(const Library *library, const char *path, const char *folder, const char *paths); |
| 76 | char *sb_search(const Library *const *libraries, size_t count, const char *section, const char *query); |
| 77 | char *sb_library_tagged(const Library *library); |
| 78 | bool sb_library_unlock(const Library *library, const char *path, const char *password); |
| 79 | void sb_library_lock_all(const Library *library); |
| 80 | char *sb_library_sync_status(const Library *library); |
| 81 | void sb_library_set_offline(const Library *library, bool offline); |
| 82 | void sb_library_touched(const Library *library, const char *path); |
| 83 | void sb_library_sync_now(const Library *library); |
| 84 | // Publishes, keeping offline copies; sb_library_close is Close Notebook and deletes them. |
| 85 | bool sb_library_flush(const Library *library, double seconds, char **error); |
| 86 | bool sb_library_close(const Library *library, double seconds, char **error); |
| 87 | void sb_library_free(const Library *library); |
| 88 | |
| 89 | Share *sb_share_connect(const char *address, const char *share, const char *user, const char *password, |
| 90 | const char *domain, char **error); |
| 91 | char *sb_share_list(const Share *share, const char *path); |
| 92 | void sb_share_free(Share *share); |
| 93 | |
| 94 | typedef void (*sb_wake)(uintptr_t token); |
| 95 | Section *sb_section_open(const Library *library, const char *path, const char *author, sb_wake wake, |
| 96 | uintptr_t token, char **error); |
| 97 | char *sb_section_pages(const Section *section); |
| 98 | uint32_t sb_section_poll(const Section *section, uint8_t *status); |
| 99 | char *sb_section_new_page(const Section *section, const char *parent, const char *date, const char *time); |
| 100 | bool sb_section_delete_page(const Section *section, const char *id, const char *date, const char *time); |
| 101 | bool sb_section_arrange(const Section *section, const char *order, const char *moved); |
| 102 | char *sb_section_themes(const Section *section, const char *id); |
| 103 | bool sb_section_set_theme(const Section *section, const char *id, uint8_t scope, const char *theme); |
| 104 | bool sb_section_flush(const Section *section, double seconds); |
| 105 | void sb_section_wake(const Section *section); |
| 106 | void sb_section_set_author(const Section *section, const char *author); |
| 107 | void sb_section_free(Section *section); |
| 108 | |
| 109 | #if defined(__ANDROID__) |
| 110 | struct ANativeWindow; |
| 111 | // Acquires its own window reference; caller retains ownership of its reference. |
| 112 | View *sb_view_new_android(struct ANativeWindow *window, const Section *section, const char *id, float width, float height, float scale); |
| 113 | // Detach before SurfaceDestroyed returns; editor, selection and Undo remain alive. |
| 114 | void sb_view_detach_android(View *view); |
| 115 | // Attach at the last size/scale, then resize on SurfaceChanged; detach an attached view first. |
| 116 | bool sb_view_attach_android(View *view, struct ANativeWindow *window); |
| 117 | #else |
| 118 | View *sb_view_new(void *layer, const Section *section, const char *id, float width, float height, float scale); |
| 119 | #endif |
| 120 | // Serialize all view calls; free only when the editor is no longer needed. |
| 121 | void sb_view_free(View *view); |
| 122 | // Dimensions are host points; scale is pixels per point. Invalid sizes leave the view unchanged. |
| 123 | void sb_view_resize(View *view, float width, float height, float scale); |
| 124 | bool sb_view_render(View *view); |
| 125 | bool sb_view_frame_pending(const View *view); |
| 126 | void sb_view_set_dark(View *view, bool dark); |
| 127 | bool sb_view_read_only(const View *view); |
| 128 | char *sb_view_reading(const View *view, float width); |
| 129 | // Preserves the nearest source caret's host offset from the page-point anchor at scale 1. |
| 130 | bool sb_view_set_reading(View *view, float width, float anchor[2]); |
| 131 | bool sb_view_reload_ready(const View *view); |
| 132 | // A non-null page-point anchor follows its source caret across the refresh. |
| 133 | bool sb_view_reload(View *view, bool discard, float anchor[2]); |
| 134 | bool sb_view_keep(const View *view); |
| 135 | void sb_view_focus(View *view, bool focused); |
| 136 | void sb_view_content(View *view, float bounds[4]); |
| 137 | bool sb_view_block(const View *view, float x, float y, float rect[4]); |
| 138 | void sb_view_set_transform(View *view, float zoom, float x, float y); |
| 139 | uint8_t sb_view_target(const View *view, float x, float y); |
| 140 | void sb_view_pressure(View *view, float pressure); |
| 141 | void sb_set_snap_to_grid(bool on); |
| 142 | void sb_set_default_font(const char *face, float size); |
| 143 | void sb_set_markdown_shortcuts(bool on); |
| 144 | bool sb_view_press(View *view, float x, float y); |
| 145 | bool sb_view_drag(View *view, float x, float y); |
| 146 | bool sb_view_release(View *view); |
| 147 | bool sb_view_undo(View *view, bool redo); |
| 148 | bool sb_view_can_undo(const View *view, bool redo); |
| 149 | uint64_t sb_view_format(const View *view); |
| 150 | bool sb_view_apply(View *view, uint8_t command); |
| 151 | bool sb_view_highlight(View *view, int64_t color); |
| 152 | bool sb_view_style(View *view, uint8_t place); |
| 153 | int32_t sb_view_style_place(const View *view); |
| 154 | char *sb_view_correction(const View *view); |
| 155 | bool sb_view_correct(View *view, uint8_t command, const char *text); |
| 156 | char *sb_view_title(const View *view); |
| 157 | bool sb_view_focus_title(View *view); |
| 158 | bool sb_view_find(View *view, const char *query); |
| 159 | bool sb_view_select_paragraph(View *view, const char *id); |
| 160 | char *sb_view_copy(View *view, bool cut); |
| 161 | void sb_view_insert_space(View *view); |
| 162 | void sb_view_set_tool(View *view, uint8_t tool, uint8_t detail, uint32_t section); |
| 163 | bool sb_view_cancel(View *view); |
| 164 | bool sb_view_ink_selection(const View *view, float rect[4]); |
| 165 | char *sb_view_paper(const View *view); |
| 166 | bool sb_view_set_paper(View *view, int16_t red, uint8_t green, uint8_t blue, int8_t ruled); |
| 167 | bool sb_view_set_art(View *view, const char *name); |
| 168 | uint8_t *sb_view_pdf(const View *view, float width, float height, const char *section, size_t *length); |
| 169 | void sb_bytes_free(uint8_t *bytes, size_t length); |
| 170 | int8_t sb_view_date_request(View *view, int64_t *seconds); |
| 171 | bool sb_view_change_date(View *view, int64_t seconds, const char *date, const char *time); |
| 172 | bool sb_view_insert_picture(View *view, const uint8_t *bytes, size_t length, float width, float height); |
| 173 | |
| 174 | typedef struct Movie Movie; |
| 175 | uint32_t sb_recording_rate(void); |
| 176 | bool sb_view_start_recording(View *view, bool video, const char *date, const char *time); |
| 177 | int64_t sb_view_recording(const View *view, bool *paused); |
| 178 | void sb_view_pause_recording(View *view, bool paused); |
| 179 | bool sb_view_finish_recording(View *view, const uint8_t *bytes, size_t length, bool video); |
| 180 | char *sb_view_play_request(View *view, const char *folder); |
| 181 | bool sb_view_played(View *view, int64_t at_ms); |
| 182 | Movie *sb_movie_new(void); |
| 183 | void sb_movie_picture(Movie *movie, uint64_t at_us, const uint8_t *bgra, uint32_t width, uint32_t height, |
| 184 | size_t stride); |
| 185 | void sb_movie_sound(Movie *movie, const uint8_t *pcm, size_t length); |
| 186 | uint8_t *sb_movie_finish(Movie *movie, uint64_t duration_us, size_t *length); |
| 187 | |
| 188 | uint32_t sb_text_length(const View *view); |
| 189 | char *sb_text(const View *view, uint32_t start, uint32_t end); |
| 190 | void sb_selection(const View *view, uint32_t range[2]); |
| 191 | bool sb_select(View *view, uint32_t start, uint32_t end); |
| 192 | bool sb_select_more(View *view); |
| 193 | bool sb_marked(const View *view, uint32_t range[2]); |
| 194 | bool sb_set_marked(View *view, const char *text, uint32_t selected_start, uint32_t selected_end); |
| 195 | void sb_unmark(View *view); |
| 196 | bool sb_insert(View *view, const char *text); |
| 197 | bool sb_replace(View *view, uint32_t start, uint32_t end, const char *text); |
| 198 | bool sb_paste(View *view, const char *text, const char *language); |
| 199 | bool sb_delete_backward(View *view); |
| 200 | bool sb_caret_rect(const View *view, uint32_t offset, float rect[4]); |
| 201 | size_t sb_range_rects(const View *view, uint32_t start, uint32_t end, float (*rects)[4], size_t capacity); |
| 202 | uint32_t sb_closest(const View *view, float x, float y); |