[comp.graphics] Color shift in Suntools

gautam@pyr.gatech.EDU (Gautam Shah) (06/30/89)

I'm posting this for a friend. Please direct all responses to
him at the address given below.

Thanks.
-----------------------------------------------------------
I had a question about the color palette limitations on a
Sun. When a 256 color picture (say a GIF) is viewed on the 
screen and the cursor is placed on it, the rest of the screen,
with all its windows, seems to undergo a shift in palette.
Then when the cursor is moved to on any other window the picture
becomes dark and invisible. Please correct me if it is something
else. (8=)

The question is : Is there a way of finding out what colors
should be used for the Suntools Windows so that if the picture
in question is displayed on the screen then the color shift 
does not occur and the picture is visible too without the 
cursor on it.

Please direct any personal correspondence towards the following
address

	*---->	mephdbo@prism.gatech.edu
Thanks a lot

Deeptendu Majumder
---------------------------------------------------------
Phone: (404)-894-2262 (O)     |
------------------------------|
Office: 4E Coon Building      |	Mail: 	Box 30963
	Mechanical Engineering|		Georgia Tech
	----------------------|		Atlanta, GA 30332
	CAE/CAD Laboratory    |
	French Building       |
---------------------------------------------------------
uucp: ...!{allegra,amd,hplabs,seismo,ut-ngp}!gatech!prism!mephdbo
ARPA: mephdbo@prism.gatech.edu
      dips@french.gatech.edu
BITNET: meibmdm@gitvm2
---------------------------------------------------------

falk@sun.Eng.Sun.COM (Ed Falk) (06/30/89)

In article <8620@pyr.gatech.EDU>, gautam@pyr.gatech.EDU (Gautam Shah) writes:
> 
> I had a question about the color palette limitations on a
> Sun. When a 256 color picture (say a GIF) is viewed on the 
> screen and the cursor is placed on it, the rest of the screen,
> with all its windows, seems to undergo a shift in palette.
> Then when the cursor is moved to on any other window the picture
> becomes dark and invisible. Please correct me if it is something
> else. (8=)

What you're seeing is the dreaded "flashing effect".  (At least *I*
dread it, it hurts my eyes.)

[Mini lecture follows -- caveat: this is only stuff I learned
empirically from writing suntools applications, I don't speak
officially]

What happens is this, the physical frame buffer only has 256 colors
(addressed by 8-bit pixels).  Every window on the screen is allocated a
chunk of this colormap for itself.  Most tools only use two colors
(foreground & background) so you can fit a lot of windows onto the
screen at one time when you have 256 colors to allocate.  Some tools
use more than two colors (such as /usr/demo/cursor_demo which uses
eight).

Also, windows that will be using the same colors can cooperate with
each other and share colormap entries.  The way this is done is to give
each colormap segment a name.  Two windows opening the same named
colormap segment will be using the same locations in the physical color
table.  At startup, suntools creates a two-entry colormap segment named
"monochrome".  All windows use this colormap segment unless explicitly
changed.

Sunwindows allocates colormap segments from high to low, always
starting at a power-of-two boundary.  Also, for some reason I am
unaware of, if a window requests a colormap segment that is not a power
of two in length, sunwindows will allocate this segment starting at 0.

Anyway, if the windows on the screen ask for more colors than are
available (usually because one of those tools has asked for 256
colors), then you have a problem.  Some window systems handle this case
by refusing to let the requesting window have the all colors it
requested.  Sun's solution was rather clever:  they start "paging" the
colormap.  Whichever window has the cursor, that's the one that has the
colormap.  The unfortunate side effect to this is that as you move the
cursor in and out of a window, all the windows on the screen suddenly
change color as the colormap is paged in and out.  Also, if the current
window is doing colormap double-buffering, all other windows on the
screen will flash back and forth at frame rate as the double-buffering
application keeps changing the colormap.

There is no general solution to this problem, all 8-bit frame buffers
suffer from it.  The only fixes are to not run application that uses
too much of the colormap, to change the window system to not let the
application have the whole colormap, or to run the application
fullscreen so you can't see the other windows.

However, this *is* a cute workaround.  Simply write your tool so that
it doesn't allocate the entire colormap.  What I usually do is to
allocate 240 entries instead of 256.  This leaves 16 entries behind for
the window system.  This is supported in sunwindows, but I don't know
about X or NeWS.

Finally, there is a bug that is triggered by using a funny-length
colormap:  the pixwin function pw_putattributes will munge your write
mask (for reasons I don't want to get into here).  The workaround for
this is this function:

	#include <sunwindow/window_hs.h>

	set_write_mask(pw, mask)
		struct	pixwin	*pw;
		int 		mask;
	{
		struct colormapseg	cms;
		int			oldmask;

		(void)pw_getcmsdata(pw, &cms, &oldmask);

	#ifdef  planes_fully_implemented 
		pr_putattributes(pw->pw_pixrect, &mask);
	#else
		(void)pw_full_putattributes(pw->pw_pixrect, &mask);
	#endif  planes_fully_implemented

		if (oldmask != mask)
			(void)pw_getclipping(pw);
	}

-- 
		-ed falk, sun microsystems, sun!falk, falk@sun.com

  "If you wrapped yourself in the flag like George Bush does, you'd
  be worried about flag-burning too"