mirror of
https://codeberg.org/vyivel/dulcepan/
synced 2025-12-17 23:55:12 +02:00
Switch back to Cairo for drawing selection
This commit is contained in:
@@ -43,6 +43,7 @@ add_project_arguments(cc.get_supported_arguments([
|
|||||||
wayland_client = dependency('wayland-client')
|
wayland_client = dependency('wayland-client')
|
||||||
wayland_protos = dependency('wayland-protocols')
|
wayland_protos = dependency('wayland-protocols')
|
||||||
|
|
||||||
|
cairo = dependency('cairo')
|
||||||
pixman = dependency('pixman-1')
|
pixman = dependency('pixman-1')
|
||||||
spng = dependency('spng', fallback: 'libspng')
|
spng = dependency('spng', fallback: 'libspng')
|
||||||
xkbcommon = dependency(
|
xkbcommon = dependency(
|
||||||
@@ -75,6 +76,7 @@ executable(
|
|||||||
dependencies: [
|
dependencies: [
|
||||||
client_protos,
|
client_protos,
|
||||||
wayland_client,
|
wayland_client,
|
||||||
|
cairo,
|
||||||
pixman,
|
pixman,
|
||||||
spng,
|
spng,
|
||||||
xkbcommon,
|
xkbcommon,
|
||||||
|
|||||||
@@ -10,10 +10,9 @@
|
|||||||
|
|
||||||
#define CONFIG_SUBPATH "dulcepan.cfg"
|
#define CONFIG_SUBPATH "dulcepan.cfg"
|
||||||
|
|
||||||
static void bytes_to_color(uint8_t bytes[static 4], float out[static 4]) {
|
static inline void bytes_to_color(uint8_t bytes[static 4], float out[static 4]) {
|
||||||
out[3] = (float)bytes[3] / UINT8_MAX;
|
for (size_t i = 0; i < 4; i++) {
|
||||||
for (size_t i = 0; i < 3; i++) {
|
out[i] = (float)bytes[i] / UINT8_MAX;
|
||||||
out[i] = (float)bytes[i] * out[3] / UINT8_MAX;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#ifndef DULCEPAN_H
|
#ifndef DULCEPAN_H
|
||||||
#define DULCEPAN_H
|
#define DULCEPAN_H
|
||||||
|
|
||||||
#include <pixman.h>
|
#include <cairo.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <wayland-util.h>
|
#include <wayland-util.h>
|
||||||
@@ -18,7 +18,8 @@ enum dp_status {
|
|||||||
|
|
||||||
struct dp_buffer {
|
struct dp_buffer {
|
||||||
struct wl_buffer *wl_buffer;
|
struct wl_buffer *wl_buffer;
|
||||||
pixman_image_t *image;
|
cairo_t *cairo;
|
||||||
|
cairo_surface_t *cairo_surface;
|
||||||
void *data;
|
void *data;
|
||||||
size_t size;
|
size_t size;
|
||||||
bool used;
|
bool used;
|
||||||
@@ -123,6 +124,7 @@ enum dp_file_format {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct dp_config {
|
struct dp_config {
|
||||||
|
// RGBA, not premultiplied
|
||||||
float unselected_color[4];
|
float unselected_color[4];
|
||||||
float selected_color[4];
|
float selected_color[4];
|
||||||
float border_color[4];
|
float border_color[4];
|
||||||
@@ -161,10 +163,6 @@ struct dp_state {
|
|||||||
enum dp_file_format output_format;
|
enum dp_file_format output_format;
|
||||||
|
|
||||||
bool show_cursors;
|
bool show_cursors;
|
||||||
|
|
||||||
pixman_image_t *unselected_fill_image;
|
|
||||||
pixman_image_t *selected_fill_image;
|
|
||||||
pixman_image_t *border_fill_image;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void dp_config_load(struct dp_config *config, const char *user_path);
|
void dp_config_load(struct dp_config *config, const char *user_path);
|
||||||
|
|||||||
18
src/main.c
18
src/main.c
@@ -166,16 +166,6 @@ static void help(const char *prog) {
|
|||||||
prog);
|
prog);
|
||||||
}
|
}
|
||||||
|
|
||||||
static pixman_image_t *make_image(float color[static 4]) {
|
|
||||||
pixman_color_t pixman_color = {
|
|
||||||
.red = (uint16_t)(color[0] * UINT16_MAX),
|
|
||||||
.green = (uint16_t)(color[1] * UINT16_MAX),
|
|
||||||
.blue = (uint16_t)(color[2] * UINT16_MAX),
|
|
||||||
.alpha = (uint16_t)(color[3] * UINT16_MAX),
|
|
||||||
};
|
|
||||||
return pixman_image_create_solid_fill(&pixman_color);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
struct dp_state state = {0};
|
struct dp_state state = {0};
|
||||||
|
|
||||||
@@ -233,16 +223,8 @@ int main(int argc, char **argv) {
|
|||||||
dp_log_fatal("Failed to connect to a Wayland compositor");
|
dp_log_fatal("Failed to connect to a Wayland compositor");
|
||||||
}
|
}
|
||||||
|
|
||||||
state.unselected_fill_image = make_image(state.config.unselected_color);
|
|
||||||
state.selected_fill_image = make_image(state.config.selected_color);
|
|
||||||
state.border_fill_image = make_image(state.config.border_color);
|
|
||||||
|
|
||||||
run(&state);
|
run(&state);
|
||||||
|
|
||||||
pixman_image_unref(state.unselected_fill_image);
|
|
||||||
pixman_image_unref(state.selected_fill_image);
|
|
||||||
pixman_image_unref(state.border_fill_image);
|
|
||||||
|
|
||||||
xkb_context_unref(state.xkb_context);
|
xkb_context_unref(state.xkb_context);
|
||||||
|
|
||||||
wl_display_disconnect(state.display);
|
wl_display_disconnect(state.display);
|
||||||
|
|||||||
45
src/output.c
45
src/output.c
@@ -208,8 +208,9 @@ static void output_handle_done(void *data, struct wl_output *wl_output) {
|
|||||||
buffer->wl_buffer =
|
buffer->wl_buffer =
|
||||||
dp_buffer_create(state, output->transformed_width, output->transformed_height,
|
dp_buffer_create(state, output->transformed_width, output->transformed_height,
|
||||||
stride, WL_SHM_FORMAT_ARGB8888, &buffer->data, &buffer->size);
|
stride, WL_SHM_FORMAT_ARGB8888, &buffer->data, &buffer->size);
|
||||||
buffer->image = pixman_image_create_bits(PIXMAN_a8r8g8b8, output->transformed_width,
|
buffer->cairo_surface = cairo_image_surface_create_for_data(buffer->data,
|
||||||
output->transformed_height, buffer->data, stride);
|
CAIRO_FORMAT_ARGB32, output->transformed_width, output->transformed_height, stride);
|
||||||
|
buffer->cairo = cairo_create(buffer->cairo_surface);
|
||||||
|
|
||||||
wl_buffer_add_listener(buffer->wl_buffer, &buffer_listener, buffer);
|
wl_buffer_add_listener(buffer->wl_buffer, &buffer_listener, buffer);
|
||||||
}
|
}
|
||||||
@@ -242,6 +243,10 @@ static const struct wl_callback_listener redraw_callback_listener = {
|
|||||||
.done = redraw_callback_handle_done,
|
.done = redraw_callback_handle_done,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static inline void set_cairo_color(cairo_t *cairo, float color[static 4]) {
|
||||||
|
cairo_set_source_rgba(cairo, color[0], color[1], color[2], color[3]);
|
||||||
|
}
|
||||||
|
|
||||||
static void redraw(struct dp_output *output) {
|
static void redraw(struct dp_output *output) {
|
||||||
assert(output->redraw_callback == NULL);
|
assert(output->redraw_callback == NULL);
|
||||||
|
|
||||||
@@ -260,30 +265,29 @@ static void redraw(struct dp_output *output) {
|
|||||||
buffer->used = true;
|
buffer->used = true;
|
||||||
|
|
||||||
struct dp_state *state = output->state;
|
struct dp_state *state = output->state;
|
||||||
|
struct dp_config *config = &state->config;
|
||||||
|
|
||||||
pixman_image_composite32(PIXMAN_OP_SRC, state->unselected_fill_image, NULL, buffer->image, 0, 0,
|
cairo_set_operator(buffer->cairo, CAIRO_OPERATOR_SOURCE);
|
||||||
0, 0, 0, 0, output->transformed_width, output->transformed_height);
|
|
||||||
|
set_cairo_color(buffer->cairo, config->unselected_color);
|
||||||
|
cairo_paint(buffer->cairo);
|
||||||
|
|
||||||
struct dp_selection *selection = &state->selection;
|
struct dp_selection *selection = &state->selection;
|
||||||
if (output == selection->output) {
|
if (output == selection->output) {
|
||||||
int border_size = state->config.border_size;
|
int border_size = config->border_size;
|
||||||
if (border_size != 0) {
|
if (border_size != 0) {
|
||||||
pixman_image_composite32(PIXMAN_OP_SRC, state->border_fill_image, NULL, buffer->image,
|
cairo_set_line_width(buffer->cairo, border_size);
|
||||||
0, 0, 0, 0, selection->x - border_size, selection->y - border_size,
|
double off = border_size / 2.0;
|
||||||
selection->width + border_size * 2, border_size);
|
cairo_rectangle(buffer->cairo, selection->x - off, selection->y - off,
|
||||||
pixman_image_composite32(PIXMAN_OP_SRC, state->border_fill_image, NULL, buffer->image,
|
selection->width + border_size, selection->height + border_size);
|
||||||
0, 0, 0, 0, selection->x - border_size, selection->y + selection->height,
|
set_cairo_color(buffer->cairo, config->border_color);
|
||||||
selection->width + border_size * 2, border_size);
|
cairo_stroke(buffer->cairo);
|
||||||
pixman_image_composite32(PIXMAN_OP_SRC, state->border_fill_image, NULL, buffer->image,
|
|
||||||
0, 0, 0, 0, selection->x - border_size, selection->y, border_size,
|
|
||||||
selection->height);
|
|
||||||
pixman_image_composite32(PIXMAN_OP_SRC, state->border_fill_image, NULL, buffer->image,
|
|
||||||
0, 0, 0, 0, selection->x + selection->width, selection->y, border_size,
|
|
||||||
selection->height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pixman_image_composite32(PIXMAN_OP_SRC, state->selected_fill_image, NULL, buffer->image, 0,
|
cairo_rectangle(
|
||||||
0, 0, 0, selection->x, selection->y, selection->width, selection->height);
|
buffer->cairo, selection->x, selection->y, selection->width, selection->height);
|
||||||
|
set_cairo_color(buffer->cairo, config->selected_color);
|
||||||
|
cairo_fill(buffer->cairo);
|
||||||
}
|
}
|
||||||
|
|
||||||
wl_surface_attach(output->select_surface, buffer->wl_buffer, 0, 0);
|
wl_surface_attach(output->select_surface, buffer->wl_buffer, 0, 0);
|
||||||
@@ -335,7 +339,8 @@ void dp_output_destroy(struct dp_output *output) {
|
|||||||
for (size_t i = 0; i < DP_SWAPCHAIN_LEN; i++) {
|
for (size_t i = 0; i < DP_SWAPCHAIN_LEN; i++) {
|
||||||
struct dp_buffer *buffer = &output->swapchain[i];
|
struct dp_buffer *buffer = &output->swapchain[i];
|
||||||
wl_buffer_destroy(buffer->wl_buffer);
|
wl_buffer_destroy(buffer->wl_buffer);
|
||||||
pixman_image_unref(buffer->image);
|
cairo_destroy(buffer->cairo);
|
||||||
|
cairo_surface_destroy(buffer->cairo_surface);
|
||||||
munmap(buffer->data, buffer->size);
|
munmap(buffer->data, buffer->size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <pixman.h>
|
||||||
#include <spng.h>
|
#include <spng.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|||||||
Reference in New Issue
Block a user