diff options
Diffstat (limited to 'include/yasl')
| -rw-r--r-- | include/yasl/timing.h | 51 | ||||
| -rw-r--r-- | include/yasl/yasl.h | 358 |
2 files changed, 409 insertions, 0 deletions
diff --git a/include/yasl/timing.h b/include/yasl/timing.h new file mode 100644 index 0000000..7c66967 --- /dev/null +++ b/include/yasl/timing.h @@ -0,0 +1,51 @@ +#ifndef YASL_TIMING_H +#define YASL_TIMING_H + +#include <stdbool.h> +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +struct yasl_resize_stats { + uint64_t count; + double avg_us; + double max_us; + long minflt; +}; + +struct yasl_timing { + double refresh_ns; + uint64_t last_present_ns; + uint64_t next_present_ns; + uint64_t frames_skipped; + struct yasl_resize_stats resize; +}; + +#define YASL_REFRESH_DEFAULT_NS 16666666.0 + +struct yasl_frame_clock { + uint64_t last_present_ns; + uint64_t resize_count; + uint64_t resize_sum_ns; + uint64_t resize_max_ns; + long resize_minflt; + uint64_t frame_time_ns; + double refresh_ns; +}; + +uint64_t yasl_clock_extend_ms(uint32_t ms, uint64_t now_ns); +void yasl_clock_presented(struct yasl_frame_clock *c, uint64_t now, bool sample); +void yasl_clock_note_resize(struct yasl_frame_clock *c, uint64_t dt_ns); +void yasl_clock_resize_stats(const struct yasl_frame_clock *c, + struct yasl_resize_stats *out); +double yasl_clock_refresh_ms(const struct yasl_frame_clock *c); +uint64_t yasl_clock_next_present_ns(const struct yasl_frame_clock *c); +uint64_t yasl_clock_frame_timestamp_ns(struct yasl_frame_clock *c, uint64_t now); + +#ifdef __cplusplus +} +#endif + +#endif /* YASL_TIMING_H */ diff --git a/include/yasl/yasl.h b/include/yasl/yasl.h new file mode 100644 index 0000000..0c2235a --- /dev/null +++ b/include/yasl/yasl.h @@ -0,0 +1,358 @@ +#ifndef YASL_H +#define YASL_H + +#include <stdbool.h> +#include <stddef.h> +#include <stdint.h> + +#include "yasl/timing.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(_WIN32) || defined(__CYGWIN__) + #if defined(YASL_BUILD_SHARED) + #define YASL_API __declspec(dllexport) + #elif defined(YASL_SHARED) + #define YASL_API __declspec(dllimport) + #else + #define YASL_API + #endif +#elif defined(__GNUC__) && __GNUC__ >= 4 + #define YASL_API __attribute__((visibility("default"))) +#else + #define YASL_API +#endif + +struct yasl_display; +struct yasl_surface; +struct yasl_loop; + +/* Geometry */ +struct yasl_vector2i { + int x; + int y; +}; + +struct yasl_rect2i { + int x; + int y; + int width; + int height; +}; + +#define YASL_SCALE_UNIT 120 +#define YASL_MIN_LOGICAL_PX 64 + +static inline int yasl_scale_to_device(double logical, uint32_t scale_120) +{ + return (int)((logical * (double)scale_120 + YASL_SCALE_UNIT / 2) / YASL_SCALE_UNIT); +} + +static inline int yasl_scale_to_logical(int device, uint32_t scale_120) +{ + return (int)(((int64_t)device * YASL_SCALE_UNIT + scale_120 / 2) / scale_120); +} + +/* Capabilities */ +enum yasl_display_cap : uint32_t { + YASL_CAP_POPUPS = 1 << 0, + YASL_CAP_DRAG = 1 << 1, + YASL_CAP_DRAG_CARRY = 1 << 2, + YASL_CAP_PLACE_WINDOW = 1 << 3, + YASL_CAP_PRIMARY_SELECTION = 1 << 4, + YASL_CAP_CSD = 1 << 5, +}; + +enum yasl_selection : uint8_t { + YASL_CLIPBOARD, + YASL_PRIMARY, +}; + +enum yasl_surface_state : uint32_t { + YASL_STATE_FULLSCREEN = 1 << 0, + YASL_STATE_MAXIMIZED = 1 << 1, + YASL_STATE_ACTIVATED = 1 << 2, + YASL_STATE_SUSPENDED = 1 << 3, + YASL_STATE_CSD = 1 << 4, +}; + +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_NONE, +}; + +enum yasl_resize_edge : uint32_t { + YASL_EDGE_NONE = 0, + 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, +}; + +/* Damage & Framebuffer */ +#define YASL_DAMAGE_MAX 64 + +struct yasl_damage_list { + int n; /* -1 means full repaint */ + struct yasl_rect2i bounds; + struct yasl_rect2i rects[YASL_DAMAGE_MAX]; +}; + +struct yasl_framebuffer { + uint32_t *pixels; + struct yasl_vector2i size; + int buffer; + bool cleared; + struct yasl_damage_list *damage; + void *native_drawable; + bool transaction; +}; + +struct yasl_frame { + struct yasl_surface *surface; + struct yasl_framebuffer target; +}; + +/* Drag and Drop */ +enum yasl_drag_event { + YASL_DRAG_OVER, + YASL_DRAG_LEAVE, + YASL_DRAG_DROP, +}; + +enum yasl_drop_event { + YASL_DROP_OVER, + YASL_DROP_LEAVE, +}; + +enum yasl_drag_end { + YASL_DRAG_DROPPED, + YASL_DRAG_CANCELLED, +}; + +struct yasl_drag_image { + const uint32_t *pixels; + struct yasl_vector2i size; + struct yasl_vector2i hotspot; +}; + +struct yasl_drag_listener { + void (*end)(void *ud, enum yasl_drag_end how); +}; + +struct yasl_geometry { + struct yasl_vector2i size; + uint32_t scale_120; +}; + +/* Input Model */ +enum yasl_key_action { + YASL_KEY_PRESS, + YASL_KEY_RELEASE, + YASL_KEY_REPEAT, +}; + +enum yasl_mod : uint32_t { + YASL_MOD_SHIFT = 1 << 0, + YASL_MOD_ALT = 1 << 1, + YASL_MOD_CTRL = 1 << 2, + YASL_MOD_SUPER = 1 << 3, + YASL_MOD_CAPS = 1 << 4, +}; + +enum yasl_pointer_kind { + YASL_PTR_PRESS, + YASL_PTR_RELEASE, + YASL_PTR_MOTION, + YASL_PTR_LEAVE, + YASL_PTR_SCROLL, +}; + +enum yasl_pointer_device { + YASL_PTR_DEV_MOUSE, + YASL_PTR_DEV_TOUCH, + YASL_PTR_DEV_PEN, + YASL_PTR_DEV_ERASER, +}; + +struct yasl_pointer_pen { + uint16_t pressure; + int8_t tilt_x; + int8_t tilt_y; +}; + +struct yasl_key_event { + uint32_t key; + uint32_t keypad; + enum yasl_key_action action; + uint32_t mods; + uint32_t codepoint; + uint32_t shifted; + uint32_t base; + uint32_t text; +}; + +struct yasl_mouse_event { + struct yasl_vector2i pos; + int button; + enum yasl_pointer_kind kind; + uint32_t mods; + int scroll_lines; + float scroll_delta; + enum yasl_pointer_device device; + struct yasl_pointer_pen pen; +}; + +enum yasl_input_kind { + YASL_INPUT_KEY, + YASL_INPUT_MOUSE, + YASL_INPUT_FOCUS, + YASL_INPUT_PASTE, + YASL_INPUT_DROP_FILES, + YASL_INPUT_TEXT, +}; + +struct yasl_input_event { + enum yasl_input_kind kind; + struct yasl_surface *surface; + union { + struct yasl_key_event key; + struct yasl_mouse_event mouse; + struct { bool focused; } focus; + struct { const char *text; size_t len; } text; + struct { const char *text; size_t len; } paste; + struct { const char *files; size_t len; } drop_files; + }; +}; + +/* Callbacks */ +struct yasl_display_cbs { + void (*quit)(void *ud); + void (*reopen)(void *ud); + void (*lost)(void *ud); +}; + +struct yasl_surface_cbs { + void (*draw)(struct yasl_surface *s, struct yasl_frame *frame, void *ud); + void (*configure)(struct yasl_surface *s, struct yasl_geometry geometry, void *ud); + void (*close)(struct yasl_surface *s, void *ud); + void (*state)(struct yasl_surface *s, uint32_t state, void *ud); + void (*drag)(struct yasl_surface *s, enum yasl_drag_event ev, + struct yasl_vector2i pos, void *ud); + void (*drop)(struct yasl_surface *s, enum yasl_drop_event ev, + struct yasl_vector2i pos, void *ud); +}; + +/* Display Lifecycle */ +struct yasl_display_spec { + const char *app_id; + const struct yasl_display_cbs *cbs; + void *ud; +}; + +YASL_API struct yasl_display *yasl_display_open(struct yasl_loop *loop, + const struct yasl_display_spec *spec); +YASL_API void yasl_display_close(struct yasl_display *d); +YASL_API uint32_t yasl_display_caps(const struct yasl_display *d); +YASL_API void yasl_display_dispatch(struct yasl_display *d); +YASL_API void yasl_display_flush(struct yasl_display *d); +YASL_API int yasl_display_modifiers(const struct yasl_display *d); +YASL_API void yasl_display_copy(struct yasl_display *d, enum yasl_selection sel, const char *text); +YASL_API void yasl_display_paste(struct yasl_display *d, enum yasl_selection sel, struct yasl_surface *target); + +YASL_API bool yasl_display_drag_start(struct yasl_display *d, struct yasl_surface *origin, + const struct yasl_drag_image *image, + const struct yasl_drag_listener *l, void *ud); +YASL_API void yasl_display_drag_cancel(struct yasl_display *d); + +/* Surface Lifecycle */ +struct yasl_surface_spec { + const char *title; + struct yasl_vector2i size; + bool fullscreen; + bool tearing; + void *graphics_device; +}; + +struct yasl_popup_spec { + struct yasl_vector2i size; + struct yasl_rect2i anchor; + bool beside; + struct yasl_vector2i content_offset; + struct yasl_vector2i content_size; +}; + +YASL_API struct yasl_surface *yasl_surface_create_toplevel(struct yasl_display *d, + const struct yasl_surface_spec *spec); +YASL_API struct yasl_surface *yasl_surface_create_popup(struct yasl_surface *parent, + const struct yasl_popup_spec *spec); +YASL_API bool yasl_surface_popup_reposition(struct yasl_surface *popup, + const struct yasl_popup_spec *spec); +YASL_API void yasl_surface_destroy(struct yasl_surface *s); +YASL_API struct yasl_display *yasl_surface_display(const struct yasl_surface *s); + +YASL_API void yasl_surface_set_callbacks(struct yasl_surface *s, + const struct yasl_surface_cbs *cbs, void *ud); +YASL_API void yasl_surface_set_title(struct yasl_surface *s, const char *title); +YASL_API void yasl_surface_schedule_redraw(struct yasl_surface *s); +YASL_API bool yasl_surface_present(struct yasl_surface *s, const struct yasl_framebuffer *fb, + const struct yasl_damage_list *damage); +YASL_API bool yasl_surface_input_poll(struct yasl_surface *s, struct yasl_input_event *ev); + +YASL_API struct yasl_vector2i yasl_surface_size(const struct yasl_surface *s); +YASL_API uint32_t yasl_surface_scale_120(const struct yasl_surface *s); +YASL_API uint32_t yasl_surface_state(const struct yasl_surface *s); +YASL_API struct yasl_timing yasl_surface_timing(const struct yasl_surface *s); +YASL_API uint64_t yasl_surface_frame_time_ns(struct yasl_surface *s, uint64_t now); +YASL_API void yasl_surface_set_cursor(struct yasl_surface *s, enum yasl_cursor cursor); +YASL_API void yasl_surface_set_background_color(struct yasl_surface *s, uint32_t bg); + +/* IME Support */ +YASL_API const char *yasl_surface_ime_preedit(const struct yasl_surface *s); +YASL_API bool yasl_surface_ime_preedit_cursor(const struct yasl_surface *s, int *begin, int *end); +YASL_API void yasl_surface_set_ime_caret(struct yasl_surface *s, struct yasl_rect2i caret); + +/* Client-Side Decorations (CSD) Actions */ +YASL_API bool yasl_surface_start_interactive_move(struct yasl_surface *s); +YASL_API bool yasl_surface_start_interactive_resize(struct yasl_surface *s, enum yasl_resize_edge edge); +YASL_API bool yasl_surface_show_window_menu(struct yasl_surface *s, struct yasl_vector2i pos); + +/* Drag Support */ +YASL_API bool yasl_surface_drag_carry(struct yasl_surface *s, struct yasl_vector2i offset); +YASL_API bool yasl_surface_place_under_pointer(struct yasl_surface *s, struct yasl_vector2i at); + +/* Native Interoperability Handles */ +YASL_API void *yasl_display_get_native_handle(struct yasl_display *d); +YASL_API void *yasl_surface_get_native_handle(struct yasl_surface *s); + +/* Integrated Event Loop */ +YASL_API struct yasl_loop *yasl_loop_create(void); +YASL_API void yasl_loop_destroy(struct yasl_loop *l); +YASL_API int yasl_loop_run(struct yasl_loop *l); +YASL_API void yasl_loop_quit(struct yasl_loop *l); +YASL_API void yasl_loop_kick(struct yasl_loop *l); +YASL_API uint64_t yasl_loop_now_ns(void); +YASL_API int yasl_loop_add_fd(struct yasl_loop *l, int fd, short events, + int (*fn)(int fd, short revents, void *ud), void *ud); +YASL_API int yasl_loop_del_fd(struct yasl_loop *l, int id); +YASL_API int yasl_loop_set_fd_events(struct yasl_loop *l, int id, short events); + +#ifdef __cplusplus +} +#endif + +#endif /* YASL_H */ |
