Question

I am writing an application using Xlib. I set the foreground of the window up like this:

XSetForeground (dpy, gc, WhitePixel (dpy, scr));

But now I need to change the drawing colour to something else, I first wanted to do that like this:

void update_window (Display* d, Window w, GC gc, Colormap cmap) 
{
    XWindowAttributes winatt;
    XColor bcolor;
    char bar_color[] = "#4E4E4E";

    XGetWindowAttributes (d, w, &winatt);

    XParseColor(d, cmap, bar_color, &bcolor);
    XAllocColor(d, cmap, &bcolor);

    // Draws the menu bar.
    XFillRectangle (d, w, gc, 0, 0, winatt.width, 30);

    XFreeColormap (d, cmap);
}

But this doesn't work. What does XParseColor and XAllocColor do then? And do I need to use XSetForeground again to change the colour?

Was it helpful?

Solution

You need to use XSetForeground. Try something like this:

XColor xcolour;

// I guess XParseColor will work here
xcolour.red = 32000; xcolour.green = 65000; xcolour.blue = 32000;
xcolour.flags = DoRed | DoGreen | DoBlue;
XAllocColor(d, cmap, &xcolour);

XSetForeground(d, gc, xcolour.pixel);
XFillRectangle(d, w, gc, 0, 0, winatt.width, 30);
XFlush(d);

Also, I don't think you can use that color string. Take a look into this page:

A numerical color specification consists of a color space name and a set of values in the following syntax:

<color_space_name>:<value>/.../<value>

The following are examples of valid color strings.

"CIEXYZ:0.3227/0.28133/0.2493"
"RGBi:1.0/0.0/0.0"
"rgb:00/ff/00"
"CIELuv:50.0/0.0/0.0"

Edit/Update: as @JoL mentions in the comment, you can still use the old syntax, but the usage is discouraged:

For backward compatibility, an older syntax for RGB Device is supported, but its continued use is not encouraged. The syntax is an initial sharp sign character followed by a numeric specification, in one of the following formats:

OTHER TIPS

//I write additional function _RGB(...) where r,g,b is components in range 0...255
unsigned long _RGB(int r,int g, int b)
{
    return b + (g<<8) + (r<<16);
}


void some_fun()
{
  //sample set color, where r=255 g=0 b=127
  XSetForeground(display, gc, _RGB(255,0,127));

  //draw anything
  XFillRectangle( display, window, gc, x, y, len, hei );

}

All colour changes are done with respect to a certain GC. That GC is then used for drawing. Yes XSetForeground is the most convenient way to do that.

You can have several GCs if you have a handful of colours you use often.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top