mirror of
https://codeberg.org/vyivel/dulcepan/
synced 2025-06-23 22:14:18 +03:00
Compare commits
5 Commits
d2620c60c5
...
9879f3ad69
Author | SHA1 | Date | |
---|---|---|---|
9879f3ad69 | |||
51f744c876 | |||
640b015053 | |||
0ccb868b39 | |||
7cc26b8e38 |
@ -40,6 +40,7 @@ persistence = true
|
|||||||
# PNG (zlib) compression level, 0-9
|
# PNG (zlib) compression level, 0-9
|
||||||
png-compression = 6
|
png-compression = 6
|
||||||
|
|
||||||
# Key bindings
|
# Key bindings. Each binding is a comma-separated list of key names; empty names
|
||||||
|
# are ignored. A binding may be empty.
|
||||||
quit-key = Escape
|
quit-key = Escape
|
||||||
save-key = Space
|
save-key = Space,Enter
|
||||||
|
60
src/config.c
60
src/config.c
@ -15,7 +15,22 @@ static inline void bytes_to_color(uint8_t bytes[static 4], float out[static 4])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void load_color(const char *value, int line_idx, float out[static 4]) {
|
static void keybinding_init(struct dp_keybinding *kb, xkb_keysym_t *syms, size_t n_syms) {
|
||||||
|
*kb = (struct dp_keybinding){
|
||||||
|
.syms = dp_zalloc(sizeof(*kb->syms) * n_syms),
|
||||||
|
.n_syms = n_syms,
|
||||||
|
};
|
||||||
|
for (size_t i = 0; i < n_syms; i++) {
|
||||||
|
xkb_keysym_t sym = syms[i];
|
||||||
|
kb->syms[i] = sym;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void keybinding_finish(struct dp_keybinding *kb) {
|
||||||
|
free(kb->syms);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void load_color(char *value, int line_idx, float out[static 4]) {
|
||||||
size_t len = strlen(value);
|
size_t len = strlen(value);
|
||||||
|
|
||||||
uint8_t bytes[4] = {0, 0, 0, 0};
|
uint8_t bytes[4] = {0, 0, 0, 0};
|
||||||
@ -46,7 +61,7 @@ bad:
|
|||||||
dp_log_fatal("Config: invalid color %s on line %d", value, line_idx);
|
dp_log_fatal("Config: invalid color %s on line %d", value, line_idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void load_int(const char *value, int line_idx, int min, int max, int *out) {
|
static void load_int(char *value, int line_idx, int min, int max, int *out) {
|
||||||
const char *p = value;
|
const char *p = value;
|
||||||
int mul = 1;
|
int mul = 1;
|
||||||
if (*p == '-') {
|
if (*p == '-') {
|
||||||
@ -68,7 +83,7 @@ static void load_int(const char *value, int line_idx, int min, int max, int *out
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void load_bool(const char *value, int line_idx, bool *out) {
|
static void load_bool(char *value, int line_idx, bool *out) {
|
||||||
if (strcmp(value, "true") == 0) {
|
if (strcmp(value, "true") == 0) {
|
||||||
*out = true;
|
*out = true;
|
||||||
} else if (strcmp(value, "false") == 0) {
|
} else if (strcmp(value, "false") == 0) {
|
||||||
@ -78,19 +93,31 @@ static void load_bool(const char *value, int line_idx, bool *out) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void load_key(const char *value, int line_idx, xkb_keysym_t *out) {
|
static void load_key(char *value, int line_idx, struct dp_keybinding *out) {
|
||||||
*out = xkb_keysym_from_name(value, XKB_KEYSYM_CASE_INSENSITIVE);
|
size_t n_syms = 0;
|
||||||
if (*out == XKB_KEY_NoSymbol) {
|
xkb_keysym_t syms[32];
|
||||||
dp_log_fatal("Config: unknown key %s on line %d", value, line_idx);
|
|
||||||
|
char *save_ptr = NULL;
|
||||||
|
for (char *name; (name = strtok_r(value, ",", &save_ptr)) != NULL; value = NULL) {
|
||||||
|
if (n_syms == sizeof(syms) / sizeof(*syms)) {
|
||||||
|
// chill out
|
||||||
|
dp_log_fatal("Config: too many keys on line %d", line_idx);
|
||||||
|
}
|
||||||
|
xkb_keysym_t sym = xkb_keysym_from_name(name, XKB_KEYSYM_CASE_INSENSITIVE);
|
||||||
|
if (sym == XKB_KEY_NoSymbol) {
|
||||||
|
dp_log_fatal("Config: unknown key \"%s\" on line %d", name, line_idx);
|
||||||
|
}
|
||||||
|
syms[n_syms++] = sym;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
keybinding_finish(out);
|
||||||
|
keybinding_init(out, syms, n_syms);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dp_config_load(struct dp_state *state, const char *user_path) {
|
void dp_config_load(struct dp_state *state, const char *user_path) {
|
||||||
struct dp_config *config = &state->config;
|
struct dp_config *config = &state->config;
|
||||||
|
|
||||||
*config = (struct dp_config){
|
*config = (struct dp_config){
|
||||||
.quit_key = XKB_KEY_Escape,
|
|
||||||
.save_key = XKB_KEY_space,
|
|
||||||
.border_size = 2,
|
.border_size = 2,
|
||||||
.border_gradient = DP_BORDER_GRADIENT_NONE,
|
.border_gradient = DP_BORDER_GRADIENT_NONE,
|
||||||
.gradient_angle = 45,
|
.gradient_angle = 45,
|
||||||
@ -100,11 +127,15 @@ void dp_config_load(struct dp_state *state, const char *user_path) {
|
|||||||
.quick_select = false,
|
.quick_select = false,
|
||||||
.persistence = true,
|
.persistence = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
bytes_to_color((uint8_t[]){0xff, 0xff, 0xff, 0x40}, config->unselected_color);
|
bytes_to_color((uint8_t[]){0xff, 0xff, 0xff, 0x40}, config->unselected_color);
|
||||||
bytes_to_color((uint8_t[]){0x00, 0x00, 0x00, 0x00}, config->selected_color);
|
bytes_to_color((uint8_t[]){0x00, 0x00, 0x00, 0x00}, config->selected_color);
|
||||||
bytes_to_color((uint8_t[]){0xff, 0xff, 0xff, 0xff}, config->border_color);
|
bytes_to_color((uint8_t[]){0xff, 0xff, 0xff, 0xff}, config->border_color);
|
||||||
bytes_to_color((uint8_t[]){0x00, 0x00, 0x00, 0xff}, config->border_secondary_color);
|
bytes_to_color((uint8_t[]){0x00, 0x00, 0x00, 0xff}, config->border_secondary_color);
|
||||||
|
|
||||||
|
keybinding_init(&config->quit_kb, (xkb_keysym_t[]){XKB_KEY_Escape}, 1);
|
||||||
|
keybinding_init(&config->save_kb, (xkb_keysym_t[]){XKB_KEY_space, XKB_KEY_Return}, 2);
|
||||||
|
|
||||||
FILE *fp = NULL;
|
FILE *fp = NULL;
|
||||||
if (user_path != NULL) {
|
if (user_path != NULL) {
|
||||||
fp = fopen(user_path, "r");
|
fp = fopen(user_path, "r");
|
||||||
@ -215,9 +246,9 @@ void dp_config_load(struct dp_state *state, const char *user_path) {
|
|||||||
} else if (strcmp(key, "persistence") == 0) {
|
} else if (strcmp(key, "persistence") == 0) {
|
||||||
load_bool(value, line_idx, &config->persistence);
|
load_bool(value, line_idx, &config->persistence);
|
||||||
} else if (strcmp(key, "quit-key") == 0) {
|
} else if (strcmp(key, "quit-key") == 0) {
|
||||||
load_key(value, line_idx, &config->quit_key);
|
load_key(value, line_idx, &config->quit_kb);
|
||||||
} else if (strcmp(key, "save-key") == 0) {
|
} else if (strcmp(key, "save-key") == 0) {
|
||||||
load_key(value, line_idx, &config->save_key);
|
load_key(value, line_idx, &config->save_kb);
|
||||||
} else {
|
} else {
|
||||||
dp_log_error("Config: unknown key %s on line %d", key, line_idx);
|
dp_log_error("Config: unknown key %s on line %d", key, line_idx);
|
||||||
}
|
}
|
||||||
@ -226,3 +257,10 @@ void dp_config_load(struct dp_state *state, const char *user_path) {
|
|||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dp_config_finish(struct dp_state *state) {
|
||||||
|
struct dp_config *config = &state->config;
|
||||||
|
|
||||||
|
keybinding_finish(&config->quit_kb);
|
||||||
|
keybinding_finish(&config->save_kb);
|
||||||
|
}
|
||||||
|
@ -141,6 +141,11 @@ enum dp_border_gradient {
|
|||||||
DP_BORDER_GRADIENT_LOOP,
|
DP_BORDER_GRADIENT_LOOP,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct dp_keybinding {
|
||||||
|
xkb_keysym_t *syms;
|
||||||
|
size_t n_syms;
|
||||||
|
};
|
||||||
|
|
||||||
struct dp_config {
|
struct dp_config {
|
||||||
// RGBA, not premultiplied
|
// RGBA, not premultiplied
|
||||||
float unselected_color[4];
|
float unselected_color[4];
|
||||||
@ -148,8 +153,8 @@ struct dp_config {
|
|||||||
float border_color[4];
|
float border_color[4];
|
||||||
float border_secondary_color[4];
|
float border_secondary_color[4];
|
||||||
|
|
||||||
xkb_keysym_t quit_key;
|
struct dp_keybinding quit_kb;
|
||||||
xkb_keysym_t save_key;
|
struct dp_keybinding save_kb;
|
||||||
|
|
||||||
int border_size; // 0 if disabled
|
int border_size; // 0 if disabled
|
||||||
enum dp_border_gradient border_gradient;
|
enum dp_border_gradient border_gradient;
|
||||||
@ -204,6 +209,7 @@ struct dp_state {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void dp_config_load(struct dp_state *state, const char *user_path);
|
void dp_config_load(struct dp_state *state, const char *user_path);
|
||||||
|
void dp_config_finish(struct dp_state *state);
|
||||||
|
|
||||||
// When done, data must be unmapped
|
// When done, data must be unmapped
|
||||||
struct wl_buffer *dp_buffer_create(struct dp_state *state, int32_t width, int32_t height,
|
struct wl_buffer *dp_buffer_create(struct dp_state *state, int32_t width, int32_t height,
|
||||||
|
@ -278,6 +278,8 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
run(&state);
|
run(&state);
|
||||||
|
|
||||||
|
dp_config_finish(&state);
|
||||||
|
|
||||||
cairo_pattern_destroy(state.border_pattern);
|
cairo_pattern_destroy(state.border_pattern);
|
||||||
|
|
||||||
xkb_context_unref(state.xkb_context);
|
xkb_context_unref(state.xkb_context);
|
||||||
|
22
src/seat.c
22
src/seat.c
@ -50,6 +50,15 @@ static void keyboard_handle_leave(
|
|||||||
// Ignored
|
// Ignored
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool match_keybinding(struct dp_keybinding *kb, uint32_t sym) {
|
||||||
|
for (size_t i = 0; i < kb->n_syms; i++) {
|
||||||
|
if (sym == kb->syms[i]) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static void keyboard_handle_key(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial,
|
static void keyboard_handle_key(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial,
|
||||||
uint32_t time_msec, uint32_t keycode, enum wl_keyboard_key_state key_state) {
|
uint32_t time_msec, uint32_t keycode, enum wl_keyboard_key_state key_state) {
|
||||||
struct dp_seat *seat = data;
|
struct dp_seat *seat = data;
|
||||||
@ -62,9 +71,9 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *wl_keyboard, uin
|
|||||||
struct dp_state *state = seat->state;
|
struct dp_state *state = seat->state;
|
||||||
struct dp_config *config = &state->config;
|
struct dp_config *config = &state->config;
|
||||||
|
|
||||||
if (keysym == config->quit_key) {
|
if (match_keybinding(&config->quit_kb, keysym)) {
|
||||||
state->status = DP_STATUS_QUIT;
|
state->status = DP_STATUS_QUIT;
|
||||||
} else if (keysym == config->save_key) {
|
} else if (match_keybinding(&config->save_kb, keysym)) {
|
||||||
state->status = DP_STATUS_SAVED;
|
state->status = DP_STATUS_SAVED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -86,10 +95,10 @@ static const struct wl_keyboard_listener keyboard_listener = {
|
|||||||
static enum wp_cursor_shape_device_v1_shape get_cursor_shape(struct dp_selection *selection) {
|
static enum wp_cursor_shape_device_v1_shape get_cursor_shape(struct dp_selection *selection) {
|
||||||
switch (selection->action) {
|
switch (selection->action) {
|
||||||
case DP_SELECTION_ACTION_NONE:
|
case DP_SELECTION_ACTION_NONE:
|
||||||
return WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_CROSSHAIR;
|
break;
|
||||||
case DP_SELECTION_ACTION_RESIZING:
|
case DP_SELECTION_ACTION_RESIZING:
|
||||||
if (selection->width == 0 || selection->height == 0) {
|
if (selection->width == 0 || selection->height == 0) {
|
||||||
return WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_CROSSHAIR;
|
break;
|
||||||
}
|
}
|
||||||
switch (selection->resize_edges) {
|
switch (selection->resize_edges) {
|
||||||
case DP_EDGE_TOP:
|
case DP_EDGE_TOP:
|
||||||
@ -116,11 +125,12 @@ static enum wp_cursor_shape_device_v1_shape get_cursor_shape(struct dp_selection
|
|||||||
selection->width == selection->output->effective_width &&
|
selection->width == selection->output->effective_width &&
|
||||||
selection->height == selection->output->effective_height) {
|
selection->height == selection->output->effective_height) {
|
||||||
// Moving is impossible
|
// Moving is impossible
|
||||||
return WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_DEFAULT;
|
break;
|
||||||
}
|
}
|
||||||
return WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_MOVE;
|
return WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_MOVE;
|
||||||
}
|
}
|
||||||
abort(); // Unreachable
|
// The default cursor
|
||||||
|
return WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_CROSSHAIR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_cursor(struct dp_seat *seat) {
|
static void update_cursor(struct dp_seat *seat) {
|
||||||
|
@ -187,6 +187,8 @@ void dp_select_start_interactive(struct dp_selection *selection, struct dp_outpu
|
|||||||
selection->resize_edges = DP_EDGE_BOTTOM | DP_EDGE_RIGHT;
|
selection->resize_edges = DP_EDGE_BOTTOM | DP_EDGE_RIGHT;
|
||||||
|
|
||||||
init_resize(selection, x, y);
|
init_resize(selection, x, y);
|
||||||
|
|
||||||
|
dp_output_redraw(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dp_select_stop_interactive(struct dp_selection *selection) {
|
void dp_select_stop_interactive(struct dp_selection *selection) {
|
||||||
|
@ -28,6 +28,10 @@ void dp_log_fatal(const char *fmt, ...) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void *dp_zalloc(size_t size) {
|
void *dp_zalloc(size_t size) {
|
||||||
|
if (size == 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void *ptr = calloc(1, size);
|
void *ptr = calloc(1, size);
|
||||||
if (ptr == NULL) {
|
if (ptr == NULL) {
|
||||||
dp_log_fatal("Failed to allocate %zu bytes", size);
|
dp_log_fatal("Failed to allocate %zu bytes", size);
|
||||||
|
Reference in New Issue
Block a user