pacman-key --init
pacman -Syu --noconfirm
pacman -S --noconfirm git meson clang wlroots libdrm libinput \
- wayland-protocols cairo pango libxml2 xorg-xwayland
+ wayland-protocols cairo pango libxml2 xorg-xwayland librsvg
- name: Install Debian Testing dependencies
if: matrix.name == 'Debian'
apt-get upgrade -y
apt-get install -y git clang \
hwdata \
- libxml2-dev libcairo2-dev libpango1.0-dev
+ libxml2-dev libcairo2-dev libpango1.0-dev \
+ librsvg2-dev
apt-get build-dep -y wlroots
- name: Install FreeBSD dependencies
xcb-util-cursor-devel xcb-util-devel xcb-util-image-devel \
xcb-util-keysyms-devel xcb-util-xrm-devel xorg-server-xwayland \
hwids \
+ librsvg-devel \
libglib-devel cairo-devel pango-devel
- name: Build with gcc
- wlroots, wayland, libinput, xkbcommon
- libxml2, cairo, pango, glib-2.0
+- libpng, librsvg-2.0
- xwayland, xcb (optional)
Build dependencies include:
precedence, where the first format in the list is searched for first.
- png
+- svg
- xbm
By default, buttons are 1-bit xbm (X Bitmaps). These are masks where 0=clear and
--- /dev/null
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef LABWC_BUTTON_SVG_H
+#define LABWC_BUTTON_SVG_H
+
+struct lab_data_buffer;
+
+void button_svg_load(const char *button_name, struct lab_data_buffer **buffer,
+ int size);
+
+#endif /* LABWC_BUTTON_SVG_H */
input = dependency('libinput', version: '>=1.14')
math = cc.find_library('m')
png = dependency('libpng')
+svg = dependency('librsvg-2.0', version: '>=2.46', required: false)
if get_option('xwayland').enabled() and not wlroots_has_xwayland
error('no wlroots Xwayland support')
conf_data = configuration_data()
conf_data.set10('HAVE_XWAYLAND', have_xwayland)
+conf_data.set10('HAVE_RSVG', svg.found())
+
msgfmt = find_program('msgfmt', required: get_option('nls'))
if msgfmt.found()
source_root = meson.current_source_dir()
math,
png,
]
+if svg.found()
+ labwc_deps += [
+ svg,
+ ]
+endif
subdir('include')
subdir('src')
#Ignore Page<foo> variants
$var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ &&
-#Ignore some pango and libxml2 CamelCase variants
+#labwc-custom check to ignore some pango/libxml2/etc CamelCase variants
$var !~ /^(?:PangoLayout|PangoFontDescription)/ &&
$var !~ /^(?:PangoTabArray|PangoRectangle)/ &&
$var !~ /^(?:PangoWeight|_PangoFontDescription)/ &&
$var !~ /^(?:xmlParseMemory)/ &&
$var !~ /^(?:xmlFree)/ &&
$var !~ /^(?:GString|GError)/ &&
+ $var !~ /^(?:RsvgRectangle|RsvgHandle)/ &&
$var !~ /^(?:XKB_KEY_XF86Switch_VT_1)/ &&
#Ignore SI style variants like nS, mV and dB
char path[4096] = { 0 };
button_filename(button_name, path, sizeof(path));
- if (!file_exists(path) || !ispng(path)) {
+ if (!ispng(path)) {
return;
}
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) Johan Malm 2023
+ */
+#define _POSIX_C_SOURCE 200809L
+#include <cairo.h>
+#include <librsvg/rsvg.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <wlr/util/log.h>
+#include "buffer.h"
+#include "button/button-svg.h"
+#include "button/common.h"
+#include "common/file-helpers.h"
+#include "labwc.h"
+#include "theme.h"
+
+void
+button_svg_load(const char *button_name, struct lab_data_buffer **buffer,
+ int size)
+{
+ if (*buffer) {
+ wlr_buffer_drop(&(*buffer)->base);
+ *buffer = NULL;
+ }
+
+ char filename[4096] = { 0 };
+ button_filename(button_name, filename, sizeof(filename));
+
+ GError *err = NULL;
+ RsvgRectangle viewport = { .width = size, .height = size };
+ RsvgHandle *svg = rsvg_handle_new_from_file(filename, &err);
+ if (err) {
+ wlr_log(WLR_DEBUG, "error reading svg %s-%s\n", filename, err->message);
+ g_error_free(err);
+ /*
+ * rsvg_handle_new_from_file() returns NULL if an error occurs,
+ * so there is no need to free svg here.
+ */
+ return;
+ }
+
+ cairo_surface_t *image = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, size, size);
+ cairo_t *cr = cairo_create(image);
+
+ rsvg_handle_render_document(svg, cr, &viewport, &err);
+ if (err) {
+ wlr_log(WLR_ERROR, "error rendering svg %s-%s\n", filename, err->message);
+ g_error_free(err);
+ goto error;
+ }
+
+ if (cairo_surface_status(image)) {
+ wlr_log(WLR_ERROR, "error reading svg button '%s'", filename);
+ goto error;
+ }
+ cairo_surface_flush(image);
+
+ double w = cairo_image_surface_get_width(image);
+ double h = cairo_image_surface_get_height(image);
+ *buffer = buffer_create_cairo((int)w, (int)h, 1.0, /* free_on_destroy */ true);
+ cairo_t *cairo = (*buffer)->cairo;
+ cairo_set_source_surface(cairo, image, 0, 0);
+ cairo_paint_with_alpha(cairo, 1.0);
+
+error:
+ cairo_destroy(cr);
+ cairo_surface_destroy(image);
+ g_object_unref(svg);
+}
'button-xbm.c',
'common.c',
)
+
+if svg.found()
+ labwc_sources += files(
+ 'button-svg.c',
+ )
+endif
+
*/
#define _POSIX_C_SOURCE 200809L
+#include "config.h"
#include <cairo.h>
#include <ctype.h>
#include <drm_fourcc.h>
#include "common/string-helpers.h"
#include "config/rcxml.h"
#include "button/button-png.h"
+
+#if HAVE_RSVG
+#include "button/button-svg.h"
+#endif
+
#include "button/button-xbm.h"
#include "theme.h"
#include "buffer.h"
} active, inactive;
};
+static void
+drop(struct lab_data_buffer **buffer)
+{
+ if (*buffer) {
+ wlr_buffer_drop(&(*buffer)->base);
+ *buffer = NULL;
+ }
+}
+
static void
load_buttons(struct theme *theme)
{
for (size_t i = 0; i < sizeof(buttons) / sizeof(buttons[0]); ++i) {
struct button *b = &buttons[i];
+ drop(b->active.buffer);
+ drop(b->inactive.buffer);
+
/* Try png icon first */
snprintf(filename, sizeof(filename), "%s-active.png", b->name);
png_load(filename, b->active.buffer);
snprintf(filename, sizeof(filename), "%s-inactive.png", b->name);
png_load(filename, b->inactive.buffer);
- /* If there were no png buttons, use xbm */
+#if HAVE_RSVG
+ /* Then try svg icon */
+ int size = theme->title_height - 2 * theme->padding_height;
+ if (!*b->active.buffer) {
+ snprintf(filename, sizeof(filename), "%s-active.svg", b->name);
+ button_svg_load(filename, b->active.buffer, size);
+ }
+ if (!*b->inactive.buffer) {
+ snprintf(filename, sizeof(filename), "%s-inactive.svg", b->name);
+ button_svg_load(filename, b->inactive.buffer, size);
+ }
+#endif
+
+ /* If there were no png/svg buttons, use xbm */
snprintf(filename, sizeof(filename), "%s.xbm", b->name);
if (!*b->active.buffer) {
button_xbm_load(filename, b->active.buffer,