Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Xlib, help on font colours

74 views
Skip to first unread message

NickC

unread,
Nov 28, 2009, 12:07:57 AM11/28/09
to

Background: For my first Xlib application, I want to write a status bar
suitable for any tiling window manager and providing similar functionality
as dzen2 and xmobar. Since the app will run 24/7, I want to minimise its
resource use as much as possible.

The data will be generated combined from several functions in intervals
from every update to once an hour depending on what it is; the window will
update every (user-selectable), say, 1 or 2 seconds. The window will be
about 20 pixels high and screen-width wide on the root window.

Problem: For v1.0, the output will be text only, so the first cut is
simple: fill a char array from data provided by the various functions and
call XDrawString every update. But, I want certain "fields", like CPU
usage, to change colour according to some pre-defined parameter, so now I
need to change colours throughout the string. How?

Two thoughts:

1) each function maintains a GC and sets its colours before returning some
sort of structure like:
static struct field{
char *text;
GC *gc;
};
which means each function has a GC in memory and lots of GC switching as
the output is written. The advantage is the output function doesn't worry
about GCs, it just writes that field with that GC, then moves on to the
next field; easier for each function to change several things like fg and
bg colours, fonts, etc; or

2) there is a global GC; each function returns a data string and a colour
integer; the output function writes that field's output, changing the
global GC with XSetForeground(..., colour) as it writes the strings. The
disadvantage is it's harder to make each field much different from the
others except for fg colour.

Any other ideas?

I imagine this is a very simple problem, but I have no experience to draw
on, so hoping some X11 gurus can give me some guidance.

[Is this the right group for Xlib questions? Coudn't find a specific
active group.]

Many thanks,
--
NickC

Jens Thoms Toerring

unread,
Nov 28, 2009, 6:01:04 AM11/28/09
to

> Two thoughts:

> Any other ideas?

Not being an "X11 guru" I can only repeat what the Xlib Programming
Manual says in sections 5.2 and 5.9, i.e. that it's not clear if
using a lot of GCs is better than changing a single one (or a few).
It depends on how many GCs the X server can cache. If that number
is sufficient then solution 2 should be faster (no extra calls to
the server for changing GCs necessary, and switching between GCs
thus tending to be cheap), while on servers that can't cache GCs
(or only a very small number) solution 1 might be faster. But then
the Xlib Programming Manual is from 1992, i.e. from a time when me-
mory was a much more limited resource than it is today, so I would
tend to assume that Xservers nowadays will cache a lot more data
than they did nearly 20 years ago. Perhaps the best solution would
be to have a number of pre-made GCs with all the color and font set-
tings etc. that may be be used and have the functions just tell
which one of those to use (instead of each function maintaining its
own set of GCs).

> [Is this the right group for Xlib questions? Coudn't find a specific
> active group.]

I would guess comp.windows.x is the best choice. Maybe it's not
extremely active, but then there aren't that many people that
write applications using Xlib directly.

Regards, Jens
--
\ Jens Thoms Toerring ___ j...@toerring.de
\__________________________ http://toerring.de

Bjarni Juliusson

unread,
Nov 28, 2009, 11:45:31 AM11/28/09
to
>> Two thoughts:
>
>> 1) each function maintains a GC and sets its colours before returning some
>> sort of structure like:
>> static struct field{
>> char *text;
>> GC *gc;
>> };
>> which means each function has a GC in memory and lots of GC switching as
>> the output is written. The advantage is the output function doesn't worry
>> about GCs, it just writes that field with that GC, then moves on to the
>> next field; easier for each function to change several things like fg and
>> bg colours, fonts, etc; or
>
>> 2) there is a global GC; each function returns a data string and a colour
>> integer; the output function writes that field's output, changing the
>> global GC with XSetForeground(..., colour) as it writes the strings. The
>> disadvantage is it's harder to make each field much different from the
>> others except for fg colour.

> Not being an "X11 guru" I can only repeat what the Xlib Programming


> Manual says in sections 5.2 and 5.9, i.e. that it's not clear if
> using a lot of GCs is better than changing a single one (or a few).
> It depends on how many GCs the X server can cache. If that number
> is sufficient then solution 2 should be faster (no extra calls to
> the server for changing GCs necessary, and switching between GCs
> thus tending to be cheap), while on servers that can't cache GCs
> (or only a very small number) solution 1 might be faster. But then
> the Xlib Programming Manual is from 1992, i.e. from a time when me-
> mory was a much more limited resource than it is today, so I would
> tend to assume that Xservers nowadays will cache a lot more data
> than they did nearly 20 years ago. Perhaps the best solution would
> be to have a number of pre-made GCs with all the color and font set-
> tings etc. that may be be used and have the functions just tell
> which one of those to use (instead of each function maintaining its
> own set of GCs).

There seems to be some confusion here about the nature of GCs. To clarify:

A GC is a server-side resource, which is created in the server's memory
once by a request from the client and then only referenced in subsequent
drawing requests by means of an ID returned by the server upon creating
the GC. Thus, by using the concept of a GC, X avoids the need to pass
drawing parameters with each request.

Therefore, the appropriate way to handle multiple drawing contexts, such
as various modules in your program needing to draw text in different
colours or with different fonts, is to have each module create a GC on
the server, and for the GC parameter in each drawing request then pass
the ID indicated by the responsible module. This is what happens in
method 1 above.

Using method 2 introduces overhead for sending GC update requests for
the one global GC to the server between drawing requests, which will
degrade performance to some extent (probably small).

As long as you don't create preposterous numbers of GCs, having one for
each different context and not changing them a whole lot is the way to
go and is what GCs are for.


Bjarni
--

INFORMATION WANTS TO BE FREE

NickC

unread,
Nov 29, 2009, 6:36:45 AM11/29/09
to
Many thanks for both of those comments. Thanks Jens for the idea of
creating a few standardised GCs, which is what I'll do. Thanks Bjarni for
clarifying the GC process, very informative.

I'll give c.windows.x a try next time, must have missed it when I was
searching for a relevant group.


--
NickC

0 new messages