windowmaker-wl/WINGs/wcolor_x11.c

132 lines
2.8 KiB
C

/*
* wcolor_x11.c - X11 color backend for WINGs
*
* Allocates colors via XAllocColor on the X11 colormap.
*/
#include "WINGsP.h"
#include "WINGs/WINGsX11.h"
#include <wraster.h>
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);
}