From: mouse@thunder.mcrcim.mcgill.edu (der Mouse)
Newsgroups: fj.mail-lists.x-window
Subject: Re: How do %$#*#!$ overlay planes work?!?
Date: 5 Nov 92 12:13:37 GMT
Distribution: fj
Organization: McGill Research Centre for Intelligent Machines

Date: Sun, 1 Nov 92 09:13:32 GMT
Message-Id: <1992Nov1.091332.27339@thunder.mcrcim.mcgill.edu>
Newsgroups: comp.windows.x

In article <1992Oct29.212051.12869@mcs.anl.gov>, korp@atlantis.eid.anl.gov (Peter Korp) writes:

> Okay, I have what I consider to be a fairly simple request. I want to
> allocate colors in a colormap in such a way that I have three planes
> with 7 distinct colors in them.

> Background Plane:		"Red", "Green", "Blue"
> Overlay Plane #1:		"Yellow", "White", "Magenta"
> Overlay Plane #2:		"Black", but could be any color

I assume you're talking about a PseudoColor visual.  I also assume that
overlay #2 is to be visually "in front of" overlay #1.

Okay.  First, we need to determine just what resources you need.

Your background consists of three colors.  The first overlay consists
of three colors, plus transparent making four, needing two planes; the
second of one, plus transparent making two, needing one plane.

Thus, you want to call XAllocColorCells with nplanes=3 (two for one
overlay plus one for the other) and npixels=3 (the three
background-plane colors).  Unless you have some additional requirement
you haven't mentioned, you can use contig=False, which will make your
request more likely to succeed if colormap cells are running short.

Then you need to use XStoreColor (or more likely XStoreColors) to load
the resulting cells.  You have allocated 24 cells in the colormap
(npixels*2^nplanes = 3*2^3).  These are:

	pixels[0]
	pixels[0] | planes[0]
	pixels[0]             | planes[1]
	pixels[0] | planes[0] | planes[1]
	pixels[0]                         | planes[2]
	pixels[0] | planes[0]             | planes[2]
	pixels[0]             | planes[1] | planes[2]
	pixels[0] | planes[0] | planes[1] | planes[2]
	pixels[1]
	pixels[1] | planes[0]
	.....

So, what colors do you store into these cells?  Well, first of all, all
the cells with planes[2] set have overlay #2 set, so they get black.
Of the remainder, those with either planes[0] or planes[1] set belong
to overlay #1, so they get yellow, white, and magenta, depending on
which bits are set.  I will arbitrarily use yellow for planes[0], white
for planes[1], and magenta for planes[0]|planes[1].  The remainder are
those cells with none of the overlay plane bits set; they get red,
green, and blue.  Again arbitrarily, I'll assume pixels[0] gets red,
pixels[1] green, and pixels[2] blue.  Thus, we have

red	pixels[0]
yellow	pixels[0] | planes[0]
white	pixels[0]             | planes[1]
magenta	pixels[0] | planes[0] | planes[1]
black	pixels[0]                         | planes[2]
black	pixels[0] | planes[0]             | planes[2]
black	pixels[0]             | planes[1] | planes[2]
black	pixels[0] | planes[0] | planes[1] | planes[2]
green	pixels[1]
yellow	pixels[1] | planes[0]
white	pixels[1]             | planes[1]
magenta	pixels[1] | planes[0] | planes[1]
black	pixels[1]                         | planes[2]
	....

Then, you just need to fiddle the plane-mask and foreground values in
your GCs to draw into the appropriate bits.  To draw into the
background plane, set the plane-mask to everything but the overlay
bits, that is, ~(planes[0]|planes[1]|planes[2]), and set the foreground
pixel value to pixels[0], pixels[1], or pixels[2], depending on which
color you wish to draw.  To draw into overlay #1, set the plane-mask to
overlay #1's planes - planes[0]|planes[1] - and the foreground value to
0 (to draw transparent), planes[0] (to draw yellow), planes[1] (to draw
white), or planes[0]|planes[1] (to draw magenta).  To draw into overlay
#2, set the plane-mask to overlay #2's plane - planes[2] - and set the
foreground value to 0 (to draw transparent) or planes[2] (to draw
black).  You said you wanted to do rubber-banding in overlay #2, so you
presumably want to do XOR drawing there; for that, set the plane-mask
to planes[2] (so you affect only overlay #2) and the foreground to the
XOR of the two values you wish to switch between, which means planes[2]
(since the values are transparent and black, and one is zero and the
other is planes[2] - and 0 XOR planes[2] is simply planes[2]).

> Oh... How can I turn off the background plane but leave the overlay
> planes showing?

Depends on what you mean by "turn off" the background plane.  You want
all the background pixels to go black?  Go white?  Go some other color?
In any case, you can do this by reloading the pixels[0], pixels[1], and
pixels[2] entries in the colormap - just run through the above logic
only with all three background-plane colors the same....

If you want to "turn off" an overlay plane, all you need to do is go
through the above procedure for loading the colormap again, only
pretend that all the overlay bits for that plane are zero, regardless
of what they actually are.  To turn off overlay #1, for example, we get

red	pixels[0]
red	pixels[0] | planes[0]
red	pixels[0]             | planes[1]
red	pixels[0] | planes[0] | planes[1]
black	pixels[0]                         | planes[2]
black	pixels[0] | planes[0]             | planes[2]
	....

> Can I just twiddle a bit and cause the image in the background plane
> to reappear?

Yes.  Just reload the colormap cells with the values worked out by the
procedure I outlined at first...everything is still there; loading the
colormap as I described just makes it invisible.  If you want to truly
get rid of it, then instead of fiddling the colormap, just draw zeroes
(=transparent) in the appropriate overlay.

(Note to pedants: yes, you don't *have* to use zero as the transparent
value in the overlays.  I wanted to keep this simple, and if you're
going to make this quibble, you already understand what I was trying to
explain anyway.  Also, there may be other possible values for the
plane-mask when drawing into the background plane, depending on
precisely what values are in pixels[] and the window's background.)

					der Mouse

			    mouse@larry.mcrcim.mcgill.edu