summaryrefslogtreecommitdiff
path: root/include/yasl/yasl.h
blob: c0ebb75dc6591a31943ea630e58f004bab147907 (plain)
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/** @file Windows, input and events. The first surface starts the backend; use the
 * creating thread (main on Cocoa) for every call except yasl_wake. Coordinates are
 * logical units unless named pixel. */
#ifndef YASL_H
#define YASL_H
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "yasl/keycodes.h"
#if defined(__GNUC__)
#define YASL_API __attribute__((visibility("default")))
#else
#define YASL_API
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef struct yasl_surface yasl_surface;
typedef struct yasl_event yasl_event;
enum yasl_backend { YASL_BACKEND_AUTO, YASL_BACKEND_WAYLAND, YASL_BACKEND_X11, YASL_BACKEND_COCOA };
enum yasl_surface_flags { YASL_SURFACE_CPU=1u, YASL_SURFACE_HIDDEN=2u, YASL_SURFACE_UNDECORATED=4u, YASL_SURFACE_FIXED_SIZE=8u };
enum yasl_error { YASL_ERROR_NONE, YASL_ERROR_INVALID, YASL_ERROR_UNSUPPORTED, YASL_ERROR_NO_MEMORY,
    YASL_ERROR_NOT_INITIALIZED, YASL_ERROR_BUSY, YASL_ERROR_WRONG_THREAD, YASL_ERROR_CONTEXT_EXPIRED, YASL_ERROR_IO, YASL_ERROR_DISCONNECTED };
enum yasl_selection { YASL_CLIPBOARD, YASL_PRIMARY };
enum yasl_key_action { YASL_KEY_PRESS, YASL_KEY_RELEASE, YASL_KEY_REPEAT };
enum yasl_mod { YASL_MOD_SHIFT=1u, YASL_MOD_ALT=2u, YASL_MOD_CTRL=4u, YASL_MOD_SUPER=8u, YASL_MOD_CAPS=16u };
enum yasl_pointer_action { YASL_POINTER_MOVE, YASL_POINTER_DOWN, YASL_POINTER_UP, YASL_POINTER_LEAVE };
enum yasl_pointer_mode { YASL_POINTER_NORMAL, YASL_POINTER_RELATIVE };
enum yasl_button { YASL_BUTTON_PRIMARY, YASL_BUTTON_MIDDLE, YASL_BUTTON_SECONDARY, YASL_BUTTON_BACK, YASL_BUTTON_FORWARD };
#define YASL_BUTTON_BIT(button) (1u << (button))
enum yasl_pen_tool { YASL_PEN_UNKNOWN, YASL_PEN_PEN, YASL_PEN_ERASER, YASL_PEN_BRUSH, YASL_PEN_AIRBRUSH, YASL_PEN_PENCIL };
enum yasl_pen_action { YASL_PEN_ENTER, YASL_PEN_LEAVE, YASL_PEN_MOVE, YASL_PEN_DOWN, YASL_PEN_UP, YASL_PEN_BUTTON, YASL_PEN_CANCEL };
enum yasl_pen_axis { YASL_PEN_PRESSURE=1u, YASL_PEN_TILT=2u, YASL_PEN_ROTATION=4u, YASL_PEN_DISTANCE=8u, YASL_PEN_TANGENTIAL=16u, YASL_PEN_WHEEL=32u };
enum yasl_scroll_valid { YASL_SCROLL_LINES=1u, YASL_SCROLL_PIXELS=2u };
enum yasl_scroll_source { YASL_SCROLL_UNKNOWN, YASL_SCROLL_WHEEL, YASL_SCROLL_FINGER, YASL_SCROLL_CONTINUOUS };
enum yasl_scroll_phase { YASL_SCROLL_PHASE_UNKNOWN, YASL_SCROLL_BEGIN, YASL_SCROLL_UPDATE, YASL_SCROLL_END };
enum yasl_transfer_status { YASL_TRANSFER_OK, YASL_TRANSFER_UNAVAILABLE, YASL_TRANSFER_FAILED };
enum yasl_text_purpose { YASL_TEXT_NORMAL, YASL_TEXT_PASSWORD, YASL_TEXT_NUMBER, YASL_TEXT_TERMINAL };
enum yasl_cursor { YASL_CURSOR_ARROW, YASL_CURSOR_TEXT, YASL_CURSOR_LINK, YASL_CURSOR_CROSSHAIR, YASL_CURSOR_MOVE,
    YASL_CURSOR_RESIZE_NWSE, YASL_CURSOR_RESIZE_NESW, YASL_CURSOR_RESIZE_EW, YASL_CURSOR_RESIZE_NS, YASL_CURSOR_HIDDEN };
enum yasl_surface_state { YASL_STATE_FULLSCREEN=1u, YASL_STATE_MAXIMIZED=2u, YASL_STATE_ACTIVATED=4u,
    YASL_STATE_SUSPENDED=8u, YASL_STATE_CSD=16u, YASL_STATE_TILED=32u };
enum yasl_feature { YASL_CAP_POPUPS=1u, YASL_CAP_DRAG=2u, YASL_CAP_DRAG_CARRY=4u, YASL_CAP_PLACE_WINDOW=8u,
    YASL_CAP_PRIMARY_SELECTION=16u, YASL_CAP_CSD=32u, YASL_CAP_NATIVE_GRAPHICS=64u, YASL_CAP_FRAME_PACING=128u,
    YASL_CAP_TABLET=256u, YASL_CAP_OPENGL=512u, YASL_CAP_VULKAN=1024u, YASL_CAP_TEXT_INPUT=2048u };
enum yasl_popup_edge { YASL_POPUP_CENTER, YASL_POPUP_TOP, YASL_POPUP_BOTTOM, YASL_POPUP_LEFT,
    YASL_POPUP_RIGHT, YASL_POPUP_TOP_LEFT, YASL_POPUP_BOTTOM_LEFT, YASL_POPUP_TOP_RIGHT, YASL_POPUP_BOTTOM_RIGHT };
enum yasl_popup_constraint { YASL_POPUP_SLIDE_X=1u, YASL_POPUP_SLIDE_Y=2u, YASL_POPUP_FLIP_X=4u,
    YASL_POPUP_FLIP_Y=8u, YASL_POPUP_RESIZE_X=16u, YASL_POPUP_RESIZE_Y=32u };
enum yasl_resize_edge { YASL_EDGE_TOP=1, YASL_EDGE_BOTTOM=2, YASL_EDGE_LEFT=4, YASL_EDGE_TOP_LEFT=5,
    YASL_EDGE_BOTTOM_LEFT=6, YASL_EDGE_RIGHT=8, YASL_EDGE_TOP_RIGHT=9, YASL_EDGE_BOTTOM_RIGHT=10 };
enum yasl_event_type { YASL_EVENT_NONE, YASL_EVENT_CLOSE, YASL_EVENT_QUIT, YASL_EVENT_REOPEN, YASL_EVENT_WINDOW,
    YASL_EVENT_REFRESH, YASL_EVENT_KEY, YASL_EVENT_TEXT, YASL_EVENT_POINTER, YASL_EVENT_SCROLL, YASL_EVENT_PEN,
    YASL_EVENT_INPUT_RESET, YASL_EVENT_COMPOSITION, YASL_EVENT_TEXT_EDIT, YASL_EVENT_CLIPBOARD, YASL_EVENT_DROP,
    YASL_EVENT_DRAG, YASL_EVENT_DISPLAY_LOST, YASL_EVENT_DISPLAY_RESTORED };
enum yasl_drop_action { YASL_DROP_OVER, YASL_DROP_LEAVE, YASL_DROP_DATA };
enum yasl_drag_action { YASL_DRAG_OVER, YASL_DRAG_LEAVE, YASL_DRAG_DROP };
struct yasl_window_payload { int width,height,pixel_width,pixel_height; double scale; unsigned state; };
struct yasl_key_payload { enum yasl_key key; enum yasl_key_action action; unsigned mods;
        uint32_t codepoint, shifted, native_code; };
struct yasl_text_payload { const char *data; size_t length; };
struct yasl_pointer_payload { double x,y,dx,dy; enum yasl_pointer_action action; unsigned button,buttons,mods; };
struct yasl_scroll_payload { double x,y,lines_x,lines_y,pixels_x,pixels_y; unsigned valid,source,phase,mods; bool momentum; };
struct yasl_pen_payload { uint64_t device_id,tool_id; double x,y,pressure,tilt_x,tilt_y,rotation,distance,tangential,wheel_degrees;
        unsigned axes_valid,axes_changed,buttons,changed_button,tool,action; bool in_contact; };
struct yasl_composition_payload { const char *data; size_t length; int begin,end; bool active; uint64_t revision,generation; };
struct yasl_text_edit_payload { const char *data; size_t length,begin,end; uint64_t revision,generation; };
struct yasl_clipboard_payload { const char *data; size_t length; uint64_t request_id; enum yasl_transfer_status status; };
struct yasl_drop_payload { enum yasl_drop_action action; double x,y; const char *data; size_t length; };
struct yasl_drag_payload { enum yasl_drag_action action; double x,y; };

/** Read the union member named by type. Strings stay valid until the next wait.
 * CLOSE: the user closed this window. QUIT: the system asked the app to quit.
 * WINDOW: size, scale or state changed. REFRESH: draw now; sent once the window
 * has a size, after every resize and when the system needs the contents again.
 * INPUT_RESET: forget held keys, buttons and strokes. DROP: external data over
 * the window, delivered as DATA. DRAG: another YASL surface dragged over.
 * DISPLAY_LOST: the display server went away. Destroy Vulkan surfaces and GL
 * objects now; windows stay valid. Wayland reconnects, then sends DISPLAY_RESTORED:
 * recreate them (GL contexts are new and must be bound again). Elsewhere loss is
 * final and later waits fail. */
struct yasl_event {
    enum yasl_event_type type;
    yasl_surface *surface;
    uint64_t time_ns;
    union {
        struct yasl_window_payload window;
        struct yasl_key_payload key;
        struct yasl_text_payload text;
        struct yasl_pointer_payload pointer;
        struct yasl_scroll_payload scroll;
        struct yasl_pen_payload pen;
        struct yasl_composition_payload composition;
        struct yasl_text_edit_payload text_edit;
        struct yasl_clipboard_payload clipboard;
        /** DATA carries a text/uri-list for yasl_drop_next_path; x/y are set for OVER. */
        struct yasl_drop_payload drop;
        struct yasl_drag_payload drag;
    };
};
/** Last error on this thread; success does not clear it. */
YASL_API enum yasl_error yasl_get_error(const char **description);
YASL_API int yasl_get_native_error(void);
/** Only before the first surface is created. */
YASL_API bool yasl_set_app_id(const char *app_id);
YASL_API bool yasl_set_backend(enum yasl_backend backend);
/** Flags zero creates a surface for your own Vulkan or Metal renderer. */
YASL_API yasl_surface *yasl_surface_create(const char *title, int width, int height, unsigned flags);
/** Also destroys its popups. */
YASL_API void yasl_surface_destroy(yasl_surface *surface);
/** Destroys all surfaces. Release your GPU objects first. */
YASL_API void yasl_shutdown(void);
/** 1 event, 0 none (timeout or wake), -1 failure. timeout_ms zero polls, negative
 * waits forever. Without an event, out->type is NONE. */
YASL_API int yasl_wait_event(yasl_event *out, int timeout_ms);
/** Makes a waiting yasl_wait_event return. Thread-safe. */
YASL_API void yasl_wake(void);
YASL_API uint64_t yasl_time_ns(void);
YASL_API enum yasl_backend yasl_surface_backend(const yasl_surface *surface);
YASL_API unsigned yasl_surface_features(const yasl_surface *surface);
YASL_API void yasl_surface_get_size(const yasl_surface *surface, int *width, int *height);
YASL_API void yasl_surface_get_framebuffer_size(const yasl_surface *surface, int *width, int *height);
YASL_API double yasl_surface_get_scale(const yasl_surface *surface);
YASL_API unsigned yasl_surface_state(const yasl_surface *surface);
YASL_API void *yasl_surface_userdata(const yasl_surface *surface);
YASL_API void yasl_surface_set_userdata(yasl_surface *surface, void *userdata);
YASL_API bool yasl_surface_set_title(yasl_surface *surface, const char *title);
/** Requests; the result arrives as a WINDOW event. */
YASL_API bool yasl_surface_request_size(yasl_surface *surface, int width, int height);
YASL_API bool yasl_surface_request_fullscreen(yasl_surface *surface, bool enabled);
YASL_API bool yasl_surface_request_maximized(yasl_surface *surface, bool enabled);
YASL_API bool yasl_surface_request_minimize(yasl_surface *surface);
YASL_API bool yasl_surface_set_cursor(yasl_surface *surface, enum yasl_cursor cursor);
YASL_API bool yasl_surface_set_pointer_mode(yasl_surface *surface, enum yasl_pointer_mode mode);
/** Draws during native modal loops such as a live resize. The callback may render
 * but must not wait, create or destroy surfaces, or shut down. */
YASL_API void yasl_surface_set_refresh_callback(yasl_surface *surface, void (*refresh)(yasl_surface *,void *), void *userdata);
YASL_API int yasl_double_click_ms(void);
YASL_API bool yasl_clipboard_set(enum yasl_selection selection, const char *text);
/** Returns a request ID; the text arrives as a CLIPBOARD event. Zero on failure. */
YASL_API uint64_t yasl_clipboard_request(yasl_surface *target, enum yasl_selection selection);
/** IME support for a text field. */
YASL_API bool yasl_surface_set_text_input(yasl_surface *surface, bool active, enum yasl_text_purpose purpose);
/** UTF-8; selection offsets are bytes. */
YASL_API bool yasl_surface_set_surrounding_text(yasl_surface *surface, const char *text, size_t length,
    size_t selection_begin, size_t selection_end, uint64_t revision);
YASL_API bool yasl_surface_set_ime_caret(yasl_surface *surface, double x, double y, double width, double height);
/** Anchor picks a point on the x/y/anchor rectangle of the parent; gravity is the
 * direction the popup grows. Functions taking a trigger need a recent press event. */
YASL_API yasl_surface *yasl_popup_create(yasl_surface *parent, int width, int height,
    double x, double y, double anchor_width, double anchor_height, enum yasl_popup_edge anchor,
    enum yasl_popup_edge gravity, unsigned constraints, const yasl_event *trigger);
YASL_API bool yasl_popup_reposition(yasl_surface *popup, int width, int height,
    double x, double y, double anchor_width, double anchor_height, enum yasl_popup_edge anchor,
    enum yasl_popup_edge gravity, unsigned constraints);
YASL_API bool yasl_surface_start_interactive_move(yasl_surface *surface, const yasl_event *trigger);
YASL_API bool yasl_surface_start_interactive_resize(yasl_surface *surface, enum yasl_resize_edge edge, const yasl_event *trigger);
YASL_API bool yasl_surface_show_window_menu(yasl_surface *surface, double x, double y, const yasl_event *trigger);
YASL_API bool yasl_drag_start(yasl_surface *origin, const yasl_event *trigger,
    const uint32_t *pixels, int width, int height, int hotspot_x, int hotspot_y);
YASL_API void yasl_drag_cancel(void);
YASL_API bool yasl_surface_drag_carry(yasl_surface *surface, double x, double y);
YASL_API bool yasl_surface_place_under_pointer(yasl_surface *surface, double x, double y);
YASL_API size_t yasl_drop_next_path(const char **cursor, char *out, size_t capacity);
#ifdef __cplusplus
}
#endif
#endif