fonts and colors - Xwindows
This is a discussion on fonts and colors - Xwindows ; Hello,
what's wrong with this code? It has to show a window with a string
printed in a color
on another color background, but every time I run it (on linux) these
colors change
and sometimes the window is completely ...
-
fonts and colors
Hello,
what's wrong with this code? It has to show a window with a string
printed in a color
on another color background, but every time I run it (on linux) these
colors change
and sometimes the window is completely blank in dispect of my XMap,
XFlush calls.
Can anybody explain me?
Thanks,
Gaetano
#include
#include
#include
#include
#define EXAMPLE_STRING "string example"
#define EXAMPLE_FONT
"-adobe-helvetica-medium-r-*-*-14-*-*-*-*-*-iso8859-1"
#define EXAMPLE_FG_COLOR "rgb:ff/ff/ff"
#define EXAMPLE_BG_COLOR "rgb:00/00/00"
#define DEFAULT_X 100
#define DEFAULT_Y 100
int main (void)
{
Display *dspl;
Window wndw;
GC gc;
XGCValues vls;
Colormap cmap;
XColor fgclr, bgclr;
XFontStruct *fnt;
XCharStruct overall;
int scrn, dir, fa, fd;
if (!(dspl = XOpenDisplay(NULL))) {
fprintf(stderr, "cannot open display\n");
exit(EXIT_FAILURE);
}
scrn = DefaultScreen(dspl);
if (!(fnt = XLoadQueryFont(dspl, EXAMPLE_FONT))) {
fprintf(stderr, "cannot load font\n");
exit(EXIT_FAILURE);
}
XTextExtents(fnt, EXAMPLE_STRING, strlen(EXAMPLE_STRING), &dir,
&fa, &fd, &overall);
wndw = XCreateSimpleWindow(dspl, DefaultRootWindow(dspl),
DEFAULT_X, DEFAULT_Y, overall.width, overall.ascent + overall.descent,
0, 0,
XMapWindow(dspl, wndw);
XFlush(dspl);
cmap = DefaultColormap(dspl, scrn);
if (!XParseColor(dspl, cmap, EXAMPLE_FG_COLOR, &fgclr) ||
!XParseColor(dspl, cmap, EXAMPLE_BG_COLOR, &bgclr)) {
fprintf(stderr, "cannot parse colors\n");
exit(EXIT_FAILURE);
}
vls.foreground = fgclr.pixel;
vls.background = bgclr.pixel;
vls.font = fnt->fid;
gc = XCreateGC(dspl, wndw, GCForeground | GCBackground |
GCFont, &vls);
XDrawImageString(dspl, wndw, gc, 0, overall.ascent,
EXAMPLE_STRING, strlen(EXAMPLE_STRING));
XMapWindow(dspl, wndw);
XFlush(dspl);
for (;
;
}
-
Re: fonts and colors
In comp.windows.x, gaetanoortisi@yahoo.it
wrote
on 2 Oct 2006 05:09:52 -0700
<1159790992.121299.168880@e3g2000cwe.googlegroups.c om>:
> Hello,
> what's wrong with this code? It has to show a window with a string
> printed in a color
> on another color background, but every time I run it (on linux) these
> colors change
> and sometimes the window is completely blank in dispect of my XMap,
> XFlush calls.
> Can anybody explain me?
> Thanks,
> Gaetano
>
> #include
> #include
> #include
> #include
>
> #define EXAMPLE_STRING "string example"
> #define EXAMPLE_FONT
> "-adobe-helvetica-medium-r-*-*-14-*-*-*-*-*-iso8859-1"
> #define EXAMPLE_FG_COLOR "rgb:ff/ff/ff"
> #define EXAMPLE_BG_COLOR "rgb:00/00/00"
>
> #define DEFAULT_X 100
> #define DEFAULT_Y 100
>
> int main (void)
> {
> Display *dspl;
> Window wndw;
> GC gc;
> XGCValues vls;
> Colormap cmap;
> XColor fgclr, bgclr;
> XFontStruct *fnt;
> XCharStruct overall;
> int scrn, dir, fa, fd;
>
> if (!(dspl = XOpenDisplay(NULL))) {
> fprintf(stderr, "cannot open display\n");
> exit(EXIT_FAILURE);
> }
> scrn = DefaultScreen(dspl);
> if (!(fnt = XLoadQueryFont(dspl, EXAMPLE_FONT))) {
> fprintf(stderr, "cannot load font\n");
> exit(EXIT_FAILURE);
> }
> XTextExtents(fnt, EXAMPLE_STRING, strlen(EXAMPLE_STRING), &dir,
> &fa, &fd, &overall);
>
> wndw = XCreateSimpleWindow(dspl, DefaultRootWindow(dspl),
> DEFAULT_X, DEFAULT_Y, overall.width, overall.ascent + overall.descent,
> 0, 0,
>
> XMapWindow(dspl, wndw);
> XFlush(dspl);
>
> cmap = DefaultColormap(dspl, scrn);
> if (!XParseColor(dspl, cmap, EXAMPLE_FG_COLOR, &fgclr) ||
> !XParseColor(dspl, cmap, EXAMPLE_BG_COLOR, &bgclr)) {
> fprintf(stderr, "cannot parse colors\n");
> exit(EXIT_FAILURE);
> }
>
> vls.foreground = fgclr.pixel;
> vls.background = bgclr.pixel;
> vls.font = fnt->fid;
>
> gc = XCreateGC(dspl, wndw, GCForeground | GCBackground |
> GCFont, &vls);
>
> XDrawImageString(dspl, wndw, gc, 0, overall.ascent,
> EXAMPLE_STRING, strlen(EXAMPLE_STRING));
>
> XMapWindow(dspl, wndw);
> XFlush(dspl);
>
***
> for (;
> ;
***
> }
>
A partial rewrite, to put in a proper event loop:
gc = XCreateGC(dspl, windw, GCForeground|GCbackground|GCFont, &vls);
/* new call; add more masks as needed */
XSelectInput(dspl, wndw, ExposureMask);
XMapWindow(dspl, wndw);
for(;
{
XEvent ev;
XNextEvent(dspl, &ev);
switch(ev.type)
{
case Expose:
XDrawImageString(dspl, wndw, gc, 0, overall.ascent,
EXAMPLE_STRING, strlen(EXAMPLE_STRING));
break;
/* add more cases as needed */
}
}
With these programming changes not only will you not
needlessly consume CPU (for(;
; with an empty body
that loops forever is sometimes called a "busyloop",
and nowadays is considered bad programming practice),
but it will also refresh properly whenever needed.
--
#191, ewill3@earthlink.net
/dev/signature: Not a text file
-
Re: fonts and colors
gaetanoortisi@yahoo.it wrote:
> Hello,
> what's wrong with this code? It has to show a window with a string
> printed in a color on another color background, but every time I run
> it (on linux) these colors change and sometimes the window is
> completely blank in dispect of my XMap, XFlush calls. Can anybody
> explain me?
> Thanks,
> Gaetano
>
> [some code deleted]
> cmap = DefaultColormap(dspl, scrn);
> if (!XParseColor(dspl, cmap, EXAMPLE_FG_COLOR, &fgclr) ||
> !XParseColor(dspl, cmap, EXAMPLE_BG_COLOR, &bgclr)) {
> fprintf(stderr, "cannot parse colors\n");
> exit(EXIT_FAILURE);
> }
>
> vls.foreground = fgclr.pixel;
> vls.background = bgclr.pixel;
> [some code deleted]
It has been a while since I've used Xlib's color functions so don't
take this as gospel. But if I recall correctly...
The XParseColor() function converts a color's name to an RGB value,
but doesn't allocate it. Consequently, it doesn't fill in the pixel
field of the XColor struct; it only fills in the red, green, and blue
fields.
Try using XAllocNamedColor() instead:
if (!XAllocNamedColor(dspl, cmap, EXAMPLE_FG_COLOR, &fgclr, &fgclr) ||
!XAllocNamedColor(dspl, cmap, EXAMPLE_BG_COLOR, &bgclr, &bgclr)) {
Note that the first four parameters of XAllocNamedColor() are the
same as for XParseColor(). The fifth parameter is where it stores
information about the allocated color. When you use the same XColor
struct for both the fourth and fifth parameters, the result of the
pixel field is always guaranteed to be set properly (unless the
function fails), but the red, green, and blue field could be either
the exact values from the color name lookup, or the approximations
that the colormap actually supports. Since you only care about the
pixel field in this program, it's safe for you to use the same XColor
for both parameters.
If your program frequently allocates colors this way, then you'll need
to free any unused colors by calling XFreeColors(). (Really this is
only important when your using an 8-bit pseudocolor screen, but you
might as well write portable code, right?) You do *NOT* need to free
colors when your program terminates, because the X server will do that
automatically.
-
Re: fonts and colors
>
> The XParseColor() function converts a color's name to an RGB value,
> but doesn't allocate it. Consequently, it doesn't fill in the pixel
> field of the XColor struct; it only fills in the red, green, and blue
> fields.
I had the erroneus convinction that XAlloc color function have to be
used only with "palette"
colormap.
>
> Try using XAllocNamedColor() instead:
>
> if (!XAllocNamedColor(dspl, cmap, EXAMPLE_FG_COLOR, &fgclr, &fgclr) ||
> !XAllocNamedColor(dspl, cmap, EXAMPLE_BG_COLOR, &bgclr, &bgclr)) {
>
Yes, now it works.
> [..] but the red, green, and blue field could be either
> the exact values from the color name lookup, or the approximations
> that the colormap actually supports. Since you only care about the
> pixel field in this program, it's safe for you to use the same XColor
> for both parameters.
To obtain the nearest color also in pixel field?
Writing portable code is difficult (Any suggestion to make a program
that works well
in 65536 colors environment, for example?)
Thanks,
Gaetano