diff --git a/WINGs/WINGs/WINGsP.h.in b/WINGs/WINGs/WINGsP.h.in index 14cbdb3..d30247b 100644 --- a/WINGs/WINGs/WINGsP.h.in +++ b/WINGs/WINGs/WINGsP.h.in @@ -564,6 +564,9 @@ typedef struct W_RenderBackend { void (*fill_arc)(void *rctx, WMDrawable d, WMColor *color, int x, int y, unsigned int w, unsigned int h, int angle1, int angle2); + /* Create a stippled disabled mask from a source mask pixmap */ + Pixmap (*create_disabled_mask)(void *rctx, Pixmap src_mask, + unsigned int width, unsigned int height); } W_RenderBackend; extern const W_RenderBackend W_RenderBackendX11; diff --git a/WINGs/wbutton.c b/WINGs/wbutton.c index fe045aa..f9ab561 100644 --- a/WINGs/wbutton.c +++ b/WINGs/wbutton.c @@ -219,41 +219,19 @@ WMButton *WMCreateButton(WMWidget * parent, WMButtonType type) static void updateDisabledMask(WMButton * bPtr) { WMScreen *scr = WMWidgetScreen(bPtr); - Display *dpy = scr->display; + const W_RenderBackend *R = scr->renderBackend; + void *rctx = scr->renderBackendCtx; if (bPtr->image) { - XGCValues gcv; - if (bPtr->dimage->mask) { - XFreePixmap(dpy, bPtr->dimage->mask); + R->pixmap_free(rctx, (WMDrawable)bPtr->dimage->mask); bPtr->dimage->mask = None; } if (bPtr->flags.dimsWhenDisabled) { - bPtr->dimage->mask = XCreatePixmap(dpy, scr->stipple, - bPtr->dimage->width, bPtr->dimage->height, 1); - - XSetForeground(dpy, scr->monoGC, 0); - XFillRectangle(dpy, bPtr->dimage->mask, scr->monoGC, 0, 0, - bPtr->dimage->width, bPtr->dimage->height); - - gcv.foreground = 1; - gcv.background = 0; - gcv.stipple = scr->stipple; - gcv.fill_style = FillStippled; - gcv.clip_mask = bPtr->image->mask; - gcv.clip_x_origin = 0; - gcv.clip_y_origin = 0; - - XChangeGC(dpy, scr->monoGC, GCForeground | GCBackground | GCStipple - | GCFillStyle | GCClipMask | GCClipXOrigin | GCClipYOrigin, &gcv); - - XFillRectangle(dpy, bPtr->dimage->mask, scr->monoGC, 0, 0, - bPtr->dimage->width, bPtr->dimage->height); - - gcv.fill_style = FillSolid; - gcv.clip_mask = None; - XChangeGC(dpy, scr->monoGC, GCFillStyle | GCClipMask, &gcv); + bPtr->dimage->mask = R->create_disabled_mask(rctx, + bPtr->image->mask, + bPtr->dimage->width, bPtr->dimage->height); } } } diff --git a/WINGs/wrender_wl.c b/WINGs/wrender_wl.c index 62bfc8d..cf2b14f 100644 --- a/WINGs/wrender_wl.c +++ b/WINGs/wrender_wl.c @@ -235,6 +235,31 @@ render_wl_fill_arc(void *rctx, WMDrawable d, WMColor *color, } } +static Pixmap +render_wl_create_disabled_mask(void *rctx, Pixmap src_mask, + unsigned int width, unsigned int height) +{ + (void)rctx; + pixman_image_t *mask = pixman_image_create_bits(PIXMAN_a8, width, height, NULL, 0); + pixman_image_t *src = src_mask ? (pixman_image_t *)(uintptr_t)src_mask : NULL; + uint8_t *mdata = (uint8_t *)pixman_image_get_data(mask); + int stride = pixman_image_get_stride(mask); + uint8_t *sdata = src ? (uint8_t *)pixman_image_get_data(src) : NULL; + int sstride = src ? pixman_image_get_stride(src) : 0; + + for (unsigned int y = 0; y < height; y++) { + for (unsigned int x = 0; x < width; x++) { + int stipple = ((x + y) & 1); + int src_opaque = 1; + if (sdata) + src_opaque = sdata[y * sstride + x] > 0; + mdata[y * stride + x] = (stipple && src_opaque) ? 0xFF : 0x00; + } + } + + return (Pixmap)(uintptr_t)mask; +} + const W_RenderBackend W_RenderBackendWL = { .screen_init = render_wl_screen_init, .screen_fini = render_wl_screen_fini, @@ -248,4 +273,5 @@ const W_RenderBackend W_RenderBackendWL = { .composite_pixmap = render_wl_composite_pixmap, .fill_polygon = render_wl_fill_polygon, .fill_arc = render_wl_fill_arc, + .create_disabled_mask = render_wl_create_disabled_mask, }; diff --git a/WINGs/wrender_x11.c b/WINGs/wrender_x11.c index 9087427..f696c4a 100644 --- a/WINGs/wrender_x11.c +++ b/WINGs/wrender_x11.c @@ -123,6 +123,41 @@ render_x11_fill_arc(void *rctx, WMDrawable d, WMColor *color, x, y, w, h, angle1, angle2); } +static Pixmap +render_x11_create_disabled_mask(void *rctx, Pixmap src_mask, + unsigned int width, unsigned int height) +{ + RenderCtxX11 *ctx = rctx; + W_Screen *scr = ctx->scr; + Display *dpy = scr->display; + XGCValues gcv; + Pixmap mask; + + mask = XCreatePixmap(dpy, scr->stipple, width, height, 1); + + XSetForeground(dpy, scr->monoGC, 0); + XFillRectangle(dpy, mask, scr->monoGC, 0, 0, width, height); + + gcv.foreground = 1; + gcv.background = 0; + gcv.stipple = scr->stipple; + gcv.fill_style = FillStippled; + gcv.clip_mask = src_mask; + gcv.clip_x_origin = 0; + gcv.clip_y_origin = 0; + + XChangeGC(dpy, scr->monoGC, GCForeground | GCBackground | GCStipple + | GCFillStyle | GCClipMask | GCClipXOrigin | GCClipYOrigin, &gcv); + + XFillRectangle(dpy, mask, scr->monoGC, 0, 0, width, height); + + gcv.fill_style = FillSolid; + gcv.clip_mask = None; + XChangeGC(dpy, scr->monoGC, GCFillStyle | GCClipMask, &gcv); + + return mask; +} + const W_RenderBackend W_RenderBackendX11 = { .screen_init = render_x11_screen_init, .screen_fini = render_x11_screen_fini, @@ -136,4 +171,5 @@ const W_RenderBackend W_RenderBackendX11 = { .composite_pixmap = render_x11_composite_pixmap, .fill_polygon = render_x11_fill_polygon, .fill_arc = render_x11_fill_arc, + .create_disabled_mask = render_x11_create_disabled_mask, };