Hrvoje Niksic wrote:
In my .emacs, I have a variation of default.emacs code that sets the
gc glyph to `recycle.xpm':
(set-glyph-image gc-pointer-glyph
(expand-file-name "recycle.xpm" data-directory))
However, the colors don't come out right -- the recycle symbol pointer
comes out in a single sickly darkish green tone, instead of the nice
color. In fact, it looks the way it used to look look on my 8bit
display when I would run out of colors. As I run under a 16bpp
TrueColor display, that should be moderately impossible.
To prove the latter point, inserting it in a buffer results in nice
colors. So I wonder if there is an explanation for that. Does the
code that instantiates pointers differ from the code that handles
buffer images?
Yes.
XCreatePixmapCursor only accepts pixmaps of depth 1, so the cursor can
only have two colours (plus a mask).
Searching for XCreatePixmapCursor reveals the following comment in
glyphs-x.c:
/* With an XBM file, it's obvious which bit is foreground
and which is background, or rather, it's implicit: in
an XBM file, a 1 bit is foreground, and a 0 bit is
background.
XCreatePixmapCursor() assumes this property of the
pixmap it is called with as well; the `foreground'
color argument is used for the 1 bits.
With an XPM file, it's tricker, since the elements of
the pixmap don't represent FG and BG, but are actual
pixel values. So we need to figure out which of those
pixels is the foreground color and which is the
background. We do it by comparing RGB and assuming
that the darker color is the foreground. This works
with the result of xbmtopbm|ppmtoxpm, at least.
It might be nice if there was some way to tag the
colors in the XPM file with whether they are the
foreground - perhaps with logical color names somehow?
Once we have decided which color is the foreground, we
need to ensure that that color corresponds to a `1' bit
in the Pixmap. The XPM library wrote into the (1-bit)
pixmap with XPutPixel, which will ignore all but the
least significant bit.
This means that a 1 bit in the image corresponds to
`fg' only if `fg.pixel' is odd.
(This also means that the image will be all the same
color if both `fg' and `bg' are odd or even, but we can
safely assume that that won't happen if the XPM file is
sensible I think.)
The desired result is that the image use `1' to
represent the foreground color, and `0' to represent
the background color. So, we may need to invert the
image to accomplish this; we invert if fg is
odd. (Remember that WhitePixel and BlackPixel are not
necessarily 1 and 0 respectively, though I think it
might be safe to assume that one of them is always 1
and the other is always 0. We also pretty much need to
assume that one is even and the other is odd.)
*/
My guess (and it is just that) is that on an PseudoColor display, the
foreground and background colours would often be allocated adjacent
colourmap cells, resulting in one being odd and the other being even,
whilst on a DirectColor display, the values would be fixed.
--
Glynn Clements <glynn(a)sensei.co.uk>