132 lines
2.8 KiB
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);
|
|
}
|