Global Namespace

Overview

// typedefs

typedef int (*shell_widget_draw_label_t)(
    struct shell_widget *,
    struct shell_widget_label *
    );

typedef int (*shell_widget_setup_cb_t)(struct shell_widget *);

typedef int (*shell_widget_path_find_t)(
    struct shell_widget *,
    char *path
    );

typedef void (*tw_xdg_layout_fun_t)(
    const enum tw_xdg_layout_command command,
    const struct tw_xdg_layout_op *arg,
    struct tw_xdg_view *v,
    struct tw_xdg_layout *l,
    struct tw_xdg_layout_op *ops
    );

typedef bool (*tw_key_binding)(
    struct tw_keyboard *keyboard,
    uint32_t time,
    uint32_t key,
    uint32_t mods,
    uint32_t option,
    void *data
    );

typedef bool (*tw_btn_binding)(
    struct tw_pointer *pointer,
    uint32_t time_msec,
    uint32_t btn,
    uint32_t mods,
    void *data
    );

typedef bool (*tw_axis_binding)(
    struct tw_pointer *pointer,
    uint32_t time,
    double delta,
    enum wl_pointer_axis direction,
    uint32_t mods,
    void *data
    );

typedef bool (*tw_touch_binding)(
    struct tw_touch *touch,
    uint32_t time,
    uint32_t mods,
    void *data
    );

typedef hash_cmp_val (*hash_cmp_func_t)(
    const void *a,
    const void *intable
    );

typedef uint64_t (*hash_func_t)(const void *addr);
typedef struct dhash_table dhashtab_t;

typedef hash_cmp_val (*hash_cmp_func_t)(
    const void *a,
    const void *intable
    );

typedef uint64_t (*hash_func_t)(const void *addr);
typedef struct dhash_table dhashtab_t;

typedef int (*cmpfun)(
    const void *elemAddr1,
    const void *elemAddr2
    );

typedef void (*freefun)(void *elemAddr);

typedef void (*VecMapF)(
    void *elemAddr,
    void *auxData
    );

typedef int (*cmpfun)(
    const void *elemAddr1,
    const void *elemAddr2
    );

typedef void (*freefun)(void *elemAddr);

typedef void (*VecMapF)(
    void *elemAddr,
    void *auxData
    );

typedef struct list_t list_t;
typedef struct list_t list_t;
typedef int (*tdbus_read_signal_f)(const struct tdbus_signal *);
typedef int (*tdbus_read_call_f)(const struct tdbus_method_call *);
typedef int (*tdbus_read_reply_f)(const struct tdbus_reply *);

typedef void (*tdbus_add_watch_f)(
    void *user_data,
    int unix_fd,
    struct tdbus *bus,
    uint32_t mask,
    void *watch_data
    );

typedef void (*tdbus_ch_watch_f)(
    void *user_data,
    int unix_fd,
    struct tdbus *bus,
    uint32_t mask,
    void *watch_data
    );

typedef void (*tdbus_rm_watch_f)(
    void *user_data,
    int unix_fd,
    struct tdbus *bus,
    void *watch_data
    );

typedef void (*nk_wl_drawcall_t)(
    struct nk_context *ctx,
    float width,
    float height,
    struct tw_appsurf *app
    );

typedef const char* app_mime[TW_MIME_TYPE_MAX];

typedef void (*frame_t)(
    struct tw_appsurf *,
    const struct tw_app_event *e
    );

typedef void (*shm_buffer_draw_t)(
    struct tw_appsurf *surf,
    struct wl_buffer *buffer,
    struct tw_bbox *geo
    );

typedef void (*eglwin_draw_t)(
    struct tw_appsurf *surf,
    struct tw_bbox *geo
    );

typedef void (*tw_surface_commit_cb_t)(struct tw_surface *surface);

// enums

enum POINTER_EVENT_CODE;
enum TDBUS_TYPE;
enum TW_KEYBOARD_LED;
enum TW_KEYBOARD_MODIFIER;
enum TW_LOG_LEVEL;
enum console_icon_type;
enum hash_cmp_val;
enum hash_cmp_val;
enum icon_section_type;
enum icon_type;
enum nk_wl_font_slant;
enum taiwins_modifier_mask;
enum tdbus_arg_type;
enum tdbus_event_mask;
enum tdbus_message_type;
enum tw_app_event_type;
enum tw_appsurf_flag;
enum tw_appsurf_mime_type;
enum tw_appsurf_type;
enum tw_backend_event_type;
enum tw_binding_type;
enum tw_builtin_binding_t;
enum tw_config_enable_global;
enum tw_desktop_init_option;
enum tw_desktop_surface_tiled_state;
enum tw_desktop_surface_type;
enum tw_dmabuf_attributes_flags;
enum tw_event_op;
enum tw_gl_stage_option;
enum tw_input_device_cap;
enum tw_layer_pos;
enum tw_layout_type;
enum tw_shell_ui_anchor_pos;
enum tw_surface_state;
enum tw_xdg_layout_command;
enum tw_xdg_view_resize_option;
enum tw_xdg_view_state;
enum xdg_app_section_type;

// structs

struct _tdbus_message_itr;
struct anonymous_buff_t;
struct app_module_data;
struct auth_buffer;
struct battery_widget_data;
struct buff_list_t;
struct char_map;
struct clock_user_data_t;
struct console_icon_key;
struct console_module;
struct console_search_entry_t;
struct cstack_t;
struct data_offer_data;
struct data_source;
struct desktop_console;
struct desktop_shell;
struct dhash_table;
struct event_map;
struct gles_debug_procs;
struct icon_cache_config;
struct icon_cache_option;
struct icon_dir;
struct icontheme_dir;
struct image_cache;
struct list_t;
struct module_search_cache;
struct nk_wl_font_config;
struct queue_t;
struct selected_search_entry;
struct shell_config;
struct shell_notif;
struct shell_output;
struct shell_widget;
struct shell_widget_label;
struct shell_widget_runtime;
struct size_state;
struct tdbus;
struct tdbus_array;
struct tdbus_call_answer;
struct tdbus_message;
struct tdbus_message_arg;
struct tdbus_message_itr;
struct tdbus_method_call;
struct tdbus_method_record;
struct tdbus_reply;
struct tdbus_signal;
struct tdbus_signal_match;
struct tdbus_str;
struct tdbus_timeout_record;
struct tiling_output;
struct tiling_user_data;
struct tiling_view;
struct tw_app_event;
struct tw_app_event_container;
struct tw_app_event_filter;
struct tw_appsurf;
struct tw_axis_motion;
struct tw_backend;
struct tw_backend_impl;
struct tw_backend_output;
struct tw_backend_output_mode;
struct tw_backend_seat;
struct tw_bbox;
struct tw_binding;
struct tw_binding_node;
struct tw_bindings;
struct tw_btn_press;
struct tw_bus;
struct tw_compositor;
struct tw_config;
struct tw_config_obj;
struct tw_config_output;
struct tw_config_table;
struct tw_config_transform_t;
struct tw_console;
struct tw_cursor;
struct tw_cursor_constrain;
struct tw_data_device;
struct tw_data_device_manager;
struct tw_data_drag;
struct tw_data_offer;
struct tw_data_source;
struct tw_decision_key;
struct tw_desktop_manager;
struct tw_desktop_surface;
struct tw_desktop_surface_api;
struct tw_dmabuf_attributes;
struct tw_dmabuf_buffer;
struct tw_egl_env;
struct tw_event;
struct tw_event_buffer_uploading;
struct tw_event_get_wl_subsurface;
struct tw_event_new_cursor;
struct tw_event_new_wl_region;
struct tw_event_new_wl_surface;
struct tw_event_queue;
struct tw_event_source;
struct tw_event_surface_frame;
struct tw_fb_texture;
struct tw_gl_stage;
struct tw_gl_texture;
struct tw_globals;
struct tw_key_press;
struct tw_keyboard;
struct tw_keyboard_grab_interface;
struct tw_layer;
struct tw_layer_renderer;
struct tw_layers_manager;
struct tw_linux_dmabuf;
struct tw_mat3;
struct tw_mat4;
struct tw_menu_item;
struct tw_observer;
struct tw_options;
struct tw_output;
struct tw_plane;
struct tw_point2d;
struct tw_pointer;
struct tw_pointer_grab_interface;
struct tw_popup_grab;
struct tw_presentation;
struct tw_presentation_feedback;
struct tw_profiler;
struct tw_profiler_scope;
struct tw_quad_color_shader;
struct tw_quad_tex_shader;
struct tw_region;
struct tw_render_texture;
struct tw_renderer;
struct tw_seat;
struct tw_seat_client;
struct tw_seat_events;
struct tw_seat_keyboard_grab;
struct tw_seat_pointer_grab;
struct tw_seat_touch_grab;
struct tw_server;
struct tw_shell;
struct tw_shell_output;
struct tw_shell_ui;
struct tw_shm_pool;
struct tw_signal;
struct tw_subprocess;
struct tw_subsurface;
struct tw_surface;
struct tw_surface_buffer;
struct tw_surface_manager;
struct tw_theme_color;
struct tw_theme_default;
struct tw_theme_global;
struct tw_touch;
struct tw_touch_action;
struct tw_touch_grab_interface;
struct tw_vec3;
struct tw_view;
struct tw_viewport;
struct tw_viewporter;
struct tw_window_brief;
struct tw_wl_shell_surface;
struct tw_workspace;
struct tw_xdg;
struct tw_xdg_grab_interface;
struct tw_xdg_layout;
struct tw_xdg_layout_op;
struct tw_xdg_output;
struct tw_xdg_output_info_event;
struct tw_xdg_output_manager;
struct tw_xdg_positioner;
struct tw_xdg_surface;
struct tw_xdg_view;
struct tw_xwayland;
struct vector_t;
struct vtree_node;
struct widget_colors;
struct widget_launch_info;
struct wl_buffer_node;
struct xdg_app_entry;

// unions

union tdbus_arg_value;

// global variables

static struct tw_app_event_filter console_key_filter = {     .intercept = suspend_console_on_esc,    .type = TW_KEY_BTN,   .link.prev =&console_key_filter.link,   .link.next =&console_key_filter.link, };
struct taiwins_console_listener console_impl = {   .application_configure = update_app_config,     .start = start_console,     .exec = exec_application, };
static const struct taiwins_theme_listener theme_impl = {  .theme = console_apply_theme,   .cursor = console_apply_cursor, };
static struct wl_registry_listener registry_listener = {   .global = announce_globals,     .global_remove = announce_global_remove };
static struct tw_console s_console;
static struct taiwins_console_interface console_impl = {   .launch = set_console,  .submit = close_console };
struct console_module cmd_module;
struct console_module path_module;
struct console_module app_module;
static struct app_module_data module_data = {0};
struct console_module app_module = {  .name = "MODULE_APP",   .exec = xdg_app_module_exec,    .search = xdg_app_module_search,    .init_hook = xdg_app_module_init,   .destroy_hook = xdg_app_module_destroy,     .filter_test = xdg_app_filter,  .support_cache = true,  .supported_icons = CONSOLE_ICON_APP | CONSOLE_ICON_MIME,  .user_data =&module_data, };
struct console_module cmd_module = {  .name = "MODULE_CMD",   .filter_test = console_cmd_module_filter_test,  .exec = console_cmd_module_exec,    .search = console_cmd_module_search,    .init_hook = console_cmd_module_init,   .destroy_hook = console_cmd_module_destroy,     .supported_icons = CONSOLE_ICON_MIME,    .support_cache = true, };
struct console_module path_module = {    .name = "MODULE_PATH",  .exec = console_path_module_exec,   .search = console_path_module_search,   .support_cache = true, };
static struct taiwins_shell_listener tw_shell_impl = {     .output_configure = desktop_shell_output_configure,     .client_msg = desktop_shell_recv_msg, };
static const struct nk_wl_font_config icon_config = {  .name = "icons",    .slant = NK_WL_SLANT_ROMAN,    .pix_size = 16,     .scale = 1,   .TTFonly = false, };
static const struct taiwins_theme_listener tw_theme_impl = {   .theme = desktop_shell_apply_theme,     .cursor = desktop_shell_apply_cursor, };
static struct wl_registry_listener registry_listener = {   .global = announce_globals,     .global_remove = announce_global_remove };
static struct tw_shell s_shell = {0};
static const struct taiwins_ui_interface tw_ui_impl = {  .destroy = shell_ui_destroy_resource, };
static struct taiwins_shell_interface shell_impl = {     .create_panel = create_shell_panel,     .create_background = create_shell_background,   .create_locker = create_shell_locker,   .launch_widget = launch_shell_widget,   .server_msg = recv_client_msg, };
static struct auth_buffer AUTH;
static struct tw_menu_item shell_default_menu[] = {  {       .endnode.title = "Application",         .has_submenu = true,        .len = 0,   },  {       .endnode.title = "System",      .has_submenu = true,        .len = 1,   },  {       .endnode.title = "Reconfigure",         .has_submenu = false,   }, };
static struct shell_widget menu_widget = {     .w = 120,   .h = 110,   .draw_cb = shell_draw_menu, };
struct shell_widget notification_widget = {    .w = 200,   .h = 40,    .draw_cb = shell_draw_notif, };
static struct taiwins_ui_listener widget_impl = {   .close = widget_should_close, };
static const char* usage =    "usage: taiwins_update_icon_cache [OPTION...]\n"    "\n"    "Help option:\n"    "  --help\t\t\tshow help\n"     "\n"    "Application options:\n"    "  -f, --force\t\t\tIgnore the existing cache\n"    "  -h, --hires\t\t\tSpecify the highest resolution to sample, maximum 256, default 128\n"   "  -l, --lowres\t\t\tSpecify the lowest resolution to sample, minimum 32, default 32\n"     "  -t, --theme\t\t\tSepcify the theme to update, default all\n"     "  -u, --updates\t\t\tSpecify the update list in(apps,mimes,places,status,devices). default all\n"  "\n";
static const char* hicolor_path = "/usr/share/icons/hicolor";
static struct battery_widget_data battery_sys_files = {   .energy_now = "\0",     .energy_full = "\0",    .charging = "\0", };
struct shell_widget battery_widget = {   .ancre_cb = battery_anchor,     .draw_cb = NULL,    .w = 200,   .h = 150,   .path_find = battery_sysfile_find,  .user_data =&battery_sys_files,     .interval = {{0}, {0}},     .file_path = NULL,  };
static const char* MONTHS[] = {     "January", "Feburary", "March", "April",    "May", "June", "July", "August",    "September", "October", "November", "December", };
static const char* WEEKDAYS[] = {   "S", "M", "T", "W", "T", "F", "S", };
static struct clock_user_data_t clock_user_data;
struct shell_widget clock_widget = {   .ancre_cb = clock_widget_anchor,    .setup_cb = clock_setup,    .draw_cb = calendar,    .w = 200,   .h = 200,   .interval = {       .it_value = {           .tv_sec = 1,            .tv_nsec = 0,       },      .it_interval = {            .tv_sec = 1,            .tv_nsec = 0,       },  },  .file_path = NULL,  .user_data =&clock_user_data, };
struct shell_widget clock_widget;
struct shell_widget what_up_widget = {    .ancre_cb = whatup_ancre,   .draw_cb = NULL,    .w = 200,   .h = 150,   .path_find = NULL,  .interval = {{0},{0}},  .file_path = NULL, };
struct shell_widget battery_widget;
type __pad0__;
type value;
type description;
type type;
type choices;
type damage;
type clip;
static struct tw_backend s_tw_backend = {0};
static struct tw_backend_impl s_tw_backend_impl;
static const uint32_t TW_CONFIG_GLOBAL_DEFAULT =   TW_CONFIG_GLOBAL_BUS |     TW_CONFIG_GLOBAL_TAIWINS_SHELL |   TW_CONFIG_GLOBAL_TAIWINS_CONSOLE |     TW_CONFIG_GLOBAL_TAIWINS_THEME |   TW_CONFIG_GLOBAL_LAYER_SHELL |     TW_CONFIG_GLOBAL_XWAYLAND |    TW_CONFIG_GLOBAL_DESKTOP;
static struct tw_bus s_bus;
static struct tdbus_call_answer tw_bus_answer = {  .interface = "org.taiwins.example",     .method = "Hello",  .in_signature = "s",    .out_signature = "s",   .reader = tw_bus_read_request, };
static tw_config_transform_t TRANSFORMS[] = {     {0, false, WL_OUTPUT_TRANSFORM_NORMAL},     {90, false, WL_OUTPUT_TRANSFORM_90},    {180, false, WL_OUTPUT_TRANSFORM_180},  {270, false, WL_OUTPUT_TRANSFORM_270},  {0, true, WL_OUTPUT_TRANSFORM_FLIPPED},     {90, true, WL_OUTPUT_TRANSFORM_FLIPPED_90},     {180, true, WL_OUTPUT_TRANSFORM_FLIPPED_180},   {270, true, WL_OUTPUT_TRANSFORM_FLIPPED_270}, };
static const struct event_map modifiers_map[] = {    {"C", TW_MODIFIER_CTRL},  {"Ctrl",  TW_MODIFIER_CTRL},  {"M", TW_MODIFIER_ALT},   {"Alt",   TW_MODIFIER_ALT},   {"s", TW_MODIFIER_SUPER}, {"Super", TW_MODIFIER_SUPER},     {"S", TW_MODIFIER_SHIFT}, {"Shift", TW_MODIFIER_SHIFT}, };
static const struct event_map special_keys_table[] = {       {"F1", KEY_F1}, {"F2", KEY_F2}, {"F3", KEY_F3},     {"F4", KEY_F4}, {"F5", KEY_F5}, {"F6", KEY_F6},     {"F7", KEY_F7}, {"F8", KEY_F8}, {"F9", KEY_F9},     {"F10", KEY_F10}, {"F11", KEY_F11}, {"F12", KEY_F12},       {"enter", KEY_ENTER}, {"minus", KEY_MINUS},     {"del", KEY_DELETE}, {"home", KEY_HOME},    {"end", KEY_END}, {"pgup", KEY_PAGEUP},     {"pgdn", KEY_PAGEDOWN},     {"pause", KEY_PAUSE}, {"break", KEY_BREAK},     {"scrlk", KEY_SCROLLLOCK}, {"insert", KEY_INSERT},  {"prtsc", KEY_RESERVED},        {"left", KEY_LEFT}, {"right", KEY_RIGHT},   {"up", KEY_UP}, {"down", KEY_DOWN},     {"mute", KEY_MUTE}, {"volume_dn", KEY_VOLUMEDOWN},  {"volume_up", KEY_VOLUMEUP},    {"bn_up", KEY_BRIGHTNESSUP}, {"bn_dn", KEY_BRIGHTNESSDOWN},     {"bs", KEY_BACKSPACE}, {"tab", KEY_TAB}, };
static const struct event_map btns_table[] = {       {"btn_l", BTN_LEFT}, {"btn_r", BTN_RIGHT},  {"btn_m", BTN_MIDDLE}, };
static const struct event_map axis_table[] = {   {"axis_x", WL_POINTER_AXIS_HORIZONTAL_SCROLL},  {"axis_y", WL_POINTER_AXIS_VERTICAL_SCROLL}, };
static struct char_map chars_table[];
static const uint32_t TILINT_STATE =   TW_XDG_VIEW_TILED_LEFT | TW_XDG_VIEW_TILED_RIGHT |    TW_XDG_VIEW_TILED_TOP | TW_XDG_VIEW_TILED_BOTTOM;
static struct tw_xdg s_desktop = {0};
static const struct tw_desktop_surface_api desktop_impl =  {     .ping_timeout = twdesk_ping_timeout,    .pong = twdesk_pong,    .surface_added = twdesk_surface_added,  .surface_removed = twdesk_surface_removed,  .committed = twdesk_surface_committed,  .set_parent = twdesk_set_parent,    .show_window_menu = twdesk_surface_show_window_menu,    .move = twdesk_surface_move,    .resize = twdesk_surface_resize,    .fullscreen_requested = twdesk_fullscreen,  .maximized_requested = twdesk_maximized,    .minimized_requested = twdesk_minimized, };
static const struct tw_pointer_grab_interface move_pointer_grab_impl = {    .motion = handle_move_pointer_grab_motion,  .button = handle_move_pointer_grab_button,  .cancel = handle_move_pointer_grab_cancel, };
static const struct tw_pointer_grab_interface resize_pointer_grab_impl = {  .motion = handle_resize_pointer_grab_motion,    .button = handle_move_pointer_grab_button,      .cancel = handle_move_pointer_grab_cancel,  };
static const struct tw_keyboard_grab_interface task_switching_impl = {     .key = handle_task_switching_key,   .modifiers = handle_task_switching_modifiers,   .cancel = handle_task_switching_cancel, };
static const struct tw_keyboard_grab_interface keybinding_impl = {     .key = binding_key,     .cancel = binding_key_cancel, };
static const struct tw_pointer_grab_interface pointer_impl = {  .button = binding_btn,  .axis = binding_axis,   .cancel = binding_pointer_cancel, };
static const struct tw_touch_grab_interface touch_impl = {    .down = binding_touch,  .cancel = binding_touch_cancel, };
static const struct tw_keyboard_grab_interface session_switch_impl = {     .key = session_switch_key, };
static const EGLint gles3_config_attribs[] = {   EGL_SURFACE_TYPE, EGL_WINDOW_BIT,   EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT,    EGL_NONE, };
static const EGLint gles2_config_attribs[] = {   EGL_SURFACE_TYPE, EGL_WINDOW_BIT,   EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,    EGL_NONE, };
static const struct wlr_renderer_impl tw_renderer_wlr_impl = {   .begin = base_begin,    .end = base_end,    .clear = base_clear,    .scissor = base_scissor,    .render_texture_with_matrix = noop_render_texture_with_matrix,  .render_quad_with_matrix = noop_render_quad_with_matrix,    .render_ellipse_with_matrix = noop_render_ellipse_with_matrix,  .formats = base_formats,    .format_supported = base_format_supported,  .texture_from_pixels = noop_texture_from_pixels,    .init_wl_display = base_init_wl_display, };
static struct gles_debug_procs s_gles_debug_procs;
static const GLchar quad_vs[] =   "uniform mat3 proj;\n"  "uniform vec4 color;\n"     "attribute vec2 pos;\n"     "attribute vec2 texcoord;\n"    "varying vec4 o_color;\n"   "varying vec2 o_texcoord;\n"    "\n"    "void main() {\n"   "   gl_Position = vec4(proj* vec3(pos, 1.0), 1.0);\n"   "   o_color = color;\n"     "   o_texcoord = texcoord;\n"   "}\n";
static const GLchar color_quad_fs[] =     "precision mediump float;\n"    "uniform float alpha;\n"    "varying vec4 o_color;\n"   "varying vec2 o_texcoord;\n"    "\n"    "void main() {\n"   "   gl_FragColor = o_color* alpha;\n"   "}\n"   "\n";
static const GLchar tex_quad_fs[] =   "precision mediump float;\n"    "uniform float alpha;\n"    "uniform sampler2D tex;\n"  "varying vec4 o_color;\n"   "varying vec2 o_texcoord;\n"    "\n"    "void main() {\n"   "   gl_FragColor = texture2D(tex, o_texcoord)* alpha;\n"    "}\n"   "\n";
const GLchar tex_quad_ext_fs[] =  "#extension GL_OES_EGL_image_external : require\n\n"    "precision mediump float;\n"    "varying vec4 o_color;\n"   "varying vec2 o_texcoord;\n"    "uniform samplerExternalOES tex;\n"     "uniform float alpha;\n"    "\n"    "void main() {\n"   "   gl_FragColor = texture2D(tex, o_texcoord)* alpha;\n"    "}\n";
static const GLchar tex_gaussian_fs[] =   "precision mediump float;\n"    "uniform float alpha;\n"    "uniform sampler2D tex;\n"  "uniform vec2 texsize;\n"   "varying vec4 o_color;\n"   "varying vec2 o_texcoord;\n"    "\n"    "float gaussian_kernel(int x, int y) {\n"   "   mat3 kernel = mat3(\n"  "           1.0/16.0, 1.0/8.0, 1.0/16.0,\n"     "           1.0/8.0, 1.0/4.0, 1.0/8.0,\n"   "           1.0/16.0, 1.0/8.0, 1.0/16.0);\n"    "   return kernel[x+1][y+1];\n"     "}\n"   "\n"    "void main() {\n"   "   vec2 step = vec2(1.0/texsize.x, 1.0/texsize.y);\n"  "   vec4 color = vec4(0.0f);\n"     "   for(int i = -1; i<= 1; i++) {\n"    "       for(int j = -1; j<= 1; j++) {\n"    "           vec2 coord = vec2(o_texcoord.x+i*step.x, \n"    "                             o_texcoord.y+j*step.y);\n"    "           color += gaussian_kernel(i,j)* \n"  "               texture2D(tex, coord);\n"   "       }\n"    "   }\n"    "   gl_FragColor = color* alpha;\n"     "}\n"   "\n";
static const struct zwlr_layer_shell_v1_interface layer_shell_impl = {   .get_layer_surface = layer_shell_handle_get_layer_surface, };
static const struct zwlr_layer_surface_v1_interface layer_surface_impl = {   .destroy = resource_handle_destroy,     .ack_configure = layer_surface_handle_ack_configure,    .set_size = layer_surface_handle_set_size,  .set_anchor = layer_surface_handle_set_anchor,  .set_exclusive_zone = layer_surface_handle_set_exclusive_zone,  .set_margin = layer_surface_handle_set_margin,  .set_keyboard_interactivity = layer_surface_set_keyboard_interactivity,     .get_popup = layer_surface_handle_get_popup,    .set_layer = layer_surface_set_layer, };
struct tw_theme_global THEME;
static const struct tw_theme_color taiwins_default_theme;
static struct tw_xwayland s_xwayland;
char app_name[128];
bool floating;
int scale;
struct tw_window_brief __attribute__;
static struct wl_buffer_listener buffer_listener = {    .release = wl_buffer_release_notify };
static const DBusObjectPathVTable server_vtable = {     .message_function = tdbus_server_handle_method,     .unregister_function = tdbus_server_unregister, };
static const struct wl_callback_listener tw_appsurf_wl_frame_impl = {     .done = tw_appsurf_frame_done, };
static const struct wl_callback_listener tw_appsurf_frame_event_impl = {  .done = tw_appsurf_run_frame_event, };
static struct wl_shm_listener shm_listener = {     shm_format };
static struct wl_seat_listener seat_listener = {   .capabilities = seat_capabilities,  .name = seat_name, };
static struct wl_data_offer_listener data_offer_listener = {   .offer = data_offer_offered,    .source_actions = data_offer_source_actions,    .action = data_offer_action, };
static struct wl_data_device_listener data_device_listener = {     .data_offer = data_offer,   .enter = data_enter,    .leave = data_leave,    .motion = data_motion,  .drop = data_drop,  .selection = data_selection, };
static struct wl_data_source_listener data_source_listener = {    .target = data_source_target,   .send = data_source_send,   .cancelled = data_source_cancelled,     .dnd_drop_performed = data_source_dnd_drop_performed,   .dnd_finished = data_source_dnd_finished,   .action = data_source_action, };
static const struct wl_data_source_interface data_source_impl = {  .offer = data_source_offer,     .destroy = data_source_destroy,     .set_actions = data_source_set_actions, };
static const EGLint egl_context_attribs[] = {     EGL_CONTEXT_MAJOR_VERSION, 3,   EGL_CONTEXT_MINOR_VERSION, 3,   EGL_CONTEXT_OPENGL_PROFILE_MASK, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,   EGL_NONE, };
static struct udev* UDEV = NULL;
static struct wl_keyboard_listener keyboard_listener = {     .key = handle_key,  .modifiers = handle_modifiers,  .enter = handle_keyboard_enter,     .leave = handle_keyboard_leave,     .keymap = handle_keymap,    .repeat_info = handle_repeat_info,  };
static struct wl_pointer_listener pointer_listener = {0};
static struct wl_touch_listener touch_listener = {    .down = handle_touch_down,  .up = handle_touch_up,  .motion = handle_touch_motion,  .frame = handle_touch_frame,    .cancel = handle_touch_cancel,  .shape = handle_touch_shape,    .orientation = handle_touch_orientation, };
static struct tw_compositor s_tw_compositor = {0};
static const struct wl_subcompositor_interface subcompositor_impl = {  .destroy = destroy_wl_subcompositor,    .get_subsurface = get_wl_subsurface, };
static const struct wl_compositor_interface compositor_impl = {    .create_surface = create_wl_surface,    .create_region = create_wl_region, };
static struct tw_data_device_manager s_tw_data_device_manager;
static const struct wl_data_device_interface data_device_impl = {    .start_drag = data_device_start_drag,   .set_selection = data_device_set_selection,     .release = data_device_release, };
static const struct wl_data_device_manager_interface data_device_manager_impl = {    .create_data_source = create_data_source,   .get_data_device = get_data_device, };
static const struct tw_pointer_grab_interface dnd_pointer_grab_impl = {     .enter = dnd_pointer_enter,     .motion = dnd_pointer_motion,   .button = dnd_pointer_button,   .cancel = dnd_pointer_cancel, };
static const struct tw_keyboard_grab_interface dnd_keyboard_grab_impl = {  .enter = dnd_keyboard_enter, };
static const struct wl_data_offer_interface data_offer_impl = {   .accept = data_offer_accept,    .receive = data_offer_receive,  .destroy = data_offer_handle_destroy,   .finish = data_offer_finish,    .set_actions = data_offer_set_actions, };
static const char* TW_DESKTOP_TOPLEVEL_WL_SHELL_NAME = "wl_shell_toplevel";
static const char* TW_DESKTOP_POPUP_WL_SHELL_NAME = "wl_shell_popup";
static const char* TW_DESKTOP_TRANSIENT_WL_SHELL_NAME = "wl_shell_transient";
static const struct wl_shell_surface_interface wl_shell_surf_impl = {  .pong = handle_surface_pong,    .move = handle_surface_move,    .resize = handle_surface_resize,    .set_toplevel = handle_set_toplevel,    .set_transient = handle_set_transient,  .set_fullscreen = handle_set_fullscreen,    .set_popup = handle_set_popup,  .set_maximized = handle_set_maximized,  .set_title = handle_set_title,  .set_class = handle_set_class, };
static const struct wl_shell_interface wl_shell_impl = {   .get_shell_surface = handle_get_wl_shell_surface, };
static const struct xdg_surface_interface xdg_surface_impl = {    .destroy = handle_destroy_xdg_surface,  .get_toplevel = handle_get_toplevel,    .get_popup = handle_get_popup,  .set_window_geometry = handle_set_window_geometry,  .ack_configure = handle_ack_configure, };
static const char* XDG_TOPLEVEL_ROLE_NAME = "XDG_TOPLEVEL";
static const char* XDG_POPUP_ROLE_NAME = "XDG_POPUP";
static const struct xdg_toplevel_interface toplevel_impl = {  .destroy = handle_toplevel_destroy,     .set_parent = handle_toplevel_set_parent,   .set_title = handle_toplevel_set_title,     .set_app_id = handle_toplevel_set_app_id,   .show_window_menu = handle_toplevel_show_window_menu,   .move = handle_toplevel_move,   .resize = handle_toplevel_resize,   .set_max_size = handle_toplevel_set_max_size,   .set_min_size = handle_toplevel_set_min_size,   .set_maximized = handle_toplevel_set_maximized,     .unset_maximized = handle_toplevel_unset_maximized,     .set_fullscreen = handle_toplevel_set_fullscreen,   .unset_fullscreen = handle_toplevel_unset_fullscreen,   .set_minimized = handle_toplevel_minimize, };
static const struct xdg_popup_interface popup_impl = {    .destroy = handle_popup_destroy,    .grab = handle_popup_grab,  .reposition = handle_popup_reposition, };
static const struct xdg_positioner_interface xdg_positioner_impl = {  .destroy = handle_positioner_destroy,   .set_size = handle_positioner_set_size,     .set_anchor_rect = handle_positioner_set_anchor_rect,   .set_anchor = handle_positioner_set_anchor,     .set_gravity = handle_positioner_set_gravity,   .set_constraint_adjustment = handle_positioner_constraint_adjustment,   .set_reactive = handle_positioner_set_reactive,     .set_offset = handle_positioner_set_offset,     .set_parent_size = handle_positioner_set_parent_size,   .set_parent_configure = handle_positioner_set_parent_configure, };
static struct xdg_wm_base_interface xdg_wm_base_impl = {  .destroy = handle_destroy_wm_base,  .create_positioner = handle_create_positioner,  .get_xdg_surface = handle_create_xdg_surface,   .pong = handle_pong, };
static const struct zwp_linux_buffer_params_v1_interface buffer_params_impl = {    .destroy = buffer_params_destroy_resource,  .add = buffer_params_add,   .create = buffer_params_create,     .create_immed = buffer_params_create_immed, };
static struct tw_linux_dmabuf s_tw_linux_dmabuf = {0};
static const struct wl_buffer_interface wl_buffer_impl = {     .destroy = buffer_destroy, };
static const struct zwp_linux_dmabuf_v1_interface dmabuf_v1_impl = {   .destroy = linux_dmabuf_destroy,    .create_params = linux_dmabuf_create_params, };
static struct tw_layers_manager s_layers_manager = {0};
static FILE* tw_logfile = NULL;
static const struct tw_mat3 transform_2ds[8];
static enum wl_output_transform transform_yup_to_ydown[8] = {  [WL_OUTPUT_TRANSFORM_NORMAL] = WL_OUTPUT_TRANSFORM_NORMAL,  [WL_OUTPUT_TRANSFORM_90] = WL_OUTPUT_TRANSFORM_270,     [WL_OUTPUT_TRANSFORM_180] = WL_OUTPUT_TRANSFORM_180,    [WL_OUTPUT_TRANSFORM_270] = WL_OUTPUT_TRANSFORM_90,     [WL_OUTPUT_TRANSFORM_FLIPPED] = WL_OUTPUT_TRANSFORM_FLIPPED,    [WL_OUTPUT_TRANSFORM_FLIPPED_90] = WL_OUTPUT_TRANSFORM_FLIPPED_270,     [WL_OUTPUT_TRANSFORM_FLIPPED_180] = WL_OUTPUT_TRANSFORM_FLIPPED_180,    [WL_OUTPUT_TRANSFORM_FLIPPED_270] = WL_OUTPUT_TRANSFORM_FLIPPED_90 };
static const struct wl_output_interface output_impl = {    .release = handle_output_release, };
static const struct tw_pointer_grab_interface popup_pointer_grab_impl = {     .enter = popup_pointer_grab_enter,  .motion = popup_pointer_grab_motion,    .button = popup_pointer_grab_button,    .axis = popup_pointer_grab_axis,    .frame = popup_pointer_grab_frame,  .cancel = popup_pointer_grab_cancel, };
static const struct tw_touch_grab_interface popup_touch_grab_impl = {   .down = popup_touch_grab_down,  .up = popup_touch_grab_up,  .motion = popup_touch_grab_motion,  .enter = popup_touch_grab_enter,    .touch_cancel = popup_touch_grab_touch_cancel,  .cancel = popup_touch_grab_cancel, };
static const struct wp_presentation_interface presentation_impl = {    .feedback = handle_presentation_feedback,   .destroy = handle_presentation_destroy, };
static struct tw_profiler s_profiler = {0};
static const struct wl_region_interface region_impl = {    .destroy = region_destroy,  .add = region_add,  .subtract = region_subtract, };
static const struct wl_seat_interface seat_impl = {  .get_pointer = seat_get_pointer,    .get_keyboard = seat_get_keyboard,  .get_touch = seat_get_touch,    .release = seat_client_release, };
static const struct wl_keyboard_interface keyboard_impl = {  .release = release_device, };
static const struct wl_pointer_interface pointer_impl = {    .set_cursor = set_pointer_cursor,   .release = release_device, };
static const struct wl_touch_interface touch_impl = {    .release = release_device, };
static const struct tw_keyboard_grab_interface default_grab_impl = {  .enter = notify_keyboard_enter,     .key = notify_keyboard_key,     .modifiers = notify_keyboard_modifiers,     .cancel = notify_keyboard_cancel, };
static const struct tw_pointer_grab_interface default_grab_impl = {     .enter = notify_pointer_enter,  .motion = notify_pointer_motion,    .button = notify_pointer_button,    .axis = notify_pointer_axis,    .frame = notify_pointer_frame,  .cancel = notify_pointer_cancel, };
static const struct tw_touch_grab_interface default_grab_impl = {   .enter = notify_touch_enter,    .down = notify_touch_down,  .up = notify_touch_up,  .motion = notify_touch_motion,  .touch_cancel = notify_touch_cancel_event,  .cancel = notify_touch_cancel, };
static const struct wl_subsurface_interface subsurface_impl = {    .destroy = subsurface_handle_destroy,   .set_position = subsurface_set_position,    .place_above = subsurface_place_above,  .place_below = subsurface_place_below,  .set_sync = subsurface_set_sync,    .set_desync = subsurface_set_desync, };
static const struct wl_surface_interface surface_impl = {     .destroy = surface_destroy,     .attach = surface_attach,   .frame = surface_frame,     .damage = surface_damage,   .set_opaque_region = surface_set_opaque_region,     .set_input_region = surface_set_input_region,   .commit = surface_commit,   .set_buffer_transform = surface_set_buffer_transform,   .set_buffer_scale = surface_set_buffer_scale,   .damage_buffer = surface_damage_buffer, };
static struct tw_viewporter s_tw_viewporter = {0};
static const struct wp_viewport_interface viewport_impl = {    .destroy = viewport_handle_destroy,     .set_source = viewport_set_source,  .set_destination = viewport_set_destination, };
static struct wp_viewporter_interface viewporter_impl = {  .destroy = viewporter_handle_destroy_viewporter,    .get_viewport = viewporter_get_viewport, };
static const struct zxdg_output_v1_interface xdg_output_impl = {  .destroy = handle_output_destroy, };
static const struct zxdg_output_manager_v1_interface xdg_output_man_impl = {  .destroy = handle_manager_destroy,  .get_xdg_output = handle_get_xdg_output, };

// global functions

static hash_cmp_val icon_key_cmp(const void* sa, const void* sb);
static uint64_t hash_icon_key1(const void* sa);
static uint64_t hash_icon_key2(const void* sa);
static int console_do_submit(struct tw_event* e, int fd);

static void console_issue_commands(
    struct desktop_console* console,
    const struct nk_str* str
    );

static bool console_has_selected(struct desktop_console* console);
static void console_clear_selected(struct desktop_console* console);
static void console_clear_edit(struct desktop_console* console);
static bool console_edit_changed(struct desktop_console* console, int* prev_len);
static bool console_update_search_results(struct desktop_console* console);
static bool console_select_default(struct desktop_console* console);
static void console_update_selected(struct desktop_console* console);
static void console_handle_tab(struct desktop_console* console);
static void console_handle_nav(struct desktop_console* console, bool up);
static int console_resize(struct tw_event* e, int fd);

static bool console_draw_module_results(
    struct nk_context* ctx,
    struct desktop_console* console,
    struct console_module* module,
    vector_t* results,
    struct nk_rect* selected_bound
    );

static void console_calc_scroll(
    const struct nk_rect* selected,
    const struct nk_rect* bound,
    struct nk_scroll* scroll
    );

static bool console_draw_search_results(
    struct nk_context* ctx,
    struct desktop_console* console
    );

static int console_edit_filter(const struct nk_text_edit* box, nk_rune unicode);
static void console_clean_nav_key(struct nk_context* ctx);

static void console_draw(
    struct nk_context* ctx,
    float width,
    float height,
    struct tw_appsurf* surf
    );

static bool suspend_console_on_esc(
    struct tw_appsurf* app,
    const struct tw_app_event* e
    );

static void update_app_config(
    void* data,
    struct taiwins_console* tw_console,
    const char* app_name,
    uint32_t floating,
    wl_fixed_t scale
    );

static void start_console(
    void* data,
    struct taiwins_console* tw_console,
    wl_fixed_t width,
    wl_fixed_t height,
    wl_fixed_t scale
    );

static void exec_application(
    void* data,
    struct taiwins_console* protocol,
    uint32_t id
    );

static void console_apply_theme(
    void* data,
    struct taiwins_theme* taiwins_theme,
    const char* name,
    int32_t fd,
    uint32_t size
    );

static void console_apply_cursor(
    void* data,
    struct taiwins_theme* taiwins_theme,
    const char* name,
    uint32_t size
    );

static void console_release_module(void* m);
static void console_free_search_results(void* m);
static void free_defunct_app(int signum);

static void update_console_icon_search(
    struct desktop_console* console,
    struct image_cache* cache
    );

static void load_console_icons(struct desktop_console* console, uint32_t icons);
static void release_console_modules(struct desktop_console* console);
static void reload_console_modules(struct desktop_console* console);
static void post_init_console(struct desktop_console* console);
static void init_console(struct desktop_console* console);
static void end_console(struct desktop_console* console);

static void announce_globals(
    void* data,
    struct wl_registry* wl_registry,
    uint32_t name,
    const char* interface,
    uint32_t version
    );

static void announce_global_remove(
    void* data,
    struct wl_registry* wl_registry,
    uint32_t name
    );

struct nk_wl_backend* desktop_console_aquire_nk_backend(struct desktop_console* console);

const struct nk_image* desktop_console_request_image(
    struct desktop_console* console,
    const char* name,
    const char* fallback
    );

void desktop_console_append_module(
    struct desktop_console* console,
    struct console_module* module
    );

void desktop_console_load_icons(
    struct desktop_console* console,
    const struct wl_array* handle_list,
    const struct wl_array* string_list
    );

int main(int argc, char* argv[]);

static void notify_console_surface_destroy(
    struct wl_listener* listener,
    void* data
    );

static void close_console(
    struct wl_client* client,
    struct wl_resource* resource,
    struct wl_resource* wl_buffer,
    uint32_t exec_id
    );

static void set_console(
    struct wl_client* client,
    struct wl_resource* resource,
    uint32_t ui_elem,
    struct wl_resource* wl_surface,
    struct wl_resource* wl_seat
    );

static void unbind_console(struct wl_resource* r);

static void bind_console(
    struct wl_client* client,
    void* data,
    uint32_t version,
    uint32_t id
    );

static void launch_console_client(void* data);
void tw_console_start_client(struct tw_console* console);
static void end_console(struct wl_listener* listener, void* data);

struct tw_console* tw_console_create_global(
    struct wl_display* display,
    const char* path,
    struct tw_backend* backend,
    struct tw_shell* shell
    );

struct nk_wl_backend* desktop_console_aquire_nk_backend(struct desktop_console* console);

const struct nk_image* desktop_console_request_image(
    struct desktop_console* console,
    const char* name,
    const char* fallback
    );

void desktop_console_load_icons(
    struct desktop_console* console,
    const struct wl_array* handle_list,
    const struct wl_array* string_list
    );

void desktop_console_append_module(
    struct desktop_console* console,
    struct console_module* module
    );

void* desktop_console_run_config_lua(
    struct desktop_console* console,
    const char* path
    );

void desktop_console_release_lua_config(
    struct desktop_console* console,
    void* config_data
    );

int desktop_console_take_search_result(
    struct console_module* module,
    vector_t* ret
    );

int desktop_console_take_exec_result(
    struct console_module* module,
    char** result
    );

void console_module_init(
    struct console_module* module,
    struct desktop_console* console
    );

void console_module_release(struct console_module* module);

void console_module_command(
    struct console_module* module,
    const char* search,
    const char* exec
    );

static bool search_entry_empty(const console_search_entry_t* entry);
static const char* search_entry_get_string(const console_search_entry_t* entry);

static void search_entry_move(
    console_search_entry_t* dst,
    console_search_entry_t* src
    );

bool search_entry_equal(console_search_entry_t*, console_search_entry_t*);
void search_entry_assign(void* dst, const void* src);
void search_entry_free(void*);

struct console* tw_setup_console(
    struct weston_compositor* compositor,
    const char* exec_path,
    struct shell* shell
    );

void tw_console_start_client(struct console* console);
static void tolowers(char* line);
void remove_exec_param(char* exec);

static int xdg_app_module_exec(
    struct console_module* module,
    const char* entry,
    char** result
    );

static int xdg_app_module_search(
    struct console_module* module,
    const char* to_search,
    vector_t* result
    );

static bool xdg_app_filter(const char* command, const char* last);
static void xdg_app_module_update_icons(struct console_module* module);
static void xdg_app_module_init(struct console_module* module);
static void xdg_app_module_destroy(struct console_module* module);

static bool console_cmd_module_filter_test(
    const char* command,
    const char* candidate
    );

static int console_cmd_module_exec(
    struct console_module* module,
    const char* entry,
    char** result
    );

static int console_cmd_module_search(
    struct console_module* module,
    const char* to_search,
    vector_t* result
    );

static void gather_all_cmds(rax* radix);
static void console_cmd_module_init(struct console_module* module);
static void console_cmd_module_destroy(struct console_module* module);
static bool _lua_istable(lua_State* L, int pos, const char* type);
static void* _lua_isudata(lua_State* L, int pos, const char* type);
static struct desktop_console* _lua_to_console(lua_State* L);
static int _lua_n_console_modules(lua_State* L);
static void _lua_add_console_module(lua_State* L);
static pthread_mutex_t* _lua_get_lock(lua_State* L, const char* type);

static int console_lua_module_get_table(
    lua_State* L,
    struct console_module* module
    );

static void collect_search_entries(lua_State* L, int pos, vector_t* results);

static int console_lua_module_search(
    struct console_module* module,
    const char* keyword,
    vector_t* result
    );

static int console_lua_module_exec(
    struct console_module* module,
    const char* entry,
    UNUSED_ARG(char**result)
    );

static void console_lua_module_init(UNUSED_ARG(struct console_module*module));
static void console_lua_module_destroy(UNUSED_ARG(struct console_module*module));

static void console_module_assign_table(
    lua_State* L,
    struct console_module* m,
    int table_pos
    );

static bool console_module_valid_lua_search(lua_State* L, int pos);
static bool console_module_valid_lua_exec(lua_State* L, int pos);
static bool console_module_get_name(lua_State* L, int pos, char module_name[32]);
static int console_module_from_lua_table(lua_State* L, int pos);
static int console_module_from_lua_file(lua_State* L, const char* module);
static void _lua_collect_module(lua_State* L, struct console_module* module);
static struct console_module* _lua_module_from_collection(lua_State* L, int i);
static void _lua_clear_module_in_collection(lua_State* L, int i);
static int _lua_img_width(lua_State* L);
static int _lua_img_height(lua_State* L);
static int _lua_new_search_entry(lua_State* L);
static int _lua_request_console_img(lua_State* L);
static int _lua_load_module(lua_State* L);
static int _lua_load_builtin_module(lua_State* L);
static int _lua_request_module_metatable(lua_State* L);
static int _lua_console_load_images(lua_State* L);
static int _lua_console_config_path(lua_State* L);
static int luaopen_taiwins_console(lua_State* L);

static void _lua_register_metatables(
    lua_State* L,
    struct desktop_console* console
    );

void* desktop_console_run_config_lua(
    struct desktop_console* console,
    const char* path
    );

void desktop_console_release_lua_config(
    UNUSED_ARG(struct desktop_console*console),
    void* config_data
    );

void search_entry_assign(void* dst, const void* src);
void search_entry_free(void* m);
bool search_entry_equal(console_search_entry_t* l, console_search_entry_t* r);

static void cache_takes(
    struct module_search_cache* cache,
    vector_t* v,
    const char* command
    );

static void cache_init(struct module_search_cache* cache);
static void cache_free(struct module_search_cache* cache);

static void cache_filter(
    struct module_search_cache* cache,
    char* command,
    vector_t* v,
    bool(*)(const char*cmd, const char*candidate) filter_test
    );

static bool cachable(const struct module_search_cache* cache, char* command);
void* thread_run_module(void* arg);
static bool console_module_filter_test(const char* cmd, const char* entry);

void console_module_init(
    struct console_module* module,
    struct desktop_console* console
    );

void console_module_release(struct console_module* module);

void console_module_command(
    struct console_module* module,
    const char* search,
    const char* exec
    );

int desktop_console_take_search_result(
    struct console_module* module,
    vector_t* ret
    );

int desktop_console_take_exec_result(
    struct console_module* module,
    char** result
    );

static int console_path_module_exec(
    struct console_module* module,
    const char* entry,
    char** result
    );

static int console_path_module_search(
    struct console_module* module,
    const char* to_search,
    vector_t* result
    );

static void shell_output_set_major(struct shell_output* w);

static void shell_output_init(
    struct shell_output* w,
    const struct tw_bbox geo,
    bool major
    );

static void shell_output_release(struct shell_output* w);

static void shell_output_resize(
    struct shell_output* w,
    const struct tw_bbox geo
    );

static void desktop_shell_recv_msg(
    void* data,
    UNUSED_ARG(struct taiwins_shell*tw_shell),
    uint32_t type,
    struct wl_array* arr
    );

static void desktop_shell_output_configure(
    void* data,
    struct taiwins_shell* tw_shell,
    uint32_t id,
    uint32_t width,
    uint32_t height,
    uint32_t scale,
    uint32_t major,
    uint32_t msg
    );

static void desktop_shell_apply_theme(
    void* data,
    struct taiwins_theme* taiwins_theme,
    const char* name,
    int32_t fd,
    uint32_t size
    );

static void desktop_shell_apply_cursor(
    void* data,
    UNUSED_ARG(struct taiwins_theme*taiwins_theme),
    const char* name,
    uint32_t size
    );

static void desktop_shell_init(
    struct desktop_shell* shell,
    struct wl_display* display
    );

static void desktop_shell_release(struct desktop_shell* shell);

static void announce_globals(
    void* data,
    struct wl_registry* wl_registry,
    uint32_t name,
    const char* interface,
    uint32_t version
    );

static void announce_global_remove(
    void* data,
    struct wl_registry* wl_registry,
    uint32_t name
    );

int main(UNUSED_ARG(int argc), UNUSED_ARG(char*argv[]));

static void notify_shell_ui_surface_destroy(
    struct wl_listener* listener,
    void* data
    );

struct tw_shell_ui* shell_create_ui_element(
    struct tw_shell* shell,
    struct tw_shell_ui* elem,
    struct wl_resource* ui_resource,
    struct tw_surface* surface,
    struct tw_shell_output* output,
    uint32_t x,
    uint32_t y,
    struct tw_layer* layer,
    tw_surface_commit_cb_t commit_cb
    );

void shell_ui_set_role(
    struct tw_shell_ui* ui,
    void(*)(struct tw_surface*surface) commit,
    struct tw_surface* surface
    );

static void shell_ui_unset_role(struct tw_shell_ui* ui);

struct tw_shell_output* shell_output_from_backend_output(
    struct tw_shell* shell,
    struct tw_backend_output* output
    );

static void shell_change_desktop_area(void* data);
static void panel_size_changed(struct tw_shell_output* shell_output);
static void commit_panel(struct tw_surface* surface);
static void commit_fullscreen(struct tw_surface* surface);
static void commit_widget(struct tw_surface* surface);

static void shell_ui_destroy_resource(
    UNUSED_ARG(struct wl_client*client),
    struct wl_resource* resource
    );

static void shell_ui_unbind(struct wl_resource* resource);
static void shell_ui_unbind_free(struct wl_resource* resource);

static struct tw_layer* shell_ui_type_to_layer(
    struct tw_shell* shell,
    enum taiwins_ui_type type
    );

tw_surface_commit_cb_t shell_ui_type_to_commit_cb(enum taiwins_ui_type type);

static void create_ui_element(
    struct wl_client* client,
    struct tw_shell* shell,
    struct tw_shell_ui* elem,
    uint32_t tw_ui,
    struct wl_resource* wl_surface,
    struct tw_shell_output* output,
    uint32_t x,
    uint32_t y,
    enum taiwins_ui_type type
    );

static void create_shell_panel(
    struct wl_client* client,
    struct wl_resource* resource,
    uint32_t tw_ui,
    struct wl_resource* wl_surface,
    int idx
    );

static void notify_shell_widget_close(struct wl_listener* listener, void* data);

static void launch_shell_widget(
    struct wl_client* client,
    struct wl_resource* resource,
    uint32_t tw_ui,
    struct wl_resource* wl_surface,
    struct wl_resource* wl_seat,
    int32_t idx,
    uint32_t x,
    uint32_t y
    );

static void create_shell_background(
    struct wl_client* client,
    struct wl_resource* resource,
    uint32_t tw_ui,
    struct wl_resource* wl_surface,
    int32_t tw_ouptut
    );

static void create_shell_locker(
    struct wl_client* client,
    struct wl_resource* resource,
    uint32_t tw_ui,
    struct wl_resource* wl_surface,
    UNUSED_ARG(int32_t tw_output)
    );

static void recv_client_msg(
    UNUSED_ARG(struct wl_client*client),
    UNUSED_ARG(struct wl_resource*resource),
    UNUSED_ARG(uint32_t key),
    UNUSED_ARG(struct wl_array*value)
    );

static void launch_shell_client(void* data);

static struct tw_shell_output* shell_output_from_tw_backend_output(
    struct tw_shell* shell,
    struct tw_backend_output* output
    );

static void shell_send_panel_pos(struct tw_shell* shell);
static void shell_send_default_config(struct tw_shell* shell);
static void unbind_shell(struct wl_resource* resource);

static void bind_shell(
    struct wl_client* client,
    void* data,
    UNUSED_ARG(uint32_t version),
    uint32_t id
    );

void tw_shell_create_ui_elem(
    struct tw_shell* shell,
    struct wl_client* client,
    struct tw_backend_output* output,
    uint32_t tw_ui,
    struct wl_resource* wl_surface,
    uint32_t x,
    uint32_t y,
    enum taiwins_ui_type type
    );

void tw_shell_post_data(
    struct tw_shell* shell,
    uint32_t type,
    struct wl_array* msg
    );

void tw_shell_post_message(
    struct tw_shell* shell,
    uint32_t type,
    const char* msg
    );

pixman_rectangle32_t tw_shell_output_available_space(
    struct tw_shell* shell,
    struct tw_backend_output* output
    );

struct wl_signal* tw_shell_get_desktop_area_signal(struct tw_shell* shell);

void tw_shell_set_panel_pos(
    struct tw_shell* shell,
    enum taiwins_shell_panel_pos pos
    );

static void shell_new_output(struct wl_listener* listener, void* data);
static void shell_rm_output(struct wl_listener* listener, void* data);

static void shell_compositor_idle(
    struct wl_listener* listener,
    UNUSED_ARG(void*data)
    );

static void shell_resize_output(struct wl_listener* listener, void* data);
static void end_shell(struct wl_listener* listener, UNUSED_ARG(void*data));

static void shell_add_listeners(
    struct tw_shell* shell,
    struct tw_backend* backend
    );

struct tw_shell* tw_shell_create_global(
    struct wl_display* display,
    struct tw_backend* backend,
    bool enable_layer_shell,
    const char* path
    );

static int desktop_shell_n_outputs(struct desktop_shell* shell);
static void shell_end_transient_surface(struct desktop_shell* shell);
void shell_load_wallpaper(struct desktop_shell* shell, const char* path);
void shell_init_bg_for_output(struct shell_output* output);
void shell_resize_bg_for_output(struct shell_output* output);
void shell_init_panel_for_output(struct shell_output* output);
void shell_resize_panel_for_output(struct shell_output* output);
void shell_locker_init(struct desktop_shell* shell);

void shell_process_msg(
    struct desktop_shell* shell,
    uint32_t type,
    const struct wl_array* data
    );

static void shell_notif_msg(
    struct desktop_shell* shell,
    int maxlen,
    const char* format,
    ...
    );

void shell_tdbus_init(struct desktop_shell* shell);
void shell_tdbus_end(struct desktop_shell* shell);
void shell_cleanup_notifications(struct desktop_shell* shell);

void shell_launch_menu(
    struct desktop_shell* shell,
    struct shell_output* o,
    uint32_t x,
    uint32_t y
    );

void shell_launch_notif(struct desktop_shell* shell, struct shell_notif* n);
void shell_launch_widget(struct desktop_shell* shell);
void shell_close_widget(struct desktop_shell* shell);
void* shell_config_run_lua(struct shell_config* config, const char* path);

struct tw_shell* tw_shell_create_global(
    struct wl_display* display,
    struct tw_backend* backend,
    bool enable_layer_shell,
    const char* path
    );

void tw_shell_create_ui_elem(
    struct tw_shell* shell,
    struct wl_client* client,
    struct tw_backend_output* output,
    uint32_t tw_ui,
    struct wl_resource* wl_surface,
    uint32_t x,
    uint32_t y,
    enum taiwins_ui_type type
    );

void tw_shell_post_data(
    struct tw_shell* shell,
    uint32_t type,
    struct wl_array* msg
    );

void tw_shell_post_message(
    struct tw_shell* shell,
    uint32_t type,
    const char* msg
    );

pixman_rectangle32_t tw_shell_output_available_space(
    struct tw_shell* shell,
    struct tw_backend_output* output
    );

struct wl_signal* tw_shell_get_desktop_area_signal(struct tw_shell* shell);

void tw_shell_set_panel_pos(
    struct tw_shell* shell,
    enum taiwins_shell_panel_pos pos
    );

struct tw_theme_global* tw_theme_create_global(struct wl_display* display);
void tw_theme_notify(struct tw_theme_global* global, struct tw_theme* new_theme);

struct tw_console* tw_console_create_global(
    struct wl_display* display,
    const char* path,
    struct tw_backend* backend,
    struct tw_shell* shell
    );

void tw_console_start_client(struct tw_console* console);

static bool shell_background_start_menu(
    struct tw_appsurf* surf,
    const struct tw_app_event* e
    );

static void shell_background_frame(
    struct tw_appsurf* surf,
    struct wl_buffer* buffer,
    struct tw_bbox* geo
    );

static void shell_background_impl_filter(
    struct wl_list* head,
    struct tw_app_event_filter* filter
    );

void shell_init_bg_for_output(struct shell_output* w);
void shell_resize_bg_for_output(struct shell_output* w);
void shell_load_wallpaper(struct desktop_shell* shell, const char* path);
static int dispatch_watch(struct tw_event* event, UNUSED_ARG(int fd));

static void shell_bus_add_watch(
    void* user_data,
    int fd,
    struct tdbus* bus,
    uint32_t mask,
    void* watch_data
    );

static void shell_bus_change_watch(
    void* user_data,
    int fd,
    struct tdbus* bus,
    uint32_t mask,
    void* watch_data
    );

static void shell_bus_remove_watch(
    void* user_data,
    int fd,
    struct tdbus* bus,
    void* watch_data
    );

static int dispatch_tdbus(struct tw_event* event, int fd);
void shell_tdbus_init(struct desktop_shell* shell);
void shell_tdbus_end(struct desktop_shell* shell);

static int conversation(
    int num_msg,
    const struct pam_message** msgs,
    struct pam_response** resp,
    void* appdata_ptr
    );

static int run_pam(struct tw_event* event, int fd);

static void shell_locker_frame(
    struct nk_context* ctx,
    float width,
    float height,
    struct tw_appsurf* locker
    );

void shell_locker_init(struct desktop_shell* shell);
static bool lua_isluafunction(lua_State* L, int pos);
static bool lua_toluafunction(lua_State* L, int pos);
static bool _lua_istable(lua_State* L, int pos, const char* type);
static void* _lua_isudata(lua_State* L, int pos, const char* type);
static struct desktop_shell* _lua_to_shell(lua_State* L);
static int _lua_set_wallpaper(lua_State* L);
static bool _lua_is_menu_item(struct lua_State* L, int idx);
static bool _lua_parse_menu(struct lua_State* L, vector_t* menus);
static int _lua_set_menu(lua_State* L);
static int _lua_n_widgets(lua_State* L);
static void _lua_set_widget_func(lua_State* L, int pos, const char* type);
static void _lua_get_widget_func(lua_State* L, const char* type);

static void _lua_get_widget_userdata(
    lua_State* L,
    struct shell_widget_runtime* runtime
    );

static int _lua_widget_anchor(
    struct shell_widget* widget,
    struct shell_widget_label* label
    );

static void _lua_widget_draw(
    struct nk_context* ctx,
    UNUSED_ARG(float width),
    UNUSED_ARG(float height),
    struct tw_appsurf* app
    );

static void _lua_init_widget_runtime(
    struct shell_widget_runtime* runtime,
    lua_State* L,
    int index
    );

static int _lua_add_widget_data(
    lua_State* L,
    struct shell_widget_runtime* runtime
    );

static int _lua_add_widget_watchers(
    lua_State* L,
    struct shell_widget_runtime* runtime
    );

static int _lua_new_widget_from_table(lua_State* L);
static int _lua_widget_done(lua_State* L);
static int _lua_widget_set_anchor(lua_State* L);
static int _lua_widget_set_draw_func(lua_State* L);
static int _lua_widget_set_width(lua_State* L);
static int _lua_widget_set_height(lua_State* L);
static int _lua_widget_set_timer(lua_State* L);
static int _lua_widget_watch_file(lua_State* L);
static int _lua_widget_watch_device(lua_State* L);
static int _lua_new_widget_empty(lua_State* L);
static int _lua_register_widget(lua_State* L);

static bool _lua_check_widget_exists(
    lua_State* L,
    const struct shell_widget* check
    );

static int _lua_register_builtin_widget(lua_State* L);
static int luaopen_taiwins_shell(lua_State* L);
static struct shell_widget* clone_widget(struct shell_widget* wig);
static void shell_config_fini_lua(struct shell_config* config);
static char* shell_config_request_lua_wallpaper(struct shell_config* config);
void* shell_config_run_lua(struct shell_config* config, const char* path);
static struct shell_notif* make_shell_notif(const char* msg);

static void shell_add_notif(
    struct desktop_shell* shell,
    struct shell_notif* notif
    );

static void shell_destroy_notify(
    struct desktop_shell* shell,
    struct shell_notif* notif
    );

void shell_cleanup_notifications(struct desktop_shell* shell);
static void desktop_shell_setup_locker(struct desktop_shell* shell);

void shell_process_msg(
    struct desktop_shell* shell,
    uint32_t type,
    const struct wl_array* data
    );

static int panel_launch_widget(struct tw_event* event, UNUSED_ARG(int fd));

static struct nk_vec2 widget_launch_point_flat(
    struct nk_vec2* label_span,
    struct shell_widget* clicked,
    struct tw_appsurf* panel_surf
    );

static void shell_panel_measure_leading(
    struct nk_context* ctx,
    float width,
    float height,
    struct tw_appsurf* panel_surf
    );

static void shell_panel_frame(
    struct nk_context* ctx,
    float width,
    float height,
    struct tw_appsurf* panel_surf
    );

void shell_init_panel_for_output(struct shell_output* w);
void shell_resize_panel_for_output(struct shell_output* w);

static void shell_draw_submenu(
    struct nk_context* ctx,
    struct tw_menu_item* item,
    int id
    );

static void shell_draw_menu(
    struct nk_context* ctx,
    float width,
    float height,
    struct tw_appsurf* app
    );

static void shell_draw_notif(
    struct nk_context* ctx,
    float width,
    float height,
    struct tw_appsurf* app
    );

static void widget_should_close(void* data, struct taiwins_ui* ui_elem);
void shell_close_widget(struct desktop_shell* shell);
void shell_launch_widget(struct desktop_shell* shell);

void shell_launch_menu(
    struct desktop_shell* shell,
    struct shell_output* output,
    uint32_t x,
    uint32_t y
    );

void shell_launch_notif(struct desktop_shell* shell, struct shell_notif* notif);
static enum icon_type icon_type_from_name(const char* name);
static const char* name_from_icon_type(uint32_t type);
static bool cache_needs_update(const char* cache_file, const char* theme_path);

static bool parse_arguments(
    int argc,
    char* argv[],
    struct icon_cache_option* option
    );

static bool retrieve_themes_to_search(
    vector_t* theme_lookups,
    const struct icon_cache_option* option
    );

static void path_to_node(char output[256], const char* input);
static bool icon_is_app(const char* key, void* user_data);

static void update_theme(
    const struct icon_cache_config* current,
    const struct icon_cache_option* option,
    const struct icontheme_dir* hicolor,
    struct dhash_table* table
    );

int main(int argc, char* argv[]);

static int battery_anchor(
    struct shell_widget* widget,
    struct shell_widget_label* label
    );

static int battery_sysfile_find(struct shell_widget* widget, char* path);

static int clock_widget_anchor(
    struct shell_widget* widget,
    struct shell_widget_label* label
    );

static struct tm reduce_a_month(const struct tm* date);
static struct tm forward_a_month(const struct tm* date);
static int days_in_a_year(int year);

static void calendar(
    struct nk_context* ctx,
    float width,
    float height,
    struct tw_appsurf* app
    );

static int clock_setup(struct shell_widget* widget);
void shell_widget_release_with_runtime(struct shell_widget* widget);
static int redraw_panel_for_file(struct tw_event* e, int fd);
static int redraw_panel_for_dev(struct tw_event* e, int fd);
static int redraw_panel_for_timer(struct tw_event* e, int fd);

static void shell_widget_event_from_timer(
    struct shell_widget* widget,
    struct itimerspec* time,
    struct tw_event_queue* event_queue
    );

static void shell_widget_event_from_file(
    struct shell_widget* widget,
    const char* path,
    struct tw_event_queue* event_queue
    );

static void shell_widget_event_from_device(
    struct shell_widget* widget,
    const char* subsystem,
    const char* dev,
    struct tw_event_queue* event_queue
    );

bool shell_widget_builtin(struct shell_widget* widget);
const struct shell_widget* shell_widget_get_builtin_by_name(const char* name);

void shell_widget_activate(
    struct shell_widget* widget,
    struct tw_event_queue* queue
    );

void shell_widget_disactivate(
    struct shell_widget* widget,
    struct tw_event_queue* queue
    );

void shell_widgets_load_default(struct wl_list* head);

static int whatup_ancre(
    struct shell_widget* widget,
    struct shell_widget_label* label
    );

void shell_widget_activate(
    struct shell_widget* widget,
    struct tw_event_queue* queue
    );

void shell_widget_disactivate(
    struct shell_widget* widget,
    struct tw_event_queue* queue
    );

bool shell_widget_builtin(struct shell_widget* widget);
void shell_widgets_load_default(struct wl_list* head);

void shell_widgets_load_script(
    struct wl_list* head,
    struct tw_event_queue* queue,
    const char* path
    );

const struct shell_widget* shell_widget_get_builtin_by_name(const char* name);

static void shell_widget_hook_panel(
    struct shell_widget* widget,
    struct tw_appsurf* panel
    );

option(
    'enable-profiler',
    type:'boolean',
    value:false,
    description:'Enable taiwins profiler'
    );

void tw_backend_defer_outputs(struct tw_backend* backend, bool defer);
void tw_backend_flush(struct tw_backend* backend);
void* tw_backend_get_backend(struct tw_backend* backend);
struct tw_backend_output* tw_backend_focused_output(struct tw_backend* backend);
struct tw_backend_output* tw_backend_output_from_cursor_pos(struct tw_backend* backend);
struct tw_backend_output* tw_backend_output_from_resource(struct wl_resource* resource);

static struct tw_surface* try_pick_subsurfaces(
    struct tw_surface* parent,
    float x,
    float y,
    float* sx,
    float* sy
    );

struct tw_surface* tw_backend_pick_surface_from_layers(
    struct tw_backend* backend,
    float x,
    float y,
    float* sx,
    float* sy
    );

static bool tw_backend_init_globals(struct tw_backend* backend);
static void release_backend(struct wl_listener* listener, UNUSED_ARG(void*data));

struct tw_backend* tw_backend_create_global(
    struct wl_display* display,
    wlr_renderer_create_func_t render_create
    );

void tw_backend_add_listener(
    struct tw_backend* backend,
    enum tw_backend_event_type event,
    struct wl_listener* listener
    );

void tw_backend_switch_session(struct tw_backend* backend, uint32_t id);

static void surface_add_to_outputs_list(
    struct tw_backend* backend,
    struct tw_surface* surface
    );

static void subsurface_add_to_list(
    struct wl_list* parent_head,
    struct tw_surface* surface
    );

static void surface_add_to_list(
    struct tw_backend* backend,
    struct tw_surface* surface
    );

void tw_backend_build_surface_list(struct tw_backend* backend);

static void notify_buffer_on_surface_destroy(
    struct wl_listener* listener,
    void* data
    );

static bool shm_buffer_compatible(
    struct wl_shm_buffer* shmbuf,
    struct tw_surface_buffer* buffer
    );

static bool update_texture(
    struct tw_event_buffer_uploading* event,
    struct tw_renderer* rdr
    );

static bool renderer_import_buffer(
    struct tw_event_buffer_uploading* event,
    void* data
    );

static bool renderer_test_import_dmabuf(
    struct tw_dmabuf_attributes* attrs,
    void* data
    );

static void renderer_format_request(
    struct tw_linux_dmabuf* dmabuf,
    void* callback,
    int* formats,
    size_t* n_formats
    );

static void renderer_modifiers_request(
    struct tw_linux_dmabuf* dmabuf,
    void* callback,
    int format,
    uint64_t* modifiers,
    size_t* n_modifiers
    );

static void update_surface_mask(
    struct tw_surface* surface,
    struct tw_backend_output* major,
    uint32_t mask
    );

static void reassign_surface_outputs(
    struct tw_surface* surface,
    struct tw_backend* backend
    );

static void notify_new_output(struct wl_listener* listener, void* data);
static void notify_new_input(struct wl_listener* listener, void* data);
static void notify_new_wl_surface(struct wl_listener* listener, void* data);
static void notify_new_wl_subsurface(struct wl_listener* listener, void* data);
static void notify_new_wl_region(struct wl_listener* listener, void* data);
static void notify_dirty_wl_surface(struct wl_listener* listener, void* data);
static void notify_rm_wl_surface(struct wl_listener* listener, void* data);

void tw_backend_init_impl(
    struct tw_backend_impl* impl,
    struct tw_backend* backend
    );

void tw_backend_fini_impl(struct tw_backend_impl* impl);

struct tw_backend_seat* tw_backend_seat_find_create(
    struct tw_backend* backend,
    struct wlr_input_device* dev,
    enum tw_input_device_cap cap
    );

void tw_backend_seat_destroy(struct tw_backend_seat* seat);

void tw_backend_new_output(
    struct tw_backend* backend,
    struct wlr_output* wlr_output
    );

void tw_backend_new_keyboard(
    struct tw_backend* backend,
    struct wlr_input_device* dev
    );

void tw_backend_new_pointer(
    struct tw_backend* backend,
    struct wlr_input_device* dev
    );

void tw_backend_new_touch(
    struct tw_backend* backend,
    struct wlr_input_device* dev
    );

void tw_backend_init_impl(
    struct tw_backend_impl* impl,
    struct tw_backend* backend
    );

void tw_backend_fini_impl(struct tw_backend_impl* impl);
bool tw_backend_valid_libinput_device(struct libinput_device* device);
static bool validate_keyboard(struct libinput_device* dev);
static bool validate_pointer(struct libinput_device* dev);
static bool validate_touch(struct libinput_device* dev);
bool tw_backend_valid_libinput_device(struct libinput_device* dev);
static enum wl_output_transform inverse_wl_transform(enum wl_output_transform t);
static void build_output_2d_view(struct tw_backend_output* o);

static struct wlr_output_mode* pick_output_mode(
    struct tw_backend_output* o,
    struct wlr_output* output
    );

static void correct_output_mode(struct tw_backend_output* o);
void tw_backend_commit_output_state(struct tw_backend_output* o);
static void init_output_state(struct tw_backend_output* o);
static void fini_output_state(struct tw_backend_output* o);
static void shuffle_output_damage(struct tw_backend_output* output);

static int rectify_output_buffer_age(
    struct tw_backend_output* output,
    int buffer_age
    );

static void notify_new_output_frame(struct wl_listener* listener, void* data);

static void notify_output_remove(
    struct wl_listener* listener,
    UNUSED_ARG(void*data)
    );

void tw_backend_new_output(
    struct tw_backend* backend,
    struct wlr_output* wlr_output
    );

struct tw_backend_output* tw_backend_find_output(
    struct tw_backend* backend,
    const char* name
    );

void tw_backend_set_output_scale(struct tw_backend_output* output, float scale);

void tw_backend_set_output_transformation(
    struct tw_backend_output* output,
    enum wl_output_transform transform
    );

int tw_backend_get_output_modes(
    struct tw_backend_output* output,
    struct tw_backend_output_mode* modes
    );

void tw_backend_set_output_mode(
    struct tw_backend_output* output,
    const struct tw_backend_output_mode* mode
    );

void tw_backend_set_output_position(
    struct tw_backend_output* output,
    uint32_t x,
    uint32_t y
    );

void tw_backend_output_clone(
    struct tw_backend_output* dst,
    const struct tw_backend_output* src
    );

void tw_backend_output_enable(struct tw_backend_output* output, bool enable);
void tw_backend_output_set_gamma(struct tw_backend_output* output, float gamma);
void tw_backend_output_dirty(struct tw_backend_output* output);

struct wl_resource* tw_backend_output_get_wl_output(
    struct tw_backend_output* output,
    struct wl_resource* reference
    );

static void notify_backend_keyboard_remove(
    struct wl_listener* listener,
    void* data
    );

static void notify_backend_keyboard_modifiers(
    struct wl_listener* listener,
    void* data
    );

static void notify_backend_keyboard_key(
    struct wl_listener* listener,
    void* data
    );

void tw_backend_new_keyboard(
    struct tw_backend* backend,
    struct wlr_input_device* dev
    );

static void pointer_focus_motion(
    struct tw_backend_seat* seat,
    uint32_t timespec
    );

static void notify_backend_set_cursor(struct wl_listener* listener, void* data);

static void notify_backend_pointer_button(
    struct wl_listener* listener,
    void* data
    );

static void notify_backend_pointer_motion(
    struct wl_listener* listener,
    void* data
    );

static void notify_backend_pointer_motion_abs(
    struct wl_listener* listener,
    void* data
    );

static void notify_backend_pointer_axis(
    struct wl_listener* listener,
    void* data
    );

static void notify_backend_pointer_frame(
    struct wl_listener* listener,
    void* data
    );

static void notify_backend_pointer_remove(
    struct wl_listener* listener,
    void* data
    );

void tw_backend_new_pointer(
    struct tw_backend* backend,
    struct wlr_input_device* dev
    );

static void notify_backend_touch_remove(
    struct wl_listener* listener,
    void* data
    );

static void notify_backend_touch_down(struct wl_listener* listener, void* data);
static void notify_backend_touch_up(struct wl_listener* listener, void* data);

static void notify_backend_touch_motion(
    struct wl_listener* listener,
    void* data
    );

static void notify_backend_touch_cancel(
    struct wl_listener* listener,
    void* data
    );

void tw_backend_new_touch(
    struct tw_backend* backend,
    struct wlr_input_device* dev
    );

static struct tw_backend_seat* find_seat_missing_dev(
    struct tw_backend* backend,
    struct wlr_input_device* dev,
    enum tw_input_device_cap cap
    );

static struct tw_backend_seat* new_seat_for_backend(
    struct tw_backend* backend,
    struct wlr_input_device* dev
    );

struct tw_backend_seat* tw_backend_seat_find_create(
    struct tw_backend* backend,
    struct wlr_input_device* dev,
    enum tw_input_device_cap cap
    );

void tw_backend_seat_destroy(struct tw_backend_seat* seat);

void tw_backend_seat_set_xkb_rules(
    struct tw_backend_seat* seat,
    struct xkb_rule_names* rules
    );

struct tw_backend_seat* tw_backend_get_focused_seat(struct tw_backend* backend);

static struct tw_binding_node* make_binding_node(
    uint32_t code,
    uint32_t mod,
    uint32_t option,
    const tw_key_binding func,
    const void* data,
    bool end
    );

static bool key_presses_end(
    const struct tw_key_press presses[MAX_KEY_SEQ_LEN],
    int i
    );

static void notify_bindings_destroy(struct wl_listener* listener, void* data);
static void tw_bindings_release(struct tw_bindings* bindings);
struct tw_bindings* tw_bindings_create(struct wl_display* display);
void tw_bindings_destroy(struct tw_bindings* bindings);
void tw_bindings_move(struct tw_bindings* dst, struct tw_bindings* src);

struct tw_binding_node* tw_binding_node_step(
    struct tw_binding_node* tree,
    uint32_t keycode,
    uint32_t mod_mask
    );

struct tw_binding* tw_binding_node_get_binding(struct tw_binding_node* state);

struct tw_binding_node* tw_bindings_find_key(
    struct tw_bindings* bindings,
    uint32_t key,
    uint32_t mod_mask
    );

struct tw_binding* tw_bindings_find_btn(
    struct tw_bindings* bindings,
    uint32_t btn,
    uint32_t mod_mask
    );

struct tw_binding* tw_bindings_find_axis(
    struct tw_bindings* bindings,
    enum wl_pointer_axis action,
    uint32_t mod_mask
    );

struct tw_binding* tw_bindings_find_touch(
    struct tw_bindings* bindings,
    uint32_t mod_mask
    );

bool tw_bindings_add_axis(
    struct tw_bindings* root,
    const struct tw_axis_motion* motion,
    const tw_axis_binding binding,
    void* data
    );

bool tw_bindings_add_btn(
    struct tw_bindings* root,
    const struct tw_btn_press* press,
    const tw_btn_binding binding,
    void* data
    );

bool tw_bindings_add_touch(
    struct tw_bindings* root,
    uint32_t modifiers,
    const tw_touch_binding binding,
    void* data
    );

bool tw_bindings_add_key(
    struct tw_bindings* root,
    const struct tw_key_press presses[MAX_KEY_SEQ_LEN],
    const tw_key_binding func,
    uint32_t option,
    void* data
    );

static void print_node(const struct vtree_node* n);
void tw_bindings_print(struct tw_bindings* root);

static bool copy_builtin_bindings(
    struct tw_binding* dst,
    const struct tw_binding* src
    );

static void purge_xkb_rules(struct xkb_rule_names* rules);

static void move_xkb_rules(
    struct xkb_rule_names* dst,
    struct xkb_rule_names* src
    );

const char* tw_config_retrieve_error(struct tw_config* config);

static void tw_config_copy_registry(
    struct tw_config* dst,
    struct tw_config* src
    );

void tw_config_register_object(
    struct tw_config* config,
    const char* name,
    void* obj
    );

void* tw_config_request_object(struct tw_config* config, const char* name);
static void tw_swap_config(struct tw_config* dst, struct tw_config* src);

static bool tw_try_config(
    struct tw_config* tmp_config,
    struct tw_config* main_config
    );

static bool tw_config_wake_compositor(struct tw_config* c);
bool tw_run_config(struct tw_config* config);
bool tw_run_default_config(struct tw_config* c);

static struct tw_config_output* tw_config_output_from_backend_output(
    struct tw_config_table* t,
    struct tw_backend_output* output
    );

static void tw_config_apply_output(
    struct tw_config_table* t,
    struct tw_backend_output* bo
    );

static void notify_config_output_create(
    struct wl_listener* listener,
    void* data
    );

static void notify_config_seat_change(struct wl_listener* listener, void* data);

struct tw_config* tw_config_create(
    struct tw_backend* backend,
    struct tw_bindings* bindings
    );

void tw_config_destroy(struct tw_config* config);
void tw_config_table_dirty(struct tw_config_table* t, bool dirty);
void tw_config_table_flush(struct tw_config_table* t);

static bool quit_compositor(
    struct tw_keyboard* keyboard,
    uint32_t time,
    uint32_t key,
    uint32_t modifiers,
    uint32_t option,
    void* data
    );

static bool close_application(
    struct tw_keyboard* keyboard,
    uint32_t time,
    uint32_t key,
    uint32_t mods,
    uint32_t option,
    void* data
    );

static bool reload_config(
    struct tw_keyboard* keyboard,
    uint32_t time,
    uint32_t key,
    uint32_t mods,
    uint32_t option,
    void* data
    );

static bool should_start_console(
    struct tw_keyboard* keyboard,
    uint32_t time,
    uint32_t key,
    uint32_t mods,
    uint32_t option,
    void* data
    );

static bool zoom_axis(
    struct tw_pointer* pointer,
    uint32_t time,
    double delta,
    enum wl_pointer_axis direction,
    uint32_t modifiers,
    void* data
    );

static bool alpha_axis(
    struct tw_pointer* pointer,
    uint32_t time,
    double delta,
    enum wl_pointer_axis direction,
    uint32_t modifiers,
    void* data
    );

static bool moving_surface_pointer(
    struct tw_pointer* pointer,
    const uint32_t time,
    uint32_t button,
    uint32_t modifiers,
    void* data
    );

static bool click_activate_surface(
    struct tw_pointer* pointer,
    uint32_t time,
    uint32_t button,
    uint32_t modifiers,
    void* data
    );

static bool resize_view(
    struct tw_keyboard* keyboard,
    uint32_t time,
    uint32_t key,
    uint32_t mods,
    uint32_t option,
    void* data
    );

static bool switch_workspace(
    struct tw_keyboard* keyboard,
    uint32_t time,
    uint32_t key,
    uint32_t modifiers,
    uint32_t switch_left,
    void* data
    );

static bool switch_workspace_last(
    struct tw_keyboard* keyboard,
    uint32_t time,
    uint32_t key,
    uint32_t mods,
    uint32_t option,
    void* data
    );

static bool toggle_view_vertical(
    struct tw_keyboard* keyboard,
    uint32_t time,
    uint32_t key,
    uint32_t mods,
    uint32_t option,
    void* data
    );

static bool toggle_view_layout(
    struct tw_keyboard* keyboard,
    uint32_t time,
    uint32_t key,
    uint32_t mods,
    uint32_t option,
    void* data
    );

static bool split_desktop_view(
    struct tw_keyboard* keyboard,
    uint32_t time,
    uint32_t key,
    uint32_t mods,
    uint32_t vsplit,
    void* data
    );

static bool merge_desktop_view(
    struct tw_keyboard* keyboard,
    uint32_t time,
    uint32_t key,
    uint32_t mods,
    uint32_t option,
    void* data
    );

static bool desktop_recent_view(
    struct tw_keyboard* keyboard,
    uint32_t time,
    uint32_t key,
    uint32_t mods,
    uint32_t option,
    void* data
    );

void tw_config_default_bindings(struct tw_config* c);
bool tw_config_install_bindings(struct tw_config* c, struct tw_bindings* root);
static struct tw_bus* get_bus(void);
static int tw_dbus_dispatch_watch(int fd, uint32_t mask, void* data);

static void tw_bus_add_watch(
    void* user_data,
    int unix_fd,
    struct tdbus* bus,
    uint32_t mask,
    void* watch_data
    );

static void tw_bus_ch_watch(
    void* user_data,
    int unix_fd,
    struct tdbus* bus,
    uint32_t mask,
    void* watch_data
    );

static void tw_bus_rm_watch(
    void* user_data,
    int unix_fd,
    struct tdbus* bus,
    void* watch_data
    );

static int tw_bus_dispatch(int fd, uint32_t mask, void* data);
static void tw_bus_end(struct wl_listener* listener, void* data);
static int tw_bus_read_request(const struct tdbus_method_call* call);
struct tw_bus* tw_bus_create_global(struct wl_display* display);
typedef OPTION(enum wl_output_transform, transform);
typedef OPTION(enum tw_layout_type, layout);
typedef OPTION(bool, enable);
typedef OPTION(enum taiwins_shell_task_switch_effect, eff);
typedef OPTION(enum taiwins_shell_panel_pos, pos);
typedef OPTION(int32_t, val);
typedef OPTION(uint32_t, uval);
typedef OPTION(struct tw_theme*, theme);
void tw_config_default_bindings(struct tw_config* c);
bool tw_config_install_bindings(struct tw_config* c, struct tw_bindings* root);

bool parse_one_press(
    const char* str,
    const enum tw_binding_type type,
    uint32_t* mod,
    uint32_t* code
    );

const char* tw_config_retrieve_error(struct tw_config*);
struct tw_bus* tw_bus_create_global(struct wl_display* display);
void tw_config_table_dirty(struct tw_config_table* table, bool dirty);
void tw_config_table_flush(struct tw_config_table* table);
bool tw_luaconfig_read(struct tw_config* c, const char* path);
char* tw_luaconfig_read_error(struct tw_config* c);
void tw_luaconfig_fini(struct tw_config* c);
void tw_luaconfig_init(struct tw_config* c);
static struct tw_config* to_user_config(lua_State* L);
static void _lua_run_binding(void* data);

static bool _lua_run_keybinding(
    struct tw_keyboard* keyboard,
    uint32_t time,
    uint32_t key,
    uint32_t mods,
    uint32_t option,
    void* data
    );

static bool _lua_run_btnbinding(
    struct tw_pointer* pointer,
    uint32_t time,
    uint32_t btn,
    uint32_t mods,
    void* data
    );

static bool _lua_run_axisbinding(
    struct tw_pointer* pointer,
    uint32_t time,
    double delta,
    enum wl_pointer_axis direction,
    uint32_t mods,
    void* data
    );

static struct tw_binding* _new_lua_binding(
    struct tw_config* config,
    enum tw_binding_type type
    );

static bool _parse_binding(struct tw_binding* b, const char* seq_string);

static struct tw_binding* _find_default_binding(
    struct tw_config* config,
    const char* name
    );

static const char* _binding_type_name(enum tw_binding_type type);
static int _lua_bind(lua_State* L, enum tw_binding_type binding_type);
static int _lua_bind_key(lua_State* L);
static int _lua_bind_btn(lua_State* L);
static int _lua_bind_axis(lua_State* L);
static int _lua_bind_tch(lua_State* L);
static struct tw_config_table* _lua_to_config_table(lua_State* L);
int tw_theme_read(lua_State* L, struct tw_theme* theme);

static enum wl_output_transform _lua_output_transfrom_from_value(
    lua_State* L,
    int rotate,
    bool flip
    );

static int _lua_read_display_rotate_flip(
    lua_State* L,
    struct tw_config_table* t,
    int idx
    );

static int _lua_read_display_scale(
    lua_State* L,
    struct tw_config_table* t,
    int idx
    );

static int _lua_read_display_mode(
    lua_State* L,
    struct tw_config_table* t,
    int idx
    );

static int _lua_read_display_position(
    lua_State* L,
    struct tw_config_table* t,
    int idx
    );

static int _lua_read_display_enable(
    lua_State* L,
    struct tw_config_table* t,
    int idx
    );

static int _lua_read_display(
    lua_State* L,
    struct tw_config_table* t,
    uint32_t idx
    );

static int _lua_config_display(lua_State* L);
static int _lua_set_ws_layout(lua_State* L);
static int _lua_request_workspaces(lua_State* L);

static int _lua_enable_object(
    lua_State* L,
    char* name,
    enum tw_config_enable_global global
    );

static int _lua_enable_xwayland(lua_State* L);
static int _lua_enable_desktop(lua_State* L);
static int _lua_enable_bus(lua_State* L);
static int _lua_enable_taiwins_shell(lua_State* L);
static int _lua_enable_layer_shell(lua_State* L);
static int _lua_enable_taiwins_console(lua_State* L);
static int _lua_enable_taiwins_theme(lua_State* L);
static int _lua_set_keyboard_model(lua_State* L);
static int _lua_set_keyboard_layout(lua_State* L);
static int _lua_set_keyboard_options(lua_State* L);
static int _lua_set_repeat_info(lua_State* L);
static int _lua_read_theme(lua_State* L);
static int _lua_get_config(lua_State* L);
static int _lua_set_panel_position(lua_State* L);
static int _lua_set_sleep_timer(lua_State* L);
static int _lua_set_lock_timer(lua_State* L);
static int _lua_desktop_gap(lua_State* L);
static int luaopen_taiwins(lua_State* L);
bool tw_luaconfig_read(struct tw_config* c, const char* path);
char* tw_luaconfig_read_error(struct tw_config* c);
void tw_luaconfig_fini(struct tw_config* c);
void tw_luaconfig_init(struct tw_config* c);

static bool parse_table(
    const char* ptr,
    const struct event_map* table,
    size_t table_len,
    uint32_t* code
    );

static unsigned int parse_modifier(const char* str);

static bool parse_code(
    const char* code_str,
    enum tw_binding_type type,
    uint32_t* code
    );

bool parse_one_press(
    const char* code_str,
    const enum tw_binding_type type,
    uint32_t* modifier,
    uint32_t* code
    );

static bool tw_lua_isnumber(lua_State* L, int pos);
static bool tw_lua_isstring(lua_State* L, int pos);
static bool tw_lua_istable(lua_State* L, int pos, const char* type);
static void* tw_lua_isudata(lua_State* L, int pos, const char* type);
static int tw_lua_stackcheck(lua_State* L, int size);
static void tw_lua_assert(lua_State* L, int pass, const char* format, ...);
static bool tw_lua_is_rgb_str(lua_State* L, int pos, uint32_t* code);
static bool tw_lua_is_rgb_tuple(lua_State* L, int pos, uint32_t* code);
static bool tw_lua_is_rgb_dict(lua_State* L, int pos, uint32_t* code);
static bool tw_lua_is_rgb(lua_State* L, int pos, uint32_t* code);
static bool tw_lua_is_tuple2(lua_State* L, int pos, int* x, int* y);
static bool tw_lua_is_int2str(lua_State* L, int pos, int* x, int* y);
static bool is_file_image_type(const char* path);
static struct tw_theme* tw_theme_from_lua_state(lua_State* L);
static struct tw_theme_default* tw_theme_defaults_from_lua_state(lua_State* L);
static int tw_theme_add_color(lua_State* L, tw_rgba_t* color);
static void tw_theme_add_float(lua_State* L, float* value);
static void tw_theme_add_handle(lua_State* L, theme_option_handle* handle);
static void tw_theme_add_bool(lua_State* L, int* value);
static void tw_theme_add_vec2(lua_State* L, tw_vec2_t* vec);
static void tw_theme_add_item(lua_State* L, theme_option_style* option);
static void tw_theme_add_alignment(lua_State* L, tw_flags* flags);

static void tw_theme_add_header_align(
    lua_State* L,
    enum tw_style_header_align* align
    );

static void tw_theme_add_text(lua_State* L, struct tw_style_text* style);
static void tw_theme_add_button(lua_State* L, struct tw_style_button* style);
static void tw_theme_add_toggle(lua_State* L, struct tw_style_toggle* style);

static void tw_theme_add_selectable(
    lua_State* L,
    struct tw_style_selectable* style
    );

static void tw_theme_add_progress(lua_State* L, struct tw_style_progress* style);
static void tw_theme_add_chart(lua_State* L, struct tw_style_chart* style);

static void tw_theme_default_scroll_btn(
    lua_State* L,
    struct tw_style_scrollbar* scroll,
    struct tw_style_button* scroll_btn
    );

static void tw_theme_add_scroll(lua_State* L, struct tw_style_scrollbar* style);
static void tw_theme_add_slider(lua_State* L, struct tw_style_slider* style);
static void tw_theme_add_edit(lua_State* L, struct tw_style_edit* style);
static void tw_theme_add_property(lua_State* L, struct tw_style_property* style);
static void tw_theme_add_tab(lua_State* L, struct tw_style_tab* style);

static void tw_theme_default_combo_btn(
    struct tw_style_combo* style,
    struct tw_style_button* btn
    );

static void tw_theme_add_combo(lua_State* L, struct tw_style_combo* style);

static void tw_theme_add_header(
    lua_State* L,
    struct tw_style_window_header* style
    );

static void tw_theme_add_window(lua_State* L, struct tw_style_window* style);

static void tw_theme_read_defaults(
    lua_State* L,
    struct tw_theme_default* colors
    );

int tw_theme_read(lua_State* L, struct tw_theme* theme);

void tw_xdg_layout_emplace_noop(
    const enum tw_xdg_layout_command command,
    const struct tw_xdg_layout_op* arg,
    struct tw_xdg_view* v,
    struct tw_xdg_layout* l,
    struct tw_xdg_layout_op* ops
    );

void emplace_tiling(
    const enum tw_xdg_layout_command command,
    const struct tw_xdg_layout_op* arg,
    struct tw_xdg_view* v,
    struct tw_xdg_layout* l,
    struct tw_xdg_layout_op* ops
    );

void emplace_float(
    const enum tw_xdg_layout_command command,
    const struct tw_xdg_layout_op* arg,
    struct tw_xdg_view* v,
    struct tw_xdg_layout* l,
    struct tw_xdg_layout_op* ops
    );

void tw_xdg_layout_init(struct tw_xdg_layout* l);
void tw_xdg_layout_release(struct tw_xdg_layout* l);
void tw_xdg_layout_add_output(struct tw_xdg_layout* l, struct tw_xdg_output* o);
void tw_xdg_layout_rm_output(struct tw_xdg_layout* l, struct tw_xdg_output* o);

void tw_xdg_layout_resize_output(
    struct tw_xdg_layout* l,
    struct tw_xdg_output* o
    );

void tw_xdg_layout_init(struct tw_xdg_layout* l);
void tw_xdg_layout_release(struct tw_xdg_layout* l);
void tw_xdg_layout_add_output(struct tw_xdg_layout* l, struct tw_xdg_output* o);
void tw_xdg_layout_rm_output(struct tw_xdg_layout* l, struct tw_xdg_output* o);

void tw_xdg_layout_resize_output(
    struct tw_xdg_layout* l,
    struct tw_xdg_output* o
    );

void tw_xdg_layout_init_floating(struct tw_xdg_layout* tw_xdg_layout);
void tw_xdg_layout_end_floating(struct tw_xdg_layout* l);
void tw_xdg_layout_init_maximized(struct tw_xdg_layout* layout);
void tw_xdg_layout_end_maximized(struct tw_xdg_layout* layout);
void tw_xdg_layout_init_fullscreen(struct tw_xdg_layout* layout);
void tw_xdg_layout_end_fullscreen(struct tw_xdg_layout* layout);
void tw_xdg_layout_init_tiling(struct tw_xdg_layout* layout);
void tw_xdg_layout_end_tiling(struct tw_xdg_layout* layout);

void tw_xdg_layout_emplace_noop(
    const enum tw_xdg_layout_command command,
    const struct tw_xdg_layout_op* arg,
    struct tw_xdg_view* v,
    struct tw_xdg_layout* l,
    struct tw_xdg_layout_op* ops
    );

static void emplace_float(
    const enum tw_xdg_layout_command command,
    const struct tw_xdg_layout_op* arg,
    struct tw_xdg_view* v,
    struct tw_xdg_layout* l,
    struct tw_xdg_layout_op* ops
    );

void tw_xdg_layout_init_floating(struct tw_xdg_layout* layout);
void tw_xdg_layout_end_floating(struct tw_xdg_layout* layout);

static void floating_add(
    const enum tw_xdg_layout_command command,
    const struct tw_xdg_layout_op* arg,
    struct tw_xdg_view* v,
    struct tw_xdg_layout* l,
    struct tw_xdg_layout_op* ops
    );

static void floating_deplace(
    const enum tw_xdg_layout_command command,
    const struct tw_xdg_layout_op* arg,
    struct tw_xdg_view* v,
    struct tw_xdg_layout* l,
    struct tw_xdg_layout_op* ops
    );

static void floating_resize(
    const enum tw_xdg_layout_command command,
    const struct tw_xdg_layout_op* arg,
    struct tw_xdg_view* v,
    struct tw_xdg_layout* l,
    struct tw_xdg_layout_op* ops
    );

static void emplace_fullscreen(
    const enum tw_xdg_layout_command command,
    const struct tw_xdg_layout_op* arg,
    struct tw_xdg_view* v,
    struct tw_xdg_layout* l,
    struct tw_xdg_layout_op* ops
    );

void tw_xdg_layout_init_fullscreen(struct tw_xdg_layout* layout);
void tw_xdg_layout_end_fullscreen(struct tw_xdg_layout* layout);

static void fullscreen_add(
    const enum tw_xdg_layout_command command,
    const struct tw_xdg_layout_op* arg,
    struct tw_xdg_view* v,
    struct tw_xdg_layout* l,
    struct tw_xdg_layout_op* ops
    );

static void emplace_maximized(
    const enum tw_xdg_layout_command command,
    const struct tw_xdg_layout_op* arg,
    struct tw_xdg_view* v,
    struct tw_xdg_layout* l,
    struct tw_xdg_layout_op* ops
    );

void tw_xdg_layout_init_maximized(struct tw_xdg_layout* layout);
void tw_xdg_layout_end_maximized(struct tw_xdg_layout* layout);

static void maximized_add(
    const enum tw_xdg_layout_command command,
    const struct tw_xdg_layout_op* arg,
    struct tw_xdg_view* v,
    struct tw_xdg_layout* l,
    struct tw_xdg_layout_op* ops
    );

void emplace_tiling(
    const enum tw_xdg_layout_command command,
    const struct tw_xdg_layout_op* arg,
    struct tw_xdg_view* v,
    struct tw_xdg_layout* l,
    struct tw_xdg_layout_op* ops
    );

static struct tiling_view* tiling_new_view(
    struct tw_xdg_view* v,
    struct tiling_output* output
    );

static void tiling_free_view(struct tiling_view* v);
static void _free_tiling_output_view(void* data);
void tw_xdg_layout_init_tiling(struct tw_xdg_layout* layout);
void tw_xdg_layout_end_tiling(struct tw_xdg_layout* l);

static struct tiling_output* tiling_output_find(
    struct tw_xdg_layout* l,
    struct tw_xdg_output* o
    );

static struct tiling_view* tiling_view_ith_node(
    struct tiling_view* parent,
    off_t index
    );

static int cmp_views(const void* v, const struct vtree_node* n);

static struct tiling_view* tiling_view_find(
    struct tiling_view* root,
    struct tw_xdg_view* v
    );

static void tiling_update_children(struct tiling_view* parent);

static bool is_subtree_valid(
    const pixman_rectangle32_t* space,
    const bool vertical,
    const float portions[],
    const size_t len,
    const struct tiling_output* constrain
    );

static bool tiling_view_insert(
    struct tiling_view* parent,
    struct tiling_view* tv,
    off_t offset,
    const pixman_rectangle32_t* parent_geo,
    const struct tiling_output* output
    );

static struct tiling_view* tiling_view_erase(struct tiling_view* view);

static bool tiling_view_resize(
    struct tiling_view* view,
    float delta_head,
    float delta_tail,
    const pixman_rectangle32_t* parent_geo,
    const struct tiling_output* output
    );

void tiling_view_shift(struct tiling_view* view, bool forward);

static pixman_rectangle32_t tiling_subtree_space(
    struct tiling_view* v,
    struct tiling_view* root,
    const pixman_rectangle32_t* space
    );

static int tiling_arrange_subtree(
    struct tiling_view* subtree,
    pixman_rectangle32_t* geo,
    struct tw_xdg_layout_op* data,
    const struct tiling_output* o
    );

static struct tiling_view* tiling_find_launch_point(
    struct tw_xdg_layout* l,
    struct tiling_output* to,
    struct tw_xdg_view* focused
    );

static void tiling_add(
    const enum tw_xdg_layout_command command,
    const struct tw_xdg_layout_op* arg,
    struct tw_xdg_view* v,
    struct tw_xdg_layout* l,
    struct tw_xdg_layout_op* ops
    );

static void tiling_del(
    const enum tw_xdg_layout_command command,
    const struct tw_xdg_layout_op* arg,
    struct tw_xdg_view* v,
    struct tw_xdg_layout* l,
    struct tw_xdg_layout_op* ops
    );

static enum wl_shell_surface_resize _tiling_resize_correct_edge(struct tiling_view* view);

static void _tiling_resize(
    const struct tw_xdg_layout_op* arg,
    struct tiling_view* view,
    struct tw_xdg_layout* l,
    struct tw_xdg_layout_op* ops,
    bool force_update
    );

static void tiling_resize(
    const enum tw_xdg_layout_command command,
    const struct tw_xdg_layout_op* arg,
    struct tw_xdg_view* v,
    struct tw_xdg_layout* l,
    struct tw_xdg_layout_op* ops
    );

static void _tiling_split(
    const enum tw_xdg_layout_command command,
    const struct tw_xdg_layout_op* arg,
    struct tw_xdg_view* v,
    struct tw_xdg_layout* l,
    bool vertical,
    struct tw_xdg_layout_op* ops
    );

static void tiling_vsplit(
    const enum tw_xdg_layout_command command,
    const struct tw_xdg_layout_op* arg,
    struct tw_xdg_view* v,
    struct tw_xdg_layout* l,
    struct tw_xdg_layout_op* ops
    );

static void tiling_hsplit(
    const enum tw_xdg_layout_command command,
    const struct tw_xdg_layout_op* arg,
    struct tw_xdg_view* v,
    struct tw_xdg_layout* l,
    struct tw_xdg_layout_op* ops
    );

static void tiling_merge(
    const enum tw_xdg_layout_command command,
    const struct tw_xdg_layout_op* arg,
    struct tw_xdg_view* v,
    struct tw_xdg_layout* l,
    struct tw_xdg_layout_op* ops
    );

static void tiling_toggle(
    const enum tw_xdg_layout_command command,
    const struct tw_xdg_layout_op* arg,
    struct tw_xdg_view* v,
    struct tw_xdg_layout* l,
    struct tw_xdg_layout_op* ops
    );

static void tiling_add_output(
    const enum tw_xdg_layout_command command,
    const struct tw_xdg_layout_op* arg,
    struct tw_xdg_view* v,
    struct tw_xdg_layout* l,
    struct tw_xdg_layout_op* ops
    );

static void tiling_rm_output(
    const enum tw_xdg_layout_command command,
    const struct tw_xdg_layout_op* arg,
    struct tw_xdg_view* v,
    struct tw_xdg_layout* l,
    struct tw_xdg_layout_op* ops
    );

static void tiling_resize_output(
    const enum tw_xdg_layout_command command,
    const struct tw_xdg_layout_op* arg,
    struct tw_xdg_view* v,
    struct tw_xdg_layout* l,
    struct tw_xdg_layout_op* ops
    );

struct tw_xdg_view* tw_xdg_view_create(struct tw_desktop_surface* dsurf);
void tw_xdg_view_destroy(struct tw_xdg_view* view);
void tw_xdg_view_set_position(struct tw_xdg_view* view, int x, int y);
static void tw_xdg_view_configure(struct tw_xdg_view* view);
void tw_xdg_view_set_focus(struct tw_xdg_view* view, bool focus);
static void tw_xdg_view_backup_geometry(struct tw_xdg_view* v);
struct tw_xdg_view* tw_xdg_view_from_tw_surface(struct tw_surface* surface);

void tw_workspace_init(
    struct tw_workspace* wp,
    struct tw_layers_manager* layers,
    uint32_t idx
    );

void tw_workspace_release(struct tw_workspace* ws);

bool tw_workspace_has_view(
    const struct tw_workspace* ws,
    const struct tw_xdg_view* v
    );

struct tw_xdg_view* tw_workspace_get_top_view(const struct tw_workspace* ws);

static struct tw_xdg_layout* tw_workspace_view_pick_layout(
    const struct tw_workspace* ws,
    const struct tw_xdg_view* v
    );

static struct tw_layer* tw_workspace_view_pick_layer(
    struct tw_workspace* ws,
    struct tw_xdg_view* v
    );

static void tw_workspace_view_pick_settings(
    struct tw_workspace* ws,
    struct tw_xdg_view* v
    );

static uint32_t tw_workspace_n_surfaces(
    const struct tw_workspace* ws,
    bool include_fullscreen
    );

static void apply_layout_operations(
    const struct tw_xdg_layout_op* ops,
    const int len
    );

static void arrange_view_for_layout(
    struct tw_workspace* ws,
    struct tw_xdg_layout* layout,
    struct tw_xdg_view* view,
    const enum tw_xdg_layout_command command,
    const struct tw_xdg_layout_op* arg
    );

static void arrange_view_for_workspace(
    struct tw_workspace* ws,
    struct tw_xdg_view* v,
    const enum tw_xdg_layout_command command,
    const struct tw_xdg_layout_op* arg
    );

struct tw_xdg_view* tw_workspace_switch(
    struct tw_workspace* to,
    struct tw_workspace* from
    );

static void tw_workspace_move_front_views(struct tw_workspace* ws);
bool tw_workspace_focus_view(struct tw_workspace* ws, struct tw_xdg_view* v);

struct tw_xdg_view* tw_workspace_defocus_view(
    struct tw_workspace* ws,
    struct tw_xdg_view* v
    );

static void tw_workspace_add_view_with_geometry(
    struct tw_workspace* w,
    struct tw_xdg_view* view,
    pixman_rectangle32_t* geo
    );

void tw_workspace_add_view(struct tw_workspace* w, struct tw_xdg_view* view);
bool tw_workspace_remove_view(struct tw_workspace* w, struct tw_xdg_view* view);

bool tw_workspace_move_view(
    struct tw_workspace* w,
    struct tw_xdg_view* view,
    double dx,
    double dy
    );

void tw_workspace_resize_view(
    struct tw_workspace* w,
    struct tw_xdg_view* v,
    double dx,
    double dy,
    enum wl_shell_surface_resize edge
    );

void tw_workspace_fullscreen_view(
    struct tw_workspace* w,
    struct tw_xdg_view* v,
    struct tw_xdg_output* output,
    bool fullscreen
    );

void tw_workspace_maximize_view(
    struct tw_workspace* w,
    struct tw_xdg_view* v,
    bool maximized
    );

void tw_workspace_minimize_view(struct tw_workspace* w, struct tw_xdg_view* v);

void tw_workspace_switch_layout(
    struct tw_workspace* w,
    enum tw_layout_type type
    );

void tw_workspace_run_command(
    struct tw_workspace* w,
    enum tw_xdg_layout_command command,
    struct tw_xdg_view* view
    );

void tw_workspace_add_output(
    struct tw_workspace* ws,
    struct tw_xdg_output* output
    );

void tw_workspace_resize_output(
    struct tw_workspace* ws,
    struct tw_xdg_output* output
    );

void tw_workspace_remove_output(
    struct tw_workspace* ws,
    struct tw_xdg_output* output
    );

struct tw_xdg_view* tw_xdg_view_create(struct tw_desktop_surface* dsurf);
void tw_xdg_view_destroy(struct tw_xdg_view* view);
void tw_xdg_view_set_position(struct tw_xdg_view* view, int x, int y);
void tw_xdg_view_set_focus(struct tw_xdg_view* view, bool focus);

void tw_workspace_init(
    struct tw_workspace* wp,
    struct tw_layers_manager* layers,
    uint32_t idx
    );

void tw_workspace_release(struct tw_workspace*);

struct tw_xdg_view* tw_workspace_switch(
    struct tw_workspace* to,
    struct tw_workspace* from
    );

struct tw_xdg_view* tw_workspace_get_top_view(const struct tw_workspace* ws);

bool tw_workspace_has_view(
    const struct tw_workspace* ws,
    const struct tw_xdg_view* v
    );

bool tw_workspace_empty(const struct tw_workspace* ws);
bool tw_workspace_focus_view(struct tw_workspace* ws, struct tw_xdg_view* v);

struct tw_xdg_view* tw_workspace_defocus_view(
    struct tw_workspace* ws,
    struct tw_xdg_view* v
    );

void tw_workspace_add_view(struct tw_workspace* w, struct tw_xdg_view* v);

bool tw_workspace_move_view(
    struct tw_workspace* w,
    struct tw_xdg_view* v,
    double dx,
    double dy
    );

void tw_workspace_resize_view(
    struct tw_workspace* w,
    struct tw_xdg_view* v,
    double dx,
    double dy,
    enum wl_shell_surface_resize edge
    );

void tw_workspace_run_command(
    struct tw_workspace* w,
    enum tw_xdg_layout_command command,
    struct tw_xdg_view* view
    );

bool tw_workspace_remove_view(struct tw_workspace* w, struct tw_xdg_view* v);

void tw_workspace_fullscreen_view(
    struct tw_workspace* w,
    struct tw_xdg_view* v,
    struct tw_xdg_output* output,
    bool fullscreen
    );

void tw_workspace_maximize_view(
    struct tw_workspace* w,
    struct tw_xdg_view* v,
    bool maximized
    );

void tw_workspace_minimize_view(struct tw_workspace* w, struct tw_xdg_view* v);

void tw_workspace_switch_layout(
    struct tw_workspace* w,
    enum tw_layout_type type
    );

void tw_workspace_add_output(
    struct tw_workspace* wp,
    struct tw_xdg_output* output
    );

void tw_workspace_remove_output(
    struct tw_workspace* w,
    struct tw_xdg_output* output
    );

void tw_workspace_resize_output(
    struct tw_workspace* wp,
    struct tw_xdg_output* output
    );

static struct tw_xdg_output* xdg_output_from_backend_output(
    struct tw_xdg* xdg,
    struct tw_backend_output* output
    );

static bool twdesk_view_should_map_immediately(struct tw_xdg_view* view);

static struct tw_workspace* twdesk_view_find_workspace(
    struct tw_xdg* xdg,
    struct tw_xdg_view* view
    );

static void twdesk_surface_focus(
    struct tw_xdg* xdg,
    struct tw_desktop_surface* dsurf
    );

static void twdesk_refocus(void* user_data);

static void twdesk_ping_timeout(
    struct tw_desktop_surface* client,
    void* user_data
    );

static void twdesk_pong(struct tw_desktop_surface* client, void* user_data);

static void twdesk_surface_added(
    struct tw_desktop_surface* dsurf,
    void* user_data
    );

static void twdesk_surface_removed(
    struct tw_desktop_surface* dsurf,
    void* user_data
    );

static void twdesk_surface_committed(
    struct tw_desktop_surface* dsurf,
    void* user_data
    );

static void twdesk_surface_show_window_menu(
    struct tw_desktop_surface* surface,
    struct wl_resource* seat,
    int32_t x,
    int32_t y,
    void* user_data
    );

static void twdesk_set_parent(
    struct tw_desktop_surface* surface,
    struct tw_desktop_surface* parent,
    void* user_data
    );

static void twdesk_surface_move(
    struct tw_desktop_surface* dsurf,
    struct wl_resource* seat_resource,
    uint32_t serial,
    void* user_data
    );

static void twdesk_surface_resize(
    struct tw_desktop_surface* dsurf,
    struct wl_resource* seat_resource,
    uint32_t serial,
    enum wl_shell_surface_resize edge,
    void* user_data
    );

static void twdesk_fullscreen(
    struct tw_desktop_surface* dsurf,
    struct wl_resource* output_resource,
    bool fullscreen,
    void* user_data
    );

static void twdesk_maximized(
    struct tw_desktop_surface* dsurf,
    bool maximized,
    void* user_data
    );

static void twdesk_minimized(struct tw_desktop_surface* dsurf, void* user_data);

static void handle_desktop_output_create(
    struct wl_listener* listener,
    void* data
    );

static void handle_desktop_output_destroy(
    struct wl_listener* listener,
    void* data
    );

static void handle_desktop_area_change(struct wl_listener* listener, void* data);
static void end_desktop(struct wl_listener* listener, UNUSED_ARG(void*data));
static void init_desktop_listeners(struct tw_xdg* xdg);
static void init_desktop_workspaces(struct tw_xdg* xdg);
static void init_desktop_layouts(struct tw_xdg* xdg);
void tw_xdg_view_activate(struct tw_xdg* xdg, struct tw_xdg_view* view);
void tw_xdg_toggle_view_split(struct tw_xdg* xdg, struct tw_xdg_view* view);
void tw_xdg_toggle_view_layout(struct tw_xdg* xdg, struct tw_xdg_view* view);

void tw_xdg_split_on_view(
    struct tw_xdg* xdg,
    struct tw_xdg_view* view,
    bool vsplit
    );

void tw_xdg_merge_view(struct tw_xdg* xdg, struct tw_xdg_view* view);

void tw_xdg_resize_view(
    struct tw_xdg* xdg,
    struct tw_xdg_view* view,
    int32_t dx,
    int32_t dy,
    enum wl_shell_surface_resize edge
    );

int tw_xdg_current_workspace_idx(struct tw_xdg* xdg);
int tw_xdg_last_workspace_idx(struct tw_xdg* xdg);

void tw_xdg_set_workspace_layout(
    struct tw_xdg* xdg,
    int32_t idx,
    enum tw_layout_type layout
    );

void tw_xdg_switch_workspace(struct tw_xdg* xdg, uint32_t to);
const char* tw_xdg_workspace_layout_name(struct tw_xdg* xdg, uint32_t i);
int tw_xdg_layout_type_from_name(const char* name);
void tw_xdg_set_desktop_gap(struct tw_xdg* xdg, uint32_t igap, uint32_t ogap);

struct tw_xdg* tw_xdg_create_global(
    struct wl_display* display,
    struct tw_shell* shell,
    struct tw_backend* backend
    );

static void tw_xdg_grab_interface_destroy(struct tw_xdg_grab_interface* gi);

static void notify_grab_interface_view_destroy(
    struct wl_listener* listener,
    void* data
    );

static struct tw_xdg_grab_interface* tw_xdg_grab_interface_create(
    struct tw_xdg_view* view,
    struct tw_xdg* xdg,
    const struct tw_pointer_grab_interface* pi,
    const struct tw_keyboard_grab_interface* ki,
    const struct tw_touch_grab_interface* ti
    );

static void handle_move_pointer_grab_motion(
    struct tw_seat_pointer_grab* grab,
    uint32_t time_msec,
    double sx,
    double sy
    );

static void handle_move_pointer_grab_button(
    struct tw_seat_pointer_grab* grab,
    uint32_t time_msec,
    uint32_t button,
    enum wl_pointer_button_state state
    );

static void handle_move_pointer_grab_cancel(struct tw_seat_pointer_grab* grab);

static void handle_resize_pointer_grab_motion(
    struct tw_seat_pointer_grab* grab,
    uint32_t time_msec,
    double sx,
    double sy
    );

static bool find_task_view(struct tw_workspace* ws, struct tw_xdg_view* view);

static void handle_task_switching_key(
    struct tw_seat_keyboard_grab* grab,
    uint32_t time_msec,
    uint32_t key,
    uint32_t state
    );

static void handle_task_switching_modifiers(
    struct tw_seat_keyboard_grab* grab,
    uint32_t mods_depressed,
    uint32_t mods_latched,
    uint32_t mods_locked,
    uint32_t group
    );

static void handle_task_switching_cancel(struct tw_seat_keyboard_grab* grab);

bool tw_xdg_start_moving_grab(
    struct tw_xdg* xdg,
    struct tw_xdg_view* view,
    struct tw_seat* seat
    );

bool tw_xdg_start_resizing_grab(
    struct tw_xdg* xdg,
    struct tw_xdg_view* view,
    enum wl_shell_surface_resize edge,
    struct tw_seat* seat
    );

bool tw_xdg_start_task_switching_grab(
    struct tw_xdg* xdg,
    uint32_t time,
    uint32_t key,
    uint32_t modifiers_state,
    struct tw_seat* seat
    );

struct tw_backend* tw_backend_create_global(
    struct wl_display* display,
    wlr_renderer_create_func_t render_create
    );

void tw_backend_flush(struct tw_backend* backend);
void* tw_backend_get_backend(struct tw_backend* backend);
struct tw_backend_output* tw_backend_focused_output(struct tw_backend* backend);
struct tw_backend_output* tw_backend_output_from_cursor_pos(struct tw_backend* backend);
struct tw_backend_output* tw_backend_output_from_resource(struct wl_resource* resource);
void tw_backend_defer_outputs(struct tw_backend* backend, bool defer);
void tw_backend_commit_output_state(struct tw_backend_output* o);

void tw_backend_add_listener(
    struct tw_backend* backend,
    enum tw_backend_event_type event,
    struct wl_listener* listener
    );

struct tw_backend_output* tw_backend_find_output(
    struct tw_backend* backend,
    const char* name
    );

struct tw_surface* tw_backend_pick_surface_from_layers(
    struct tw_backend* backend,
    float x,
    float y,
    float* sx,
    float* sy
    );

void tw_backend_build_surface_list(struct tw_backend* backend);
void tw_backend_set_output_scale(struct tw_backend_output* output, float scale);

void tw_backend_set_output_transformation(
    struct tw_backend_output* output,
    enum wl_output_transform transform
    );

int tw_backend_get_output_modes(
    struct tw_backend_output* output,
    struct tw_backend_output_mode* modes
    );

void tw_backend_set_output_mode(
    struct tw_backend_output* output,
    const struct tw_backend_output_mode* mode
    );

void tw_backend_set_output_position(
    struct tw_backend_output* output,
    uint32_t x,
    uint32_t y
    );

void tw_backend_output_clone(
    struct tw_backend_output* dst,
    const struct tw_backend_output* src
    );

void tw_backend_output_enable(struct tw_backend_output* output, bool enable);
void tw_backend_output_set_gamma(struct tw_backend_output* output, float gamma);
void tw_backend_output_dirty(struct tw_backend_output* output);

struct wl_resource* tw_backend_output_get_wl_output(
    struct tw_backend_output* output,
    struct wl_resource* reference
    );

struct tw_backend_seat* tw_backend_get_focused_seat(struct tw_backend* backend);

void tw_backend_seat_set_xkb_rules(
    struct tw_backend_seat* seat,
    struct xkb_rule_names* rules
    );

void tw_backend_set_repeat_info(
    struct tw_backend* backend,
    unsigned int rate,
    unsigned int delay
    );

void tw_backend_switch_session(struct tw_backend* backend, uint32_t session);
struct tw_bindings* tw_bindings_create(struct wl_display*);
void tw_bindings_move(struct tw_bindings* dst, struct tw_bindings* src);
void tw_bindings_destroy(struct tw_bindings*);

bool tw_bindings_add_key(
    struct tw_bindings* root,
    const struct tw_key_press presses[MAX_KEY_SEQ_LEN],
    const tw_key_binding binding,
    uint32_t option,
    void* data
    );

bool tw_bindings_add_btn(
    struct tw_bindings* root,
    const struct tw_btn_press* press,
    const tw_btn_binding binding,
    void* data
    );

bool tw_bindings_add_axis(
    struct tw_bindings* root,
    const struct tw_axis_motion* motion,
    const tw_axis_binding binding,
    void* data
    );

bool tw_bindings_add_touch(
    struct tw_bindings* root,
    uint32_t modifier,
    const tw_touch_binding binding,
    void* data
    );

struct tw_binding_node* tw_bindings_find_key(
    struct tw_bindings* bindings,
    uint32_t key,
    uint32_t mod_mask
    );

struct tw_binding* tw_bindings_find_btn(
    struct tw_bindings* bindings,
    uint32_t btn,
    uint32_t mod_mask
    );

struct tw_binding* tw_bindings_find_axis(
    struct tw_bindings* bindings,
    enum wl_pointer_axis action,
    uint32_t mod_mask
    );

struct tw_binding* tw_bindings_find_touch(
    struct tw_bindings* bindings,
    uint32_t mod_mask
    );

struct tw_binding* tw_binding_node_get_binding(struct tw_binding_node* state);

struct tw_binding_node* tw_binding_node_step(
    struct tw_binding_node* keystate,
    uint32_t keycode,
    uint32_t mod_mask
    );

void tw_bindings_print(struct tw_bindings* root);

struct tw_config* tw_config_create(
    struct tw_backend* backend,
    struct tw_bindings* bindings
    );

bool tw_run_config(struct tw_config* config);
bool tw_run_default_config(struct tw_config* c);
void tw_config_destroy(struct tw_config* config);

void tw_config_register_object(
    struct tw_config* config,
    const char* name,
    void* obj
    );

void* tw_config_request_object(struct tw_config* config, const char* name);

struct tw_xdg* tw_xdg_create_global(
    struct wl_display* display,
    struct tw_shell* shell,
    struct tw_backend* backend
    );

int tw_xdg_current_workspace_idx(struct tw_xdg* xdg);
int tw_xdg_last_workspace_idx(struct tw_xdg* xdg);
void tw_xdg_switch_workspace(struct tw_xdg* xdg, uint32_t to);
const char* tw_xdg_workspace_layout_name(struct tw_xdg* xdg, uint32_t i);

void tw_xdg_set_workspace_layout(
    struct tw_xdg* xdg,
    int32_t idx,
    enum tw_layout_type layout
    );

int tw_xdg_layout_type_from_name(const char* name);
void tw_xdg_set_desktop_gap(struct tw_xdg* xdg, uint32_t igap, uint32_t ogap);
struct tw_xdg_view* tw_xdg_view_from_tw_surface(struct tw_surface* surface);
void tw_xdg_view_activate(struct tw_xdg* xdg, struct tw_xdg_view* view);
void tw_xdg_toggle_view_split(struct tw_xdg* xdg, struct tw_xdg_view* view);
void tw_xdg_toggle_view_layout(struct tw_xdg* xdg, struct tw_xdg_view* view);

void tw_xdg_split_on_view(
    struct tw_xdg* xdg,
    struct tw_xdg_view* view,
    bool vsplit
    );

void tw_xdg_merge_view(struct tw_xdg* xdg, struct tw_xdg_view* view);

void tw_xdg_resize_view(
    struct tw_xdg* xdg,
    struct tw_xdg_view* view,
    int32_t dx,
    int32_t dy,
    enum wl_shell_surface_resize edge
    );

bool tw_xdg_start_moving_grab(
    struct tw_xdg* xdg,
    struct tw_xdg_view* view,
    struct tw_seat* seat
    );

bool tw_xdg_start_resizing_grab(
    struct tw_xdg* xdg,
    struct tw_xdg_view* view,
    enum wl_shell_surface_resize edge,
    struct tw_seat* seat
    );

bool tw_xdg_start_task_switching_grab(
    struct tw_xdg* xdg,
    uint32_t time,
    uint32_t key,
    uint32_t modifiers_state,
    struct tw_seat* seat
    );

static uint32_t curr_modmask(struct tw_seat_events* seat_events);
static uint32_t curr_ledmask(struct tw_seat_events* seat_events);
static void binding_key_cancel(struct tw_seat_keyboard_grab* grab);

static void binding_key(
    struct tw_seat_keyboard_grab* grab,
    uint32_t time_msec,
    uint32_t key,
    uint32_t state
    );

static void binding_pointer_cancel(struct tw_seat_pointer_grab* grab);

static void binding_btn(
    struct tw_seat_pointer_grab* grab,
    uint32_t time,
    uint32_t button,
    enum wl_pointer_button_state state
    );

static void binding_axis(
    struct tw_seat_pointer_grab* grab,
    uint32_t time_msec,
    enum wl_pointer_axis orientation,
    double value,
    int32_t value_discrete,
    enum wl_pointer_axis_source source
    );

static void binding_touch(
    struct tw_seat_touch_grab* grab,
    uint32_t time,
    uint32_t touch_id,
    double sx,
    double sy
    );

static void binding_touch_cancel(struct tw_seat_touch_grab* grab);

static int session_switch_get_index(
    uint32_t key,
    struct tw_seat_events* seat_events
    );

static void session_switch_key(
    struct tw_seat_keyboard_grab* grab,
    uint32_t time_msec,
    uint32_t key,
    uint32_t state
    );

static void handle_key_input(struct wl_listener* listener, void* data);
static void handle_modifiers_input(struct wl_listener* listener, void* data);
static void handle_btn_input(struct wl_listener* listener, void* data);
static void handle_axis_input(struct wl_listener* listener, void* data);
static void handle_touch_input(struct wl_listener* listener, void* data);
static void handle_seat_change(struct wl_listener* listener, void* data);

void tw_seat_events_init(
    struct tw_seat_events* seat_events,
    struct tw_backend_seat* seat,
    struct tw_bindings* bindings
    );

void tw_seat_events_fini(struct tw_seat_events* seat_events);

void tw_seat_events_init(
    struct tw_seat_events* events,
    struct tw_backend_seat* seat,
    struct tw_bindings* bindings
    );

void tw_seat_events_fini(struct tw_seat_events* events);
void tw_bindings_add_dummy(struct tw_bindings* bindings);
static bool bind_backend(struct tw_server* server);
static bool bind_config(struct tw_server* server);
static void notify_adding_seat(struct wl_listener* listener, void* data);
static void notify_removing_seat(struct wl_listener* listener, void* data);
static void bind_listeners(struct tw_server* server);
static bool tw_server_init(struct tw_server* server, struct wl_display* display);
static void tw_server_fini(struct tw_server* server);
static bool tw_set_socket(struct wl_display* display);
static int tw_term_on_signal(int sig_num, void* data);
static int tw_handle_sigchld(int sig_num, void* data);
static bool drop_permissions(void);
static void print_help(void);
static void verify_set_executable(const char** dst, const char* src);
static void parse_options(struct tw_options* options, int argc, char** argv);
int main(int argc, char* argv[]);

static void surface_accumulate_damage(
    struct tw_surface* surface,
    pixman_region32_t* clipped
    );

static void tw_layer_renderer_stack_damage(
    struct tw_backend* backend,
    struct tw_plane* plane
    );

static void layer_renderer_scissor_surface(
    struct tw_renderer* renderer,
    struct tw_backend_output* output,
    pixman_box32_t* box
    );

static void layer_renderer_draw_quad(bool y_inverted);

static void layer_renderer_cleanup_buffer(
    struct tw_renderer* renderer,
    struct tw_backend_output* output
    );

static void layer_renderer_paint_surface(
    struct tw_surface* surface,
    struct tw_layer_renderer* rdr,
    struct tw_backend_output* o,
    pixman_region32_t* output_damage
    );

static void layer_renderer_compose_output_buffer_damage(
    struct tw_backend_output* output,
    pixman_region32_t* damage,
    int buffer_age
    );

static void layer_renderer_repaint_output(
    struct tw_renderer* renderer,
    struct tw_backend_output* output,
    int buffer_age
    );

static void layer_renderer_handle_surface_destroy(
    struct tw_renderer* renderer,
    struct tw_surface* surface
    );

static void tw_layer_renderer_destroy(struct wlr_renderer* wlr_renderer);

struct wlr_renderer* tw_layer_renderer_create(
    struct wlr_egl* egl,
    EGLenum platform,
    void* remote_display,
    EGLint* config_attribs,
    EGLint visual_id
    );

static struct tw_renderer* tw_renderer_from_wlr_renderer(struct wlr_renderer* wlr_renderer);

static void base_begin(
    struct wlr_renderer* wlr_renderer,
    uint32_t width,
    uint32_t height
    );

static void base_end(struct wlr_renderer* wlr_renderer);

static void base_clear(
    struct wlr_renderer* wlr_renderer,
    const float color[static 4]
    );

static void base_scissor(struct wlr_renderer* wlr_renderer, struct wlr_box* box);

static bool base_init_wl_display(
    struct wlr_renderer* wlr_renderer,
    struct wl_display* display
    );

static bool noop_render_texture_with_matrix(
    struct wlr_renderer* renderer,
    struct wlr_texture* texture,
    const float matrix[static 9],
    float alpha
    );

static void noop_render_quad_with_matrix(
    struct wlr_renderer* renderer,
    const float color[static 4],
    const float matrix[static 9]
    );

static void noop_render_ellipse_with_matrix(
    struct wlr_renderer* wlr_renderer,
    const float color[static 4],
    const float matrix[static 9]
    );

static enum wl_shm_format* base_formats(
    struct wlr_renderer* wlr_renderer,
    size_t* len
    );

static bool base_format_supported(
    struct wlr_renderer* wlr_renderer,
    enum wl_shm_format fmt
    );

static struct wlr_texture* noop_texture_from_pixels(
    struct wlr_renderer* renderer,
    enum wl_shm_format fmt,
    uint32_t stride,
    uint32_t width,
    uint32_t height,
    const void* data
    );

static enum TW_LOG_LEVEL gles_get_log_level(GLenum type);

static void gles2_log(
    GLenum src,
    GLenum type,
    GLuint id,
    GLenum severity,
    GLsizei len,
    const GLchar* msg,
    const void* user
    );

void tw_gles_debug_push(const char* func);
void tw_gles_debug_pop(void);

static bool add_wl_shm_format(
    struct tw_renderer* renderer,
    enum wl_shm_format format
    );

static bool check_glext(const char* exts, const char* ext);
static void* get_glproc(const char* name);
static bool query_extensions(struct tw_renderer* renderer);

bool tw_renderer_init(
    struct tw_renderer* renderer,
    struct wlr_egl* egl,
    EGLenum platform,
    void* remote_display,
    EGLint visual_id
    );

void tw_renderer_fini(struct tw_renderer* renderer);
void tw_gles_debug_push(const char* func);
void tw_gles_debug_pop(void);

bool tw_renderer_import_dma(
    struct tw_render_texture* texture,
    struct tw_renderer* rdr,
    struct tw_dmabuf_attributes* dma_attributes
    );

bool tw_renderer_texture_update(
    struct tw_render_texture* texture,
    struct tw_renderer* rdr,
    struct wl_shm_buffer* shmbuf,
    uint32_t src_x,
    uint32_t src_y,
    uint32_t dst_x,
    uint32_t dst_y,
    uint32_t width,
    uint32_t height
    );

bool tw_renderer_init_texture(
    struct tw_render_texture* texture,
    struct tw_renderer* rdr,
    struct wl_resource* buffer
    );

struct tw_render_texture* tw_renderer_new_texture(
    struct tw_renderer* rdr,
    struct wl_resource* buffer
    );

void tw_render_texture_destroy(struct tw_render_texture* texture);

bool tw_renderer_init(
    struct tw_renderer* renderer,
    struct wlr_egl* egl,
    EGLenum platform,
    void* remote_display,
    EGLint visual_id
    );

void tw_renderer_fini(struct tw_renderer* renderer);

struct wlr_renderer* tw_layer_renderer_create(
    struct wlr_egl* egl,
    EGLenum platform,
    void* remote_display,
    EGLint* config_attribs,
    EGLint visual_id
    );

static void diagnose_shader(GLuint shader, GLenum type);
static void diagnose_program(GLuint prog);
static GLuint compile_shader(GLenum type, const GLchar* src);
GLuint tw_renderer_create_program(const GLchar* vs_src, const GLchar* fs_src);
void tw_quad_color_shader_init(struct tw_quad_color_shader* shader);
void tw_quad_color_shader_fini(struct tw_quad_color_shader* shader);
void tw_quad_tex_blend_shader_init(struct tw_quad_tex_shader* shader);
void tw_quad_tex_blend_shader_fini(struct tw_quad_tex_shader* shader);
void tw_quad_tex_ext_blend_shader_init(struct tw_quad_tex_shader* shader);
void tw_quad_tex_ext_blend_shader_fini(struct tw_quad_tex_shader* shader);
void tw_quad_tex_blur_shader_init(struct tw_quad_tex_shader* shader);
void tw_quad_tex_blur_shader_fini(struct tw_quad_tex_shader* shader);
GLuint tw_renderer_create_program(const GLchar* vs_src, const GLchar* fs_src);
void tw_quad_color_shader_init(struct tw_quad_color_shader* shader);
void tw_quad_color_shader_fini(struct tw_quad_color_shader* shader);
void tw_quad_tex_blend_shader_init(struct tw_quad_tex_shader* shader);
void tw_quad_tex_blend_shader_fini(struct tw_quad_tex_shader* shader);
void tw_quad_tex_ext_blend_shader_init(struct tw_quad_tex_shader* shader);
void tw_quad_tex_ext_blend_shader_fini(struct tw_quad_tex_shader* shader);
void tw_quad_tex_blur_shader_init(struct tw_quad_tex_shader* shader);
void tw_quad_tex_blur_shader_fini(struct tw_quad_tex_shader* shader);

static bool wl_format_supported(
    struct tw_renderer* renderer,
    enum wl_shm_format format
    );

static GLuint wl_format_to_gl_format(enum wl_shm_format format);
static bool wl_format_has_alpha(enum wl_shm_format format);
static void tw_render_texture_fini(struct tw_render_texture* texture);
static void tw_render_texture_free(struct tw_render_texture* texture);
void tw_render_texture_destroy(struct tw_render_texture* texture);

static bool tw_render_texture_init_pixels(
    struct tw_render_texture* texture,
    struct tw_renderer* rdr,
    struct wl_shm_buffer* buffer
    );

static bool wl_buffer_is_drm_texture(
    struct tw_renderer* rdr,
    struct wl_resource* buffer
    );

static bool tw_render_texture_init_wl_drm(
    struct tw_render_texture* texture,
    struct tw_renderer* rdr,
    struct wl_resource* buffer
    );

static void dma_attributes_translate(
    struct wlr_dmabuf_attributes* dst,
    struct tw_dmabuf_attributes* src
    );

static bool tw_render_texture_init_dma(
    struct tw_render_texture* texture,
    struct tw_renderer* rdr,
    struct tw_dmabuf_attributes* dma_attributes
    );

bool tw_renderer_init_texture(
    struct tw_render_texture* texture,
    struct tw_renderer* rdr,
    struct wl_resource* buffer
    );

struct tw_render_texture* tw_renderer_new_texture(
    struct tw_renderer* rdr,
    struct wl_resource* buffer
    );

bool tw_renderer_texture_update(
    struct tw_render_texture* texture,
    struct tw_renderer* rdr,
    struct wl_shm_buffer* buffer,
    uint32_t src_x,
    uint32_t src_y,
    uint32_t dst_x,
    uint32_t dst_y,
    uint32_t width,
    uint32_t height
    );

bool tw_renderer_import_dma(
    struct tw_render_texture* texture,
    struct tw_renderer* rdr,
    struct tw_dmabuf_attributes* dma_attributes
    );

bool shell_impl_layer_shell(struct tw_shell* shell, struct wl_display* display);

struct tw_shell_ui* shell_create_ui_element(
    struct tw_shell* shell,
    struct tw_shell_ui* elem,
    struct wl_resource* ui_resource,
    struct tw_surface* surface,
    struct tw_shell_output* output,
    uint32_t x,
    uint32_t y,
    struct tw_layer* layer,
    tw_surface_commit_cb_t commit_cb
    );

void shell_ui_set_role(
    struct tw_shell_ui* ui,
    void(*)(struct tw_surface*surface) commit,
    struct tw_surface* surface
    );

struct tw_shell_output* shell_output_from_backend_output(
    struct tw_shell* shell,
    struct tw_backend_output* output
    );

static void calculate_geometry(void* user_data);
static void shell_ui_calculate_geometry_idle(struct tw_shell_ui* ui);
static struct tw_shell_ui* shell_ui_from_resource(struct wl_resource* resource);

static void resource_handle_destroy(
    struct wl_client* client,
    struct wl_resource* resource
    );

static void layer_surface_handle_set_size(
    struct wl_client* client,
    struct wl_resource* resource,
    uint32_t width,
    uint32_t height
    );

static void layer_surface_handle_ack_configure(
    struct wl_client* client,
    struct wl_resource* resource,
    uint32_t serial
    );

static void layer_surface_handle_set_anchor(
    struct wl_client* client,
    struct wl_resource* resource,
    uint32_t anchor
    );

static void layer_surface_handle_set_exclusive_zone(
    struct wl_client* client,
    struct wl_resource* resource,
    int32_t zone
    );

static void layer_surface_set_keyboard_interactivity(
    struct wl_client* client,
    struct wl_resource* resource,
    uint32_t keyboard_interactivity
    );

static void layer_surface_handle_set_margin(
    struct wl_client* client,
    struct wl_resource* resource,
    int32_t top,
    int32_t right,
    int32_t bottom,
    int32_t left
    );

static void layer_surface_handle_get_popup(
    struct wl_client* client,
    struct wl_resource* resource,
    struct wl_resource* popup
    );

static void layer_surface_set_layer(
    struct wl_client* client,
    struct wl_resource* resource,
    uint32_t layer
    );

static void layer_surface_destroy_resource(struct wl_resource* resource);
static struct tw_shell* tw_shell_from_layer_shell_resoruce(struct wl_resource* resource);
static void commit_layer_surface(struct tw_surface* surface);

static void layer_shell_handle_get_layer_surface(
    struct wl_client* wl_client,
    struct wl_resource* client_resource,
    uint32_t id,
    struct wl_resource* surface_resource,
    struct wl_resource* output_resource,
    uint32_t layer,
    const char* namespace
    );

static void bind_layer_shell(
    struct wl_client* client,
    void* data,
    uint32_t version,
    uint32_t id
    );

bool shell_impl_layer_shell(struct tw_shell* shell, struct wl_display* display);
struct tw_theme_global* tw_theme_get_global(void);
void tw_theme_notify(struct tw_theme_global* theme, struct tw_theme* new_theme);
static void unbind_theme(struct wl_resource* resource);

static void bind_theme(
    struct wl_client* client,
    void* data,
    UNUSED_ARG(uint32_t version),
    uint32_t id
    );

static void end_theme(struct wl_listener* listener, void* data);
struct tw_theme_global* tw_theme_create_global(struct wl_display* display);
static tw_rgba_t tw_make_rgba(int r, int g, int b, int a);
static tw_vec2_t tw_make_vec2(float x, float y);
static theme_option_style tw_make_color_item(tw_rgba_t rgba);
static theme_option_style tw_make_transparent_item();

static void tw_make_trans_button(
    struct tw_style_button* button,
    tw_rgba_t bg_color,
    tw_rgba_t text_color,
    float padding,
    float rounding
    );

static void tw_make_trans_edit(
    struct tw_style_edit* edit,
    tw_rgba_t bg_color,
    tw_rgba_t text_color,
    tw_rgba_t edit_color,
    struct tw_style_scrollbar* scroll,
    tw_vec2_t bar_size,
    float padding,
    float rounding
    );

WL_EXPORT void tw_theme_init_from_fd(
    struct tw_theme* theme,
    int fd,
    size_t size
    );

WL_EXPORT int tw_theme_to_fd(struct tw_theme* theme);
WL_EXPORT void tw_theme_init_default(struct tw_theme* theme);
WL_EXPORT void tw_theme_fini(struct tw_theme* theme);
static void tw_xwayland_handle_chld(struct tw_subprocess* chld, int status);

static void tw_xwayland_on_destroy(
    struct wl_listener* listener,
    UNUSED_ARG(void*data)
    );

static int tw_xwayland_handle_sigusr1(UNUSED_ARG(int signal_number), void* data);
static int tw_xwayland_fork(pid_t pid, struct tw_subprocess* chld);
static int tw_xwayland_exec(const char* path, struct tw_subprocess* chld);

static pid_t tw_spawn_xwayland(
    void* user_data,
    const char* display,
    int abstract_fd,
    int unix_fd
    );

struct tw_xwayland* tw_xwayland_get_global();
void tw_xwayland_enable(struct tw_xwayland* tw_xwayland, bool enable);
struct tw_xwayland* tw_setup_xwayland(struct weston_compositor* ec);
struct tw_decision_key __attribute__((aligned(DECISION_STRIDE)));
static void tw_config_dir(char config_home[PATH_MAX]);
static bool tw_create_config_dir(void);
static void tw_cache_dir(char cache_home[PATH_MAX]);
static bool tw_create_cache_dir(void);
add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/twclient");
nklua add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/tdbus");
taiwins protocols PARENT_SCOPE set(RAX_DIR "${CMAKE_CURRENT_SOURCE_DIR}/rax");
add_library(rax STATIC ${RAX_DIR}/rax. c);
target_link_libraries(rax PRIVATE m);
libweston set(LIBWESTON_BUILD_DIR "${CMAKE_BINARY_DIR}/libweston");
libweston install set();
libweston taiwins include(WestonVersionParser);
ExternalProject_Add();
cmake_minimum_required(VERSION 3.1. 0);
lib set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/ lib);
bin set(CMAKE_C_STANDARD 11);
cmake_minimum_required(VERSION 3.12. 0);
cmake_minimum_required(VERSION 3.12. 0);
add_library(twclient OBJECT client.c appsurf.c egl.c glhelper.c buffer.c event_queue.c keyboard.c pointer. c);
cmake_minimum_required(VERSION 3.1. 0);
lib set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/ lib);
bin set(CMAKE_C_STANDARD 11);
hash_cmp_val hash_cmp_str(const void* sa, const void* sb);
uint64_t hash_djb2(const void* str);
uint64_t hash_sdbm(const void* str);

void dhash_init(
    dhashtab_t* t,
    hash_func_t h0,
    hash_func_t h1,
    hash_cmp_func_t cmp,
    size_t keysize,
    size_t esize,
    freefun keyfree,
    freefun datafree
    );

void dhash_destroy(dhashtab_t* t);
void dhash_insert(dhashtab_t* t, const void* key, const void* elem);
void* dhash_search(dhashtab_t* t, const void* key);
hash_cmp_val hash_cmp_str(const void* sa, const void* sb);
uint64_t hash_djb2(const void* str);
uint64_t hash_sdbm(const void* str);

void dhash_init(
    dhashtab_t* t,
    hash_func_t h0,
    hash_func_t h1,
    hash_cmp_func_t cmp,
    size_t keysize,
    size_t esize,
    freefun keyfree,
    freefun datafree
    );

void dhash_destroy(dhashtab_t* t);
void dhash_insert(dhashtab_t* t, const void* key, const void* elem);
void* dhash_search(dhashtab_t* t, const void* key);
void dummy_free(void* addr);
void dummy_free(void* addr);
void list_init(list_t* list);
void list_insert(list_t* list, list_t* elm);
list_t* list_insert_list(list_t* list, list_t* another);
void list_append(list_t* list, list_t* other);
list_t* list_append_list(list_t* list, list_t* ol);
void list_swap(list_t* one, list_t* another);
int list_length(const list_t* list);
void list_remove(list_t* elm);
bool list_empty(const list_t* header);
void list_init(list_t* list);
void list_insert(list_t* list, list_t* elm);
list_t* list_insert_list(list_t* list, list_t* another);
void list_append(list_t* list, list_t* other);
list_t* list_append_list(list_t* list, list_t* ol);
void list_swap(list_t* one, list_t* another);
int list_length(const list_t* list);
void list_remove(list_t* elm);
bool list_empty(const list_t* header);

int anonymous_buff_new(
    struct anonymous_buff_t* buff,
    off_t size,
    int prot,
    int flags
    );

int anonymous_buff_alloc_by_offset(struct anonymous_buff_t* buff, off_t newsize);
void* anonymous_buff_alloc_by_addr(struct anonymous_buff_t* buff, off_t newsize);
int anonymous_buff_resize(struct anonymous_buff_t* buff, off_t size);
void anonymous_buff_close_file(struct anonymous_buff_t* buff);

int anonymous_buff_new(
    struct anonymous_buff_t* buff,
    off_t size,
    int prot,
    int flags
    );

int anonymous_buff_alloc_by_offset(struct anonymous_buff_t* buff, off_t newsize);
void* anonymous_buff_alloc_by_addr(struct anonymous_buff_t* buff, off_t newsize);
int anonymous_buff_resize(struct anonymous_buff_t* buff, off_t size);
void anonymous_buff_close_file(struct anonymous_buff_t* buff);
int fork_exec(int argc, char*const argv[]);
int fork_exec(int argc, char*const argv[]);
size_t file_read(const char* f, char* mem, int max_size);
bool is_dir_empty(DIR* dir);
int mkdir_p(const char* path, mode_t mode);
bool find_executable(const char* exe, char* fullpath, unsigned max_len);
static bool is_file_exist(const char* abs_path);
static bool is_dir_exist(const char* abs_path);
static bool is_file_type(const char* f, const char* niddle);
static struct dirent* dir_find_pattern(DIR* dir, const char* format, ...);
static char* path_concat(char* path, int max_len, int narg, ...);
static char* path_join(char* path, int max_len, int narg, ...);
size_t file_read(const char* f, char* mem, int max_size);
bool is_dir_empty(DIR* dir);
int mkdir_p(const char* path, mode_t mode);
bool find_executable(const char* exe, char* fullpath, unsigned max_len);
static bool is_file_exist(const char* abs_path);
static bool is_dir_exist(const char* abs_path);
static bool is_file_type(const char* f, const char* niddle);
static struct dirent* dir_find_pattern(DIR* dir, const char* format, ...);
static char* path_concat(char* path, int max_len, int narg, ...);
static char* path_join(char* path, int max_len, int narg, ...);
int os_socketpair_cloexec(int domain, int type, int protocol, int* sv);
int os_epoll_create_cloexec(void);
int os_create_anonymous_file(off_t size);
int os_socketpair_cloexec(int domain, int type, int protocol, int* sv);
int os_epoll_create_cloexec(void);
int os_create_anonymous_file(off_t size);
int os_create_anonymous_file(off_t size);
int os_resize_anonymous_file(int fd, off_t size);
int os_epoll_create_cloexec(void);
int os_socketpair_cloexec(int domain, int type, int protocol, int* sv);
void queue_init(queue_t* queue, size_t esize, void(*)(void*) free_func);
void queue_pop(queue_t* queue);
void queue_append(queue_t* queue, void* e);
void* queue_top(queue_t* queue);
bool queue_empty(queue_t* queue);
void queue_destroy(queue_t* q);
void queue_init(queue_t* queue, size_t esize, void(*)(void*) free_func);
void queue_pop(queue_t* queue);
void queue_append(queue_t* queue, void* e);
void* queue_top(queue_t* queue);
bool queue_empty(queue_t* queue);
void queue_destroy(queue_t* q);
void cstack_init(cstack_t* stack, size_t esize, void(*)(void*) free_func);
void cstack_pop(cstack_t* stack);
void cstack_append(cstack_t* stack, void* e);
void* cstack_top(cstack_t* stack);
bool cstack_empty(cstack_t* stack);
void cstack_destroy(cstack_t* s);
void cstack_init(cstack_t* stack, size_t esize, void(*)(void*) free_func);
void cstack_pop(cstack_t* stack);
void cstack_append(cstack_t* stack, void* e);
void* cstack_top(cstack_t* stack);
bool cstack_empty(cstack_t* stack);
void cstack_destroy(cstack_t* s);
static char* strop_ncpy(char* dest, const char* src, size_t size);
static char* strop_ltrim(char* line);
static void strop_rtrim(char* line);
static char* strop_ncpy(char* dest, const char* src, size_t size);
static char* strop_ltrim(char* line);
static void strop_rtrim(char* line);
void* vtree_container(struct vtree_node* p);
void vtree_node_init(struct vtree_node* n, unsigned int offset);
static size_t vtree_len(const struct vtree_node* n);
static struct vtree_node* vtree_ith_child(struct vtree_node* n, off_t i);
static void vtree_node_add_child(struct vtree_node* p, struct vtree_node* c);

static void vtree_node_insert(
    struct vtree_node* p,
    struct vtree_node* c,
    off_t idx
    );

static void vtree_node_remove(struct vtree_node* p, off_t i);
void vtree_node_shift(struct vtree_node* v, bool forward);
void vtree_sort(struct vtree_node* p, int(*)(const void*, const void*) cmpfun);

off_t vtree_find(
    struct vtree_node* p,
    const void*,
    int(*)(const void*, const struct vtree_node*) cmpfun
    );

void vtree_print(
    const struct vtree_node* p,
    void(*)(const struct vtree_node*) print,
    int indent
    );

int vtree_iterate(
    const struct vtree_node* root,
    void* data,
    void(*)(const struct vtree_node*, void*) visit
    );

struct vtree_node* vtree_search(
    const struct vtree_node* root,
    void* data,
    int(*)(const void*, const struct vtree_node*) cmpfun
    );

void vtree_destroy(struct vtree_node* p, void(*)(void*) freefun);
void vtree_destroy_children(struct vtree_node* p, void(*)(void*) freefun);
void* vtree_container(struct vtree_node* p);
void vtree_node_init(struct vtree_node* n, unsigned int offset);
static size_t vtree_len(const struct vtree_node* n);
static struct vtree_node* vtree_ith_child(struct vtree_node* n, off_t i);
static void vtree_node_add_child(struct vtree_node* p, struct vtree_node* c);

static void vtree_node_insert(
    struct vtree_node* p,
    struct vtree_node* c,
    off_t idx
    );

static void vtree_node_remove(struct vtree_node* p, off_t i);
void vtree_node_shift(struct vtree_node* v, bool forward);
void vtree_sort(struct vtree_node* p, int(*)(const void*, const void*) cmpfun);

off_t vtree_find(
    struct vtree_node* p,
    const void*,
    int(*)(const void*, const struct vtree_node*) cmpfun
    );

void vtree_print(
    const struct vtree_node* p,
    void(*)(const struct vtree_node*) print,
    int indent
    );

int vtree_iterate(
    const struct vtree_node* root,
    void* data,
    void(*)(const struct vtree_node*, void*) visit
    );

struct vtree_node* vtree_search(
    const struct vtree_node* root,
    void* data,
    int(*)(const void*, const struct vtree_node*) cmpfun
    );

void vtree_destroy(struct vtree_node* p, void(*)(void*) freefun);
void vtree_destroy_children(struct vtree_node* p, void(*)(void*) freefun);
size_t vector_memsize(const vector_t* v);
bool vector_init(vector_t* v, size_t esize, freefun f);
void vector_init_zero(vector_t* v, size_t esize, freefun f);
void vector_destroy(vector_t* v);
void* vector_newelem(vector_t* v);
void vector_copy(vector_t* dst, vector_t* src);

void vector_copy_complex(
    vector_t* dst,
    vector_t* src,
    void(*)(void*, const void*) assign
    );

void* vector_at(vector_t* v, size_t idx);
const void* cvector_at(const vector_t* v, size_t idx);
void* vector_append(vector_t* v, void* e);
void vector_pop(vector_t* v);
void vector_insert(vector_t* v, void* e, off_t idx);
void vector_erase(vector_t* v, off_t idx);
void vector_resize(vector_t* v, size_t n);
void vector_reserve(vector_t* v, size_t n);
size_t vector_memsize(const vector_t* v);
bool vector_init(vector_t* v, size_t esize, freefun f);
void vector_init_zero(vector_t* v, size_t esize, freefun f);
void vector_destroy(vector_t* v);
void* vector_newelem(vector_t* v);
void vector_copy(vector_t* dst, vector_t* src);

void vector_copy_complex(
    vector_t* dst,
    vector_t* src,
    void(*)(void*, const void*) assign
    );

void* vector_at(vector_t* v, size_t idx);
const void* cvector_at(const vector_t* v, size_t idx);
void* vector_append(vector_t* v, void* e);
void vector_pop(vector_t* v);
void vector_insert(vector_t* v, void* e, off_t idx);
void vector_erase(vector_t* v, off_t idx);
void vector_resize(vector_t* v, size_t n);
void vector_reserve(vector_t* v, size_t n);
static uint64_t next_prime(uint64_t n);
static void expand_dhasht_if_needed(dhashtab_t* table);
static int _dhash_search(dhashtab_t* t, const void* key);
void* dhash_search(dhashtab_t* t, const void* key);
void dhash_insert(dhashtab_t* t, const void* key, const void* elem);

void dhash_init(
    dhashtab_t* t,
    hash_func_t h0,
    hash_func_t h1,
    hash_cmp_func_t cmp,
    size_t keysize,
    size_t esize,
    freefun keyfree,
    freefun datafree
    );

void dhash_destroy(dhashtab_t* t);
uint64_t hash_djb2(const void* d);
uint64_t hash_sdbm(const void* d);
hash_cmp_val hash_cmp_str(const void* a, const void* intable);
static uint64_t next_prime(uint64_t n);
static void expand_dhasht_if_needed(dhashtab_t* table);
static int _dhash_search(dhashtab_t* t, const void* key);
void* dhash_search(dhashtab_t* t, const void* key);</