summaryrefslogtreecommitdiff
path: root/include/yasl
diff options
context:
space:
mode:
Diffstat (limited to 'include/yasl')
-rw-r--r--include/yasl/timing.h51
-rw-r--r--include/yasl/yasl.h358
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 */