188 lines
4.3 KiB
C
188 lines
4.3 KiB
C
/*
|
|
* wcolor.c - Color dispatch layer for WINGs
|
|
*
|
|
* Pure logic: retain/release, accessors, system colors.
|
|
* All platform-specific operations go through W_ColorBackend vtable.
|
|
*/
|
|
|
|
#include "WINGsP.h"
|
|
#include "wconfig.h"
|
|
|
|
static WMColor *createRGBAColor(WMScreen *scr, unsigned short r, unsigned short g,
|
|
unsigned short b, unsigned short a)
|
|
{
|
|
const W_ColorBackend *cb = scr->colorBackend;
|
|
return cb->alloc_color(scr->colorBackendCtx, scr, r, g, b, a);
|
|
}
|
|
|
|
static WMColor *findCloseColor(WMScreen *scr, unsigned short r, unsigned short g,
|
|
unsigned short b, unsigned short a)
|
|
{
|
|
const W_ColorBackend *cb = scr->colorBackend;
|
|
return cb->find_close_color(scr->colorBackendCtx, scr, r, g, b, a);
|
|
}
|
|
|
|
WMColor *WMCreateRGBColor(WMScreen *scr, unsigned short red, unsigned short green,
|
|
unsigned short blue, Bool exact)
|
|
{
|
|
WMColor *color = NULL;
|
|
|
|
if (!exact || !(color = createRGBAColor(scr, red, green, blue, 0xffff))) {
|
|
color = findCloseColor(scr, red, green, blue, 0xffff);
|
|
}
|
|
if (!color)
|
|
color = scr->black;
|
|
|
|
return color;
|
|
}
|
|
|
|
RColor WMGetRColorFromColor(WMColor *color)
|
|
{
|
|
RColor rcolor;
|
|
|
|
rcolor.red = color->color.red >> 8;
|
|
rcolor.green = color->color.green >> 8;
|
|
rcolor.blue = color->color.blue >> 8;
|
|
rcolor.alpha = color->alpha >> 8;
|
|
|
|
return rcolor;
|
|
}
|
|
|
|
WMColor *WMCreateRGBAColor(WMScreen *scr, unsigned short red, unsigned short green,
|
|
unsigned short blue, unsigned short alpha, Bool exact)
|
|
{
|
|
WMColor *color = NULL;
|
|
|
|
if (!exact || !(color = createRGBAColor(scr, red, green, blue, alpha))) {
|
|
color = findCloseColor(scr, red, green, blue, alpha);
|
|
}
|
|
if (!color)
|
|
color = scr->black;
|
|
|
|
return color;
|
|
}
|
|
|
|
WMColor *WMCreateNamedColor(WMScreen *scr, const char *name, Bool exact)
|
|
{
|
|
WMColor *color;
|
|
const W_ColorBackend *cb = scr->colorBackend;
|
|
unsigned short r, g, b;
|
|
|
|
if (!cb->parse_named(scr->colorBackendCtx, scr, name, &r, &g, &b))
|
|
return NULL;
|
|
|
|
if (!exact || !(color = createRGBAColor(scr, r, g, b, 0xffff))) {
|
|
color = findCloseColor(scr, r, g, b, 0xffff);
|
|
}
|
|
return color;
|
|
}
|
|
|
|
WMColor *WMRetainColor(WMColor *color)
|
|
{
|
|
assert(color != NULL);
|
|
color->refCount++;
|
|
return color;
|
|
}
|
|
|
|
void WMReleaseColor(WMColor *color)
|
|
{
|
|
color->refCount--;
|
|
|
|
if (color->refCount < 1) {
|
|
const W_ColorBackend *cb = color->screen->colorBackend;
|
|
cb->free_color(color->screen->colorBackendCtx, color);
|
|
wfree(color);
|
|
}
|
|
}
|
|
|
|
void WMSetColorAlpha(WMColor *color, unsigned short alpha)
|
|
{
|
|
color->alpha = alpha;
|
|
}
|
|
|
|
void WMPaintColorSwatch(WMColor *color, WMDrawable d, int x, int y,
|
|
unsigned int width, unsigned int height)
|
|
{
|
|
W_Screen *scr = color->screen;
|
|
scr->renderBackend->fill_rect(scr->renderBackendCtx, d, color, x, y, width, height);
|
|
}
|
|
|
|
WMPixel WMColorPixel(WMColor *color)
|
|
{
|
|
return color->color.pixel;
|
|
}
|
|
|
|
/* "system" colors */
|
|
WMColor *WMWhiteColor(WMScreen *scr)
|
|
{
|
|
if (!scr->white) {
|
|
scr->white = WMCreateRGBColor(scr, 0xffff, 0xffff, 0xffff, True);
|
|
if (!scr->white->flags.exact)
|
|
wwarning(_("could not allocate %s color"), _("white"));
|
|
}
|
|
return WMRetainColor(scr->white);
|
|
}
|
|
|
|
WMColor *WMBlackColor(WMScreen *scr)
|
|
{
|
|
if (!scr->black) {
|
|
scr->black = WMCreateRGBColor(scr, 0, 0, 0, True);
|
|
if (!scr->black->flags.exact)
|
|
wwarning(_("could not allocate %s color"), _("black"));
|
|
}
|
|
return WMRetainColor(scr->black);
|
|
}
|
|
|
|
WMColor *WMGrayColor(WMScreen *scr)
|
|
{
|
|
if (!scr->gray) {
|
|
scr->gray = WMCreateRGBColor(scr, 0xaeba, 0xaaaa, 0xaeba, True);
|
|
if (!scr->gray->flags.exact)
|
|
wwarning(_("could not allocate %s color"), _("gray"));
|
|
}
|
|
return WMRetainColor(scr->gray);
|
|
}
|
|
|
|
WMColor *WMDarkGrayColor(WMScreen *scr)
|
|
{
|
|
if (!scr->darkGray) {
|
|
scr->darkGray = WMCreateRGBColor(scr, 0x5144, 0x5555, 0x5144, True);
|
|
if (!scr->darkGray->flags.exact)
|
|
wwarning(_("could not allocate %s color"), _("dark gray"));
|
|
}
|
|
return WMRetainColor(scr->darkGray);
|
|
}
|
|
|
|
unsigned short WMRedComponentOfColor(WMColor *color)
|
|
{
|
|
return color->color.red;
|
|
}
|
|
|
|
unsigned short WMGreenComponentOfColor(WMColor *color)
|
|
{
|
|
return color->color.green;
|
|
}
|
|
|
|
unsigned short WMBlueComponentOfColor(WMColor *color)
|
|
{
|
|
return color->color.blue;
|
|
}
|
|
|
|
unsigned short WMGetColorAlpha(WMColor *color)
|
|
{
|
|
return color->alpha;
|
|
}
|
|
|
|
char *WMGetColorRGBDescription(WMColor *color)
|
|
{
|
|
char *str = wmalloc(8);
|
|
|
|
if (snprintf(str, 8, "#%02x%02x%02x",
|
|
color->color.red >> 8, color->color.green >> 8, color->color.blue >> 8) >= 8) {
|
|
wfree(str);
|
|
return NULL;
|
|
}
|
|
|
|
return str;
|
|
}
|