#ifndef YASL_H #define YASL_H #include #include #include #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 int yasl_display_dispatch_timeout(struct yasl_display *d, int timeout_ms); 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 int yasl_loop_step(struct yasl_loop *l, int timeout_ms); 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 */