diff --git a/.ycm_extra_conf.py b/.ycm_extra_conf.py index 779de8f..fb56ce2 100644 --- a/.ycm_extra_conf.py +++ b/.ycm_extra_conf.py @@ -1,4 +1,4 @@ -# Generated by YCM Generator at 2022-09-07 00:00:45.256036 +# Generated by YCM Generator at 2022-09-07 15:55:49.892367 # This file is NOT licensed under the GPLv3, which is the license for the rest # of YouCompleteMe. @@ -36,6 +36,18 @@ import ycm_core flags = [ '-x', 'c', + '-I/usr/include/blkid', + '-I/usr/include/cairo', + '-I/usr/include/freetype2', + '-I/usr/include/fribidi', + '-I/usr/include/glib-2.0', + '-I/usr/include/harfbuzz', + '-I/usr/include/libmount', + '-I/usr/include/libpng16', + '-I/usr/include/pango-1.0', + '-I/usr/include/pixman-1', + '-I/usr/lib64/glib-2.0/include', + '-I/usr/lib64/libffi/include', '-Wall', ] diff --git a/makefile b/makefile index 5cddc21..8e76db7 100644 --- a/makefile +++ b/makefile @@ -1,7 +1,20 @@ BUILD = build CFLAGS += -Wall -LDLIBS = -lwayland-client -lrt -lcairo + +# Pango and dependencies +CFLAGS += $(shell pkg-config --cflags pangocairo) +LDLIBS += $(shell pkg-config --libs pangocairo) + +#CFLAGS += $(shell pkg-config --cflags glib-2.0) +#LDLIBS += $(shell pkg-config --libs glib-2.0) + +#CFLAGS += $(shell pkg-config --cflags harfbuzz) +#LDLIBS += $(shell pkg-config --libs harfbuzz) + +LDLIBS += -lwayland-client +LDLIBS += -lrt +LDLIBS += -lcairo $(shell mkdir -p $(BUILD)) @@ -25,4 +38,4 @@ build/wlr-layer-shell-protocol.c: wlr-layer-shell-unstable-v1.xml C_FILES = wl-overlay.c build/xdg-shell-protocol.c build/wlr-layer-shell-protocol.c build/wl-overlay: $(C_FILES) xdg-shell-client-protocol.h wlr-layer-shell-protocol.h - $(CC) $(CFLAGS) $(LDLIBS) -o "$@" $(C_FILES) + $(CC) $(CFLAGS) $(INC) $(LDFLAGS) $(LDLIBS) -o "$@" $(C_FILES) diff --git a/wl-overlay.c b/wl-overlay.c index abe26df..bad1d53 100644 --- a/wl-overlay.c +++ b/wl-overlay.c @@ -10,8 +10,11 @@ #include #include #include +#include #include "wlr-layer-shell-protocol.h" +#define STR_EQUAL 0 + /* Shared memory support code */ static void randname(char *buf) @@ -60,8 +63,14 @@ allocate_shm_file(size_t size) } /* Wayland code */ +struct user_request { + char *graphics_filename; + char *text; + bool backdrop; +}; + struct client_state { - char *filename; + struct user_request user_request; /* Globals */ struct wl_display *wl_display; struct wl_registry *wl_registry; @@ -84,6 +93,17 @@ static const struct wl_buffer_listener wl_buffer_listener = { .release = wl_buffer_release, }; +static void +draw_rounded_rectangle(cairo_t *cr, int x, int y, int width, int height, int radius) +{ + cairo_new_sub_path(cr); + cairo_arc(cr, x + radius, y + radius, radius, M_PI, 3*M_PI/2); + cairo_arc(cr, x + width - radius, y + radius, radius, 3*M_PI/2, 0); + cairo_arc(cr, x + width - radius, y + height - radius, radius, 0, M_PI/2); + cairo_arc(cr, x + radius, y + height - radius, radius, M_PI/2, M_PI); + cairo_close_path(cr); +} + static struct wl_buffer * draw_frame(struct client_state *state, const int width, const int height) { @@ -108,20 +128,45 @@ draw_frame(struct client_state *state, const int width, const int height) wl_shm_pool_destroy(pool); close(fd); - /* Load PNG */ + /* Draw background */ cairo_surface_t *cairo_target_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); cairo_t *cairo = cairo_create(cairo_target_surface); memset(cairo_image_surface_get_data(cairo_target_surface), 0, size); - cairo_surface_t *cairo_png_surface = cairo_image_surface_create_from_png(state->filename); - if (cairo_surface_status(cairo_png_surface) != CAIRO_STATUS_SUCCESS) { - fprintf(stderr, "Failed to open PNG image.\n"); - exit(1); + if (state->user_request.backdrop) { + cairo_set_source_rgba(cairo, 0x11 / 255.0, 0x11 / 255.0, 0x11 / 255.0, 0.85); + draw_rounded_rectangle(cairo, 0, 0, width, height, 15); + /*cairo_rectangle(cairo, 0, 0, width, height);*/ + cairo_fill(cairo); } - cairo_set_source_surface(cairo, cairo_png_surface, 0.0, 0.0); - cairo_paint(cairo); - memcpy(data, cairo_image_surface_get_data(cairo_target_surface), size); - cairo_surface_destroy(cairo_png_surface); + /* Load and draw PNG */ + if (strcmp("", state->user_request.graphics_filename) != STR_EQUAL) { + cairo_surface_t *cairo_png_surface = cairo_image_surface_create_from_png(state->user_request.graphics_filename); + if (cairo_surface_status(cairo_png_surface) != CAIRO_STATUS_SUCCESS) { + fprintf(stderr, "Failed to open PNG image.\n"); + exit(1); + } + cairo_set_source_surface(cairo, cairo_png_surface, 0.0, 0.0); + cairo_paint(cairo); + cairo_surface_destroy(cairo_png_surface); + } + + /* Draw text */ + if (state->user_request.text) { + PangoLayout *layout = pango_cairo_create_layout(cairo); + pango_layout_set_text(layout, state->user_request.text, -1); + PangoFontDescription *desc = pango_font_description_from_string("Fira Sans 12"); + pango_layout_set_font_description(layout, desc); + pango_font_description_free(desc); + cairo_set_source_rgb(cairo, 1.0, 1.0, 1.0); + int text_width, text_height; + pango_layout_get_size(layout, &text_width, &text_height); + cairo_move_to(cairo, (width - text_width/PANGO_SCALE)/2.0, 3*height/4.0); + pango_cairo_show_layout(cairo, layout); + g_object_unref(layout); + } + + memcpy(data, cairo_image_surface_get_data(cairo_target_surface), size); cairo_surface_destroy(cairo_target_surface); cairo_destroy(cairo); @@ -152,15 +197,15 @@ registry_global(void *data, struct wl_registry *wl_registry, uint32_t name, const char *interface, uint32_t version) { struct client_state *state = data; - if (strcmp(interface, wl_shm_interface.name) == 0) { + if (strcmp(interface, wl_shm_interface.name) == STR_EQUAL) { state->wl_shm = wl_registry_bind( wl_registry, name, &wl_shm_interface, 1); - } else if (strcmp(interface, wl_compositor_interface.name) == 0) { + } else if (strcmp(interface, wl_compositor_interface.name) == STR_EQUAL) { state->wl_compositor = wl_registry_bind( wl_registry, name, &wl_compositor_interface, 4); - } else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) { + } else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == STR_EQUAL) { state->layer_shell = wl_registry_bind( wl_registry, name, &zwlr_layer_shell_v1_interface, 1); } @@ -183,12 +228,24 @@ main(int argc, char *argv[]) { struct client_state state = { 0 }; - if (argc < 2 || strcmp("-h", argv[1]) == 0 || strcmp("--help", argv[1]) == 0) { - fprintf(stderr, "Usage: wl-overlay \n\nThe image must be a 256×256 PNG with ARGB.\n"); + int i = 1; + if (argc < 2 || strcmp("-h", argv[i]) == STR_EQUAL || strcmp("--help", argv[i]) == STR_EQUAL) { + fprintf(stderr, "Usage: wl-overlay [text]\n\nThe image must be a 256×256 PNG with ARGB.\n"); return 1; } - state.filename = strdup(argv[1]); - + if (argc > i && strcmp("--backdrop", argv[i]) == STR_EQUAL) { + state.user_request.backdrop = true; + i++; + } else { + state.user_request.backdrop = false; + } + state.user_request.graphics_filename = strdup(argv[i++]); + if (argc > i) { + state.user_request.text = strdup(argv[i++]); + } else { + state.user_request.text = NULL; + } + state.wl_display = wl_display_connect(NULL); if (!state.wl_display) { fprintf(stderr, "Could not connect to Wayland server\n"); @@ -213,7 +270,10 @@ main(int argc, char *argv[]) /* This space deliberately left blank */ } - free(state.filename); + free(state.user_request.graphics_filename); + if (state.user_request.text != NULL) { + free(state.user_request.text); + } return 0; }