Files
wmaker/WINGs/wcolor.c
T

327 lines
7.4 KiB
C
Raw Normal View History

1998-09-29 22:36:29 +00:00
#include "WINGsP.h"
2001-07-23 20:31:32 +00:00
#include "wconfig.h"
1998-09-29 22:36:29 +00:00
#include <wraster.h>
#define LIGHT_STIPPLE_WIDTH 4
#define LIGHT_STIPPLE_HEIGHT 4
2005-08-22 23:58:19 +00:00
static char LIGHT_STIPPLE_BITS[] = {
2009-08-20 00:59:40 +02:00
0x05, 0x0a, 0x05, 0x0a
};
1998-09-29 22:36:29 +00:00
#define DARK_STIPPLE_WIDTH 4
#define DARK_STIPPLE_HEIGHT 4
2005-08-22 23:58:19 +00:00
static char DARK_STIPPLE_BITS[] = {
2009-08-20 00:59:40 +02:00
0x0a, 0x04, 0x0a, 0x01
};
1998-09-29 22:36:29 +00:00
2009-08-20 00:59:40 +02:00
static WMColor *createRGBAColor(WMScreen * scr, unsigned short red,
unsigned short green, unsigned short blue, unsigned short alpha);
1998-09-29 22:36:29 +00:00
/*
* TODO: make the color creation code return the same WMColor for the
* same colors.
* make findCloseColor() find the closest color in the RContext pallette
* or in the other colors allocated by WINGs.
*/
2009-08-20 00:59:40 +02:00
static WMColor *findCloseColor(WMScreen * scr, unsigned short red, unsigned short green,
unsigned short blue, unsigned short alpha)
1998-09-29 22:36:29 +00:00
{
2009-08-20 00:59:40 +02:00
WMColor *color;
XColor xcolor;
RColor rcolor;
1998-09-29 22:36:29 +00:00
2009-08-20 00:59:40 +02:00
rcolor.red = red >> 8;
rcolor.green = green >> 8;
rcolor.blue = blue >> 8;
rcolor.alpha = alpha >> 8;
1998-09-29 22:36:29 +00:00
2009-08-20 00:59:40 +02:00
if (!RGetClosestXColor(scr->rcontext, &rcolor, &xcolor))
return NULL;
2004-10-12 21:28:27 +00:00
2009-08-20 00:59:40 +02:00
if (!XAllocColor(scr->display, scr->colormap, &xcolor))
return NULL;
1998-09-29 22:36:29 +00:00
2009-08-20 00:59:40 +02:00
color = wmalloc(sizeof(WMColor));
1998-09-29 22:36:29 +00:00
2009-08-20 00:59:40 +02:00
color->screen = scr;
color->refCount = 1;
color->color = xcolor;
color->alpha = alpha;
color->flags.exact = 0;
2009-08-20 00:59:40 +02:00
color->gc = NULL;
1998-09-29 22:36:29 +00:00
2009-08-20 00:59:40 +02:00
return color;
1998-09-29 22:36:29 +00:00
}
2009-08-20 00:59:40 +02:00
static WMColor *createRGBAColor(WMScreen * scr, unsigned short red, unsigned short green,
unsigned short blue, unsigned short alpha)
1998-09-29 22:36:29 +00:00
{
2009-08-20 00:59:40 +02:00
WMColor *color;
XColor xcolor;
xcolor.red = red;
xcolor.green = green;
xcolor.blue = blue;
xcolor.flags = DoRed | DoGreen | DoBlue;
if (!XAllocColor(scr->display, scr->colormap, &xcolor))
return NULL;
color = wmalloc(sizeof(WMColor));
color->screen = scr;
color->refCount = 1;
color->color = xcolor;
color->alpha = alpha;
color->flags.exact = 1;
color->gc = NULL;
return color;
1998-09-29 22:36:29 +00:00
}
2009-08-20 00:59:40 +02:00
WMColor *WMCreateRGBColor(WMScreen * scr, unsigned short red, unsigned short green,
unsigned short blue, Bool exact)
1998-09-29 22:36:29 +00:00
{
2009-08-20 00:59:40 +02:00
WMColor *color = NULL;
2002-10-08 08:26:06 +00:00
2009-08-20 00:59:40 +02:00
if (!exact || !(color = createRGBAColor(scr, red, green, blue, 0xffff))) {
color = findCloseColor(scr, red, green, blue, 0xffff);
}
if (!color)
color = scr->black;
2002-10-08 08:26:06 +00:00
2009-08-20 00:59:40 +02:00
return color;
2002-10-08 08:26:06 +00:00
}
2009-08-20 00:59:40 +02:00
RColor WMGetRColorFromColor(WMColor * color)
{
2009-08-20 00:59:40 +02:00
RColor rcolor;
2009-08-20 00:59:40 +02:00
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;
}
2009-08-20 00:59:40 +02:00
WMColor *WMCreateRGBAColor(WMScreen * scr, unsigned short red, unsigned short green,
unsigned short blue, unsigned short alpha, Bool exact)
2002-10-08 08:26:06 +00:00
{
2009-08-20 00:59:40 +02:00
WMColor *color = NULL;
2004-10-12 21:28:27 +00:00
2009-08-20 00:59:40 +02:00
if (!exact || !(color = createRGBAColor(scr, red, green, blue, alpha))) {
color = findCloseColor(scr, red, green, blue, alpha);
}
if (!color)
color = scr->black;
1998-09-29 22:36:29 +00:00
2009-08-20 00:59:40 +02:00
return color;
1998-09-29 22:36:29 +00:00
}
WMColor *WMCreateNamedColor(WMScreen * scr, const char *name, Bool exact)
1998-09-29 22:36:29 +00:00
{
2009-08-20 00:59:40 +02:00
WMColor *color;
XColor xcolor;
2004-10-12 21:28:27 +00:00
2009-08-20 00:59:40 +02:00
if (!XParseColor(scr->display, scr->colormap, name, &xcolor))
return NULL;
1999-03-09 14:58:01 +00:00
2009-08-20 00:59:40 +02:00
if (scr->visual->class == TrueColor)
exact = True;
1999-03-09 14:58:01 +00:00
2009-08-20 00:59:40 +02:00
if (!exact || !(color = createRGBAColor(scr, xcolor.red, xcolor.green, xcolor.blue, 0xffff))) {
color = findCloseColor(scr, xcolor.red, xcolor.green, xcolor.blue, 0xffff);
}
return color;
1998-09-29 22:36:29 +00:00
}
2009-08-20 00:59:40 +02:00
WMColor *WMRetainColor(WMColor * color)
1998-09-29 22:36:29 +00:00
{
2009-08-20 00:59:40 +02:00
assert(color != NULL);
2004-10-12 21:28:27 +00:00
2009-08-20 00:59:40 +02:00
color->refCount++;
2004-10-12 21:28:27 +00:00
2009-08-20 00:59:40 +02:00
return color;
1998-09-29 22:36:29 +00:00
}
2009-08-20 00:59:40 +02:00
void WMReleaseColor(WMColor * color)
1998-09-29 22:36:29 +00:00
{
2009-08-20 00:59:40 +02:00
color->refCount--;
if (color->refCount < 1) {
XFreeColors(color->screen->display, color->screen->colormap, &(color->color.pixel), 1, 0);
if (color->gc)
XFreeGC(color->screen->display, color->gc);
wfree(color);
}
1998-09-29 22:36:29 +00:00
}
2009-08-20 00:59:40 +02:00
void WMSetColorAlpha(WMColor * color, unsigned short alpha)
2002-10-08 08:26:06 +00:00
{
2009-08-20 00:59:40 +02:00
color->alpha = alpha;
2002-10-08 08:26:06 +00:00
}
2009-08-20 00:59:40 +02:00
void WMPaintColorSwatch(WMColor * color, Drawable d, int x, int y, unsigned int width, unsigned int height)
1998-09-29 22:36:29 +00:00
{
2009-08-20 00:59:40 +02:00
XFillRectangle(color->screen->display, d, WMColorGC(color), x, y, width, height);
1998-09-29 22:36:29 +00:00
}
2009-08-20 00:59:40 +02:00
WMPixel WMColorPixel(WMColor * color)
1998-09-29 22:36:29 +00:00
{
2009-08-20 00:59:40 +02:00
return color->color.pixel;
1998-09-29 22:36:29 +00:00
}
2009-08-20 00:59:40 +02:00
GC WMColorGC(WMColor * color)
1998-09-29 22:36:29 +00:00
{
2009-08-20 00:59:40 +02:00
if (!color->gc) {
XGCValues gcv;
WMScreen *scr = color->screen;
1999-03-09 14:58:01 +00:00
2009-08-20 00:59:40 +02:00
gcv.foreground = color->color.pixel;
gcv.graphics_exposures = False;
color->gc = XCreateGC(scr->display, scr->rcontext->drawable,
GCForeground | GCGraphicsExposures, &gcv);
}
1999-03-09 14:58:01 +00:00
2009-08-20 00:59:40 +02:00
return color->gc;
1998-09-29 22:36:29 +00:00
}
2009-08-20 00:59:40 +02:00
void WMSetColorInGC(WMColor * color, GC gc)
1998-09-29 22:36:29 +00:00
{
2009-08-20 00:59:40 +02:00
XSetForeground(color->screen->display, gc, color->color.pixel);
1998-09-29 22:36:29 +00:00
}
/* "system" colors */
2009-08-20 00:59:40 +02:00
WMColor *WMWhiteColor(WMScreen * scr)
1998-09-29 22:36:29 +00:00
{
2009-08-20 00:59:40 +02:00
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);
1998-09-29 22:36:29 +00:00
}
2009-08-20 00:59:40 +02:00
WMColor *WMBlackColor(WMScreen * scr)
1998-09-29 22:36:29 +00:00
{
2009-08-20 00:59:40 +02:00
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);
1998-09-29 22:36:29 +00:00
}
2009-08-20 00:59:40 +02:00
WMColor *WMGrayColor(WMScreen * scr)
1998-09-29 22:36:29 +00:00
{
2009-08-20 00:59:40 +02:00
if (!scr->gray) {
WMColor *color;
if (scr->depth == 1) {
Pixmap stipple;
WMColor *white = WMWhiteColor(scr);
WMColor *black = WMBlackColor(scr);
XGCValues gcv;
stipple = XCreateBitmapFromData(scr->display, W_DRAWABLE(scr),
LIGHT_STIPPLE_BITS, LIGHT_STIPPLE_WIDTH,
LIGHT_STIPPLE_HEIGHT);
color = createRGBAColor(scr, 0xffff, 0xffff, 0xffff, 0xffff);
gcv.foreground = white->color.pixel;
gcv.background = black->color.pixel;
gcv.fill_style = FillStippled;
gcv.stipple = stipple;
color->gc = XCreateGC(scr->display, W_DRAWABLE(scr), GCForeground
| GCBackground | GCStipple | GCFillStyle
| GCGraphicsExposures, &gcv);
XFreePixmap(scr->display, stipple);
WMReleaseColor(white);
WMReleaseColor(black);
} else {
color = WMCreateRGBColor(scr, 0xaeba, 0xaaaa, 0xaeba, True);
if (!color->flags.exact)
wwarning(_("could not allocate %s color"), _("gray"));
}
scr->gray = color;
}
return WMRetainColor(scr->gray);
1998-09-29 22:36:29 +00:00
}
2009-08-20 00:59:40 +02:00
WMColor *WMDarkGrayColor(WMScreen * scr)
1998-09-29 22:36:29 +00:00
{
2009-08-20 00:59:40 +02:00
if (!scr->darkGray) {
WMColor *color;
if (scr->depth == 1) {
Pixmap stipple;
WMColor *white = WMWhiteColor(scr);
WMColor *black = WMBlackColor(scr);
XGCValues gcv;
stipple = XCreateBitmapFromData(scr->display, W_DRAWABLE(scr),
DARK_STIPPLE_BITS, DARK_STIPPLE_WIDTH,
DARK_STIPPLE_HEIGHT);
color = createRGBAColor(scr, 0, 0, 0, 0xffff);
gcv.foreground = white->color.pixel;
gcv.background = black->color.pixel;
gcv.fill_style = FillStippled;
gcv.stipple = stipple;
color->gc = XCreateGC(scr->display, W_DRAWABLE(scr), GCForeground
| GCBackground | GCStipple | GCFillStyle
| GCGraphicsExposures, &gcv);
XFreePixmap(scr->display, stipple);
WMReleaseColor(white);
WMReleaseColor(black);
} else {
color = WMCreateRGBColor(scr, 0x5144, 0x5555, 0x5144, True);
if (!color->flags.exact)
wwarning(_("could not allocate %s color"), _("dark gray"));
}
scr->darkGray = color;
}
return WMRetainColor(scr->darkGray);
1998-09-29 22:36:29 +00:00
}
2009-08-20 00:59:40 +02:00
unsigned short WMRedComponentOfColor(WMColor * color)
1998-09-29 22:36:29 +00:00
{
2009-08-20 00:59:40 +02:00
return color->color.red;
1998-09-29 22:36:29 +00:00
}
2009-08-20 00:59:40 +02:00
unsigned short WMGreenComponentOfColor(WMColor * color)
1998-09-29 22:36:29 +00:00
{
2009-08-20 00:59:40 +02:00
return color->color.green;
1998-09-29 22:36:29 +00:00
}
2009-08-20 00:59:40 +02:00
unsigned short WMBlueComponentOfColor(WMColor * color)
1998-09-29 22:36:29 +00:00
{
2009-08-20 00:59:40 +02:00
return color->color.blue;
1998-09-29 22:36:29 +00:00
}
2009-08-20 00:59:40 +02:00
unsigned short WMGetColorAlpha(WMColor * color)
{
2009-08-20 00:59:40 +02:00
return color->alpha;
}
2009-08-20 00:59:40 +02:00
char *WMGetColorRGBDescription(WMColor * color)
1998-09-29 22:36:29 +00:00
{
2010-09-28 22:25:44 +02:00
char *str = wmalloc(8);
2004-10-12 21:28:27 +00:00
2010-09-28 22:25:44 +02:00
if (snprintf(str, 8, "#%02x%02x%02x",
color->color.red >> 8, color->color.green >> 8, color->color.blue >> 8) >= 8) {
wfree(str);
return NULL;
}
2004-10-12 21:28:27 +00:00
2009-08-20 00:59:40 +02:00
return str;
1998-09-29 22:36:29 +00:00
}