aboutsummaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/CMakeLists.txt15
-rw-r--r--common/background-image.c119
-rw-r--r--common/cairo.c127
-rw-r--r--common/ipc-client.c34
-rw-r--r--common/log.c151
-rw-r--r--common/meson.build23
-rw-r--r--common/pango.c72
-rw-r--r--common/readline.c4
-rw-r--r--common/unicode.c101
-rw-r--r--common/util.c24
10 files changed, 487 insertions, 183 deletions
diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt
deleted file mode 100644
index 4fa71f3a..00000000
--- a/common/CMakeLists.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-include_directories(
- ${WLC_INCLUDE_DIRS}
- ${XKBCOMMON_INCLUDE_DIRS}
-)
-
-add_library(sway-common STATIC
- ipc-client.c
- list.c
- log.c
- util.c
- readline.c
- stringop.c
-)
-
-target_link_libraries(sway-common m)
diff --git a/common/background-image.c b/common/background-image.c
new file mode 100644
index 00000000..e5fb4433
--- /dev/null
+++ b/common/background-image.c
@@ -0,0 +1,119 @@
+#include <assert.h>
+#include <stdbool.h>
+#include <wlr/util/log.h>
+#include "background-image.h"
+#include "cairo.h"
+
+enum background_mode parse_background_mode(const char *mode) {
+ if (strcmp(mode, "stretch") == 0) {
+ return BACKGROUND_MODE_STRETCH;
+ } else if (strcmp(mode, "fill") == 0) {
+ return BACKGROUND_MODE_FILL;
+ } else if (strcmp(mode, "fit") == 0) {
+ return BACKGROUND_MODE_FIT;
+ } else if (strcmp(mode, "center") == 0) {
+ return BACKGROUND_MODE_CENTER;
+ } else if (strcmp(mode, "tile") == 0) {
+ return BACKGROUND_MODE_TILE;
+ } else if (strcmp(mode, "solid_color") == 0) {
+ return BACKGROUND_MODE_SOLID_COLOR;
+ }
+ wlr_log(L_ERROR, "Unsupported background mode: %s", mode);
+ return BACKGROUND_MODE_INVALID;
+}
+
+cairo_surface_t *load_background_image(const char *path) {
+ cairo_surface_t *image;
+#ifdef HAVE_GDK_PIXBUF
+ GError *err = NULL;
+ GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(path, &err);
+ if (!pixbuf) {
+ wlr_log(L_ERROR, "Failed to load background image (%s).",
+ err->message);
+ return false;
+ }
+ image = gdk_cairo_image_surface_create_from_pixbuf(pixbuf);
+ g_object_unref(pixbuf);
+#else
+ image = cairo_image_surface_create_from_png(path);
+#endif //HAVE_GDK_PIXBUF
+ if (!image) {
+ wlr_log(L_ERROR, "Failed to read background image.");
+ return NULL;
+ }
+ if (cairo_surface_status(image) != CAIRO_STATUS_SUCCESS) {
+ wlr_log(L_ERROR, "Failed to read background image: %s."
+#ifndef HAVE_GDK_PIXBUF
+ "\nSway was compiled without gdk_pixbuf support, so only"
+ "\nPNG images can be loaded. This is the likely cause."
+#endif //HAVE_GDK_PIXBUF
+ , cairo_status_to_string(cairo_surface_status(image)));
+ return NULL;
+ }
+ return image;
+}
+
+void render_background_image(cairo_t *cairo, cairo_surface_t *image,
+ enum background_mode mode, int buffer_width, int buffer_height) {
+ double width = cairo_image_surface_get_width(image);
+ double height = cairo_image_surface_get_height(image);
+
+ switch (mode) {
+ case BACKGROUND_MODE_STRETCH:
+ cairo_scale(cairo,
+ (double)buffer_width / width,
+ (double)buffer_height / height);
+ cairo_set_source_surface(cairo, image, 0, 0);
+ break;
+ case BACKGROUND_MODE_FILL: {
+ double window_ratio = (double)buffer_width / buffer_height;
+ double bg_ratio = width / height;
+
+ if (window_ratio > bg_ratio) {
+ double scale = (double)buffer_width / width;
+ cairo_scale(cairo, scale, scale);
+ cairo_set_source_surface(cairo, image,
+ 0, (double)buffer_height / 2 / scale - height / 2);
+ } else {
+ double scale = (double)buffer_height / height;
+ cairo_scale(cairo, scale, scale);
+ cairo_set_source_surface(cairo, image,
+ (double)buffer_width / 2 / scale - width / 2, 0);
+ }
+ break;
+ }
+ case BACKGROUND_MODE_FIT: {
+ double window_ratio = (double)buffer_width / buffer_height;
+ double bg_ratio = width / height;
+
+ if (window_ratio > bg_ratio) {
+ double scale = (double)buffer_height / height;
+ cairo_scale(cairo, scale, scale);
+ cairo_set_source_surface(cairo, image,
+ (double)buffer_width / 2 / scale - width / 2, 0);
+ } else {
+ double scale = (double)buffer_width / width;
+ cairo_scale(cairo, scale, scale);
+ cairo_set_source_surface(cairo, image,
+ 0, (double)buffer_height / 2 / scale - height / 2);
+ }
+ break;
+ }
+ case BACKGROUND_MODE_CENTER:
+ cairo_set_source_surface(cairo, image,
+ (double)buffer_width / 2 - width / 2,
+ (double)buffer_height / 2 - height / 2);
+ break;
+ case BACKGROUND_MODE_TILE: {
+ cairo_pattern_t *pattern = cairo_pattern_create_for_surface(image);
+ cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT);
+ cairo_set_source(cairo, pattern);
+ break;
+ }
+ case BACKGROUND_MODE_SOLID_COLOR:
+ case BACKGROUND_MODE_INVALID:
+ assert(0);
+ break;
+ }
+ cairo_paint(cairo);
+}
diff --git a/common/cairo.c b/common/cairo.c
new file mode 100644
index 00000000..c267c77c
--- /dev/null
+++ b/common/cairo.c
@@ -0,0 +1,127 @@
+#include <stdint.h>
+#include <cairo/cairo.h>
+#include "cairo.h"
+#ifdef HAVE_GDK_PIXBUF
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#endif
+
+void cairo_set_source_u32(cairo_t *cairo, uint32_t color) {
+ cairo_set_source_rgba(cairo,
+ (color >> (3*8) & 0xFF) / 255.0,
+ (color >> (2*8) & 0xFF) / 255.0,
+ (color >> (1*8) & 0xFF) / 255.0,
+ (color >> (0*8) & 0xFF) / 255.0);
+}
+
+cairo_surface_t *cairo_image_surface_scale(cairo_surface_t *image,
+ int width, int height) {
+ int image_width = cairo_image_surface_get_width(image);
+ int image_height = cairo_image_surface_get_height(image);
+
+ cairo_surface_t *new =
+ cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
+ cairo_t *cairo = cairo_create(new);
+ cairo_scale(cairo, (double)width / image_width,
+ (double)height / image_height);
+ cairo_set_source_surface(cairo, image, 0, 0);
+
+ cairo_paint(cairo);
+ cairo_destroy(cairo);
+ return new;
+}
+
+#ifdef HAVE_GDK_PIXBUF
+cairo_surface_t* gdk_cairo_image_surface_create_from_pixbuf(const GdkPixbuf *gdkbuf) {
+ int chan = gdk_pixbuf_get_n_channels(gdkbuf);
+ if (chan < 3) {
+ return NULL;
+ }
+
+ const guint8* gdkpix = gdk_pixbuf_read_pixels(gdkbuf);
+ if (!gdkpix) {
+ return NULL;
+ }
+ gint w = gdk_pixbuf_get_width(gdkbuf);
+ gint h = gdk_pixbuf_get_height(gdkbuf);
+ int stride = gdk_pixbuf_get_rowstride(gdkbuf);
+
+ cairo_format_t fmt = (chan == 3) ? CAIRO_FORMAT_RGB24 : CAIRO_FORMAT_ARGB32;
+ cairo_surface_t * cs = cairo_image_surface_create (fmt, w, h);
+ cairo_surface_flush (cs);
+ if ( !cs || cairo_surface_status(cs) != CAIRO_STATUS_SUCCESS) {
+ return NULL;
+ }
+
+ int cstride = cairo_image_surface_get_stride(cs);
+ unsigned char * cpix = cairo_image_surface_get_data(cs);
+
+ if (chan == 3) {
+ int i;
+ for (i = h; i; --i) {
+ const guint8 *gp = gdkpix;
+ unsigned char *cp = cpix;
+ const guint8* end = gp + 3*w;
+ while (gp < end) {
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+ cp[0] = gp[2];
+ cp[1] = gp[1];
+ cp[2] = gp[0];
+#else
+ cp[1] = gp[0];
+ cp[2] = gp[1];
+ cp[3] = gp[2];
+#endif
+ gp += 3;
+ cp += 4;
+ }
+ gdkpix += stride;
+ cpix += cstride;
+ }
+ } else {
+ /* premul-color = alpha/255 * color/255 * 255 = (alpha*color)/255
+ * (z/255) = z/256 * 256/255 = z/256 (1 + 1/255)
+ * = z/256 + (z/256)/255 = (z + z/255)/256
+ * # recurse once
+ * = (z + (z + z/255)/256)/256
+ * = (z + z/256 + z/256/255) / 256
+ * # only use 16bit uint operations, loose some precision,
+ * # result is floored.
+ * -> (z + z>>8)>>8
+ * # add 0x80/255 = 0.5 to convert floor to round
+ * => (z+0x80 + (z+0x80)>>8 ) >> 8
+ * ------
+ * tested as equal to lround(z/255.0) for uint z in [0..0xfe02]
+ */
+#define PREMUL_ALPHA(x,a,b,z) \
+ G_STMT_START { z = a * b + 0x80; x = (z + (z >> 8)) >> 8; } \
+ G_STMT_END
+ int i;
+ for (i = h; i; --i) {
+ const guint8 *gp = gdkpix;
+ unsigned char *cp = cpix;
+ const guint8* end = gp + 4*w;
+ guint z1, z2, z3;
+ while (gp < end) {
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+ PREMUL_ALPHA(cp[0], gp[2], gp[3], z1);
+ PREMUL_ALPHA(cp[1], gp[1], gp[3], z2);
+ PREMUL_ALPHA(cp[2], gp[0], gp[3], z3);
+ cp[3] = gp[3];
+#else
+ PREMUL_ALPHA(cp[1], gp[0], gp[3], z1);
+ PREMUL_ALPHA(cp[2], gp[1], gp[3], z2);
+ PREMUL_ALPHA(cp[3], gp[2], gp[3], z3);
+ cp[0] = gp[3];
+#endif
+ gp += 4;
+ cp += 4;
+ }
+ gdkpix += stride;
+ cpix += cstride;
+ }
+#undef PREMUL_ALPHA
+ }
+ cairo_surface_mark_dirty(cs);
+ return cs;
+}
+#endif //HAVE_GDK_PIXBUF
diff --git a/common/ipc-client.c b/common/ipc-client.c
index 1ab6627b..117e9910 100644
--- a/common/ipc-client.c
+++ b/common/ipc-client.c
@@ -1,4 +1,4 @@
-#define _POSIX_C_SOURCE 2
+#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
@@ -14,13 +14,31 @@ static const char ipc_magic[] = {'i', '3', '-', 'i', 'p', 'c'};
static const size_t ipc_header_size = sizeof(ipc_magic)+8;
char *get_socketpath(void) {
- FILE *fp = popen("sway --get-socketpath", "r");
- if (!fp) {
- return NULL;
+ const char *swaysock = getenv("SWAYSOCK");
+ if (swaysock) {
+ return strdup(swaysock);
}
- char *line = read_line(fp);
- pclose(fp);
- return line;
+ FILE *fp = popen("sway --get-socketpath 2>/dev/null", "r");
+ if (fp) {
+ char *line = read_line(fp);
+ pclose(fp);
+ if (line && *line) {
+ return line;
+ }
+ }
+ const char *i3sock = getenv("I3SOCK");
+ if (i3sock) {
+ return strdup(i3sock);
+ }
+ fp = popen("i3 --get-socketpath 2>/dev/null", "r");
+ if (fp) {
+ char *line = read_line(fp);
+ pclose(fp);
+ if (line && *line) {
+ return line;
+ }
+ }
+ return NULL;
}
int ipc_open_socket(const char *socket_path) {
@@ -79,7 +97,7 @@ struct ipc_response *ipc_recv_response(int socketfd) {
error_2:
free(response);
error_1:
- sway_log(L_ERROR, "Unable to allocate memory for IPC response");
+ wlr_log(L_ERROR, "Unable to allocate memory for IPC response");
return NULL;
}
diff --git a/common/log.c b/common/log.c
index 6dc9d743..2cc7289c 100644
--- a/common/log.c
+++ b/common/log.c
@@ -1,167 +1,26 @@
-#define _POSIX_C_SOURCE 199506L
-#include <errno.h>
-#include <libgen.h>
#include <signal.h>
#include <stdarg.h>
-#include <stdio.h>
#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <time.h>
#include "log.h"
-#include "sway.h"
-#include "readline.h"
-static int colored = 1;
-static log_importance_t loglevel_default = L_ERROR;
-static log_importance_t v = L_SILENT;
+void sway_terminate(int code);
-static const char *verbosity_colors[] = {
- [L_SILENT] = "",
- [L_ERROR ] = "\x1B[1;31m",
- [L_INFO ] = "\x1B[1;34m",
- [L_DEBUG ] = "\x1B[1;30m",
-};
-static const char verbosity_chars[] = {
- [L_SILENT] = '\0',
- [L_ERROR ] = 'E',
- [L_INFO ] = 'I',
- [L_DEBUG ] = 'D',
-};
-
-void init_log(log_importance_t verbosity) {
- if (verbosity != L_DEBUG) {
- // command "debuglog" needs to know the user specified log level when
- // turning off debug logging.
- loglevel_default = verbosity;
- }
- v = verbosity;
-}
-
-void set_log_level(log_importance_t verbosity) {
- v = verbosity;
-}
-
-log_importance_t get_log_level(void) {
- return v;
-}
-
-void reset_log_level(void) {
- v = loglevel_default;
-}
-
-bool toggle_debug_logging(void) {
- v = (v == L_DEBUG) ? loglevel_default : L_DEBUG;
- return (v == L_DEBUG);
-}
-
-void sway_log_colors(int mode) {
- colored = (mode == 1) ? 1 : 0;
-}
-
-void _sway_vlog(const char *filename, int line, log_importance_t verbosity,
- const char *format, va_list args) {
- if (verbosity <= v) {
- // prefix the time to the log message
- static struct tm result;
- static time_t t;
- static struct tm *tm_info;
- char buffer[26];
-
- unsigned int c = verbosity;
- if (c > sizeof(verbosity_colors) / sizeof(char *) - 1) {
- c = sizeof(verbosity_colors) / sizeof(char *) - 1;
- }
-
- // First, if not printing color, show the log level
- if (!(colored && isatty(STDERR_FILENO)) && c != L_SILENT) {
- fprintf(stderr, "%c: ", verbosity_chars[c]);
- }
-
- // get current time
- t = time(NULL);
- // convert time to local time (determined by the locale)
- tm_info = localtime_r(&t, &result);
- // generate time prefix
- strftime(buffer, sizeof(buffer), "%x %X - ", tm_info);
- fprintf(stderr, "%s", buffer);
-
- if (colored && isatty(STDERR_FILENO)) {
- fprintf(stderr, "%s", verbosity_colors[c]);
- }
-
- if (filename && line) {
- const char *file = filename + strlen(filename);
- while (file != filename && *file != '/') {
- --file;
- }
- if (*file == '/') {
- ++file;
- }
- fprintf(stderr, "[%s:%d] ", file, line);
- }
-
- vfprintf(stderr, format, args);
-
- if (colored && isatty(STDERR_FILENO)) {
- fprintf(stderr, "\x1B[0m");
- }
- fprintf(stderr, "\n");
- }
-}
-
-void _sway_log(const char *filename, int line, log_importance_t verbosity, const char* format, ...) {
- va_list args;
- va_start(args, format);
- _sway_vlog(filename, line, verbosity, format, args);
- va_end(args);
-}
-
-
-void _sway_abort(const char *filename, int line, const char* format, ...) {
+void _sway_abort(const char *format, ...) {
va_list args;
va_start(args, format);
- _sway_vlog(filename, line, L_ERROR, format, args);
+ _wlr_vlog(L_ERROR, format, args);
va_end(args);
sway_terminate(EXIT_FAILURE);
}
-void sway_log_errno(log_importance_t verbosity, char* format, ...) {
- if (verbosity <= v) {
- unsigned int c = verbosity;
- if (c > sizeof(verbosity_colors) / sizeof(char *) - 1) {
- c = sizeof(verbosity_colors) / sizeof(char *) - 1;
- }
-
- if (colored && isatty(STDERR_FILENO)) {
- fprintf(stderr, "%s", verbosity_colors[c]);
- } else if (c != L_SILENT) {
- fprintf(stderr, "%c: ", verbosity_chars[c]);
- }
-
- va_list args;
- va_start(args, format);
- vfprintf(stderr, format, args);
- va_end(args);
-
- fprintf(stderr, ": ");
- fprintf(stderr, "%s", strerror(errno));
-
- if (colored && isatty(STDERR_FILENO)) {
- fprintf(stderr, "\x1B[0m");
- }
- fprintf(stderr, "\n");
- }
-}
-
-bool _sway_assert(bool condition, const char *filename, int line, const char* format, ...) {
+bool _sway_assert(bool condition, const char *format, ...) {
if (condition) {
return true;
}
va_list args;
va_start(args, format);
- _sway_vlog(filename, line, L_ERROR, format, args);
+ _wlr_vlog(L_ERROR, format, args);
va_end(args);
#ifndef NDEBUG
diff --git a/common/meson.build b/common/meson.build
new file mode 100644
index 00000000..44a29508
--- /dev/null
+++ b/common/meson.build
@@ -0,0 +1,23 @@
+lib_sway_common = static_library(
+ 'sway-common',
+ files(
+ 'background-image.c',
+ 'cairo.c',
+ 'ipc-client.c',
+ 'log.c',
+ 'list.c',
+ 'pango.c',
+ 'readline.c',
+ 'stringop.c',
+ 'unicode.c',
+ 'util.c'
+ ),
+ dependencies: [
+ cairo,
+ gdk_pixbuf,
+ pango,
+ pangocairo,
+ wlroots
+ ],
+ include_directories: sway_inc
+)
diff --git a/common/pango.c b/common/pango.c
new file mode 100644
index 00000000..658d2876
--- /dev/null
+++ b/common/pango.c
@@ -0,0 +1,72 @@
+#include <cairo/cairo.h>
+#include <pango/pangocairo.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "log.h"
+
+PangoLayout *get_pango_layout(cairo_t *cairo, const char *font,
+ const char *text, int32_t scale, bool markup) {
+ PangoLayout *layout = pango_cairo_create_layout(cairo);
+ PangoAttrList *attrs;
+ if (markup) {
+ char *buf;
+ GError *error = NULL;
+ if (!sway_assert(pango_parse_markup(
+ text, -1, 0, &attrs, &buf, NULL, &error),
+ "pango_parse_markup '%s' -> error %s", text,
+ error ? error->message : NULL)) {
+ return NULL;
+ }
+ pango_layout_set_markup(layout, buf, -1);
+ free(buf);
+ } else {
+ attrs = pango_attr_list_new();
+ pango_layout_set_text(layout, text, -1);
+ }
+ pango_attr_list_insert(attrs, pango_attr_scale_new(scale));
+ PangoFontDescription *desc = pango_font_description_from_string(font);
+ pango_layout_set_font_description(layout, desc);
+ pango_layout_set_single_paragraph_mode(layout, 1);
+ pango_layout_set_attributes(layout, attrs);
+ pango_attr_list_unref(attrs);
+ pango_font_description_free(desc);
+ return layout;
+}
+
+void get_text_size(cairo_t *cairo, const char *font, int *width, int *height,
+ int32_t scale, bool markup, const char *fmt, ...) {
+ static char buf[2048];
+
+ va_list args;
+ va_start(args, fmt);
+ if (vsnprintf(buf, 2048, fmt, args) >= 2048) {
+ strcpy(buf, "[buffer overflow]");
+ }
+ va_end(args);
+
+ PangoLayout *layout = get_pango_layout(cairo, font, buf, scale, markup);
+ pango_cairo_update_layout(cairo, layout);
+ pango_layout_get_pixel_size(layout, width, height);
+ g_object_unref(layout);
+}
+
+void pango_printf(cairo_t *cairo, const char *font,
+ int32_t scale, bool markup, const char *fmt, ...) {
+ static char buf[2048];
+
+ va_list args;
+ va_start(args, fmt);
+ if (vsnprintf(buf, 2048, fmt, args) >= 2048) {
+ strcpy(buf, "[buffer overflow]");
+ }
+ va_end(args);
+
+ PangoLayout *layout = get_pango_layout(cairo, font, buf, scale, markup);
+ pango_cairo_update_layout(cairo, layout);
+ pango_cairo_show_layout(cairo, layout);
+ g_object_unref(layout);
+}
diff --git a/common/readline.c b/common/readline.c
index cc40a2cc..ed5801de 100644
--- a/common/readline.c
+++ b/common/readline.c
@@ -8,7 +8,7 @@ char *read_line(FILE *file) {
char *string = malloc(size);
char lastChar = '\0';
if (!string) {
- sway_log(L_ERROR, "Unable to allocate memory for read_line");
+ wlr_log(L_ERROR, "Unable to allocate memory for read_line");
return NULL;
}
while (1) {
@@ -29,7 +29,7 @@ char *read_line(FILE *file) {
char *new_string = realloc(string, size *= 2);
if (!new_string) {
free(string);
- sway_log(L_ERROR, "Unable to allocate memory for read_line");
+ wlr_log(L_ERROR, "Unable to allocate memory for read_line");
return NULL;
}
string = new_string;
diff --git a/common/unicode.c b/common/unicode.c
new file mode 100644
index 00000000..38a9b48e
--- /dev/null
+++ b/common/unicode.c
@@ -0,0 +1,101 @@
+#include <stdint.h>
+#include <stddef.h>
+#include "unicode.h"
+
+size_t utf8_chsize(uint32_t ch) {
+ if (ch < 0x80) {
+ return 1;
+ } else if (ch < 0x800) {
+ return 2;
+ } else if (ch < 0x10000) {
+ return 3;
+ }
+ return 4;
+}
+
+static const uint8_t masks[] = {
+ 0x7F,
+ 0x1F,
+ 0x0F,
+ 0x07,
+ 0x03,
+ 0x01
+};
+
+uint32_t utf8_decode(const char **char_str) {
+ uint8_t **s = (uint8_t **)char_str;
+
+ uint32_t cp = 0;
+ if (**s < 128) {
+ // shortcut
+ cp = **s;
+ ++*s;
+ return cp;
+ }
+ int size = utf8_size((char *)*s);
+ if (size == -1) {
+ ++*s;
+ return UTF8_INVALID;
+ }
+ uint8_t mask = masks[size - 1];
+ cp = **s & mask;
+ ++*s;
+ while (--size) {
+ cp <<= 6;
+ cp |= **s & 0x3f;
+ ++*s;
+ }
+ return cp;
+}
+
+size_t utf8_encode(char *str, uint32_t ch) {
+ size_t len = 0;
+ uint8_t first;
+
+ if (ch < 0x80) {
+ first = 0;
+ len = 1;
+ } else if (ch < 0x800) {
+ first = 0xc0;
+ len = 2;
+ } else if (ch < 0x10000) {
+ first = 0xe0;
+ len = 3;
+ } else {
+ first = 0xf0;
+ len = 4;
+ }
+
+ for (size_t i = len - 1; i > 0; --i) {
+ str[i] = (ch & 0x3f) | 0x80;
+ ch >>= 6;
+ }
+
+ str[0] = ch | first;
+ return len;
+}
+
+
+static const struct {
+ uint8_t mask;
+ uint8_t result;
+ int octets;
+} sizes[] = {
+ { 0x80, 0x00, 1 },
+ { 0xE0, 0xC0, 2 },
+ { 0xF0, 0xE0, 3 },
+ { 0xF8, 0xF0, 4 },
+ { 0xFC, 0xF8, 5 },
+ { 0xFE, 0xF8, 6 },
+ { 0x80, 0x80, -1 },
+};
+
+int utf8_size(const char *s) {
+ uint8_t c = (uint8_t)*s;
+ for (size_t i = 0; i < sizeof(sizes) / 2; ++i) {
+ if ((c & sizes[i].mask) == sizes[i].result) {
+ return sizes[i].octets;
+ }
+ }
+ return -1;
+}
diff --git a/common/util.c b/common/util.c
index d6369853..fb7f9454 100644
--- a/common/util.c
+++ b/common/util.c
@@ -8,8 +8,8 @@
#include <stdlib.h>
#include <string.h>
#include <strings.h>
-#include <wlc/wlc.h>
#include <xkbcommon/xkbcommon-names.h>
+#include <wlr/types/wlr_keyboard.h>
#include "log.h"
#include "readline.h"
#include "util.h"
@@ -29,16 +29,16 @@ static struct modifier_key {
char *name;
uint32_t mod;
} modifiers[] = {
- { XKB_MOD_NAME_SHIFT, WLC_BIT_MOD_SHIFT },
- { XKB_MOD_NAME_CAPS, WLC_BIT_MOD_CAPS },
- { XKB_MOD_NAME_CTRL, WLC_BIT_MOD_CTRL },
- { "Ctrl", WLC_BIT_MOD_CTRL },
- { XKB_MOD_NAME_ALT, WLC_BIT_MOD_ALT },
- { "Alt", WLC_BIT_MOD_ALT },
- { XKB_MOD_NAME_NUM, WLC_BIT_MOD_MOD2 },
- { "Mod3", WLC_BIT_MOD_MOD3 },
- { XKB_MOD_NAME_LOGO, WLC_BIT_MOD_LOGO },
- { "Mod5", WLC_BIT_MOD_MOD5 },
+ { XKB_MOD_NAME_SHIFT, WLR_MODIFIER_SHIFT },
+ { XKB_MOD_NAME_CAPS, WLR_MODIFIER_CAPS },
+ { XKB_MOD_NAME_CTRL, WLR_MODIFIER_CTRL },
+ { "Ctrl", WLR_MODIFIER_CTRL },
+ { XKB_MOD_NAME_ALT, WLR_MODIFIER_ALT },
+ { "Alt", WLR_MODIFIER_ALT },
+ { XKB_MOD_NAME_NUM, WLR_MODIFIER_MOD2 },
+ { "Mod3", WLR_MODIFIER_MOD3 },
+ { XKB_MOD_NAME_LOGO, WLR_MODIFIER_LOGO },
+ { "Mod5", WLR_MODIFIER_MOD5 },
};
uint32_t get_modifier_mask_by_name(const char *name) {
@@ -113,7 +113,7 @@ uint32_t parse_color(const char *color) {
int len = strlen(color);
if (len != 6 && len != 8) {
- sway_log(L_DEBUG, "Invalid color %s, defaulting to color 0xFFFFFFFF", color);
+ wlr_log(L_DEBUG, "Invalid color %s, defaulting to color 0xFFFFFFFF", color);
return 0xFFFFFFFF;
}
uint32_t res = (uint32_t)strtoul(color, NULL, 16);