Index: [thread] [date] [subject] [author]
  From: Brian S. Julin <bri@tull.umassp.edu>
  To  : ggi-develop@eskimo.com
  Date: Sat, 3 Jul 1999 02:17:35 -0400 (EDT)

Palette proposal

I'm working on Palette handling for GGI:: v0.2 right now and a few
problems:

The GGI documentation currently states about ggiGetPalette():

ggiGetPalette returns 0 for OK, otherwise an error code. When called
   with len=0 this function will not automatically succeed, but the
   return code will indicate whether there is a readable CLUT.

Now, this is less information than really needed by apps.  This 
may be due to an assumption that the size of the palette == 
2^bpp -- that assumption is wrong.  Xlib may have a 8bpp 
visual but only a certain number of colormap entries
available for example, and the application should not know or
care about the colors owned by other apps, since if it uses them
they could be changed by other apps (plus maybe your boss could 
snoop them looking for flesh tones :).  If something doesn't do 
it already, hardware modes where there's mixed truecolor and 
palette may appear.  Personally I'm annoyed that I can have 
either truecolor or acidwarp, but not both (Do the Matrox cards 
offer this, BTW, I would figure if any card did it would be a Matrox?)

In reality (I checked), ggiGetPalette seems to return 0 when the start (s) 
parameter is a valid palette index (on my system this seems to be off by 
1 ?!?).  This undocumented feature is good because it allows one to retreive 
the size of the palette, so at least you can figure out how big a ggi_color
array to alloc to contain it.  The way you have to do it is a bit cumbersome.
Currently I'm using this XSUB function to find the palette size:

unsigned int
_pal_len(discard, vis)
        void *          discard
        ggi_visual_t    vis
        CODE:
        RETVAL = 0x80000000;
        while (RETVAL && ggiGetPalette(vis, RETVAL, 0, NULL))
                RETVAL = RETVAL >> 1;
        if (RETVAL) {
                int last;
                last = RETVAL << 1;
                while ((RETVAL <= last) &&
                        ggiGetPalette(vis, last, 0, NULL)) last--;
                RETVAL = last;
        }
        OUTPUT:
        RETVAL

Finally, it may be the case that there are palette entries shared with
other apps/visuals which are guaranteed not to change for the life
of the app, and so are safe to use, but which are not settable.

We also doc the following in ggi/errors.h:

   GGI returncode policy is usually (unless otherwise noted):

   ==0 on normal completion
    >0 when giving additional hints or returning nonnegative integer data
    <0 for errors

In line with that I suggest the following behavior be implemented
(and I'm willing to do it.):

1) The target is responsible for presenting the GGI application
with an abstracted CLUT that has a R/W region at indecis 
0..N and a R/O part of the CLUT at indecis N+1 .. M.

2) When (and only when) called with len = 0, ggiGetPalette returns
the last readable CLUT index, or -1 if there is no CLUT at all.

3) When (and only when) called with len = 0, ggiSetPalette returns
the last "nicely" writeable CLUT index, or -1 if there is no "nicely" 
writable area in the CLUT.  ("nicely" writeable means it may actually
be writable but you'd be stealing other app's colors or crowding
the colorspace.  If you don't care about that you're free to 
call ggiSetPalette with s > N and you'll get a 0 return code
if the write succeeds.  This obseletes the GGI_PALETTE_DONTCARE business.)

4) MapColor is garanteed to match the CLUT entry with the lowest
index when more than one CLUT entry exists with the same color
in it.

5) The correct pixel value for selecting the color contained in 
CLUT slot N is not necessarily N.  The correct way to get the pixel
value is to ggiMapColor or ggiPackPixel. 

6) X targets get an additional configuration switches that put 
hard limits on the number of palette entries they may read/write.

If you are doing palette swirling then you should do something to
the effect of setting the palette all black, then looping
from 0..N setting non-black colors, using MapColor(vis, &black) to 
build an array of pixel<->palette entries for later use.

... comments?

--
Brian


Index: [thread] [date] [subject] [author]