brewery
notashelf /
308c82f479ec29a9681e1702478bf2123fcaf0d5

chroma

public

Lightweight wallpaper daemon for Wayland

Star0tarball
clone
ssh://git@git.notashelf.dev:33/notashelf/chroma.git
include/chroma.hC397 lines15.3 KB
1
#ifndef CHROMA_H
2
#define CHROMA_H
3
4
#include "wlr-layer-shell-unstable-v1.h"
5
#include "xdg-shell.h"
6
#include <signal.h>
7
#include <stdbool.h>
8
#include <stdint.h>
9
#include <sys/types.h>
10
#include <wayland-client.h>
11
12
#include "chroma_version.h"
13
14
#define MAX_OUTPUTS 16
15
#define MAX_PATH_LEN 4096
16
#define CONFIG_FILE_NAME "chroma.toml"
17
18
// Log levels
19
#define CHROMA_LOG_ERROR 0
20
#define CHROMA_LOG_WARN 1
21
#define CHROMA_LOG_INFO 2
22
#define CHROMA_LOG_DEBUG 3
23
#define CHROMA_LOG_TRACE 4
24
25
// Error codes
26
typedef enum {
27
  CHROMA_OK = 0,
28
  CHROMA_ERROR_INIT = -1,
29
  CHROMA_ERROR_WAYLAND = -2,
30
  CHROMA_ERROR_EGL = -3,
31
  CHROMA_ERROR_IMAGE = -4,
32
  CHROMA_ERROR_CONFIG = -5,
33
  CHROMA_ERROR_MEMORY = -6
34
} chroma_error_t;
35
36
// Scaling modes for wallpaper display
37
typedef enum {
38
  CHROMA_SCALE_FILL = 0,    // fill entire output, crop if necessary
39
  CHROMA_SCALE_FIT = 1,     // fit image within output, add borders if needed
40
  CHROMA_SCALE_STRETCH = 2, // stretch to fill output, may distort aspect ratio
41
  CHROMA_SCALE_CENTER = 3   // center image at original size
42
} chroma_scale_mode_t;
43
44
// Anchor positions for wallpaper placement
45
typedef enum {
46
  CHROMA_ANCHOR_CENTER = 0,      // center of the output (default)
47
  CHROMA_ANCHOR_TOP = 1,         // top edge, centered horizontally
48
  CHROMA_ANCHOR_BOTTOM = 2,      // bottom edge, centered horizontally
49
  CHROMA_ANCHOR_LEFT = 3,        // left edge, centered vertically
50
  CHROMA_ANCHOR_RIGHT = 4,       // right edge, centered vertically
51
  CHROMA_ANCHOR_TOP_LEFT = 5,    // top-left corner
52
  CHROMA_ANCHOR_TOP_RIGHT = 6,   // top-right corner
53
  CHROMA_ANCHOR_BOTTOM_LEFT = 7, // bottom-left corner
54
  CHROMA_ANCHOR_BOTTOM_RIGHT = 8 // bottom-right corner
55
} chroma_anchor_t;
56
57
// Image filtering quality settings
58
typedef enum {
59
  CHROMA_FILTER_NEAREST = 0,  // nearest neighbor filtering (pixelated)
60
  CHROMA_FILTER_LINEAR = 1,   // linear filtering (smooth)
61
  CHROMA_FILTER_BILINEAR = 2, // bilinear filtering (smoother)
62
  CHROMA_FILTER_TRILINEAR = 3 // trilinear filtering (smoothest)
63
} chroma_filter_quality_t;
64
65
// Image data structure
66
typedef struct {
67
  unsigned char *data; // RGBA pixel data
68
  int width;
69
  int height;
70
  int channels;
71
  char path[MAX_PATH_LEN];
72
  bool loaded;
73
  bool data_from_stbi; // true if data was allocated by stbi_load
74
  int ref_count;       // number of outputs using this image
75
76
  // Solid color support
77
  bool is_solid_color;       // true if this is a generated solid color
78
  uint32_t solid_color_rgba; // RGBA color value (native byte order)
79
80
  // Animation support (for animated GIFs)
81
  bool is_animated;        // true if this image has multiple frames
82
  int frame_count;         // number of frames
83
  int current_frame;       // current frame index
84
  long long last_frame_ms; // timestamp of last frame advance
85
  unsigned char **frames;  // array of frame data pointers
86
  int *frame_delays_ms;    // delay per frame in milliseconds
87
  int *frame_widths;       // width per frame
88
  int *frame_heights;      // height per frame
89
} chroma_image_t;
90
91
// Wayland output information
92
typedef struct {
93
  struct wl_output *wl_output;
94
  uint32_t id;
95
  int32_t x, y;
96
  int32_t width, height;
97
  int32_t scale;
98
  enum wl_output_transform transform;
99
  char *name;
100
  char *description;
101
  bool active;
102
103
  // Back reference to state
104
  struct chroma_state *state;
105
106
  // Rendering context
107
  struct wl_surface *surface;
108
  struct zwlr_layer_surface_v1 *layer_surface;
109
  uint32_t configure_serial;
110
111
  // Shared memory buffer
112
  struct wl_buffer *shm_buffer;
113
  void *shm_data;
114
  size_t shm_size;
115
  int shm_stride;
116
117
  // Associated wallpaper
118
  chroma_image_t *image;
119
120
  // Configuration for this output
121
  chroma_scale_mode_t scale_mode;
122
  chroma_filter_quality_t filter_quality;
123
  chroma_anchor_t anchor;
124
  float anchor_x; // custom X offset (0-100, 50=center)
125
  float anchor_y; // custom Y offset (0-100, 50=center)
126
  bool config_loaded;
127
  bool configured; // track if initial configure received
128
129
  // Transition support
130
  bool in_transition;             // whether crossfade transition is active
131
  long long transition_start_ms;  // when transition began
132
  unsigned char *transition_prev; // previous frame pixel data (RGBA)
133
  size_t transition_prev_size;    // size of previous frame data
134
  int transition_prev_width;      // width of previous frame
135
  int transition_prev_height;     // height of previous frame
136
  int transition_duration_ms;     // duration for this output's transition
137
} chroma_output_t;
138
139
// Config mapping structure
140
typedef struct {
141
  char output_name[256];
142
  char image_path[MAX_PATH_LEN];
143
  chroma_scale_mode_t scale_mode;
144
  chroma_filter_quality_t filter_quality;
145
  chroma_anchor_t anchor;
146
  float anchor_x; // custom X offset (0-100, 50=center, 0=left, 100=right)
147
  float anchor_y; // custom Y offset (0-100, 50=center, 0=top, 100=bottom)
148
} chroma_config_mapping_t;
149
150
// Application configuration
151
typedef struct {
152
  chroma_config_mapping_t mappings[MAX_OUTPUTS];
153
  int mapping_count;
154
  char default_image[MAX_PATH_LEN];
155
  bool daemon_mode;
156
157
  // Global scaling and filtering settings (used as defaults)
158
  chroma_scale_mode_t default_scale_mode;
159
  chroma_filter_quality_t default_filter_quality;
160
  chroma_anchor_t default_anchor;
161
  float default_anchor_x; // custom anchor X offset (0-100, 50=center)
162
  float default_anchor_y; // custom anchor Y offset (0-100, 50=center)
163
164
  // Image downsampling settings
165
  bool enable_downsampling; // enable automatic downsampling
166
  int max_output_width;     // maximum expected output width
167
  int max_output_height;    // maximum expected output height
168
  float min_scale_factor;   // minimum scale factor (don't scale below this)
169
170
  // Solid color background support
171
  // When set via config or IPC, generates a solid color instead of loading an
172
  // image If non-empty, overrides image loading (format: "rrggbb" or
173
  // "rrggbbaa")
174
  char solid_color[10];
175
176
  // Transition settings
177
  bool transition_enabled;    // enable smooth crossfade transitions
178
  int transition_duration_ms; // crossfade duration in milliseconds
179
180
  // Animation settings
181
  bool animation_enabled; // enable animated GIF playback
182
  int animation_max_fps;  // max frames per second for animations
183
184
  // IPC settings
185
  bool ipc_enabled;                   // enable IPC command socket
186
  char ipc_socket_path[MAX_PATH_LEN]; // path to Unix domain socket
187
} chroma_config_t;
188
189
// Main application state
190
typedef struct chroma_state {
191
  // Wayland globals
192
  struct wl_display *display;
193
  struct wl_registry *registry;
194
  struct wl_compositor *compositor;
195
  struct zwlr_layer_shell_v1 *layer_shell;
196
  struct wl_shm *shm;
197
198
  // Outputs
199
  chroma_output_t outputs[MAX_OUTPUTS];
200
  int output_count;
201
202
  // Images
203
  chroma_image_t images[MAX_OUTPUTS];
204
  int image_count;
205
206
  // Configuration
207
  chroma_config_t config;
208
209
  // State flags
210
  bool running;
211
  bool initialized;
212
213
  // IPC
214
  int ipc_fd;                     // IPC socket file descriptor
215
  char config_file[MAX_PATH_LEN]; // active config file path
216
217
  // Animation timing
218
  long long last_anim_ms; // timestamp of last animation frame advance
219
} chroma_state_t;
220
221
// Initialization and cleanup
222
int chroma_init(chroma_state_t *state);
223
void chroma_cleanup(chroma_state_t *state);
224
225
// Wayland management
226
int chroma_wayland_connect(chroma_state_t *state);
227
void chroma_wayland_disconnect(chroma_state_t *state);
228
void chroma_registry_listener(void *data, struct wl_registry *registry,
229
                              uint32_t id, const char *interface,
230
                              uint32_t version);
231
void chroma_registry_remove(void *data, struct wl_registry *registry,
232
                            uint32_t id);
233
234
// Output management
235
int chroma_output_add(chroma_state_t *state, uint32_t id,
236
                      struct wl_output *output);
237
void chroma_output_remove(chroma_state_t *state, uint32_t id);
238
chroma_output_t *chroma_output_find_by_id(chroma_state_t *state, uint32_t id);
239
chroma_output_t *chroma_output_find_by_name(chroma_state_t *state,
240
                                            const char *name);
241
242
// Output event handlers
243
void chroma_output_geometry(void *data, struct wl_output *output, int32_t x,
244
                            int32_t y, int32_t physical_width,
245
                            int32_t physical_height, int32_t subpixel,
246
                            const char *make, const char *model,
247
                            int32_t transform);
248
void chroma_output_mode(void *data, struct wl_output *output, uint32_t flags,
249
                        int32_t width, int32_t height, int32_t refresh);
250
void chroma_output_scale(void *data, struct wl_output *output, int32_t scale);
251
void chroma_output_name(void *data, struct wl_output *output, const char *name);
252
void chroma_output_description(void *data, struct wl_output *output,
253
                               const char *description);
254
void chroma_output_done(void *data, struct wl_output *output);
255
256
// Rendering and surface management
257
int chroma_surface_create(chroma_state_t *state, chroma_output_t *output);
258
void chroma_surface_destroy(chroma_output_t *output);
259
int chroma_buffer_create(chroma_state_t *state, chroma_output_t *output);
260
void chroma_buffer_destroy(chroma_output_t *output);
261
void chroma_buffer_unmap(chroma_output_t *output);
262
int chroma_render_wallpaper(chroma_state_t *state, chroma_output_t *output);
263
264
// Layer shell functions
265
void chroma_layer_surface_configure(void *data,
266
                                    struct zwlr_layer_surface_v1 *layer_surface,
267
                                    uint32_t serial, uint32_t width,
268
                                    uint32_t height);
269
void chroma_layer_surface_closed(void *data,
270
                                 struct zwlr_layer_surface_v1 *layer_surface);
271
272
// Image loading
273
void chroma_image_init_stb(void);
274
int chroma_image_load(chroma_image_t *image, const char *path,
275
                      const chroma_config_t *config, int output_width,
276
                      int output_height);
277
void chroma_image_free(chroma_image_t *image);
278
void chroma_image_release(chroma_image_t *image);
279
chroma_image_t *chroma_image_find_by_path(chroma_state_t *state,
280
                                          const char *path);
281
chroma_image_t *chroma_image_get_or_load(chroma_state_t *state,
282
                                         const char *path, int output_width,
283
                                         int output_height);
284
int chroma_image_validate(const char *path);
285
int chroma_image_get_info(const char *path, int *width, int *height,
286
                          int *channels);
287
void chroma_images_cleanup(chroma_state_t *state);
288
289
// Solid color image generation
290
int chroma_image_load_color(chroma_image_t *image, uint32_t color_rgba,
291
                            int width, int height);
292
293
// Additional image format loaders
294
int chroma_image_load_farbfeld(chroma_image_t *image, const char *path);
295
int chroma_image_load_svg(chroma_image_t *image, const char *path,
296
                          int out_width, int out_height);
297
int chroma_image_load_webp(chroma_image_t *image, const char *path);
298
int chroma_image_load_tiff(chroma_image_t *image, const char *path);
299
int chroma_image_load_avif(chroma_image_t *image, const char *path);
300
int chroma_image_load_jpegxl(chroma_image_t *image, const char *path);
301
302
// Animation functions
303
int chroma_anim_load_gif(chroma_image_t *image, const char *path);
304
void chroma_anim_advance_frame(chroma_image_t *image,
305
                               long long current_time_ms);
306
void chroma_anim_free_frames(chroma_image_t *image);
307
bool chroma_anim_needs_redraw(chroma_state_t *state);
308
int chroma_anim_update_outputs(chroma_state_t *state);
309
310
// Transition functions
311
void chroma_transition_init_output(chroma_output_t *output, int duration_ms);
312
void chroma_transition_cleanup_output(chroma_output_t *output);
313
bool chroma_transition_is_active(chroma_output_t *output);
314
float chroma_transition_get_alpha(chroma_output_t *output,
315
                                  long long current_time_ms);
316
bool chroma_transition_needs_redraw(chroma_state_t *state);
317
int chroma_transition_update_outputs(chroma_state_t *state);
318
319
// IPC functions
320
int chroma_ipc_init(chroma_state_t *state);
321
void chroma_ipc_cleanup(chroma_state_t *state);
322
int chroma_ipc_process(chroma_state_t *state);
323
int chroma_ipc_get_fd(chroma_state_t *state);
324
325
// Configuration
326
int chroma_config_load(chroma_config_t *config, const char *config_file);
327
int chroma_config_load_toml(chroma_config_t *config, const char *config_file);
328
void chroma_config_free(chroma_config_t *config);
329
const char *chroma_config_get_image_for_output(chroma_config_t *config,
330
                                               const char *output_name,
331
                                               const char *output_description);
332
int chroma_config_get_mapping_for_output(
333
    chroma_config_t *config, const char *output_name,
334
    const char *output_description, chroma_scale_mode_t *scale_mode,
335
    chroma_filter_quality_t *filter_quality, chroma_anchor_t *anchor,
336
    float *anchor_x, float *anchor_y);
337
338
void chroma_config_print(const chroma_config_t *config);
339
340
// Main loop and events
341
int chroma_run(chroma_state_t *state);
342
void chroma_handle_signals(void);
343
int chroma_reload_config(chroma_state_t *state, const char *config_file);
344
int chroma_update_outputs(chroma_state_t *state);
345
void chroma_get_stats(chroma_state_t *state, int *active_outputs,
346
                      int *loaded_images);
347
void handle_output_done(chroma_state_t *state, chroma_output_t *output);
348
349
// Runtime wallpaper control
350
int chroma_set_wallpaper_for_output(chroma_state_t *state,
351
                                    const char *output_name,
352
                                    const char *image_path);
353
int chroma_set_wallpaper_for_all(chroma_state_t *state, const char *image_path);
354
int chroma_set_solid_color_for_output(chroma_state_t *state,
355
                                      const char *output_name,
356
                                      const char *hex_color);
357
int chroma_set_solid_color_for_all(chroma_state_t *state,
358
                                   const char *hex_color);
359
360
// Utilities
361
void chroma_log(const char *level, const char *format, ...);
362
const char *chroma_error_string(chroma_error_t error);
363
void chroma_set_log_level(int level);
364
int chroma_get_log_level(void);
365
void chroma_set_signal_state(chroma_state_t *state, const char *config_file);
366
void chroma_cleanup_signals(void);
367
char *chroma_expand_path(const char *path);
368
int chroma_mkdir_recursive(const char *path, mode_t mode);
369
char *chroma_get_config_dir(void);
370
bool chroma_path_exists(const char *path);
371
bool chroma_is_regular_file(const char *path);
372
bool chroma_is_directory(const char *path);
373
long chroma_get_file_size(const char *path);
374
const char *chroma_get_file_extension(const char *path);
375
long long chroma_get_time_ms(void);
376
void chroma_sleep_ms(long ms);
377
void chroma_format_memory_size(size_t bytes, char *buffer, size_t buffer_size);
378
void chroma_utils_cleanup(void);
379
380
// Memory tracking and logging
381
void chroma_log_memory_stats(const char *context);
382
size_t chroma_get_memory_usage(void);
383
void chroma_log_resource_allocation(const char *resource_type, size_t size,
384
                                    const char *description);
385
void chroma_log_resource_deallocation(const char *resource_type, size_t size,
386
                                      const char *description);
387
388
// Listener structures
389
extern const struct wl_registry_listener chroma_registry_listener_impl;
390
extern const struct wl_output_listener chroma_output_listener_impl;
391
extern const struct zwlr_layer_surface_v1_listener
392
    chroma_layer_surface_listener_impl;
393
394
// Global state for signal handling
395
extern volatile sig_atomic_t chroma_should_quit;
396
397
#endif // CHROMA_H