/* * wcolor_x11.c - X11 color backend for WINGs * * Allocates colors via XAllocColor on the X11 colormap. */ #include "WINGsP.h" #include "WINGs/WINGsX11.h" #include static void *x11_screen_init(W_Screen *scr) { return scr; } static void x11_screen_fini(void *cctx) { (void)cctx; } static WMColor *x11_alloc_color(void *cctx, W_Screen *scr, unsigned short r, unsigned short g, unsigned short b, unsigned short a) { WMColor *color; XColor xcolor; (void)cctx; xcolor.red = r; xcolor.green = g; xcolor.blue = b; xcolor.flags = DoRed | DoGreen | DoBlue; if (!XAllocColor(scr->display, scr->colormap, &xcolor)) return NULL; color = wmalloc(sizeof(WMColor)); color->screen = scr; color->refCount = 1; memcpy(&color->color, &xcolor, sizeof(xcolor)); color->alpha = a; color->flags.exact = 1; color->gc = NULL; return color; } static WMColor *x11_find_close_color(void *cctx, W_Screen *scr, unsigned short r, unsigned short g, unsigned short b, unsigned short a) { WMColor *color; XColor xcolor; RColor rcolor; (void)cctx; rcolor.red = r >> 8; rcolor.green = g >> 8; rcolor.blue = b >> 8; rcolor.alpha = a >> 8; if (!RGetClosestXColor(scr->rcontext, &rcolor, &xcolor)) return NULL; if (!XAllocColor(scr->display, scr->colormap, &xcolor)) return NULL; color = wmalloc(sizeof(WMColor)); color->screen = scr; color->refCount = 1; memcpy(&color->color, &xcolor, sizeof(xcolor)); color->alpha = a; color->flags.exact = 0; color->gc = NULL; return color; } static void x11_free_color(void *cctx, WMColor *color) { (void)cctx; XFreeColors(color->screen->display, color->screen->colormap, &(color->color.pixel), 1, 0); if (color->gc) XFreeGC(color->screen->display, color->gc); } static Bool x11_parse_named(void *cctx, W_Screen *scr, const char *name, unsigned short *r, unsigned short *g, unsigned short *b) { XColor xcolor; (void)cctx; if (!XParseColor(scr->display, scr->colormap, name, &xcolor)) return False; *r = xcolor.red; *g = xcolor.green; *b = xcolor.blue; return True; } const W_ColorBackend W_ColorBackendX11 = { .screen_init = x11_screen_init, .screen_fini = x11_screen_fini, .alloc_color = x11_alloc_color, .find_close_color = x11_find_close_color, .free_color = x11_free_color, .parse_named = x11_parse_named, }; /* X11-only public API: GC access for Xlib drawing */ GC WMColorGC(WMColor *color) { if (!color->gc) { XGCValues gcv; WMScreen *scr = color->screen; gcv.foreground = color->color.pixel; gcv.graphics_exposures = False; color->gc = XCreateGC(scr->display, scr->rcontext->drawable, GCForeground | GCGraphicsExposures, &gcv); } return color->gc; } void WMSetColorInGC(WMColor *color, GC gc) { XSetForeground(color->screen->display, gc, color->color.pixel); }