diff --git a/src/backend/wayland/wl_backend.c b/src/backend/wayland/wl_backend.c index e450508..616501e 100644 --- a/src/backend/wayland/wl_backend.c +++ b/src/backend/wayland/wl_backend.c @@ -7692,6 +7692,7 @@ static void wl_set_desktop_background(WScreen *scr, const char *texture_desc) if (!scr || !texture_desc || !wl_state.output) return; + int width = wl_state.output->width; int height = wl_state.output->height; @@ -7713,10 +7714,15 @@ static void wl_set_desktop_background(WScreen *scr, const char *texture_desc) RColor color = {0x50, 0x50, 0x75, 0xFF}; unsigned int r, g, b; if (colorstr) { - if (sscanf(colorstr, "rgb:%x/%x/%x", &r, &g, &b) == 3) { + if (sscanf(colorstr, "#%2x%2x%2x", &r, &g, &b) == 3) { color.red = r; color.green = g; color.blue = b; - } else if (sscanf(colorstr, "#%02x%02x%02x", &r, &g, &b) == 3) { + } else if (sscanf(colorstr, "rgb:%x/%x/%x", &r, &g, &b) == 3) { color.red = r; color.green = g; color.blue = b; + } else { + /* Try XParseColor-style names via wrlib */ + RColor parsed; + + color = parsed; } } bg = RCreateImage(width, height, 0); @@ -7729,16 +7735,52 @@ static void wl_set_desktop_background(WScreen *scr, const char *texture_desc) const char *c2str = WMGetFromPLString(WMGetFromPLArray(texpl, 2)); RColor color1 = {0, 0, 0, 255}, color2 = {0, 0, 0, 255}; unsigned int r, g, b; - if (c1str && sscanf(c1str, "rgb:%x/%x/%x", &r, &g, &b) == 3) { - color1.red = r; color1.green = g; color1.blue = b; + if (c1str) { + if (sscanf(c1str, "#%2x%2x%2x", &r, &g, &b) == 3) { + color1.red = r; color1.green = g; color1.blue = b; + } else if (sscanf(c1str, "rgb:%x/%x/%x", &r, &g, &b) == 3) { + color1.red = r; color1.green = g; color1.blue = b; + } } - if (c2str && sscanf(c2str, "rgb:%x/%x/%x", &r, &g, &b) == 3) { - color2.red = r; color2.green = g; color2.blue = b; + if (c2str) { + if (sscanf(c2str, "#%2x%2x%2x", &r, &g, &b) == 3) { + color2.red = r; color2.green = g; color2.blue = b; + } else if (sscanf(c2str, "rgb:%x/%x/%x", &r, &g, &b) == 3) { + color2.red = r; color2.green = g; color2.blue = b; + } } int style = (type[0] == 'v' || type[0] == 'V') ? RVerticalGradient : (type[0] == 'h' || type[0] == 'H') ? RHorizontalGradient : RDiagonalGradient; bg = RRenderGradient(width, height, &color1, &color2, style); + } else if ((strcasecmp(type, "mvgradient") == 0 || + strcasecmp(type, "mhgradient") == 0 || + strcasecmp(type, "mdgradient") == 0) && + WMGetPropListItemCount(texpl) >= 3) { + int ncolors = WMGetPropListItemCount(texpl) - 1; + RColor **colors = wmalloc((ncolors + 1) * sizeof(RColor *)); + RColor *cbuf = wmalloc(ncolors * sizeof(RColor)); + unsigned int r, g, b; + int ci; + for (ci = 0; ci < ncolors; ci++) { + const char *cs = WMGetFromPLString(WMGetFromPLArray(texpl, ci + 1)); + cbuf[ci] = (RColor){0, 0, 0, 255}; + if (cs) { + if (sscanf(cs, "#%2x%2x%2x", &r, &g, &b) == 3) { + cbuf[ci].red = r; cbuf[ci].green = g; cbuf[ci].blue = b; + } else if (sscanf(cs, "rgb:%x/%x/%x", &r, &g, &b) == 3) { + cbuf[ci].red = r; cbuf[ci].green = g; cbuf[ci].blue = b; + } + } + colors[ci] = &cbuf[ci]; + } + colors[ncolors] = NULL; + int style = (type[1] == 'v' || type[1] == 'V') ? RVerticalGradient : + (type[1] == 'h' || type[1] == 'H') ? RHorizontalGradient : + RDiagonalGradient; + bg = RRenderMultiGradient(width, height, colors, style); + wfree(cbuf); + wfree(colors); } else if ((strcasecmp(type, "pixmap") == 0 || strcasecmp(type, "spixmap") == 0 || strcasecmp(type, "mpixmap") == 0 || @@ -7774,8 +7816,10 @@ static void wl_set_desktop_background(WScreen *scr, const char *texture_desc) WMReleasePropList(texpl); - if (!bg) + if (!bg) { return; + } + /* Convert RImage to pixman_image and set as scene buffer */ struct wl_bg_buffer *buf = calloc(1, sizeof(*buf));