build: add -ldl linker flag, recursive source discovery, and API test targets to Makefile

This commit is contained in:
2026-02-07 12:04:52 +00:00
parent 8e86b2d106
commit cd9e55dc64
181 changed files with 20646 additions and 7198 deletions
+9
View File
@@ -10,6 +10,11 @@
#include "dwn.h"
#include <stdbool.h>
/* Forward declarations for libcurl types */
struct curl_slist;
struct Curl_easy;
typedef struct Curl_easy DWN_CURL;
typedef enum {
AI_STATE_IDLE,
AI_STATE_PENDING,
@@ -24,6 +29,8 @@ typedef struct AIRequest {
void (*callback)(struct AIRequest *req);
void *user_data;
struct AIRequest *next;
struct curl_slist *headers; /* Stored for proper cleanup */
struct Curl_easy *curl_handle; /* Stored for cancellation */
} AIRequest;
typedef struct {
@@ -74,6 +81,8 @@ typedef struct ExaRequest {
void (*callback)(struct ExaRequest *req);
void *user_data;
struct ExaRequest *next;
struct curl_slist *headers; /* Stored for proper cleanup */
struct Curl_easy *curl_handle; /* Stored for cancellation */
} ExaRequest;
bool exa_is_available(void);
+34
View File
@@ -55,6 +55,23 @@ typedef enum {
EVENT_NOTIFICATION_SHOWN,
EVENT_NOTIFICATION_CLOSED,
EVENT_FADE_SPEED_CHANGED,
EVENT_FADE_INTENSITY_CHANGED,
EVENT_WINDOW_SNAPPED,
EVENT_AUDIO_VOLUME_CHANGED,
EVENT_AUDIO_MUTE_TOGGLED,
EVENT_PANEL_VISIBILITY_CHANGED,
EVENT_CONFIG_RELOADED,
EVENT_AI_RESPONSE_RECEIVED,
EVENT_EXA_SEARCH_COMPLETED,
EVENT_NEWS_ARTICLE_CHANGED,
EVENT_DEMO_STARTED,
EVENT_DEMO_STOPPED,
EVENT_DEMO_PHASE_CHANGED,
EVENT_TUTORIAL_STARTED,
EVENT_TUTORIAL_STOPPED,
EVENT_COUNT
} ApiEventType;
@@ -104,4 +121,21 @@ void api_emit_show_desktop_toggled(bool shown);
void api_emit_notification_shown(unsigned int id, const char *summary, const char *body);
void api_emit_notification_closed(unsigned int id);
void api_emit_fade_speed_changed(float old_speed, float new_speed);
void api_emit_fade_intensity_changed(float old_intensity, float new_intensity);
void api_emit_window_snapped(Window window, int horizontal, int vertical);
void api_emit_audio_volume_changed(int old_volume, int new_volume);
void api_emit_audio_mute_toggled(bool muted);
void api_emit_panel_visibility_changed(const char *panel, bool visible);
void api_emit_config_reloaded(void);
void api_emit_ai_response_received(const char *prompt, const char *response, bool success);
void api_emit_exa_search_completed(const char *query, int result_count, bool success);
void api_emit_news_article_changed(int old_index, int new_index, const char *title);
void api_emit_demo_started(void);
void api_emit_demo_stopped(void);
void api_emit_demo_phase_changed(int phase, const char *phase_name);
void api_emit_tutorial_started(void);
void api_emit_tutorial_stopped(void);
#endif
+311
View File
@@ -0,0 +1,311 @@
/*
* DWN - Desktop Window Manager
* Backend Abstraction Interface
*/
#ifndef BACKEND_INTERFACE_H
#define BACKEND_INTERFACE_H
#include "core/wm_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/*==============================================================================
* Backend Capabilities
*============================================================================*/
typedef enum {
WM_BACKEND_CAP_WINDOWS = (1 << 0),
WM_BACKEND_CAP_COMPOSITING = (1 << 1),
WM_BACKEND_CAP_TRANSPARENCY = (1 << 2),
WM_BACKEND_CAP_ANIMATIONS = (1 << 3),
WM_BACKEND_CAP_MULTI_MONITOR = (1 << 4),
WM_BACKEND_CAP_INPUT_EVENTS = (1 << 5),
WM_BACKEND_CAP_CLIPBOARD = (1 << 6),
WM_BACKEND_CAP_DRAG_DROP = (1 << 7),
WM_BACKEND_CAP_TOUCH = (1 << 8),
WM_BACKEND_CAP_GESTURES = (1 << 9)
} WmBackendCapabilities;
/*==============================================================================
* Backend Information
*============================================================================*/
typedef struct {
const char *name;
const char *version;
const char *description;
uint32_t capabilities;
bool supports_multiple_instances;
bool requires_compositor;
} WmBackendInfo;
/*==============================================================================
* Backend Event Types
*============================================================================*/
typedef enum {
WM_BACKEND_EVENT_NONE,
WM_BACKEND_EVENT_EXPOSE,
WM_BACKEND_EVENT_CONFIGURE,
WM_BACKEND_EVENT_MAP,
WM_BACKEND_EVENT_UNMAP,
WM_BACKEND_EVENT_DESTROY,
WM_BACKEND_EVENT_FOCUS_IN,
WM_BACKEND_EVENT_FOCUS_OUT,
WM_BACKEND_EVENT_KEY_PRESS,
WM_BACKEND_EVENT_KEY_RELEASE,
WM_BACKEND_EVENT_BUTTON_PRESS,
WM_BACKEND_EVENT_BUTTON_RELEASE,
WM_BACKEND_EVENT_MOTION,
WM_BACKEND_EVENT_ENTER,
WM_BACKEND_EVENT_LEAVE,
WM_BACKEND_EVENT_PROPERTY,
WM_BACKEND_EVENT_CLIENT_MESSAGE,
WM_BACKEND_EVENT_SELECTION,
} WmBackendEventType;
typedef struct {
WmBackendEventType type;
WmWindowHandle window;
WmTime timestamp;
union {
struct { int x, y, width, height; } configure;
struct { int x, y; } point;
struct { unsigned int keycode; unsigned int state; } key;
struct { unsigned int button; int x, y; unsigned int state; } button;
struct { const char *name; const void *data; size_t size; } property;
} data;
} WmBackendEvent;
/*==============================================================================
* Backend Interface Definition
*============================================================================*/
typedef struct BackendInterface {
/* Identification */
const char *name;
WmBackendInfo (*get_info)(void);
/* Lifecycle */
bool (*init)(void *config);
void (*shutdown)(void);
bool (*is_initialized)(void);
/* Connection */
bool (*connect)(void);
void (*disconnect)(void);
bool (*is_connected)(void);
int (*get_file_descriptor)(void);
void (*flush)(void);
void (*sync)(void);
/* Screen/Display */
void (*get_screen_dimensions)(int *width, int *height);
int (*get_screen_count)(void);
void (*get_screen_geometry)(int screen, WmRect *geometry);
/* Monitor Management */
int (*get_monitor_count)(void);
void (*get_monitor_geometry)(int monitor, WmRect *geometry);
bool (*get_monitor_primary)(int monitor);
const char* (*get_monitor_name)(int monitor);
/* Work Area */
void (*get_work_area)(int monitor, WmRect *area);
void (*set_work_area)(int monitor, const WmRect *area);
/* Window Management - Lifecycle */
WmWindowHandle (*window_create)(const WmRect *geometry, uint32_t flags);
void (*window_destroy)(WmWindowHandle window);
WmWindowHandle (*window_create_frame)(WmWindowHandle parent, const WmRect *geometry);
/* Window Management - Geometry */
void (*window_get_geometry)(WmWindowHandle window, WmRect *geometry);
void (*window_set_geometry)(WmWindowHandle window, const WmRect *geometry);
void (*window_move)(WmWindowHandle window, int x, int y);
void (*window_resize)(WmWindowHandle window, int width, int height);
void (*window_move_resize)(WmWindowHandle window, const WmRect *geometry);
/* Window Management - Visibility */
void (*window_show)(WmWindowHandle window);
void (*window_hide)(WmWindowHandle window);
bool (*window_is_visible)(WmWindowHandle window);
void (*window_map)(WmWindowHandle window);
void (*window_unmap)(WmWindowHandle window);
bool (*window_is_mapped)(WmWindowHandle window);
/* Window Management - Stacking */
void (*window_raise)(WmWindowHandle window);
void (*window_lower)(WmWindowHandle window);
void (*window_raise_above)(WmWindowHandle window, WmWindowHandle above);
void (*window_lower_below)(WmWindowHandle window, WmWindowHandle below);
void (*window_set_stack_position)(WmWindowHandle window, int position);
int (*window_get_stack_position)(WmWindowHandle window);
/* Window Management - Reparenting */
void (*window_reparent)(WmWindowHandle window, WmWindowHandle parent, int x, int y);
WmWindowHandle (*window_get_parent)(WmWindowHandle window);
/* Window Management - Focus */
void (*window_focus)(WmWindowHandle window);
void (*window_unfocus)(WmWindowHandle window);
bool (*window_is_focused)(WmWindowHandle window);
WmWindowHandle (*window_get_focused)(void);
/* Window Management - Decoration */
void (*window_set_decorated)(WmWindowHandle window, bool decorated);
bool (*window_is_decorated)(WmWindowHandle window);
void (*window_set_border_width)(WmWindowHandle window, int width);
int (*window_get_border_width)(WmWindowHandle window);
void (*window_set_border_color)(WmWindowHandle window, WmColor color);
/* Window Management - Properties */
void (*window_set_title)(WmWindowHandle window, const char *title);
char* (*window_get_title)(WmWindowHandle window);
void (*window_set_class)(WmWindowHandle window, const char *class, const char *instance);
void (*window_get_class)(WmWindowHandle window, char **class, char **instance);
void (*window_set_icon_name)(WmWindowHandle window, const char *name);
/* Window Management - Protocols */
bool (*window_supports_protocol)(WmWindowHandle window, const char *protocol);
void (*window_send_protocol)(WmWindowHandle window, const char *protocol, WmTime timestamp);
void (*window_close)(WmWindowHandle window);
void (*window_kill)(WmWindowHandle window);
/* Window Management - State */
void (*window_set_fullscreen)(WmWindowHandle window, bool fullscreen);
bool (*window_is_fullscreen)(WmWindowHandle window);
void (*window_set_maximized)(WmWindowHandle window, bool maximized);
bool (*window_is_maximized)(WmWindowHandle window);
void (*window_set_minimized)(WmWindowHandle window, bool minimized);
bool (*window_is_minimized)(WmWindowHandle window);
void (*window_set_modal)(WmWindowHandle window, bool modal);
void (*window_set_sticky)(WmWindowHandle window, bool sticky);
void (*window_set_shaded)(WmWindowHandle window, bool shaded);
void (*window_set_skip_taskbar)(WmWindowHandle window, bool skip);
void (*window_set_skip_pager)(WmWindowHandle window, bool skip);
void (*window_set_urgent)(WmWindowHandle window, bool urgent);
bool (*window_is_urgent)(WmWindowHandle window);
/* Window Management - Type */
void (*window_set_type)(WmWindowHandle window, WmWindowType type);
WmWindowType (*window_get_type)(WmWindowHandle window);
/* Window Management - Selection */
void (*window_set_selection_owner)(WmWindowHandle window, const char *selection, WmTime time);
WmWindowHandle (*window_get_selection_owner)(const char *selection);
void (*window_convert_selection)(WmWindowHandle requestor, const char *selection,
const char *target, WmTime time);
/* Window Management - Client List */
WmContainer* (*window_get_stacking_list)(void);
WmContainer* (*window_get_client_list)(void);
/* Input - Events */
bool (*poll_event)(WmBackendEvent *event);
void (*wait_event)(WmBackendEvent *event);
bool (*check_mask_event)(uint32_t mask, WmBackendEvent *event);
void (*put_back_event)(const WmBackendEvent *event);
/* Input - Key Grabbing */
void (*grab_key)(int keycode, uint32_t modifiers, WmWindowHandle window,
bool owner_events, uint32_t pointer_mode, uint32_t keyboard_mode);
void (*ungrab_key)(int keycode, uint32_t modifiers, WmWindowHandle window);
void (*grab_keyboard)(WmWindowHandle window, bool owner_events,
uint32_t pointer_mode, uint32_t keyboard_mode, WmTime time);
void (*ungrab_keyboard)(WmTime time);
/* Input - Button Grabbing */
void (*grab_button)(int button, uint32_t modifiers, WmWindowHandle window,
bool owner_events, uint32_t event_mask,
uint32_t pointer_mode, uint32_t keyboard_mode,
WmWindowHandle confine_to, uint32_t cursor);
void (*ungrab_button)(int button, uint32_t modifiers, WmWindowHandle window);
void (*grab_pointer)(WmWindowHandle window, bool owner_events, uint32_t event_mask,
uint32_t pointer_mode, uint32_t keyboard_mode,
WmWindowHandle confine_to, uint32_t cursor, WmTime time);
void (*ungrab_pointer)(WmTime time);
/* Input - Pointer */
void (*query_pointer)(WmWindowHandle window, int *root_x, int *root_y,
int *win_x, int *win_y, uint32_t *mask);
void (*warp_pointer)(WmWindowHandle dest_w, int dest_x, int dest_y);
void (*set_cursor)(WmWindowHandle window, uint32_t cursor);
/* Rendering - Basic */
void (*fill_rectangle)(WmWindowHandle window, const WmRect *rect, WmColor color);
void (*draw_rectangle)(WmWindowHandle window, const WmRect *rect, WmColor color, int line_width);
void (*draw_line)(WmWindowHandle window, int x1, int y1, int x2, int y2,
WmColor color, int line_width);
void (*clear_window)(WmWindowHandle window);
void (*copy_area)(WmWindowHandle src, WmWindowHandle dst,
int src_x, int src_y, int width, int height,
int dst_x, int dst_y);
/* Rendering - Text (if supported) */
void* (*font_load)(const char *name, int size);
void (*font_destroy)(void *font);
int (*font_text_width)(void *font, const char *text, int len);
void (*draw_text)(WmWindowHandle window, void *font, int x, int y,
const char *text, int len, WmColor color);
/* Rendering - Images (if supported) */
void* (*image_load)(const uint8_t *data, size_t size);
void (*image_destroy)(void *image);
void (*image_get_size)(void *image, int *width, int *height);
void (*draw_image)(WmWindowHandle window, void *image, int x, int y,
int width, int height);
/* Rendering - Sync */
void (*begin_paint)(WmWindowHandle window);
void (*end_paint)(WmWindowHandle window);
/* Atoms/Properties */
uint32_t (*atom_get)(const char *name);
const char* (*atom_get_name)(uint32_t atom);
void (*property_set)(WmWindowHandle window, uint32_t property, uint32_t type,
int format, const void *data, int num_items);
int (*property_get)(WmWindowHandle window, uint32_t property, uint32_t type,
void **data, int *num_items);
void (*property_delete)(WmWindowHandle window, uint32_t property);
/* Session Management */
void (*set_selection_owner)(WmWindowHandle owner, const char *selection);
void (*send_client_message)(WmWindowHandle window, const char *message_type,
const void *data, int format);
/* Error Handling */
int (*get_last_error)(void);
void (*set_error_handler)(int (*handler)(void *display, void *event));
void (*set_io_error_handler)(int (*handler)(void *display));
} BackendInterface;
/*==============================================================================
* Backend Registration
*============================================================================*/
typedef const BackendInterface* (*BackendEntryFunc)(void);
void wm_backend_register(const char *name, BackendEntryFunc entry);
const BackendInterface* wm_backend_get(const char *name);
WmContainer* wm_backend_get_available(void);
/*==============================================================================
* Backend Helpers
*============================================================================*/
static inline bool wm_backend_has_capability(const BackendInterface *backend,
WmBackendCapabilities cap) {
WmBackendInfo info = backend->get_info();
return (info.capabilities & cap) != 0;
}
#ifdef __cplusplus
}
#endif
#endif /* BACKEND_INTERFACE_H */
+35
View File
@@ -0,0 +1,35 @@
/*
* DWN - Desktop Window Manager
* X11 Backend Header
*/
#ifndef X11_BACKEND_H
#define X11_BACKEND_H
#include "backends/backend_interface.h"
#include <X11/Xlib.h>
#ifdef __cplusplus
extern "C" {
#endif
/*==============================================================================
* X11 Backend Access
*============================================================================*/
const BackendInterface* x11_backend_get_interface(void);
Display* x11_backend_get_display(void);
Window x11_backend_get_root(void);
int x11_backend_get_screen(void);
static inline bool x11_backend_is_available(void) {
const BackendInterface *iface = x11_backend_get_interface();
return iface && iface->init(NULL);
}
#ifdef __cplusplus
}
#endif
#endif /* X11_BACKEND_H */
+9
View File
@@ -68,6 +68,10 @@ struct Config {
int demo_ai_timeout_ms;
int demo_window_timeout_ms;
/* Fade effects */
float fade_speed; /* Animation speed multiplier (0.1 - 3.0) */
float fade_intensity; /* Glow intensity (0.0 - 1.0) */
char color_panel_bg[16];
char color_panel_fg[16];
char color_workspace_active[16];
@@ -88,6 +92,7 @@ void config_destroy(Config *cfg);
bool config_load(Config *cfg, const char *path);
bool config_reload(Config *cfg);
void config_set_defaults(Config *cfg);
void config_validate(Config *cfg);
const char *config_get_terminal(void);
const char *config_get_launcher(void);
@@ -96,6 +101,10 @@ int config_get_title_height(void);
int config_get_panel_height(void);
int config_get_gap(void);
const ColorScheme *config_get_colors(void);
float config_get_fade_speed(void);
float config_get_fade_intensity(void);
void config_set_fade_speed(float speed);
void config_set_fade_intensity(float intensity);
typedef void (*ConfigCallback)(const char *section, const char *key,
const char *value, void *user_data);
+523
View File
@@ -0,0 +1,523 @@
/*
* DWN - Desktop Window Manager
* Abstract Client Interface
*/
#ifndef WM_CLIENT_H
#define WM_CLIENT_H
#include "core/wm_types.h"
#include "core/wm_string.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Forward declarations */
typedef struct Client Client; /* Legacy client structure */
/*==============================================================================
* Abstract Client Type
*============================================================================*/
typedef struct AbstractClient AbstractClient;
/*==============================================================================
* Client State Flags
*============================================================================*/
typedef enum {
WM_CLIENT_STATE_NORMAL = 0,
WM_CLIENT_STATE_FLOATING = (1 << 0),
WM_CLIENT_STATE_FULLSCREEN = (1 << 1),
WM_CLIENT_STATE_MAXIMIZED = (1 << 2),
WM_CLIENT_STATE_MINIMIZED = (1 << 3),
WM_CLIENT_STATE_URGENT = (1 << 4),
WM_CLIENT_STATE_STICKY = (1 << 5),
WM_CLIENT_STATE_HIDDEN = (1 << 6),
WM_CLIENT_STATE_FOCUS = (1 << 7),
WM_CLIENT_STATE_MAPPED = (1 << 8),
WM_CLIENT_STATE_MANAGED = (1 << 9),
WM_CLIENT_STATE_DESTROYING = (1 << 10)
} WmClientState;
/*==============================================================================
* Client Window Type
*============================================================================*/
typedef enum {
WM_CLIENT_TYPE_UNKNOWN = 0,
WM_CLIENT_TYPE_NORMAL,
WM_CLIENT_TYPE_DIALOG,
WM_CLIENT_TYPE_DOCK,
WM_CLIENT_TYPE_DESKTOP,
WM_CLIENT_TYPE_TOOLBAR,
WM_CLIENT_TYPE_MENU,
WM_CLIENT_TYPE_UTILITY,
WM_CLIENT_TYPE_SPLASH,
WM_CLIENT_TYPE_NOTIFICATION
} WmClientType;
/*==============================================================================
* Client Lifecycle
*============================================================================*/
/**
* Create an abstract client from a native window handle.
* This takes ownership of the native window.
*/
AbstractClient* wm_client_create(WmWindowHandle window, WmClientType type);
/**
* Destroy a client and release all associated resources.
*/
void wm_client_destroy(AbstractClient *client);
/**
* Check if a client is valid (not NULL and not being destroyed).
*/
bool wm_client_is_valid(const AbstractClient *client);
/*==============================================================================
* Native Access (for compatibility during migration)
*============================================================================*/
/**
* Get the native window handle.
* Note: This should be avoided in backend-agnostic code.
*/
WmWindowHandle wm_client_get_window(const AbstractClient *client);
/**
* Get the native frame window handle (if reparented).
*/
WmWindowHandle wm_client_get_frame(const AbstractClient *client);
/**
* Get the legacy Client structure.
* Note: This is for gradual migration only.
*/
Client* wm_client_get_legacy(const AbstractClient *client);
/**
* Create an abstract client wrapper around an existing legacy Client.
* Note: The abstract client does NOT own the legacy client.
*/
AbstractClient* wm_client_from_legacy(Client *client);
/*==============================================================================
* Client Identification
*============================================================================*/
/**
* Get the unique client ID.
*/
WmClientId wm_client_get_id(const AbstractClient *client);
/**
* Get the client window type.
*/
WmClientType wm_client_get_type(const AbstractClient *client);
/**
* Set the client window type.
*/
void wm_client_set_type(AbstractClient *client, WmClientType type);
/*==============================================================================
* Client State
*============================================================================*/
/**
* Get the current state flags.
*/
WmClientState wm_client_get_state(const AbstractClient *client);
/**
* Set state flags.
*/
void wm_client_set_state(AbstractClient *client, WmClientState state);
/**
* Add state flags.
*/
void wm_client_add_state(AbstractClient *client, WmClientState state);
/**
* Remove state flags.
*/
void wm_client_remove_state(AbstractClient *client, WmClientState state);
/**
* Toggle state flags.
*/
void wm_client_toggle_state(AbstractClient *client, WmClientState state);
/**
* Check if a specific state is set.
*/
bool wm_client_has_state(const AbstractClient *client, WmClientState state);
/* Convenience state checks */
static inline bool wm_client_is_floating(const AbstractClient *c) {
return c && wm_client_has_state(c, WM_CLIENT_STATE_FLOATING);
}
static inline bool wm_client_is_fullscreen(const AbstractClient *c) {
return c && wm_client_has_state(c, WM_CLIENT_STATE_FULLSCREEN);
}
static inline bool wm_client_is_maximized(const AbstractClient *c) {
return c && wm_client_has_state(c, WM_CLIENT_STATE_MAXIMIZED);
}
static inline bool wm_client_is_minimized(const AbstractClient *c) {
return c && wm_client_has_state(c, WM_CLIENT_STATE_MINIMIZED);
}
static inline bool wm_client_is_urgent(const AbstractClient *c) {
return c && wm_client_has_state(c, WM_CLIENT_STATE_URGENT);
}
static inline bool wm_client_is_sticky(const AbstractClient *c) {
return c && wm_client_has_state(c, WM_CLIENT_STATE_STICKY);
}
static inline bool wm_client_is_focused(const AbstractClient *c) {
return c && wm_client_has_state(c, WM_CLIENT_STATE_FOCUS);
}
static inline bool wm_client_is_mapped(const AbstractClient *c) {
return c && wm_client_has_state(c, WM_CLIENT_STATE_MAPPED);
}
/*==============================================================================
* Client Geometry
*============================================================================*/
/**
* Get the client geometry (position and size).
*/
WmRect wm_client_get_geometry(const AbstractClient *client);
/**
* Set the client geometry.
*/
void wm_client_set_geometry(AbstractClient *client, const WmRect *geometry);
/**
* Get the client position.
*/
WmPoint wm_client_get_position(const AbstractClient *client);
/**
* Set the client position.
*/
void wm_client_set_position(AbstractClient *client, int x, int y);
/**
* Get the client size.
*/
WmSize wm_client_get_size(const AbstractClient *client);
/**
* Set the client size.
*/
void wm_client_set_size(AbstractClient *client, int width, int height);
/**
* Get the border width.
*/
int wm_client_get_border_width(const AbstractClient *client);
/**
* Set the border width.
*/
void wm_client_set_border_width(AbstractClient *client, int width);
/**
* Store previous geometry (for restore after maximize/fullscreen).
*/
void wm_client_save_geometry(AbstractClient *client);
/**
* Restore previous geometry.
*/
void wm_client_restore_geometry(AbstractClient *client);
/*==============================================================================
* Client Workspace
*============================================================================*/
/**
* Get the client's workspace ID.
*/
WmWorkspaceId wm_client_get_workspace(const AbstractClient *client);
/**
* Set the client's workspace ID.
*/
void wm_client_set_workspace(AbstractClient *client, WmWorkspaceId workspace);
/**
* Check if the client is on a specific workspace.
*/
bool wm_client_is_on_workspace(const AbstractClient *client, WmWorkspaceId workspace);
/**
* Check if the client is visible on the current workspace.
*/
bool wm_client_is_visible_on_current(const AbstractClient *client);
/*==============================================================================
* Client Properties
*============================================================================*/
/**
* Get the client title.
* Returns a reference to the internal string (do not free).
*/
const char* wm_client_get_title(const AbstractClient *client);
/**
* Set the client title.
*/
void wm_client_set_title(AbstractClient *client, const char *title);
/**
* Get the client class (application class).
*/
const char* wm_client_get_class(const AbstractClient *client);
/**
* Set the client class.
*/
void wm_client_set_class(AbstractClient *client, const char *class_name);
/**
* Get the client instance name.
*/
const char* wm_client_get_instance(const AbstractClient *client);
/**
* Set the client instance name.
*/
void wm_client_set_instance(AbstractClient *client, const char *instance);
/**
* Get the client's taskbar color.
*/
WmColor wm_client_get_color(const AbstractClient *client);
/**
* Set the client's taskbar color.
*/
void wm_client_set_color(AbstractClient *client, WmColor color);
/*==============================================================================
* Client Actions
*============================================================================*/
/**
* Focus the client.
*/
void wm_client_focus(AbstractClient *client);
/**
* Unfocus the client.
*/
void wm_client_unfocus(AbstractClient *client);
/**
* Raise the client to the top of the stack.
*/
void wm_client_raise(AbstractClient *client);
/**
* Lower the client to the bottom of the stack.
*/
void wm_client_lower(AbstractClient *client);
/**
* Show/map the client window.
*/
void wm_client_show(AbstractClient *client);
/**
* Hide/unmap the client window.
*/
void wm_client_hide(AbstractClient *client);
/**
* Minimize the client.
*/
void wm_client_minimize(AbstractClient *client);
/**
* Restore the client from minimized state.
*/
void wm_client_restore(AbstractClient *client);
/**
* Close the client (politely request close).
*/
void wm_client_close(AbstractClient *client);
/**
* Kill the client (forcefully terminate).
*/
void wm_client_kill(AbstractClient *client);
/*==============================================================================
* Client Management
*============================================================================*/
/**
* Reparent the client into a frame window.
*/
void wm_client_reparent(AbstractClient *client, WmWindowHandle frame);
/**
* Unreparent the client from its frame.
*/
void wm_client_unreparent(AbstractClient *client);
/**
* Configure the client (apply size hints, constraints).
*/
void wm_client_configure(AbstractClient *client);
/**
* Apply size hints to constrain width/height.
*/
void wm_client_apply_size_hints(AbstractClient *client, int *width, int *height);
/**
* Move and resize a client.
*/
void wm_client_move_resize(AbstractClient *client, int x, int y, int width, int height);
/*==============================================================================
* Client List Management
*============================================================================*/
/**
* Get the next client in the global list.
*/
AbstractClient* wm_client_get_next(const AbstractClient *client);
/**
* Get the previous client in the global list.
*/
AbstractClient* wm_client_get_prev(const AbstractClient *client);
/**
* Get the first client in the global list.
*/
AbstractClient* wm_client_get_first(void);
/**
* Get the last client in the global list.
*/
AbstractClient* wm_client_get_last(void);
/**
* Get the next client in MRU (Most Recently Used) order.
*/
AbstractClient* wm_client_get_next_mru(const AbstractClient *client);
/**
* Get the previous client in MRU order.
*/
AbstractClient* wm_client_get_prev_mru(const AbstractClient *client);
/*==============================================================================
* Client Lookup
*============================================================================*/
/**
* Find a client by its window handle.
*/
AbstractClient* wm_client_find_by_window(WmWindowHandle window);
/**
* Find a client by its frame handle.
*/
AbstractClient* wm_client_find_by_frame(WmWindowHandle frame);
/**
* Find a client by its ID.
*/
AbstractClient* wm_client_find_by_id(WmClientId id);
/*==============================================================================
* Client Iteration
*============================================================================*/
typedef bool (*WmClientForeachFunc)(AbstractClient *client, void *user_data);
/**
* Iterate over all clients.
*/
void wm_client_foreach(WmClientForeachFunc func, void *user_data);
/**
* Iterate over clients on a specific workspace.
*/
void wm_client_foreach_on_workspace(WmWorkspaceId workspace,
WmClientForeachFunc func, void *user_data);
/**
* Count total clients.
*/
int wm_client_count(void);
/**
* Count clients on a specific workspace.
*/
int wm_client_count_on_workspace(WmWorkspaceId workspace);
/*==============================================================================
* Client Manager
*============================================================================*/
typedef struct WmClientManager WmClientManager;
/**
* Get the global client manager.
*/
WmClientManager* wm_client_manager_get(void);
/**
* Initialize the client manager.
*/
bool wm_client_manager_init(void);
/**
* Shutdown the client manager.
*/
void wm_client_manager_shutdown(void);
/**
* Register a client with the manager.
*/
void wm_client_manager_add(WmClientManager *mgr, AbstractClient *client);
/**
* Unregister a client from the manager.
*/
void wm_client_manager_remove(WmClientManager *mgr, AbstractClient *client);
/**
* Move a client to the front of the MRU list.
*/
void wm_client_manager_touch(WmClientManager *mgr, AbstractClient *client);
/**
* Get the focused client.
*/
AbstractClient* wm_client_manager_get_focused(const WmClientManager *mgr);
/**
* Set the focused client.
*/
void wm_client_manager_set_focused(WmClientManager *mgr, AbstractClient *client);
#ifdef __cplusplus
}
#endif
#endif /* WM_CLIENT_H */
+220
View File
@@ -0,0 +1,220 @@
/*
* DWN - Desktop Window Manager
* Generic Container Interface
*/
#ifndef WM_CONTAINER_H
#define WM_CONTAINER_H
#include "wm_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/*==============================================================================
* Container Lifecycle
*============================================================================*/
WmContainer* wm_container_create(WmContainerType type, WmDestroyFunc destroy_fn);
void wm_container_destroy(WmContainer *container);
void wm_container_clear(WmContainer *container);
WmContainer* wm_container_clone(const WmContainer *container, WmCloneFunc clone_fn);
/*==============================================================================
* Container Properties
*============================================================================*/
WmContainerType wm_container_get_type(const WmContainer *container);
size_t wm_container_size(const WmContainer *container);
bool wm_container_is_empty(const WmContainer *container);
/*==============================================================================
* List Operations
*============================================================================*/
/* These work for LIST and QUEUE */
void wm_list_append(WmContainer *list, void *data);
void wm_list_prepend(WmContainer *list, void *data);
void wm_list_insert(WmContainer *list, size_t index, void *data);
bool wm_list_remove(WmContainer *list, void *data);
void* wm_list_remove_at(WmContainer *list, size_t index);
void* wm_list_get(const WmContainer *list, size_t index);
void* wm_list_get_first(const WmContainer *list);
void* wm_list_get_last(const WmContainer *list);
size_t wm_list_index_of(const WmContainer *list, void *data);
bool wm_list_contains(const WmContainer *list, void *data);
void* wm_list_find(const WmContainer *list, WmCompareFunc cmp, const void *key);
void* wm_list_find_custom(const WmContainer *list,
bool (*predicate)(const void *item, const void *user_data),
const void *user_data);
void wm_list_sort(WmContainer *list, WmCompareFunc cmp);
void wm_list_reverse(WmContainer *list);
/*==============================================================================
* Array Operations
*============================================================================*/
void wm_array_append(WmContainer *array, void *data);
void wm_array_insert(WmContainer *array, size_t index, void *data);
void wm_array_set(WmContainer *array, size_t index, void *data);
void* wm_array_get(const WmContainer *array, size_t index);
void* wm_array_remove_at(WmContainer *array, size_t index);
void wm_array_resize(WmContainer *array, size_t new_size);
void wm_array_reserve(WmContainer *array, size_t capacity);
size_t wm_array_capacity(const WmContainer *array);
void wm_array_compact(WmContainer *array);
void wm_array_sort(WmContainer *array, WmCompareFunc cmp);
/*==============================================================================
* HashMap Operations
*============================================================================*/
/* Key types supported */
typedef enum {
WM_HASH_KEY_STRING,
WM_HASH_KEY_INT,
WM_HASH_KEY_POINTER
} WmHashKeyType;
WmContainer* wm_hashmap_create(WmHashKeyType key_type, WmDestroyFunc destroy_fn);
void wm_hashmap_insert(WmContainer *map, const void *key, void *value);
void* wm_hashmap_get(const WmContainer *map, const void *key);
bool wm_hashmap_contains(const WmContainer *map, const void *key);
bool wm_hashmap_remove(WmContainer *map, const void *key);
void* wm_hashmap_lookup(const WmContainer *map, WmCompareFunc cmp, const void *key);
WmContainer* wm_hashmap_get_keys(const WmContainer *map);
WmContainer* wm_hashmap_get_values(const WmContainer *map);
void wm_hashmap_rehash(WmContainer *map, size_t new_capacity);
float wm_hashmap_load_factor(const WmContainer *map);
/* Convenience functions for string keys */
void wm_hashmap_insert_string(WmContainer *map, const char *key, void *value);
void* wm_hashmap_get_string(const WmContainer *map, const char *key);
bool wm_hashmap_contains_string(const WmContainer *map, const char *key);
bool wm_hashmap_remove_string(WmContainer *map, const char *key);
/* Convenience functions for int keys */
void wm_hashmap_insert_int(WmContainer *map, int key, void *value);
void* wm_hashmap_get_int(const WmContainer *map, int key);
bool wm_hashmap_contains_int(const WmContainer *map, int key);
bool wm_hashmap_remove_int(WmContainer *map, int key);
/*==============================================================================
* Stack Operations
*============================================================================*/
void wm_stack_push(WmContainer *stack, void *data);
void* wm_stack_pop(WmContainer *stack);
void* wm_stack_peek(const WmContainer *stack);
/*==============================================================================
* Queue Operations
*============================================================================*/
void wm_queue_enqueue(WmContainer *queue, void *data);
void* wm_queue_dequeue(WmContainer *queue);
void* wm_queue_peek(const WmContainer *queue);
void* wm_queue_peek_tail(const WmContainer *queue);
/*==============================================================================
* Tree Operations (if type is TREE)
*============================================================================*/
typedef struct WmTreeNode WmTreeNode;
WmTreeNode* wm_tree_get_root(const WmContainer *tree);
WmTreeNode* wm_tree_node_get_left(const WmTreeNode *node);
WmTreeNode* wm_tree_node_get_right(const WmTreeNode *node);
WmTreeNode* wm_tree_node_get_parent(const WmTreeNode *node);
void* wm_tree_node_get_data(const WmTreeNode *node);
/*==============================================================================
* Iteration
*============================================================================*/
WmIterator* wm_container_iterator(const WmContainer *container);
WmIterator* wm_container_iterator_reverse(const WmContainer *container);
void wm_iterator_destroy(WmIterator *it);
bool wm_iterator_has_next(const WmIterator *it);
void* wm_iterator_next(WmIterator *it);
const void* wm_iterator_peek(const WmIterator *it);
/* HashMap iteration - returns key-value pairs */
typedef struct {
const void *key;
void *value;
} WmHashEntry;
WmIterator* wm_hashmap_iterator(const WmContainer *map);
WmHashEntry* wm_hashmap_iterator_next(WmIterator *it);
/*==============================================================================
* Functional Operations
*============================================================================*/
typedef void (*WmForeachFunc)(void *item, void *user_data);
typedef void* (*WmMapFunc)(const void *item, void *user_data);
typedef bool (*WmFilterFunc)(const void *item, void *user_data);
typedef void* (*WmReduceFunc)(void *accumulator, const void *item, void *user_data);
void wm_container_foreach(const WmContainer *container, WmForeachFunc func, void *user_data);
WmContainer* wm_container_map(const WmContainer *container, WmContainerType new_type,
WmMapFunc func, WmDestroyFunc destroy_fn, void *user_data);
WmContainer* wm_container_filter(const WmContainer *container,
WmFilterFunc predicate, void *user_data);
void* wm_container_reduce(const WmContainer *container,
WmReduceFunc func, void *initial, void *user_data);
bool wm_container_all_match(const WmContainer *container,
WmFilterFunc predicate, void *user_data);
bool wm_container_any_match(const WmContainer *container,
WmFilterFunc predicate, void *user_data);
/*==============================================================================
* Convenience Constructors
*============================================================================*/
static inline WmContainer* wm_list_create(WmDestroyFunc destroy_fn) {
return wm_container_create(WM_CONTAINER_LIST, destroy_fn);
}
static inline WmContainer* wm_array_create(WmDestroyFunc destroy_fn) {
return wm_container_create(WM_CONTAINER_ARRAY, destroy_fn);
}
static inline WmContainer* wm_hashmap_create_string(WmDestroyFunc destroy_fn) {
return wm_hashmap_create(WM_HASH_KEY_STRING, destroy_fn);
}
static inline WmContainer* wm_queue_create(WmDestroyFunc destroy_fn) {
return wm_container_create(WM_CONTAINER_QUEUE, destroy_fn);
}
static inline WmContainer* wm_stack_create(WmDestroyFunc destroy_fn) {
return wm_container_create(WM_CONTAINER_STACK, destroy_fn);
}
#ifdef __cplusplus
}
#endif
#endif /* WM_CONTAINER_H */
+265
View File
@@ -0,0 +1,265 @@
/*
* DWN - Desktop Window Manager
* Event Bus System
*/
#ifndef WM_EVENT_H
#define WM_EVENT_H
#include "wm_types.h"
#include "wm_client.h"
#include "wm_string.h"
#ifdef __cplusplus
extern "C" {
#endif
/*==============================================================================
* Event Data Structures
*============================================================================*/
typedef struct {
WmEventType type;
WmTime timestamp;
WmId source_id;
} WmEventHeader;
/* Window Events */
typedef struct {
WmEventHeader header;
AbstractClient *client;
} WmEventWindowBase;
typedef struct {
WmEventHeader header;
AbstractClient *client;
} WmEventWindowCreated;
typedef struct {
WmEventHeader header;
AbstractClient *client;
WmString *old_title;
WmString *new_title;
} WmEventWindowTitleChanged;
typedef struct {
WmEventHeader header;
AbstractClient *client;
WmRect old_geometry;
WmRect new_geometry;
} WmEventWindowMoved;
typedef struct {
WmEventHeader header;
AbstractClient *client;
WmRect old_geometry;
WmRect new_geometry;
} WmEventWindowResized;
typedef struct {
WmEventHeader header;
AbstractClient *client;
WmClientFlags old_flags;
WmClientFlags new_flags;
} WmEventWindowStateChanged;
/* Workspace Events */
typedef struct {
WmEventHeader header;
WmWorkspaceId workspace;
} WmEventWorkspaceBase;
typedef struct {
WmEventHeader header;
WmWorkspaceId old_workspace;
WmWorkspaceId new_workspace;
} WmEventWorkspaceSwitched;
typedef struct {
WmEventHeader header;
WmWorkspaceId workspace;
WmLayoutType old_layout;
WmLayoutType new_layout;
} WmEventWorkspaceLayoutChanged;
typedef struct {
WmEventHeader header;
WmWorkspaceId workspace;
AbstractClient *client;
} WmEventClientWorkspaceChanged;
/* Input Events */
typedef struct {
WmEventHeader header;
unsigned int keycode;
unsigned int keysym;
unsigned int modifiers;
const char *key_name;
} WmEventKey;
typedef struct {
WmEventHeader header;
unsigned int button;
int x;
int y;
unsigned int modifiers;
} WmEventButton;
typedef struct {
WmEventHeader header;
int x;
int y;
int delta_x;
int delta_y;
unsigned int modifiers;
} WmEventMotion;
typedef struct {
WmEventHeader header;
int delta;
int x;
int y;
} WmEventScroll;
/* Monitor Events */
typedef struct {
WmEventHeader header;
int monitor_index;
WmRect geometry;
bool primary;
} WmEventMonitorAdded;
typedef struct {
WmEventHeader header;
int monitor_index;
} WmEventMonitorRemoved;
/* Configuration Events */
typedef struct {
WmEventHeader header;
WmString *config_path;
bool success;
WmString *error_message;
} WmEventConfigReloaded;
/* Command Events */
typedef struct {
WmEventHeader header;
WmCommandType command;
bool success;
WmString *error_message;
} WmEventCommandExecuted;
/* Custom Event */
typedef struct {
WmEventHeader header;
WmString *event_name;
void *custom_data;
WmDestroyFunc destroy_func;
} WmEventCustom;
/*==============================================================================
* Event Bus Lifecycle
*============================================================================*/
WmEventBus* wm_event_bus_create(void);
void wm_event_bus_destroy(WmEventBus *bus);
WmEventBus* wm_event_bus_get_default(void);
void wm_event_bus_set_default(WmEventBus *bus);
/*==============================================================================
* Event Subscription
*============================================================================*/
WmEventSubscription* wm_event_subscribe(WmEventBus *bus,
WmEventType type,
WmEventHandler handler,
void *user_data);
WmEventSubscription* wm_event_subscribe_pattern(WmEventBus *bus,
WmEventType type_min,
WmEventType type_max,
WmEventHandler handler,
void *user_data);
WmEventSubscription* wm_event_subscribe_all(WmEventBus *bus,
WmEventHandler handler,
void *user_data);
void wm_event_unsubscribe(WmEventBus *bus, WmEventSubscription *subscription);
void wm_event_unsubscribe_all(WmEventBus *bus, void *user_data);
/*==============================================================================
* Event Emission
*============================================================================*/
void wm_event_emit(WmEventBus *bus, WmEventType type, const void *event_data);
void wm_event_emit_async(WmEventBus *bus, WmEventType type, const void *event_data);
/* Convenience emitters */
void wm_event_emit_window_created(WmEventBus *bus, AbstractClient *client);
void wm_event_emit_window_destroyed(WmEventBus *bus, AbstractClient *client);
void wm_event_emit_window_focused(WmEventBus *bus, AbstractClient *client, AbstractClient *prev_focus);
void wm_event_emit_window_moved(WmEventBus *bus, AbstractClient *client, const WmRect *old_geom);
void wm_event_emit_window_resized(WmEventBus *bus, AbstractClient *client, const WmRect *old_geom);
void wm_event_emit_window_state_changed(WmEventBus *bus, AbstractClient *client,
WmClientFlags old_flags, WmClientFlags new_flags);
void wm_event_emit_workspace_switched(WmEventBus *bus, WmWorkspaceId old_ws, WmWorkspaceId new_ws);
void wm_event_emit_workspace_layout_changed(WmEventBus *bus, WmWorkspaceId ws,
WmLayoutType old_layout, WmLayoutType new_layout);
/*==============================================================================
* Event Processing
*============================================================================*/
void wm_event_process(WmEventBus *bus);
void wm_event_process_all(WmEventBus *bus);
bool wm_event_process_one(WmEventBus *bus);
void wm_event_dispatch_pending(WmEventBus *bus);
int wm_event_get_pending_count(const WmEventBus *bus);
/*==============================================================================
* Event Data Helpers
*============================================================================*/
WmEventHeader* wm_event_get_header(void *event_data);
WmTime wm_event_get_timestamp(const void *event_data);
const char* wm_event_type_to_string(WmEventType type);
WmEventType wm_event_type_from_string(const char *str);
/*==============================================================================
* Event Blocking/Filtering
*============================================================================*/
void wm_event_begin_block(WmEventBus *bus, WmEventType type);
void wm_event_end_block(WmEventBus *bus, WmEventType type);
bool wm_event_is_blocked(const WmEventBus *bus, WmEventType type);
void wm_event_suppress(WmEventBus *bus, WmEventType type);
void wm_event_unsuppress(WmEventBus *bus, WmEventType type);
bool wm_event_is_suppressed(const WmEventBus *bus, WmEventType type);
/*==============================================================================
* Custom Events
*============================================================================*/
void wm_event_emit_custom(WmEventBus *bus, const char *event_name, void *data, WmDestroyFunc destroy_fn);
WmEventSubscription* wm_event_subscribe_custom(WmEventBus *bus, const char *event_name,
WmEventHandler handler, void *user_data);
/*==============================================================================
* Event Statistics
*============================================================================*/
uint64_t wm_event_get_emit_count(const WmEventBus *bus, WmEventType type);
uint64_t wm_event_get_total_emit_count(const WmEventBus *bus);
void wm_event_reset_statistics(WmEventBus *bus);
#ifdef __cplusplus
}
#endif
#endif /* WM_EVENT_H */
+107
View File
@@ -0,0 +1,107 @@
/*
* DWN - Desktop Window Manager
* Abstract Hash Map Container
*/
#ifndef WM_HASHMAP_H
#define WM_HASHMAP_H
#include "core/wm_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/*==============================================================================
* Opaque Types
*============================================================================*/
typedef struct WmHashMap WmHashMap;
/*==============================================================================
* Function Types
*============================================================================*/
typedef uint32_t (*WmHashFunc)(const void *key);
typedef bool (*WmKeyEqualFunc)(const void *a, const void *b);
typedef void (*WmHashForeachFunc)(void *key, void *value, void *user_data);
/*==============================================================================
* Hash Functions
*============================================================================*/
static inline uint32_t wm_hash_ptr(const void *ptr) {
uintptr_t p = (uintptr_t)ptr;
return (uint32_t)(p ^ (p >> 32));
}
static inline uint32_t wm_hash_int(int key) {
return (uint32_t)key;
}
/*==============================================================================
* Lifecycle
*============================================================================*/
WmHashMap* wm_hashmap_new(void);
WmHashMap* wm_hashmap_new_full(WmHashFunc hash_func, WmKeyEqualFunc key_equal,
WmFreeFunc key_free, WmFreeFunc value_free);
WmHashMap* wm_hashmap_new_string_key(void);
void wm_hashmap_destroy(WmHashMap *map);
WmHashMap* wm_hashmap_clone(const WmHashMap *map);
/*==============================================================================
* Capacity
*============================================================================*/
size_t wm_hashmap_size(const WmHashMap *map);
bool wm_hashmap_is_empty(const WmHashMap *map);
void wm_hashmap_clear(WmHashMap *map);
/*==============================================================================
* Element Access
*============================================================================*/
void* wm_hashmap_get(const WmHashMap *map, const void *key);
void* wm_hashmap_get_or_default(const WmHashMap *map, const void *key, void *default_val);
bool wm_hashmap_contains(const WmHashMap *map, const void *key);
/*==============================================================================
* Modifiers
*============================================================================*/
bool wm_hashmap_insert(WmHashMap *map, void *key, void *value);
bool wm_hashmap_insert_no_replace(WmHashMap *map, void *key, void *value);
void* wm_hashmap_set(WmHashMap *map, void *key, void *value);
void* wm_hashmap_remove(WmHashMap *map, const void *key);
bool wm_hashmap_steal(WmHashMap *map, const void *key);
/*==============================================================================
* Iteration
*============================================================================*/
typedef struct {
void *map; /* Opaque pointer to hashmap */
size_t bucket;
void *entry; /* Opaque pointer to current entry */
void *next_entry; /* Opaque pointer to next entry */
} WmHashMapIter;
void wm_hashmap_iter_init(WmHashMapIter *iter, WmHashMap *map);
bool wm_hashmap_iter_next(WmHashMapIter *iter, void **key, void **value);
void wm_hashmap_foreach(const WmHashMap *map, WmHashForeachFunc func, void *user_data);
/*==============================================================================
* String Helpers
*============================================================================*/
bool wm_hashmap_insert_string(WmHashMap *map, const char *key, void *value);
void* wm_hashmap_get_string(const WmHashMap *map, const char *key);
bool wm_hashmap_contains_string(const WmHashMap *map, const char *key);
void* wm_hashmap_remove_string(WmHashMap *map, const char *key);
#ifdef __cplusplus
}
#endif
#endif /* WM_HASHMAP_H */
+123
View File
@@ -0,0 +1,123 @@
/*
* DWN - Desktop Window Manager
* Abstract List Container
*/
#ifndef WM_LIST_H
#define WM_LIST_H
#include "core/wm_types.h"
#include <sys/types.h>
#ifdef __cplusplus
extern "C" {
#endif
/*==============================================================================
* Opaque Types
*============================================================================*/
typedef struct WmList WmList;
/*==============================================================================
* Function Types
*============================================================================*/
typedef void (*WmFreeFunc)(void *item);
typedef int (*WmCompareFunc)(const void *a, const void *b);
typedef bool (*WmForeachFunc)(void *item, size_t index, void *user_data);
typedef void* (*WmCloneFunc)(const void *item);
/*==============================================================================
* Lifecycle
*============================================================================*/
WmList* wm_list_new(void);
WmList* wm_list_new_sized(size_t initial_capacity);
void wm_list_destroy(WmList *list);
void wm_list_destroy_no_free(WmList *list);
WmList* wm_list_clone(const WmList *list);
void wm_list_set_free_func(WmList *list, WmFreeFunc func);
/*==============================================================================
* Capacity
*============================================================================*/
size_t wm_list_size(const WmList *list);
size_t wm_list_capacity(const WmList *list);
bool wm_list_is_empty(const WmList *list);
void wm_list_reserve(WmList *list, size_t capacity);
void wm_list_compact(WmList *list);
void wm_list_clear(WmList *list);
/*==============================================================================
* Modifiers
*============================================================================*/
void wm_list_append(WmList *list, void *item);
void wm_list_prepend(WmList *list, void *item);
void wm_list_insert(WmList *list, size_t index, void *item);
void wm_list_insert_sorted(WmList *list, void *item, WmCompareFunc compare);
void wm_list_remove(WmList *list, void *item);
void wm_list_remove_at(WmList *list, size_t index);
void* wm_list_take_at(WmList *list, size_t index);
bool wm_list_remove_one(WmList *list, void *item);
bool wm_list_remove_all(WmList *list, void *item);
void* wm_list_pop_back(WmList *list);
void* wm_list_pop_front(WmList *list);
/*==============================================================================
* Accessors
*============================================================================*/
void* wm_list_get(const WmList *list, size_t index);
void* wm_list_first(const WmList *list);
void* wm_list_last(const WmList *list);
void* wm_list_front(const WmList *list);
void* wm_list_back(const WmList *list);
void wm_list_set(WmList *list, size_t index, void *item);
/*==============================================================================
* Iteration
*============================================================================*/
void wm_list_foreach(const WmList *list, WmForeachFunc func, void *user_data);
void wm_list_foreach_reverse(const WmList *list, WmForeachFunc func, void *user_data);
/*==============================================================================
* Search
*============================================================================*/
ssize_t wm_list_index_of(const WmList *list, void *item);
bool wm_list_contains(const WmList *list, void *item);
void* wm_list_find(const WmList *list, WmCompareFunc compare, const void *key);
ssize_t wm_list_find_index(const WmList *list, WmCompareFunc compare, const void *key);
/*==============================================================================
* Sorting
*============================================================================*/
void wm_list_sort(WmList *list, WmCompareFunc compare);
/*==============================================================================
* Data Operations
*============================================================================*/
void** wm_list_data(WmList *list);
void* wm_list_steal(WmList *list, size_t index);
WmList* wm_list_slice(const WmList *list, size_t start, size_t end);
void wm_list_move(WmList *list, size_t from, size_t to);
void wm_list_swap(WmList *list, size_t i, size_t j);
/*==============================================================================
* Comparison
*============================================================================*/
bool wm_list_equals(const WmList *list1, const WmList *list2);
#ifdef __cplusplus
}
#endif
#endif /* WM_LIST_H */
+222
View File
@@ -0,0 +1,222 @@
/*
* DWN - Desktop Window Manager
* Abstract String Type
*/
#ifndef WM_STRING_H
#define WM_STRING_H
#include "wm_types.h"
#include <stdarg.h>
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
/*==============================================================================
* String Lifecycle
*============================================================================*/
WmString* wm_string_new(const char *str);
WmString* wm_string_new_empty(void);
WmString* wm_string_new_sized(size_t capacity);
WmString* wm_string_new_printf(const char *fmt, ...);
WmString* wm_string_new_vprintf(const char *fmt, va_list args);
WmString* wm_string_new_n(const char *str, size_t n);
void wm_string_destroy(WmString *str);
WmString* wm_string_clone(const WmString *str);
/*==============================================================================
* String Operations
*============================================================================*/
void wm_string_append(WmString *str, const char *suffix);
void wm_string_append_char(WmString *str, char c);
void wm_string_append_n(WmString *str, const char *suffix, size_t n);
void wm_string_append_printf(WmString *str, const char *fmt, ...);
void wm_string_append_vprintf(WmString *str, const char *fmt, va_list args);
void wm_string_append_string(WmString *str, const WmString *suffix);
void wm_string_prepend(WmString *str, const char *prefix);
void wm_string_prepend_char(WmString *str, char c);
void wm_string_insert(WmString *str, size_t pos, const char *insert);
void wm_string_insert_char(WmString *str, size_t pos, char c);
void wm_string_insert_string(WmString *str, size_t pos, const WmString *insert);
void wm_string_erase(WmString *str, size_t pos, size_t len);
void wm_string_clear(WmString *str);
/*==============================================================================
* String Queries
*============================================================================*/
const char* wm_string_cstr(const WmString *str);
char* wm_string_detach(WmString *str);
size_t wm_string_length(const WmString *str);
size_t wm_string_capacity(const WmString *str);
size_t wm_string_bytes(const WmString *str);
bool wm_string_is_empty(const WmString *str);
bool wm_string_is_null(const WmString *str);
char wm_string_char_at(const WmString *str, size_t pos);
/*==============================================================================
* String Comparison
*============================================================================*/
bool wm_string_equals(const WmString *str1, const WmString *str2);
bool wm_string_equals_cstr(const WmString *str, const char *cstr);
int wm_string_compare(const WmString *str1, const WmString *str2);
int wm_string_compare_cstr(const WmString *str, const char *cstr);
int wm_string_case_compare(const WmString *str1, const WmString *str2);
int wm_string_case_compare_cstr(const WmString *str, const char *cstr);
/*==============================================================================
* String Searching
*============================================================================*/
bool wm_string_contains(const WmString *str, const char *needle);
bool wm_string_contains_char(const WmString *str, char c);
size_t wm_string_find(const WmString *str, const char *needle, size_t start);
size_t wm_string_find_char(const WmString *str, char c, size_t start);
size_t wm_string_find_last(const WmString *str, const char *needle);
size_t wm_string_find_last_char(const WmString *str, char c);
bool wm_string_starts_with(const WmString *str, const char *prefix);
bool wm_string_starts_with_char(const WmString *str, char c);
bool wm_string_ends_with(const WmString *str, const char *suffix);
bool wm_string_ends_with_char(const WmString *str, char c);
/*==============================================================================
* String Modification
*============================================================================*/
void wm_string_trim(WmString *str);
void wm_string_trim_left(WmString *str);
void wm_string_trim_right(WmString *str);
void wm_string_replace(WmString *str, const char *search, const char *replace);
void wm_string_replace_char(WmString *str, char search, char replace);
size_t wm_string_replace_all(WmString *str, const char *search, const char *replace);
void wm_string_to_lower(WmString *str);
void wm_string_to_upper(WmString *str);
void wm_string_reverse(WmString *str);
/*==============================================================================
* String Substrings
*============================================================================*/
WmString* wm_string_substring(const WmString *str, size_t start, size_t len);
WmString* wm_string_left(const WmString *str, size_t n);
WmString* wm_string_right(const WmString *str, size_t n);
/*==============================================================================
* String Splitting and Joining
*============================================================================*/
WmContainer* wm_string_split(const WmString *str, const char *delimiter);
WmContainer* wm_string_split_chars(const WmString *str, const char *delimiters);
WmContainer* wm_string_split_lines(const WmString *str);
WmString* wm_string_join(const WmContainer *strings, const char *separator);
WmString* wm_string_join_cstr(const char **strings, size_t count, const char *separator);
/*==============================================================================
* String Formatting
*============================================================================*/
void wm_string_printf(WmString *str, const char *fmt, ...);
void wm_string_vprintf(WmString *str, const char *fmt, va_list args);
/*==============================================================================
* String Validation
*============================================================================*/
bool wm_string_is_valid_utf8(const WmString *str);
bool wm_string_is_ascii(const WmString *str);
bool wm_string_is_numeric(const WmString *str);
bool wm_string_is_integer(const WmString *str);
bool wm_string_is_float(const WmString *str);
/*==============================================================================
* String Conversion
*============================================================================*/
int wm_string_to_int(const WmString *str, int default_val);
long wm_string_to_long(const WmString *str, long default_val);
float wm_string_to_float(const WmString *str, float default_val);
double wm_string_to_double(const WmString *str, double default_val);
bool wm_string_to_bool(const WmString *str, bool default_val);
WmString* wm_string_from_int(int val);
WmString* wm_string_from_long(long val);
WmString* wm_string_from_float(float val, int precision);
WmString* wm_string_from_double(double val, int precision);
WmString* wm_string_from_bool(bool val);
/*==============================================================================
* String Hash
*============================================================================*/
uint32_t wm_string_hash(const WmString *str);
uint32_t wm_string_hash_cstr(const char *str);
/*==============================================================================
* String Escaping
*============================================================================*/
WmString* wm_string_escape_json(const WmString *str);
WmString* wm_string_escape_xml(const WmString *str);
WmString* wm_string_escape_html(const WmString *str);
WmString* wm_string_escape_shell(const WmString *str);
WmString* wm_string_escape_regex(const WmString *str);
WmString* wm_string_unescape_json(const WmString *str);
WmString* wm_string_unescape_xml(const WmString *str);
WmString* wm_string_unescape_html(const WmString *str);
/*==============================================================================
* Static String Helpers
*============================================================================*/
static inline bool wm_cstr_is_empty(const char *str) {
return str == NULL || str[0] == '\0';
}
static inline size_t wm_cstr_length(const char *str) {
return str == NULL ? 0 : strlen(str);
}
static inline bool wm_cstr_equals(const char *a, const char *b) {
if (a == b) return true;
if (a == NULL || b == NULL) return false;
return strcmp(a, b) == 0;
}
static inline bool wm_cstr_case_equals(const char *a, const char *b) {
if (a == b) return true;
if (a == NULL || b == NULL) return false;
return strcasecmp(a, b) == 0;
}
static inline void wm_cstr_copy(char *dest, const char *src, size_t size) {
if (size == 0) return;
strncpy(dest, src, size - 1);
dest[size - 1] = '\0';
}
#ifdef __cplusplus
}
#endif
#endif /* WM_STRING_H */
+490
View File
@@ -0,0 +1,490 @@
/*
* DWN - Desktop Window Manager
* Core Abstract Types
* Extreme Abstraction Architecture
*/
#ifndef WM_TYPES_H
#define WM_TYPES_H
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
/*==============================================================================
* Version and API Information
*============================================================================*/
#define WM_CORE_VERSION_MAJOR 2
#define WM_CORE_VERSION_MINOR 0
#define WM_CORE_VERSION_PATCH 0
#define WM_PLUGIN_API_VERSION 1
/*==============================================================================
* Opaque Type Declarations
*============================================================================*/
typedef struct WmCore WmCore;
typedef struct WmBackend WmBackend;
typedef struct WmPlugin WmPlugin;
typedef struct WmPluginManager WmPluginManager;
typedef struct WmEventBus WmEventBus;
typedef struct WmEventSubscription WmEventSubscription;
typedef struct WmContainer WmContainer;
typedef struct WmIterator WmIterator;
typedef struct WmString WmString;
typedef struct WmRenderer WmRenderer;
typedef struct WmSurface WmSurface;
typedef struct WmFont WmFont;
typedef struct WmImage WmImage;
typedef struct WmCommand WmCommand;
typedef struct WmCommandBuilder WmCommandBuilder;
typedef struct WmConfigSchema WmConfigSchema;
typedef struct WmConfigInstance WmConfigInstance;
typedef struct WmLayoutEngine WmLayoutEngine;
typedef struct WmPanelSystem WmPanelSystem;
typedef struct WmAnimation WmAnimation;
typedef struct WmTimer WmTimer;
typedef struct WmMutex WmMutex;
typedef struct WmCondition WmCondition;
typedef struct WmThread WmThread;
/*==============================================================================
* Basic Type Definitions
*============================================================================*/
typedef uint32_t WmColor;
typedef uint64_t WmTime;
typedef uint32_t WmHandle;
typedef uint32_t WmId;
typedef WmId WmClientId;
typedef int WmWorkspaceId;
typedef void* WmWindowHandle;
typedef void* WmNativeHandle;
/*==============================================================================
* Window Types
*============================================================================*/
typedef enum {
WM_WINDOW_TYPE_UNKNOWN = 0,
WM_WINDOW_TYPE_NORMAL,
WM_WINDOW_TYPE_DIALOG,
WM_WINDOW_TYPE_DOCK,
WM_WINDOW_TYPE_DESKTOP,
WM_WINDOW_TYPE_TOOLBAR,
WM_WINDOW_TYPE_MENU,
WM_WINDOW_TYPE_UTILITY,
WM_WINDOW_TYPE_SPLASH,
WM_WINDOW_TYPE_NOTIFICATION,
WM_WINDOW_TYPE_COMBO,
WM_WINDOW_TYPE_DND,
WM_WINDOW_TYPE_POPUP_MENU,
WM_WINDOW_TYPE_TOOLTIP
} WmWindowType;
/*==============================================================================
* Geometry Types
*============================================================================*/
typedef struct {
int x;
int y;
} WmPoint;
typedef struct {
int width;
int height;
} WmSize;
typedef struct {
int x;
int y;
int width;
int height;
} WmRect;
typedef struct {
WmPoint location;
WmSize size;
} WmGeometry;
typedef struct {
int top;
int bottom;
int left;
int right;
} WmInsets;
typedef struct {
float x;
float y;
} WmPointF;
typedef struct {
float width;
float height;
} WmSizeF;
typedef struct {
WmPointF location;
WmSizeF size;
} WmGeometryF;
/*==============================================================================
* Rectangle Operations (Inline)
*============================================================================*/
static inline WmRect wm_rect_make(int x, int y, int width, int height) {
WmRect r = { x, y, width, height };
return r;
}
static inline bool wm_rect_is_empty(const WmRect *r) {
return r == NULL || r->width <= 0 || r->height <= 0;
}
static inline bool wm_rect_contains_point(const WmRect *r, int x, int y) {
return r != NULL &&
x >= r->x && x < r->x + r->width &&
y >= r->y && y < r->y + r->height;
}
static inline bool wm_rect_intersects(const WmRect *a, const WmRect *b) {
if (a == NULL || b == NULL) return false;
return !(a->x + a->width <= b->x ||
b->x + b->width <= a->x ||
a->y + a->height <= b->y ||
b->y + b->height <= a->y);
}
static inline WmRect wm_rect_intersection(const WmRect *a, const WmRect *b) {
WmRect r = { 0, 0, 0, 0 };
if (a == NULL || b == NULL) return r;
int x1 = a->x > b->x ? a->x : b->x;
int y1 = a->y > b->y ? a->y : b->y;
int x2 = (a->x + a->width) < (b->x + b->width) ? (a->x + a->width) : (b->x + b->width);
int y2 = (a->y + a->height) < (b->y + b->height) ? (a->y + a->height) : (b->y + b->height);
if (x2 > x1 && y2 > y1) {
r.x = x1;
r.y = y1;
r.width = x2 - x1;
r.height = y2 - y1;
}
return r;
}
static inline WmRect wm_rect_union(const WmRect *a, const WmRect *b) {
WmRect r = { 0, 0, 0, 0 };
if (a == NULL && b == NULL) return r;
if (a == NULL) return *b;
if (b == NULL) return *a;
int x1 = a->x < b->x ? a->x : b->x;
int y1 = a->y < b->y ? a->y : b->y;
int x2 = (a->x + a->width) > (b->x + b->width) ? (a->x + a->width) : (b->x + b->width);
int y2 = (a->y + a->height) > (b->y + b->height) ? (a->y + a->height) : (b->y + b->height);
r.x = x1;
r.y = y1;
r.width = x2 - x1;
r.height = y2 - y1;
return r;
}
/*==============================================================================
* Color Operations (Inline)
*============================================================================*/
static inline WmColor wm_color_rgb(uint8_t r, uint8_t g, uint8_t b) {
return (0xFF << 24) | (r << 16) | (g << 8) | b;
}
static inline WmColor wm_color_rgba(uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
return (a << 24) | (r << 16) | (g << 8) | b;
}
static inline uint8_t wm_color_get_red(WmColor c) {
return (c >> 16) & 0xFF;
}
static inline uint8_t wm_color_get_green(WmColor c) {
return (c >> 8) & 0xFF;
}
static inline uint8_t wm_color_get_blue(WmColor c) {
return c & 0xFF;
}
static inline uint8_t wm_color_get_alpha(WmColor c) {
return (c >> 24) & 0xFF;
}
/*==============================================================================
* Client State Flags
*============================================================================*/
typedef enum {
WM_CLIENT_FLAG_NONE = 0,
WM_CLIENT_FLAG_FLOATING = (1 << 0),
WM_CLIENT_FLAG_FULLSCREEN = (1 << 1),
WM_CLIENT_FLAG_URGENT = (1 << 2),
WM_CLIENT_FLAG_MINIMIZED = (1 << 3),
WM_CLIENT_FLAG_STICKY = (1 << 4),
WM_CLIENT_FLAG_MAXIMIZED = (1 << 5),
WM_CLIENT_FLAG_UNMANAGING = (1 << 6),
WM_CLIENT_FLAG_FOCUSED = (1 << 7),
WM_CLIENT_FLAG_MAPPED = (1 << 8),
WM_CLIENT_FLAG_DECORATED = (1 << 9),
WM_CLIENT_FLAG_DIALOG = (1 << 10),
WM_CLIENT_FLAG_DOCK = (1 << 11),
WM_CLIENT_FLAG_UTILITY = (1 << 12),
WM_CLIENT_FLAG_SPLASH = (1 << 13),
WM_CLIENT_FLAG_MENU = (1 << 14),
WM_CLIENT_FLAG_TOOLBAR = (1 << 15)
} WmClientFlags;
/*==============================================================================
* Layout Types
*============================================================================*/
typedef enum {
WM_LAYOUT_TYPE_TILING,
WM_LAYOUT_TYPE_FLOATING,
WM_LAYOUT_TYPE_MONOCLE,
WM_LAYOUT_TYPE_GRID,
WM_LAYOUT_TYPE_SPIRAL,
WM_LAYOUT_TYPE_DWINDLE,
WM_LAYOUT_TYPE_MAX
} WmLayoutType;
/*==============================================================================
* Panel Positions
*============================================================================*/
typedef enum {
WM_PANEL_POSITION_TOP,
WM_PANEL_POSITION_BOTTOM,
WM_PANEL_POSITION_LEFT,
WM_PANEL_POSITION_RIGHT
} WmPanelPosition;
/*==============================================================================
* Event Types
*============================================================================*/
typedef enum {
/* Window events */
WM_EVENT_NONE = 0,
WM_EVENT_WINDOW_CREATED,
WM_EVENT_WINDOW_DESTROYED,
WM_EVENT_WINDOW_MAPPED,
WM_EVENT_WINDOW_UNMAPPED,
WM_EVENT_WINDOW_CONFIGURED,
WM_EVENT_WINDOW_FOCUSED,
WM_EVENT_WINDOW_UNFOCUSED,
WM_EVENT_WINDOW_RAISED,
WM_EVENT_WINDOW_LOWERED,
WM_EVENT_WINDOW_MINIMIZED,
WM_EVENT_WINDOW_RESTORED,
WM_EVENT_WINDOW_MAXIMIZED,
WM_EVENT_WINDOW_UNMAXIMIZED,
WM_EVENT_WINDOW_FULLSCREENED,
WM_EVENT_WINDOW_UNFULLSCREENED,
WM_EVENT_WINDOW_FLOATING_CHANGED,
WM_EVENT_WINDOW_PROPERTY_CHANGED,
WM_EVENT_WINDOW_STATE_CHANGED,
WM_EVENT_WINDOW_TITLE_CHANGED,
WM_EVENT_WINDOW_CLASS_CHANGED,
WM_EVENT_WINDOW_ROLE_CHANGED,
WM_EVENT_WINDOW_URGENCY_CHANGED,
WM_EVENT_WINDOW_MOVED,
WM_EVENT_WINDOW_RESIZED,
/* Workspace events */
WM_EVENT_WORKSPACE_CREATED,
WM_EVENT_WORKSPACE_DESTROYED,
WM_EVENT_WORKSPACE_SWITCHED,
WM_EVENT_WORKSPACE_RENAMED,
WM_EVENT_WORKSPACE_LAYOUT_CHANGED,
WM_EVENT_WORKSPACE_MASTER_RATIO_CHANGED,
WM_EVENT_WORKSPACE_MASTER_COUNT_CHANGED,
/* Client/workspace relationship */
WM_EVENT_CLIENT_ADDED_TO_WORKSPACE,
WM_EVENT_CLIENT_REMOVED_FROM_WORKSPACE,
/* Input events */
WM_EVENT_KEY_PRESSED,
WM_EVENT_KEY_RELEASED,
WM_EVENT_BUTTON_PRESSED,
WM_EVENT_BUTTON_RELEASED,
WM_EVENT_MOTION,
WM_EVENT_ENTER,
WM_EVENT_LEAVE,
WM_EVENT_SCROLL,
/* System events */
WM_EVENT_MONITOR_ADDED,
WM_EVENT_MONITOR_REMOVED,
WM_EVENT_MONITOR_CONFIGURED,
WM_EVENT_SCREEN_RESIZED,
/* Configuration events */
WM_EVENT_CONFIG_RELOADED,
WM_EVENT_CONFIG_CHANGED,
/* Lifecycle events */
WM_EVENT_WM_STARTED,
WM_EVENT_WM_SHUTDOWN,
WM_EVENT_WM_READY,
/* Plugin events */
WM_EVENT_PLUGIN_LOADED,
WM_EVENT_PLUGIN_UNLOADED,
WM_EVENT_PLUGIN_ERROR,
/* Custom events for plugins */
WM_EVENT_CUSTOM = 1000
} WmEventType;
/*==============================================================================
* Container Types
*============================================================================*/
typedef enum {
WM_CONTAINER_LIST,
WM_CONTAINER_ARRAY,
WM_CONTAINER_HASHMAP,
WM_CONTAINER_QUEUE,
WM_CONTAINER_STACK,
WM_CONTAINER_TREE
} WmContainerType;
/*==============================================================================
* Command Types
*============================================================================*/
typedef enum {
WM_COMMAND_NONE = 0,
/* Window commands */
WM_COMMAND_WINDOW_FOCUS,
WM_COMMAND_WINDOW_MOVE,
WM_COMMAND_WINDOW_RESIZE,
WM_COMMAND_WINDOW_MOVE_RESIZE,
WM_COMMAND_WINDOW_CLOSE,
WM_COMMAND_WINDOW_KILL,
WM_COMMAND_WINDOW_MINIMIZE,
WM_COMMAND_WINDOW_RESTORE,
WM_COMMAND_WINDOW_MAXIMIZE,
WM_COMMAND_WINDOW_UNMAXIMIZE,
WM_COMMAND_WINDOW_FULLSCREEN,
WM_COMMAND_WINDOW_UNFULLSCREEN,
WM_COMMAND_WINDOW_FLOAT,
WM_COMMAND_WINDOW_UNFLOAT,
WM_COMMAND_WINDOW_RAISE,
WM_COMMAND_WINDOW_LOWER,
WM_COMMAND_WINDOW_SET_WORKSPACE,
/* Workspace commands */
WM_COMMAND_WORKSPACE_SWITCH,
WM_COMMAND_WORKSPACE_CREATE,
WM_COMMAND_WORKSPACE_DESTROY,
WM_COMMAND_WORKSPACE_RENAME,
WM_COMMAND_WORKSPACE_SET_LAYOUT,
WM_COMMAND_WORKSPACE_ADJUST_MASTER_RATIO,
WM_COMMAND_WORKSPACE_ADJUST_MASTER_COUNT,
WM_COMMAND_WORKSPACE_SWAP,
/* Client manipulation */
WM_COMMAND_CLIENT_SWAP,
WM_COMMAND_CLIENT_SWAP_MASTER,
WM_COMMAND_CLIENT_CYCLE,
WM_COMMAND_CLIENT_CYCLE_REVERSE,
/* System commands */
WM_COMMAND_RELOAD_CONFIG,
WM_COMMAND_QUIT,
WM_COMMAND_RESTART,
/* Plugin commands */
WM_COMMAND_PLUGIN_LOAD,
WM_COMMAND_PLUGIN_UNLOAD,
WM_COMMAND_PLUGIN_ENABLE,
WM_COMMAND_PLUGIN_DISABLE
} WmCommandType;
/*==============================================================================
* Result/Error Types
*============================================================================*/
typedef enum {
WM_RESULT_OK = 0,
WM_RESULT_ERROR_GENERIC = -1,
WM_RESULT_ERROR_INVALID_ARG = -2,
WM_RESULT_ERROR_NO_MEMORY = -3,
WM_RESULT_ERROR_NOT_FOUND = -4,
WM_RESULT_ERROR_EXISTS = -5,
WM_RESULT_ERROR_PERMISSION = -6,
WM_RESULT_ERROR_NOT_SUPPORTED = -7,
WM_RESULT_ERROR_NOT_IMPLEMENTED = -8,
WM_RESULT_ERROR_BACKEND = -9,
WM_RESULT_ERROR_PLUGIN = -10,
WM_RESULT_ERROR_TIMEOUT = -11,
WM_RESULT_ERROR_CANCELED = -12
} WmResult;
/*==============================================================================
* Callback Types
*============================================================================*/
typedef void (*WmDestroyFunc)(void *data);
typedef int (*WmCompareFunc)(const void *a, const void *b);
typedef uint32_t (*WmHashFunc)(const void *key);
typedef void* (*WmCloneFunc)(const void *data);
typedef void (*WmEventHandler)(WmEventType type, const void *event_data, void *user_data);
typedef void (*WmTimerCallback)(WmTimer *timer, void *user_data);
typedef void* (*WmThreadFunc)(void *arg);
/*==============================================================================
* Memory Management Types
*============================================================================*/
typedef void* (*WmAllocFunc)(size_t size);
typedef void* (*WmReallocFunc)(void *ptr, size_t old_size, size_t new_size);
typedef void (*WmFreeFunc)(void *ptr);
typedef struct {
WmAllocFunc alloc;
WmReallocFunc realloc;
WmFreeFunc free;
} WmAllocator;
/*==============================================================================
* Logging Types
*============================================================================*/
typedef enum {
WM_LOG_LEVEL_DEBUG,
WM_LOG_LEVEL_INFO,
WM_LOG_LEVEL_WARN,
WM_LOG_LEVEL_ERROR,
WM_LOG_LEVEL_FATAL
} WmLogLevel;
typedef void (*WmLogHandler)(WmLogLevel level, const char *file, int line,
const char *func, const char *message);
#ifdef __cplusplus
}
#endif
#endif /* WM_TYPES_H */
+161
View File
@@ -0,0 +1,161 @@
/*
* DWN - Desktop Window Manager
* Abstract Workspace Interface
*/
#ifndef WM_WORKSPACE_H
#define WM_WORKSPACE_H
#include "wm_types.h"
#include "wm_client.h"
#ifdef __cplusplus
extern "C" {
#endif
/*==============================================================================
* Workspace Configuration
*============================================================================*/
#define WM_MAX_WORKSPACES 32
typedef struct {
WmLayoutType layout_type;
float master_ratio;
int master_count;
char name[64];
bool persistent;
WmString *custom_data;
} WmWorkspaceConfig;
/*==============================================================================
* Workspace Lifecycle
*============================================================================*/
bool wm_workspace_exists(WmCore *core, WmWorkspaceId id);
WmWorkspaceId wm_workspace_create(WmCore *core, const char *name);
void wm_workspace_destroy(WmCore *core, WmWorkspaceId id);
void wm_workspace_init_all(WmCore *core);
void wm_workspace_cleanup_all(WmCore *core);
/*==============================================================================
* Workspace Properties
*============================================================================*/
const char* wm_workspace_get_name(WmCore *core, WmWorkspaceId id);
void wm_workspace_set_name(WmCore *core, WmWorkspaceId id, const char *name);
bool wm_workspace_is_empty(WmCore *core, WmWorkspaceId id);
size_t wm_workspace_get_client_count(WmCore *core, WmWorkspaceId id);
/*==============================================================================
* Current Workspace
*============================================================================*/
WmWorkspaceId wm_workspace_get_current(WmCore *core);
void wm_workspace_set_current(WmCore *core, WmWorkspaceId id);
void wm_workspace_switch(WmCore *core, WmWorkspaceId id);
void wm_workspace_switch_next(WmCore *core);
void wm_workspace_switch_prev(WmCore *core);
/*==============================================================================
* Client Management
*============================================================================*/
void wm_workspace_add_client(WmCore *core, WmWorkspaceId id, AbstractClient *client);
void wm_workspace_remove_client(WmCore *core, WmWorkspaceId id, AbstractClient *client);
void wm_workspace_move_client(WmCore *core, AbstractClient *client, WmWorkspaceId to_workspace);
WmContainer* wm_workspace_get_clients(WmCore *core, WmWorkspaceId id);
AbstractClient* wm_workspace_get_focused_client(WmCore *core, WmWorkspaceId id);
void wm_workspace_set_focused_client(WmCore *core, WmWorkspaceId id, AbstractClient *client);
AbstractClient* wm_workspace_get_first_client(WmCore *core, WmWorkspaceId id);
AbstractClient* wm_workspace_get_last_client(WmCore *core, WmWorkspaceId id);
/*==============================================================================
* Layout Management
*============================================================================*/
WmLayoutType wm_workspace_get_layout(WmCore *core, WmWorkspaceId id);
void wm_workspace_set_layout(WmCore *core, WmWorkspaceId id, WmLayoutType layout);
void wm_workspace_cycle_layout(WmCore *core, WmWorkspaceId id);
void wm_workspace_cycle_layout_reverse(WmCore *core, WmWorkspaceId id);
float wm_workspace_get_master_ratio(WmCore *core, WmWorkspaceId id);
void wm_workspace_set_master_ratio(WmCore *core, WmWorkspaceId id, float ratio);
void wm_workspace_adjust_master_ratio(WmCore *core, WmWorkspaceId id, float delta);
int wm_workspace_get_master_count(WmCore *core, WmWorkspaceId id);
void wm_workspace_set_master_count(WmCore *core, WmWorkspaceId id, int count);
void wm_workspace_adjust_master_count(WmCore *core, WmWorkspaceId id, int delta);
/*==============================================================================
* Workspace Arrangement
*============================================================================*/
void wm_workspace_arrange(WmCore *core, WmWorkspaceId id);
void wm_workspace_arrange_all(WmCore *core);
void wm_workspace_arrange_current(WmCore *core);
WmRect wm_workspace_get_arrange_area(WmCore *core, WmWorkspaceId id);
/*==============================================================================
* Workspace Visibility
*============================================================================*/
void wm_workspace_show(WmCore *core, WmWorkspaceId id);
void wm_workspace_hide(WmCore *core, WmWorkspaceId id);
bool wm_workspace_is_visible(WmCore *core, WmWorkspaceId id);
/*==============================================================================
* Focus Management
*============================================================================*/
void wm_workspace_focus_next(WmCore *core, WmWorkspaceId id);
void wm_workspace_focus_prev(WmCore *core, WmWorkspaceId id);
void wm_workspace_focus_master(WmCore *core, WmWorkspaceId id);
/*==============================================================================
* MRU (Most Recently Used) Stack
*============================================================================*/
void wm_workspace_mru_push(WmCore *core, WmWorkspaceId id, AbstractClient *client);
void wm_workspace_mru_remove(WmCore *core, WmWorkspaceId id, AbstractClient *client);
AbstractClient* wm_workspace_mru_get_next(WmCore *core, WmWorkspaceId id, AbstractClient *current);
AbstractClient* wm_workspace_mru_get_prev(WmCore *core, WmWorkspaceId id, AbstractClient *current);
/*==============================================================================
* Alt-Tab Navigation
*============================================================================*/
void wm_workspace_alt_tab_start(WmCore *core, WmWorkspaceId id);
void wm_workspace_alt_tab_next(WmCore *core, WmWorkspaceId id);
void wm_workspace_alt_tab_prev(WmCore *core, WmWorkspaceId id);
void wm_workspace_alt_tab_end(WmCore *core, WmWorkspaceId id);
bool wm_workspace_alt_tab_is_active(WmCore *core, WmWorkspaceId id);
/*==============================================================================
* Workspace Iteration
*============================================================================*/
WmWorkspaceId wm_workspace_get_first(WmCore *core);
WmWorkspaceId wm_workspace_get_last(WmCore *core);
WmWorkspaceId wm_workspace_get_next(WmCore *core, WmWorkspaceId id);
WmWorkspaceId wm_workspace_get_prev(WmCore *core, WmWorkspaceId id);
/*==============================================================================
* Configuration
*============================================================================*/
void wm_workspace_save_config(WmCore *core, WmWorkspaceId id, const WmWorkspaceConfig *config);
bool wm_workspace_load_config(WmCore *core, WmWorkspaceId id, WmWorkspaceConfig *config);
#ifdef __cplusplus
}
#endif
#endif /* WM_WORKSPACE_H */
+5 -1
View File
@@ -49,6 +49,9 @@ typedef enum {
LAYOUT_TILING,
LAYOUT_FLOATING,
LAYOUT_MONOCLE,
LAYOUT_CENTERED_MASTER,
LAYOUT_COLUMNS,
LAYOUT_FIBONACCI,
LAYOUT_COUNT
} LayoutType;
@@ -64,7 +67,8 @@ typedef enum {
CLIENT_URGENT = (1 << 2),
CLIENT_MINIMIZED = (1 << 3),
CLIENT_STICKY = (1 << 4),
CLIENT_MAXIMIZED = (1 << 5)
CLIENT_MAXIMIZED = (1 << 5),
CLIENT_UNMANAGING = (1 << 6) /* Being destroyed, skip processing */
} ClientFlags;
typedef enum {
+11
View File
@@ -89,6 +89,17 @@ void key_start_demo(void);
void key_show_desktop(void);
void key_move_to_workspace_prev(void);
void key_move_to_workspace_next(void);
void key_kill_all_clients(void);
void key_move_window_left(void);
void key_move_window_right(void);
void key_move_window_up(void);
void key_move_window_down(void);
void key_resize_window_left(void);
void key_resize_window_right(void);
void key_resize_window_up(void);
void key_resize_window_down(void);
void key_set_mark(void);
void key_goto_mark(void);
void tutorial_start(void);
void tutorial_stop(void);
+3
View File
@@ -13,6 +13,9 @@ void layout_arrange(int workspace);
void layout_arrange_tiling(int workspace);
void layout_arrange_floating(int workspace);
void layout_arrange_monocle(int workspace);
void layout_arrange_centered_master(int workspace);
void layout_arrange_columns(int workspace);
void layout_arrange_fibonacci(int workspace);
int layout_get_usable_area(int *x, int *y, int *width, int *height);
int layout_count_tiled_clients(int workspace);
+33
View File
@@ -0,0 +1,33 @@
/*
* DWN - Desktop Window Manager
* retoor <retoor@molodetz.nl>
* Window marks for quick navigation
*/
#ifndef DWN_MARKS_H
#define DWN_MARKS_H
#include "dwn.h"
#include <stdbool.h>
#define MAX_MARKS 26
void marks_init(void);
void marks_cleanup(void);
void marks_set(char mark, Client *client);
Client *marks_get(char mark);
void marks_clear(char mark);
void marks_clear_all(void);
void marks_remove_client(Client *client);
bool marks_is_waiting_for_mark(void);
bool marks_is_waiting_for_goto(void);
void marks_start_set_mode(void);
void marks_start_goto_mode(void);
void marks_cancel_mode(void);
bool marks_handle_key(char key);
char marks_get_mark_for_client(Client *client);
#endif
+57
View File
@@ -0,0 +1,57 @@
/*
* DWN - Desktop Window Manager
* Built-in Layout Registration
*/
#ifndef BUILTIN_LAYOUTS_H
#define BUILTIN_LAYOUTS_H
#include "plugins/layout_plugin.h"
#include "dwn.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* Initialize and register all built-in layouts.
* Called during DWN startup.
*/
bool wm_layouts_builtin_init(void);
/**
* Get a layout plugin by legacy LayoutType.
*/
LayoutPlugin* wm_layout_get_by_type(LayoutManager *mgr, LayoutType type);
/**
* Bridge function to arrange a workspace using the plugin system.
*/
bool wm_layout_arrange_workspace(LayoutManager *mgr, int workspace, LayoutType type);
/**
* Get symbol for a layout type.
*/
const char* wm_layout_get_symbol_for_type(LayoutType type);
/**
* Get name for a layout type.
*/
const char* wm_layout_get_name_for_type(LayoutType type);
/**
* Get LayoutType from name.
*/
LayoutType wm_layout_type_from_name(const char *name);
/* External layout interface getters */
const LayoutPluginInterface* wm_layout_tiling_get_interface(void);
const LayoutPluginInterface* wm_layout_floating_get_interface(void);
const LayoutPluginInterface* wm_layout_monocle_get_interface(void);
const LayoutPluginInterface* wm_layout_grid_get_interface(void);
#ifdef __cplusplus
}
#endif
#endif /* BUILTIN_LAYOUTS_H */
+365
View File
@@ -0,0 +1,365 @@
/*
* DWN - Desktop Window Manager
* Layout Plugin Interface
*/
#ifndef LAYOUT_PLUGIN_H
#define LAYOUT_PLUGIN_H
#include "core/wm_types.h"
#include "core/wm_client.h"
#ifdef __cplusplus
extern "C" {
#endif
/*==============================================================================
* Layout Plugin API Version
*============================================================================*/
#define WM_LAYOUT_PLUGIN_API_VERSION 1
/*==============================================================================
* Forward Declarations
*============================================================================*/
typedef struct LayoutPlugin LayoutPlugin;
typedef struct LayoutContext LayoutContext;
/*==============================================================================
* Layout Geometry
*============================================================================*/
/**
* Layout geometry for a single client.
*/
typedef struct {
int x, y;
int width, height;
bool floating; /* If true, layout doesn't manage this client */
bool fullscreen; /* If true, client should be fullscreen */
bool hidden; /* If true, client should be hidden */
} WmLayoutGeometry;
/**
* Work area for layout calculations.
*/
typedef struct {
int x, y;
int width, height;
int padding_top;
int padding_bottom;
int padding_left;
int padding_right;
int gap;
} WmLayoutWorkArea;
/*==============================================================================
* Layout Configuration
*============================================================================*/
/**
* Layout configuration parameter.
*/
typedef struct {
const char *name;
const char *description;
union {
int int_value;
float float_value;
bool bool_value;
const char *string_value;
} default_value;
enum {
WM_LAYOUT_PARAM_INT,
WM_LAYOUT_PARAM_FLOAT,
WM_LAYOUT_PARAM_BOOL,
WM_LAYOUT_PARAM_STRING,
WM_LAYOUT_PARAM_CHOICE
} type;
/* For PARAM_CHOICE */
const char **choices;
int num_choices;
} WmLayoutParameter;
/**
* Layout configuration instance.
*/
typedef struct {
WmLayoutParameter *parameters;
int num_parameters;
void *user_data; /* Plugin can store parsed config here */
} WmLayoutConfig;
/*==============================================================================
* Layout State
*============================================================================*/
/**
* Opaque layout state per workspace.
* Layout plugins can store workspace-specific state here.
*/
typedef struct WmLayoutState WmLayoutState;
/*==============================================================================
* Layout Context
*============================================================================*/
/**
* Context passed to layout operations.
*/
struct LayoutContext {
/* Workspace info */
WmWorkspaceId workspace;
WmLayoutWorkArea work_area;
/* Client counts */
int client_count;
int master_count;
int stack_count;
/* Layout parameters */
float master_ratio;
int master_count_target;
int gap;
/* Configuration */
WmLayoutConfig *config;
/* Layout state (managed by plugin) */
WmLayoutState *state;
/* User data (for plugin use) */
void *user_data;
};
/*==============================================================================
* Layout Plugin Interface
*============================================================================*/
/**
* Layout plugin interface vtable.
* All layouts must implement these functions.
*/
typedef struct {
/* Version check */
int api_version;
/* Metadata */
const char *name;
const char *description;
const char *author;
const char *version;
/* Configuration */
WmLayoutParameter *parameters;
int num_parameters;
/* Lifecycle */
bool (*init)(LayoutPlugin *plugin);
void (*shutdown)(LayoutPlugin *plugin);
/* State management */
WmLayoutState* (*state_create)(LayoutPlugin *plugin, WmWorkspaceId workspace);
void (*state_destroy)(LayoutPlugin *plugin, WmLayoutState *state);
void (*state_reset)(LayoutPlugin *plugin, WmLayoutState *state);
/* Configuration */
bool (*config_parse)(LayoutPlugin *plugin, WmLayoutConfig *config,
const char *key, const char *value);
void (*config_apply)(LayoutPlugin *plugin, WmLayoutConfig *config);
/* Layout calculation */
bool (*arrange)(LayoutPlugin *plugin, LayoutContext *ctx,
AbstractClient **clients, int num_clients,
WmLayoutGeometry *geometries);
/* Client operations */
void (*client_added)(LayoutPlugin *plugin, LayoutContext *ctx,
AbstractClient *client);
void (*client_removed)(LayoutPlugin *plugin, LayoutContext *ctx,
AbstractClient *client);
void (*client_floating_changed)(LayoutPlugin *plugin, LayoutContext *ctx,
AbstractClient *client, bool floating);
/* Layout manipulation */
void (*inc_master)(LayoutPlugin *plugin, LayoutContext *ctx, int delta);
void (*set_master_ratio)(LayoutPlugin *plugin, LayoutContext *ctx, float ratio);
void (*set_master_count)(LayoutPlugin *plugin, LayoutContext *ctx, int count);
void (*swap_master)(LayoutPlugin *plugin, LayoutContext *ctx);
void (*rotate)(LayoutPlugin *plugin, LayoutContext *ctx, bool clockwise);
/* Mouse resizing support */
void (*resize_master)(LayoutPlugin *plugin, LayoutContext *ctx,
int x, int y, int *new_master_count, float *new_ratio);
} LayoutPluginInterface;
/*==============================================================================
* Layout Plugin Structure
*============================================================================*/
/**
* Layout plugin instance.
*/
struct LayoutPlugin {
/* Interface vtable */
const LayoutPluginInterface *interface;
/* Plugin handle (for dynamic loading) */
void *handle;
/* Plugin path */
char *path;
/* Enabled state */
bool enabled;
/* Global configuration */
WmLayoutConfig config;
/* Per-workspace states */
WmLayoutState **workspace_states;
int num_workspaces;
/* Plugin-private data */
void *user_data;
};
/*==============================================================================
* Layout Manager
*============================================================================*/
/**
* Layout manager handles all loaded layouts.
*/
typedef struct LayoutManager LayoutManager;
/**
* Get the global layout manager.
*/
LayoutManager* wm_layout_manager_get(void);
/**
* Initialize the layout manager.
*/
bool wm_layout_manager_init(void);
/**
* Shutdown the layout manager.
*/
void wm_layout_manager_shutdown(void);
/**
* Register a layout plugin.
*/
bool wm_layout_manager_register(LayoutManager *mgr, LayoutPlugin *plugin);
/**
* Unregister a layout plugin.
*/
void wm_layout_manager_unregister(LayoutManager *mgr, LayoutPlugin *plugin);
/**
* Load a layout plugin from a file.
*/
LayoutPlugin* wm_layout_manager_load(LayoutManager *mgr, const char *path);
/**
* Unload a layout plugin.
*/
void wm_layout_manager_unload(LayoutManager *mgr, LayoutPlugin *plugin);
/**
* Get a loaded layout by name.
*/
LayoutPlugin* wm_layout_manager_get_layout(LayoutManager *mgr, const char *name);
/**
* Get the default layout.
*/
LayoutPlugin* wm_layout_manager_get_default(LayoutManager *mgr);
/**
* Set the default layout.
*/
void wm_layout_manager_set_default(LayoutManager *mgr, LayoutPlugin *plugin);
/**
* Get list of available layouts.
*/
const char** wm_layout_manager_list(LayoutManager *mgr, int *count);
/*==============================================================================
* Layout Operations
*============================================================================*/
/**
* Apply a layout to a workspace.
*/
bool wm_layout_arrange(LayoutPlugin *plugin, WmWorkspaceId workspace);
/**
* Apply layout to specific clients.
*/
bool wm_layout_arrange_clients(LayoutPlugin *plugin, LayoutContext *ctx,
AbstractClient **clients, int num_clients);
/**
* Create a layout context for a workspace.
*/
bool wm_layout_context_init(LayoutContext *ctx, WmWorkspaceId workspace);
/**
* Clean up a layout context.
*/
void wm_layout_context_cleanup(LayoutContext *ctx);
/*==============================================================================
* Built-in Layouts
*============================================================================*/
/* Tiling layout */
extern const LayoutPluginInterface wm_layout_tiling;
/* Floating layout */
extern const LayoutPluginInterface wm_layout_floating;
/* Monocle (maximized) layout */
extern const LayoutPluginInterface wm_layout_monocle;
/* Grid layout */
extern const LayoutPluginInterface wm_layout_grid;
/* Spiral layout */
extern const LayoutPluginInterface wm_layout_spiral;
/* Dwindle layout */
extern const LayoutPluginInterface wm_layout_dwindle;
/*==============================================================================
* Plugin Entry Point
*============================================================================*/
/**
* Layout plugins must export this function.
*/
typedef const LayoutPluginInterface* (*LayoutPluginEntryFunc)(void);
#define WM_LAYOUT_PLUGIN_ENTRY "wm_layout_plugin_entry"
/*==============================================================================
* Helper Macros
*============================================================================*/
#define WM_LAYOUT_REGISTER(name, iface) \
__attribute__((unused)) static const LayoutPluginInterface* wm_layout_plugin_entry(void) { return &(iface); }
/* Typedef for built-in layout getters */
typedef const LayoutPluginInterface* (*WmLayoutBuiltinFunc)(void);
#ifdef __cplusplus
}
#endif
#endif /* LAYOUT_PLUGIN_H */
+435
View File
@@ -0,0 +1,435 @@
/*
* DWN - Desktop Window Manager
* Widget Plugin Interface
* Panel components (taskbar, clock, workspaces, etc.)
*/
#ifndef WIDGET_PLUGIN_H
#define WIDGET_PLUGIN_H
#include "core/wm_types.h"
#include "core/wm_client.h"
#ifdef __cplusplus
extern "C" {
#endif
/*==============================================================================
* Widget Plugin API Version
*============================================================================*/
#define WM_WIDGET_PLUGIN_API_VERSION 1
/*==============================================================================
* Forward Declarations
*============================================================================*/
typedef struct WidgetPlugin WidgetPlugin;
typedef struct WidgetContext WidgetContext;
typedef struct WidgetInstance WidgetInstance;
/*==============================================================================
* Widget Position
*============================================================================*/
typedef enum {
WM_WIDGET_POSITION_LEFT,
WM_WIDGET_POSITION_CENTER,
WM_WIDGET_POSITION_RIGHT
} WmWidgetPosition;
/*==============================================================================
* Widget Size Constraints
*============================================================================*/
typedef struct {
int min_width;
int min_height;
int max_width;
int max_height;
bool expand_horizontal; /* Take available horizontal space */
bool expand_vertical; /* Take available vertical space */
} WmWidgetConstraints;
/*==============================================================================
* Widget Geometry
*============================================================================*/
typedef struct {
int x, y;
int width, height;
} WmWidgetGeometry;
/*==============================================================================
* Widget State
*============================================================================*/
typedef enum {
WM_WIDGET_STATE_NORMAL = 0,
WM_WIDGET_STATE_HOVERED = (1 << 0),
WM_WIDGET_STATE_PRESSED = (1 << 1),
WM_WIDGET_STATE_ACTIVE = (1 << 2),
WM_WIDGET_STATE_DISABLED = (1 << 3),
WM_WIDGET_STATE_HIDDEN = (1 << 4),
WM_WIDGET_STATE_URGENT = (1 << 5)
} WmWidgetState;
/*==============================================================================
* Widget Context
*============================================================================*/
struct WidgetContext {
/* Position in panel */
WmWidgetPosition position;
/* Geometry */
WmWidgetGeometry geometry;
WmWidgetConstraints constraints;
/* Panel info */
WmRect panel_geometry;
bool is_top_panel;
/* Rendering context */
void *render_context; /* Backend-specific (X11 GC, cairo, etc.) */
WmColor bg_color;
WmColor fg_color;
/* Font */
void *font; /* Opaque font handle */
int font_size;
/* User data */
void *user_data;
};
/*==============================================================================
* Widget Event Types
*============================================================================*/
typedef enum {
WM_WIDGET_EVENT_NONE,
WM_WIDGET_EVENT_MOUSE_ENTER,
WM_WIDGET_EVENT_MOUSE_LEAVE,
WM_WIDGET_EVENT_MOUSE_MOVE,
WM_WIDGET_EVENT_BUTTON_PRESS,
WM_WIDGET_EVENT_BUTTON_RELEASE,
WM_WIDGET_EVENT_SCROLL,
WM_WIDGET_EVENT_KEY_PRESS,
WM_WIDGET_EVENT_FOCUS_IN,
WM_WIDGET_EVENT_FOCUS_OUT,
WM_WIDGET_EVENT_UPDATE, /* Request to redraw */
WM_WIDGET_EVENT_CONFIGURE, /* Size/position changed */
WM_WIDGET_EVENT_DATA_CHANGED /* External data changed */
} WmWidgetEventType;
typedef struct {
WmWidgetEventType type;
WmWidgetGeometry widget_geometry;
union {
struct { int x, y; } point;
struct { int button; int x, y; } button;
struct { int delta; bool horizontal; } scroll;
struct { unsigned int keycode; unsigned int state; } key;
} data;
} WmWidgetEvent;
/*==============================================================================
* Widget Configuration
*============================================================================*/
typedef struct {
const char *name;
const char *value;
} WmWidgetConfigOption;
typedef struct {
WmWidgetConfigOption *options;
int num_options;
} WmWidgetConfig;
/*==============================================================================
* Widget Information
*============================================================================*/
typedef struct {
const char *id; /* Unique identifier */
const char *name; /* Display name */
const char *description; /* Description */
const char *author; /* Author */
const char *version; /* Version */
/* Default constraints */
WmWidgetConstraints default_constraints;
/* Default position */
WmWidgetPosition default_position;
/* Configuration schema */
const char **config_options; /* List of accepted config option names */
int num_config_options;
} WmWidgetInfo;
/*==============================================================================
* Widget Plugin Interface
*============================================================================*/
typedef struct {
/* Version check */
int api_version;
/* Metadata */
WmWidgetInfo info;
/* Lifecycle */
bool (*init)(WidgetPlugin *plugin);
void (*shutdown)(WidgetPlugin *plugin);
/* Instance management */
WidgetInstance* (*instance_create)(WidgetPlugin *plugin,
const WmWidgetConfig *config);
void (*instance_destroy)(WidgetPlugin *plugin, WidgetInstance *instance);
void (*instance_configure)(WidgetPlugin *plugin, WidgetInstance *instance,
const WmWidgetConfig *config);
/* Rendering */
void (*render)(WidgetPlugin *plugin, WidgetInstance *instance,
WidgetContext *ctx);
/* Event handling */
bool (*handle_event)(WidgetPlugin *plugin, WidgetInstance *instance,
const WmWidgetEvent *event);
/* Update notification */
void (*update)(WidgetPlugin *plugin, WidgetInstance *instance);
/* Size calculation */
void (*get_preferred_size)(WidgetPlugin *plugin, WidgetInstance *instance,
int *width, int *height);
} WidgetPluginInterface;
/*==============================================================================
* Widget Instance
*============================================================================*/
struct WidgetInstance {
/* Plugin that created this instance */
WidgetPlugin *plugin;
/* Instance state */
WmWidgetState state;
WmWidgetGeometry geometry;
WmWidgetConstraints constraints;
/* Configuration */
WmWidgetConfig config;
/* Context */
WidgetContext *context;
/* Plugin-private data */
void *user_data;
/* Linked list for panel */
WidgetInstance *next;
WidgetInstance *prev;
};
/*==============================================================================
* Widget Plugin Structure
*============================================================================*/
struct WidgetPlugin {
/* Interface vtable */
const WidgetPluginInterface *interface;
/* Plugin handle (for dynamic loading) */
void *handle;
/* Plugin path */
char *path;
/* Enabled state */
bool enabled;
/* Instances */
WidgetInstance *instances;
int instance_count;
/* Plugin-private data */
void *user_data;
};
/*==============================================================================
* Widget Manager
*============================================================================*/
typedef struct WidgetManager WidgetManager;
/**
* Get the global widget manager.
*/
WidgetManager* wm_widget_manager_get(void);
/**
* Initialize the widget manager.
*/
bool wm_widget_manager_init(void);
/**
* Shutdown the widget manager.
*/
void wm_widget_manager_shutdown(void);
/**
* Register a widget plugin.
*/
bool wm_widget_manager_register(WidgetManager *mgr, WidgetPlugin *plugin);
/**
* Unregister a widget plugin.
*/
void wm_widget_manager_unregister(WidgetManager *mgr, WidgetPlugin *plugin);
/**
* Load a widget plugin from a file.
*/
WidgetPlugin* wm_widget_manager_load(WidgetManager *mgr, const char *path);
/**
* Unload a widget plugin.
*/
void wm_widget_manager_unload(WidgetManager *mgr, WidgetPlugin *plugin);
/**
* Get a loaded widget by ID.
*/
WidgetPlugin* wm_widget_manager_get_widget(WidgetManager *mgr, const char *id);
/**
* Get list of available widgets.
*/
const char** wm_widget_manager_list(WidgetManager *mgr, int *count);
/*==============================================================================
* Widget Instance Operations
*============================================================================*/
/**
* Create a widget instance.
*/
WidgetInstance* wm_widget_create_instance(WidgetPlugin *plugin,
const WmWidgetConfig *config);
/**
* Destroy a widget instance.
*/
void wm_widget_destroy_instance(WidgetInstance *instance);
/**
* Render a widget instance.
*/
void wm_widget_render(WidgetInstance *instance, WidgetContext *ctx);
/**
* Send an event to a widget instance.
*/
bool wm_widget_send_event(WidgetInstance *instance, const WmWidgetEvent *event);
/**
* Update a widget instance (request redraw).
*/
void wm_widget_update(WidgetInstance *instance);
/**
* Get preferred size for a widget instance.
*/
void wm_widget_get_preferred_size(WidgetInstance *instance,
int *width, int *height);
/*==============================================================================
* Widget Panel Integration
*============================================================================*/
typedef struct WidgetPanel WidgetPanel;
/**
* Create a widget panel (container for widget instances).
*/
WidgetPanel* wm_widget_panel_create(void);
/**
* Destroy a widget panel.
*/
void wm_widget_panel_destroy(WidgetPanel *panel);
/**
* Add a widget instance to a panel.
*/
void wm_widget_panel_add(WidgetPanel *panel, WidgetInstance *instance,
WmWidgetPosition position);
/**
* Remove a widget instance from a panel.
*/
void wm_widget_panel_remove(WidgetPanel *panel, WidgetInstance *instance);
/**
* Arrange widgets in a panel.
*/
void wm_widget_panel_arrange(WidgetPanel *panel, const WmRect *panel_geometry);
/**
* Render all widgets in a panel.
*/
void wm_widget_panel_render(WidgetPanel *panel);
/**
* Handle mouse event in a panel.
*/
bool wm_widget_panel_handle_event(WidgetPanel *panel,
const WmWidgetEvent *event);
/*==============================================================================
* Built-in Widgets
*============================================================================*/
/* Workspace switcher widget */
extern const WidgetPluginInterface wm_widget_workspaces;
/* Taskbar widget */
extern const WidgetPluginInterface wm_widget_taskbar;
/* Clock widget */
extern const WidgetPluginInterface wm_widget_clock;
/* System tray widget */
extern const WidgetPluginInterface wm_widget_systray;
/* CPU/Memory monitor widget */
extern const WidgetPluginInterface wm_widget_system_stats;
/* News ticker widget */
extern const WidgetPluginInterface wm_widget_news;
/*==============================================================================
* Plugin Entry Point
*============================================================================*/
typedef const WidgetPluginInterface* (*WidgetPluginEntryFunc)(void);
#define WM_WIDGET_PLUGIN_ENTRY "wm_widget_plugin_entry"
/*==============================================================================
* Helper Macros
*============================================================================*/
#define WM_WIDGET_REGISTER(name, iface) \
static const WidgetPluginInterface* wm_widget_plugin_entry(void) { return &(iface); }
#ifdef __cplusplus
}
#endif
#endif /* WIDGET_PLUGIN_H */
+61
View File
@@ -0,0 +1,61 @@
/*
* DWN - Desktop Window Manager
* retoor <retoor@molodetz.nl>
* Window rules engine for auto-applying settings
*/
#ifndef DWN_RULES_H
#define DWN_RULES_H
#include "dwn.h"
#include <stdbool.h>
#define MAX_RULES 64
#define RULE_PATTERN_SIZE 128
typedef enum {
RULE_MATCH_CLASS,
RULE_MATCH_TITLE,
RULE_MATCH_CLASS_AND_TITLE
} RuleMatchType;
typedef struct {
RuleMatchType match_type;
char class_pattern[RULE_PATTERN_SIZE];
char title_pattern[RULE_PATTERN_SIZE];
bool has_workspace;
int workspace;
bool has_floating;
bool floating;
bool has_sticky;
bool sticky;
bool has_fullscreen;
bool fullscreen;
bool has_size;
int width;
int height;
bool has_position;
int x;
int y;
bool has_opacity;
float opacity;
} WindowRule;
void rules_init(void);
void rules_cleanup(void);
bool rules_load(const char *path);
void rules_add(const WindowRule *rule);
void rules_clear(void);
int rules_count(void);
bool rules_apply_to_client(Client *client);
bool rules_match_pattern(const char *str, const char *pattern);
#endif
+72
View File
@@ -0,0 +1,72 @@
/*
* DWN - Desktop Window Manager
* retoor <retoor@molodetz.nl>
* Generic slider widget for panel controls
*/
#ifndef DWN_SLIDER_H
#define DWN_SLIDER_H
#include "dwn.h"
#include <stdbool.h>
#define SLIDER_WIDTH 30
#define SLIDER_HEIGHT 120
#define SLIDER_PADDING 8
#define SLIDER_KNOB_HEIGHT 8
/* Forward declaration */
typedef struct GenericSlider GenericSlider;
/* Callback type for value changes */
typedef void (*SliderValueChangedCallback)(GenericSlider *slider, int value);
/* Generic slider structure */
struct GenericSlider {
Window window;
int x, y;
int width, height;
bool visible;
bool dragging;
/* Value (always 0-100 internally) */
int value;
/* Display */
const char *label_prefix;
bool show_percentage;
/* Callback */
SliderValueChangedCallback on_value_changed;
void *user_data;
};
/* Lifecycle */
GenericSlider *slider_create(int x, int y,
const char *label_prefix,
bool show_percentage,
SliderValueChangedCallback callback,
void *user_data);
void slider_destroy(GenericSlider *slider);
/* Visibility */
void slider_show(GenericSlider *slider, int x, int y);
void slider_hide(GenericSlider *slider);
bool slider_is_visible(const GenericSlider *slider);
/* Rendering */
void slider_render(GenericSlider *slider);
/* Event handling */
void slider_handle_click(GenericSlider *slider, int x, int y);
void slider_handle_motion(GenericSlider *slider, int x, int y);
void slider_handle_release(GenericSlider *slider);
/* Value */
void slider_set_value(GenericSlider *slider, int value);
int slider_get_value(const GenericSlider *slider);
/* Hit testing */
bool slider_hit_test(const GenericSlider *slider, int x, int y);
#endif
+20
View File
@@ -8,6 +8,7 @@
#define DWN_SYSTRAY_H
#include "dwn.h"
#include "slider.h"
#include <stdbool.h>
#define MAX_TRAY_ICONS 32
@@ -84,12 +85,22 @@ typedef struct {
bool dragging;
} VolumeSlider;
/* Generic slider wrapper for fade controls */
typedef struct {
GenericSlider *slider;
int icon_x; /* Position for popup */
} FadeControl;
extern WifiState wifi_state;
extern AudioState audio_state;
extern BatteryState battery_state;
extern MultiBatteryState multi_battery_state;
extern VolumeSlider *volume_slider;
/* Fade control externs */
extern FadeControl fade_speed_control;
extern FadeControl fade_intensity_control;
void systray_init(void);
void systray_cleanup(void);
@@ -113,6 +124,15 @@ void volume_slider_handle_click(VolumeSlider *slider, int x, int y);
void volume_slider_handle_motion(VolumeSlider *slider, int x, int y);
void volume_slider_handle_release(VolumeSlider *slider);
/* Fade control functions */
void fade_controls_init(void);
void fade_controls_cleanup(void);
void fade_controls_render(Panel *panel, int x);
int fade_controls_get_width(void);
void fade_controls_handle_click(int control_id, int x, int y, int button);
int fade_controls_hit_test(int x);
void fade_controls_hide_all(void);
void systray_render(Panel *panel, int x, int *width);
int systray_get_width(void);
void systray_handle_click(int x, int y, int button);
+263
View File
@@ -0,0 +1,263 @@
/*
* DWN - Desktop Window Manager
* retoor <retoor@molodetz.nl>
* Specialized Worker Threads - High-Level API
*
* Pre-built worker types for common async operations:
* - I/O Worker: File operations, networking
* - Compute Worker: CPU-intensive tasks
* - System Worker: /proc monitoring, system stats
* - Deferred Worker: Delayed/scheduled execution
*/
#ifndef DWN_THREAD_WORKERS_H
#define DWN_THREAD_WORKERS_H
#include "threading.h"
/* ============================================================================
* I/O Worker - Async File and Network Operations
* ============================================================================ */
typedef void (*IoCallback)(void *result, size_t size, int error, void *user_data);
typedef void (*IoProgressCallback)(size_t processed, size_t total, void *user_data);
/**
* Initialize I/O worker subsystem
*/
bool io_worker_init(void);
/**
* Shutdown I/O worker subsystem
*/
void io_worker_shutdown(void);
/**
* Read file asynchronously
* @param path File path
* @param callback Called with file contents
* @param user_data Passed to callback
* @return Task handle or NULL
*/
TaskHandle io_read_file_async(const char *path, IoCallback callback, void *user_data);
/**
* Write file asynchronously
*/
TaskHandle io_write_file_async(const char *path, const void *data, size_t size,
IoCallback callback, void *user_data);
/**
* Read directory contents asynchronously
* Result is a null-separated list of filenames
*/
TaskHandle io_read_dir_async(const char *path, IoCallback callback, void *user_data);
/**
* HTTP GET request asynchronously
* @param url URL to fetch
* @param callback Called with response body
* @param user_data Passed to callback
* @return Task handle or NULL
*/
TaskHandle io_http_get_async(const char *url, IoCallback callback, void *user_data);
/**
* HTTP POST request asynchronously
*/
TaskHandle io_http_post_async(const char *url, const void *data, size_t size,
IoCallback callback, void *user_data);
/**
* Download file with progress callback
*/
TaskHandle io_download_async(const char *url, const char *dest_path,
IoProgressCallback progress,
IoCallback callback, void *user_data);
/* ============================================================================
* Compute Worker - CPU-Intensive Tasks
* ============================================================================ */
typedef void (*ComputeCallback)(void *result, void *user_data);
/**
* Initialize compute worker subsystem
*/
bool compute_worker_init(void);
/**
* Shutdown compute worker subsystem
*/
void compute_worker_shutdown(void);
/**
* Parallel for - distribute work across threads
* @param start Start index
* @param end End index (exclusive)
* @param func Function called for each index
* @param user_data Passed to each invocation
*/
void compute_parallel_for(int start, int end,
void (*func)(int index, void *user_data),
void *user_data);
/**
* Map operation - apply function to each element
*/
void* compute_map(void *array, size_t count, size_t elem_size,
void (*func)(void *in, void *out, void *user_data),
void *user_data);
/**
* Reduce operation - aggregate values
*/
void* compute_reduce(void *array, size_t count, size_t elem_size,
void (*func)(void *accum, void *elem, void *user_data),
void *initial, void *user_data);
/**
* Submit compute task
*/
TaskHandle compute_submit(void (*func)(void *user_data), void *user_data,
ComputeCallback callback, void *callback_data);
/* ============================================================================
* System Worker - System Monitoring
* ============================================================================ */
typedef struct {
float cpu_percent;
uint64_t memory_used;
uint64_t memory_total;
float memory_percent;
float load_avg[3];
uint64_t uptime_seconds;
} SystemStats;
typedef struct {
uint32_t pid;
char name[64];
float cpu_percent;
uint64_t memory_bytes;
} ProcessInfo;
typedef void (*SystemStatsCallback)(const SystemStats *stats, void *user_data);
typedef void (*ProcessListCallback)(ProcessInfo *processes, uint32_t count, void *user_data);
/**
* Initialize system worker
*/
bool system_worker_init(void);
/**
* Shutdown system worker
*/
void system_worker_shutdown(void);
/**
* Get cached system stats (non-blocking, updated periodically)
*/
bool system_worker_get_cached_stats(SystemStats *stats);
/**
* Get fresh system stats (blocking)
*/
Future* system_worker_get_stats_async(void);
/**
* Get process list asynchronously
*/
TaskHandle system_worker_get_processes_async(ProcessListCallback callback, void *user_data);
/**
* Subscribe to periodic stats updates
* @param interval_ms Update interval (0 to disable)
* @param callback Called with new stats
* @param user_data Passed to callback
* @return Subscription ID
*/
uint32_t system_worker_subscribe_stats(uint32_t interval_ms,
SystemStatsCallback callback,
void *user_data);
/**
* Unsubscribe from stats updates
*/
bool system_worker_unsubscribe_stats(uint32_t subscription_id);
/* ============================================================================
* Deferred Worker - Delayed Execution
* ============================================================================ */
typedef uint64_t DeferredId;
typedef void (*DeferredCallback)(DeferredId id, void *user_data);
/**
* Initialize deferred worker
*/
bool deferred_worker_init(void);
/**
* Shutdown deferred worker
*/
void deferred_worker_shutdown(void);
/**
* Execute after delay
* @param delay_ms Milliseconds to wait
* @param callback Function to call
* @param user_data Passed to callback
* @return Deferred ID
*/
DeferredId deferred_after(uint64_t delay_ms, DeferredCallback callback, void *user_data);
/**
* Execute at regular interval
*/
DeferredId deferred_every(uint64_t interval_ms, DeferredCallback callback, void *user_data);
/**
* Cancel deferred execution
*/
bool deferred_cancel(DeferredId id);
/**
* Process deferred tasks (call from main loop)
* @return Number of tasks executed
*/
uint32_t deferred_process(void);
/**
* Get poll fd for select()
*/
int deferred_get_poll_fd(void);
/* ============================================================================
* High-Level Integration API
* ============================================================================ */
/**
* Initialize all worker subsystems
*/
bool thread_workers_init(void);
/**
* Shutdown all worker subsystems
*/
void thread_workers_shutdown(void);
/**
* Process all pending async work (call from main loop)
* @return true if work was processed
*/
bool thread_workers_process_all(void);
/**
* Get combined poll fds for select()
* @param fds Array to fill (size at least 4)
* @return Number of fds filled
*/
int thread_workers_get_poll_fds(int *fds);
#endif /* DWN_THREAD_WORKERS_H */
+704
View File
@@ -0,0 +1,704 @@
/*
* DWN - Desktop Window Manager
* retoor <retoor@molodetz.nl>
* Extensive Abstract Threading Framework
*
* This module provides a comprehensive, abstract threading system with:
* - Lock-free data structures
* - Thread pools with work stealing
* - Async/await pattern support
* - Thread-safe event bus
* - Memory barriers and atomic operations
*/
#ifndef DWN_THREADING_H
#define DWN_THREADING_H
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#include <pthread.h>
#include <stdatomic.h>
/* ============================================================================
* Platform Abstraction Layer
* ============================================================================ */
/* Cache line size (commonly 64 bytes on x86_64) */
#define CACHE_LINE_SIZE 64
/* Align to cache line to prevent false sharing */
#define CACHE_ALIGN __attribute__((aligned(CACHE_LINE_SIZE)))
/* Memory ordering shortcuts */
#define ATOMIC_RELAXED memory_order_relaxed
#define ATOMIC_ACQUIRE memory_order_acquire
#define ATOMIC_RELEASE memory_order_release
#define ATOMIC_ACQ_REL memory_order_acq_rel
#define ATOMIC_SEQ_CST memory_order_seq_cst
/* ============================================================================
* Core Types and Status Codes
* ============================================================================ */
typedef enum {
THREAD_OK = 0,
THREAD_ERROR = -1,
THREAD_ERROR_NOMEM = -2,
THREAD_ERROR_BUSY = -3,
THREAD_ERROR_CLOSED = -4,
THREAD_ERROR_TIMEOUT = -5,
THREAD_ERROR_INVALID = -6
} ThreadStatus;
typedef enum {
TASK_PRIORITY_CRITICAL = 0, /* UI-critical, must execute immediately */
TASK_PRIORITY_HIGH = 1, /* User-initiated actions */
TASK_PRIORITY_NORMAL = 2, /* Default background work */
TASK_PRIORITY_LOW = 3, /* Maintenance tasks */
TASK_PRIORITY_IDLE = 4, /* Only when system idle */
TASK_PRIORITY_COUNT
} TaskPriority;
typedef enum {
TASK_STATE_PENDING = 0,
TASK_STATE_RUNNING = 1,
TASK_STATE_COMPLETED = 2,
TASK_STATE_CANCELLED = 3,
TASK_STATE_ERROR = 4
} TaskState;
/* Forward declarations */
typedef struct ThreadPool ThreadPool;
typedef struct Task Task;
typedef struct Channel Channel;
typedef struct Future Future;
typedef struct EventBus EventBus;
typedef struct AsyncContext AsyncContext;
typedef struct Worker Worker;
/* ============================================================================
* Task System - Abstract Unit of Work
* ============================================================================ */
/* Task function signature - receives user data and cancellation flag */
typedef void (*TaskFunc)(void *user_data, atomic_int *cancelled);
/* Callback for task completion (called in worker thread) */
typedef void (*TaskCallback)(Task *task, void *user_data, ThreadStatus status);
/* Task handle - opaque pointer */
typedef Task* TaskHandle;
/**
* Create a new task
* @param func The function to execute
* @param user_data Data passed to the function
* @param priority Task priority level
* @return Task handle or NULL on error
*/
TaskHandle task_create(TaskFunc func, void *user_data, TaskPriority priority);
/**
* Create a task with completion callback
*/
TaskHandle task_create_with_callback(TaskFunc func, void *user_data,
TaskPriority priority,
TaskCallback on_complete,
void *callback_data);
/**
* Destroy a task (only if not submitted)
*/
void task_destroy(TaskHandle task);
/**
* Cancel a task (best effort - may already be running)
*/
bool task_cancel(TaskHandle task);
/**
* Get current task state
*/
TaskState task_get_state(TaskHandle task);
/**
* Wait for task completion (blocking)
*/
ThreadStatus task_wait(TaskHandle task, uint64_t timeout_ms);
/**
* Check if task was cancelled
*/
bool task_is_cancelled(TaskHandle task);
/* ============================================================================
* Thread Pool - Manage Worker Threads
* ============================================================================ */
/* Thread pool configuration */
typedef struct {
uint32_t min_threads; /* Minimum threads to keep alive */
uint32_t max_threads; /* Maximum threads allowed */
uint32_t queue_capacity; /* Task queue capacity per priority */
uint32_t steal_attempts; /* Work stealing attempts before blocking */
uint64_t idle_timeout_ms; /* Time before idle thread terminates */
bool enable_work_stealing; /* Enable work stealing between queues */
} ThreadPoolConfig;
/* Default configuration */
#define THREAD_POOL_DEFAULT_CONFIG ((ThreadPoolConfig){ \
.min_threads = 2, \
.max_threads = 8, \
.queue_capacity = 256, \
.steal_attempts = 4, \
.idle_timeout_ms = 60000, \
.enable_work_stealing = true \
})
/**
* Create a thread pool
*/
ThreadPool* thread_pool_create(const ThreadPoolConfig *config);
/**
* Destroy thread pool, cancelling pending tasks
*/
void thread_pool_destroy(ThreadPool *pool);
/**
* Submit a task to the pool
*/
ThreadStatus thread_pool_submit(ThreadPool *pool, TaskHandle task);
/**
* Submit a function as a task (convenience)
*/
ThreadStatus thread_pool_submit_func(ThreadPool *pool, TaskFunc func,
void *user_data, TaskPriority priority);
/**
* Get number of active threads
*/
uint32_t thread_pool_active_count(ThreadPool *pool);
/**
* Get number of pending tasks
*/
uint32_t thread_pool_pending_count(ThreadPool *pool);
/**
* Shutdown pool gracefully, waiting for tasks to complete
*/
ThreadStatus thread_pool_shutdown(ThreadPool *pool, uint64_t timeout_ms);
/**
* Get the default/global thread pool
*/
ThreadPool* thread_pool_default(void);
/**
* Initialize the default thread pool
*/
ThreadStatus thread_pool_init_default(const ThreadPoolConfig *config);
/**
* Shutdown the default thread pool
*/
void thread_pool_shutdown_default(void);
/* ============================================================================
* Lock-Free Queue - Single Producer Single Consumer
* ============================================================================ */
#define SPSC_QUEUE_SIZE 1024
typedef struct {
_Atomic uint64_t head CACHE_ALIGN; /* Write index - producer only */
_Atomic uint64_t tail CACHE_ALIGN; /* Read index - consumer only */
void *buffer[SPSC_QUEUE_SIZE];
} SpscQueue;
/**
* Initialize SPSC queue
*/
void spsc_queue_init(SpscQueue *q);
/**
* Push item (producer only)
* @return false if queue full
*/
bool spsc_queue_push(SpscQueue *q, void *item);
/**
* Pop item (consumer only)
* @return false if queue empty
*/
bool spsc_queue_pop(SpscQueue *q, void **item);
/**
* Check if queue is empty (consumer only)
*/
bool spsc_queue_empty(SpscQueue *q);
/**
* Get approximate size (not synchronized)
*/
uint64_t spsc_queue_size_approx(SpscQueue *q);
/* ============================================================================
* Lock-Free Queue - Multi Producer Single Consumer
* ============================================================================ */
typedef struct MpscQueue MpscQueue;
/**
* Create MPSC queue
*/
MpscQueue* mpsc_queue_create(uint32_t capacity);
/**
* Destroy MPSC queue
*/
void mpsc_queue_destroy(MpscQueue *q);
/**
* Push item (thread-safe, any producer)
* @return false if queue full
*/
bool mpsc_queue_push(MpscQueue *q, void *item);
/**
* Pop item (consumer only - single thread)
* @return false if queue empty
*/
bool mpsc_queue_pop(MpscQueue *q, void **item);
/**
* Check if queue is empty
*/
bool mpsc_queue_empty(MpscQueue *q);
/* ============================================================================
* Channel - Thread-Safe Communication
* ============================================================================ */
typedef enum {
CHANNEL_UNBUFFERED = 0, /* Synchronous - sender blocks until received */
CHANNEL_BUFFERED = 1 /* Asynchronous - uses internal buffer */
} ChannelType;
/**
* Create a channel
* @param capacity Buffer size (0 for unbuffered synchronous channel)
*/
Channel* channel_create(uint32_t capacity);
/**
* Destroy channel
*/
void channel_destroy(Channel *ch);
/**
* Send data through channel (blocking)
* @return THREAD_OK on success, THREAD_ERROR_CLOSED if closed
*/
ThreadStatus channel_send(Channel *ch, void *data);
/**
* Send with timeout
*/
ThreadStatus channel_send_timeout(Channel *ch, void *data, uint64_t timeout_ms);
/**
* Try send (non-blocking)
*/
ThreadStatus channel_try_send(Channel *ch, void *data);
/**
* Receive from channel (blocking)
*/
ThreadStatus channel_recv(Channel *ch, void **data);
/**
* Receive with timeout
*/
ThreadStatus channel_recv_timeout(Channel *ch, void **data, uint64_t timeout_ms);
/**
* Try receive (non-blocking)
*/
ThreadStatus channel_try_recv(Channel *ch, void **data);
/**
* Close channel (no more sends allowed)
*/
void channel_close(Channel *ch);
/**
* Check if channel is closed
*/
bool channel_is_closed(Channel *ch);
/**
* Select on multiple channels (like Go's select)
* Returns index of ready channel or -1 on timeout
*/
int channel_select(Channel **channels, uint32_t count, uint64_t timeout_ms,
void **out_data);
/* ============================================================================
* Future/Promise - Async Result Handling
* ============================================================================ */
typedef void* FutureResult;
typedef void (*FutureCallback)(Future *f, FutureResult result, void *user_data);
/**
* Create a future
*/
Future* future_create(void);
/**
* Destroy future
*/
void future_destroy(Future *f);
/**
* Set the result (called by producer)
*/
void future_set_result(Future *f, FutureResult result);
/**
* Set error result
*/
void future_set_error(Future *f, int error_code);
/**
* Get result (blocking)
*/
FutureResult future_get(Future *f, ThreadStatus *status);
/**
* Get result with timeout
*/
FutureResult future_get_timeout(Future *f, uint64_t timeout_ms, ThreadStatus *status);
/**
* Check if future is ready
*/
bool future_is_ready(Future *f);
/**
* Attach callback to be called when ready (thread-safe)
*/
void future_then(Future *f, FutureCallback callback, void *user_data);
/**
* Create future that completes when all given futures complete
*/
Future* future_all(Future **futures, uint32_t count);
/**
* Create future that completes when any given future completes
*/
Future* future_any(Future **futures, uint32_t count);
/* ============================================================================
* Event Bus - Thread-Safe Pub/Sub
* ============================================================================ */
typedef uint32_t EventType;
typedef uint32_t SubscriptionId;
/* Event handler signature */
typedef void (*EventHandler)(EventType type, void *event_data, void *user_data);
/* Event filter - return true to allow event */
typedef bool (*EventFilter)(EventType type, void *event_data, void *user_data);
/**
* Create event bus
*/
EventBus* event_bus_create(void);
/**
* Destroy event bus
*/
void event_bus_destroy(EventBus *bus);
/**
* Subscribe to event type
* @return Subscription ID or 0 on error
*/
SubscriptionId event_bus_subscribe(EventBus *bus, EventType type,
EventHandler handler, void *user_data);
/**
* Subscribe with filter
*/
SubscriptionId event_bus_subscribe_filtered(EventBus *bus, EventType type,
EventHandler handler, void *user_data,
EventFilter filter, void *filter_data);
/**
* Unsubscribe
*/
bool event_bus_unsubscribe(EventBus *bus, SubscriptionId id);
/**
* Publish event (thread-safe)
*/
void event_bus_publish(EventBus *bus, EventType type, void *event_data);
/**
* Publish event with custom free function
*/
void event_bus_publish_owned(EventBus *bus, EventType type, void *event_data,
void (*free_fn)(void*));
/**
* Process pending events (call from main thread)
* @return number of events processed
*/
uint32_t event_bus_process(EventBus *bus);
/**
* Set processing limit per call
*/
void event_bus_set_batch_size(EventBus *bus, uint32_t batch_size);
/**
* Get the global/default event bus
*/
EventBus* event_bus_default(void);
/**
* Initialize default event bus
*/
bool event_bus_init_default(void);
/**
* Shutdown default event bus
*/
void event_bus_shutdown_default(void);
/* ============================================================================
* Async Context - Per-Module Async State
* ============================================================================ */
/* Context for managing async operations within a module */
struct AsyncContext {
ThreadPool *pool;
EventBus *event_bus;
Channel *completion_channel;
atomic_int operation_count;
atomic_int shutdown_requested;
pthread_mutex_t mutex;
};
/**
* Create async context
*/
AsyncContext* async_context_create(const char *name);
/**
* Destroy async context (cancels all pending operations)
*/
void async_context_destroy(AsyncContext *ctx);
/**
* Submit work to context's thread pool
*/
TaskHandle async_submit(AsyncContext *ctx, TaskFunc func, void *user_data,
TaskPriority priority);
/**
* Submit work and get future
*/
Future* async_submit_future(AsyncContext *ctx, TaskFunc func, void *user_data,
TaskPriority priority);
/**
* Check for completed operations (call from main thread)
*/
uint32_t async_poll(AsyncContext *ctx);
/**
* Get file descriptor for select() integration
* Returns -1 if not available
*/
int async_get_poll_fd(AsyncContext *ctx);
/* ============================================================================
* Timer/Scheduler - Delayed Execution
* ============================================================================ */
typedef uint64_t TimerId;
typedef void (*TimerCallback)(TimerId id, void *user_data);
/**
* Schedule one-shot timer
*/
TimerId timer_schedule(uint64_t delay_ms, TimerCallback callback, void *user_data);
/**
* Schedule repeating timer
*/
TimerId timer_schedule_repeating(uint64_t interval_ms, TimerCallback callback,
void *user_data);
/**
* Cancel timer
*/
bool timer_cancel(TimerId id);
/**
* Check if timer exists
*/
bool timer_exists(TimerId id);
/**
* Process timer events (call from main thread)
* @return Number of timers fired
*/
uint32_t timer_process(void);
/**
* Get timer file descriptor for select()
*/
int timer_get_poll_fd(void);
/**
* Initialize timer subsystem
*/
bool timer_init(void);
/**
* Shutdown timer subsystem
*/
void timer_shutdown(void);
/* ============================================================================
* Thread-Local Storage Abstraction
* ============================================================================ */
typedef struct TlsKey TlsKey;
/**
* Create TLS key
*/
TlsKey* tls_create(void (*destructor)(void*));
/**
* Destroy TLS key
*/
void tls_destroy(TlsKey *key);
/**
* Set TLS value
*/
void tls_set(TlsKey *key, void *value);
/**
* Get TLS value
*/
void* tls_get(TlsKey *key);
/* ============================================================================
* Read-Write Lock Wrapper
* ============================================================================ */
typedef struct RwLock RwLock;
RwLock* rwlock_create(void);
void rwlock_destroy(RwLock *lock);
void rwlock_read_lock(RwLock *lock);
bool rwlock_read_trylock(RwLock *lock);
void rwlock_read_unlock(RwLock *lock);
void rwlock_write_lock(RwLock *lock);
bool rwlock_write_trylock(RwLock *lock);
void rwlock_write_unlock(RwLock *lock);
/* ============================================================================
* Barrier and Synchronization
* ============================================================================ */
typedef struct Barrier Barrier;
Barrier* barrier_create(uint32_t count);
void barrier_destroy(Barrier *b);
bool barrier_wait(Barrier *b, uint64_t timeout_ms);
/* ============================================================================
* Initialization and Cleanup
* ============================================================================ */
/**
* Initialize entire threading subsystem
*/
bool threading_init(void);
/**
* Shutdown entire threading subsystem
*/
void threading_shutdown(void);
/**
* Get number of hardware threads
*/
uint32_t threading_hw_concurrency(void);
/**
* Current thread ID
*/
uint64_t threading_current_thread_id(void);
/**
* Set current thread name (for debugging)
*/
void threading_set_name(const char *name);
/**
* Yield current thread
*/
void threading_yield(void);
/* ============================================================================
* Utility Macros
* ============================================================================ */
/* Run function in background */
#define ASYNC(func, data) \
thread_pool_submit_func(thread_pool_default(), (func), (data), TASK_PRIORITY_NORMAL)
/* Run function with priority */
#define ASYNC_PRIORITY(func, data, prio) \
thread_pool_submit_func(thread_pool_default(), (func), (data), (prio))
/* Create future and submit */
#define ASYNC_FUTURE(ctx, func, data) \
async_submit_future((ctx), (func), (data), TASK_PRIORITY_NORMAL)
/* Synchronized block using mutex */
#define WITH_MUTEX(mutex, code) do { \
pthread_mutex_lock(&(mutex)); \
code; \
pthread_mutex_unlock(&(mutex)); \
} while(0)
/* Read lock block */
#define WITH_READ_LOCK(rwlock, code) do { \
rwlock_read_lock((rwlock)); \
code; \
rwlock_read_unlock((rwlock)); \
} while(0)
/* Write lock block */
#define WITH_WRITE_LOCK(rwlock, code) do { \
rwlock_write_lock((rwlock)); \
code; \
rwlock_write_unlock((rwlock)); \
} while(0)
#endif /* DWN_THREADING_H */
+75
View File
@@ -0,0 +1,75 @@
/*
* DWN - Desktop Window Manager
* retoor <retoor@molodetz.nl>
* Threading Integration Header
*/
#ifndef DWN_THREADING_INTEGRATION_H
#define DWN_THREADING_INTEGRATION_H
#include "threading.h"
#include "thread_workers.h"
#include <sys/select.h>
/**
* Initialize threading integration with main loop
*/
bool threading_integration_init(void);
/**
* Shutdown threading integration
*/
void threading_integration_shutdown(void);
/**
* Prepare fd_set for select() - adds threading fds
*/
void threading_integration_prepare_select(int xfd, fd_set *fds, int *max_fd);
/**
* Process threading events after select() returns
*/
void threading_integration_process(fd_set *fds);
/**
* Non-blocking poll for async work
*/
void threading_integration_poll(void);
/**
* Run one iteration with integrated threading
*/
void threading_integration_run_iteration(int xfd, void (*handle_xevent)(void));
/**
* Get stats string for display
*/
void threading_integration_get_stats(char *buf, size_t bufsize);
/**
* Initialize per-module async contexts
*/
bool threading_integration_init_module_contexts(void);
/**
* Cleanup per-module async contexts
*/
void threading_integration_cleanup_module_contexts(void);
/**
* Get module-specific async contexts
*/
AsyncContext* threading_integration_get_ai_context(void);
AsyncContext* threading_integration_get_screenshot_context(void);
AsyncContext* threading_integration_get_ocr_context(void);
/**
* High-level task submission
*/
TaskHandle threading_integration_submit_ai(TaskFunc func, void *user_data);
TaskHandle threading_integration_submit_screenshot(TaskFunc func, void *user_data);
TaskHandle threading_integration_submit_ocr(TaskFunc func, void *user_data);
TaskHandle threading_integration_submit_ui(TaskFunc func, void *user_data);
TaskHandle threading_integration_submit_background(TaskFunc func, void *user_data);
#endif /* DWN_THREADING_INTEGRATION_H */
+22
View File
@@ -11,6 +11,7 @@
#include <stddef.h>
#include <stdarg.h>
#include <assert.h>
#include <string.h>
#define DWN_ASSERT(cond) assert(cond)
#define DWN_ASSERT_MSG(cond, msg) assert((cond) && (msg))
@@ -46,6 +47,27 @@ bool str_ends_with(const char *str, const char *suffix);
int str_split(char *str, char delim, char **parts, int max_parts);
char *shell_escape(const char *str);
/* Safe string copy that always null-terminates */
static inline void safe_strncpy(char *dest, const char *src, size_t n)
{
if (n == 0) return;
size_t src_len = strlen(src);
size_t copy_len = (src_len < n - 1) ? src_len : n - 1;
memcpy(dest, src, copy_len);
dest[copy_len] = '\0';
}
/* Check if value is within valid range */
static inline bool in_range_int(int val, int min, int max)
{
return val >= min && val <= max;
}
static inline bool in_range_size_t(size_t val, size_t min, size_t max)
{
return val >= min && val <= max;
}
bool file_exists(const char *path);
char *file_read_all(const char *path);
bool file_write_all(const char *path, const char *content);