  LibGGI open and resolved design issues
  collected by Hartmut Niemann
  $Date: 1998/07/01 12:18:14 $

  This document tries to list all issues regarding the libggi API, list
  alternatives and keep decisions, once they are made. It is mainly for
  libggi developers.
  ______________________________________________________________________

  Table of Contents


  1. Pending issues

     1.1 Mode negotiation and graphtypes
        1.1.1 What is this about?
        1.1.2 Recent comments
           1.1.2.1 Andrew Apted, Jun 24
           1.1.2.2 Hartmut Niemann, Jun 24
           1.1.2.3 Marcus Sundberg, Jun 24
           1.1.2.4 Thomas tanner, Jun 24
           1.1.2.5 Andrew Apted, Jun 24
           1.1.2.6 Erich Schubert, Jun 26
        1.1.3 Older Opinions
     1.2 Color depth reporting
     1.3 CLUT restore
     1.4 Inactivated applications

  2. Resolved issues

     2.1 ggiCircle
        2.1.1 Decision
     2.2 Reporting internal state
        2.2.1 Decision
     2.3 ggiGetRayPos, ggiWaitRayPos
        2.3.1 Decision
     2.4 extensionInit/extensionExit, ggiInit, ggiExit
        2.4.1 Decision
     2.5 Removing the "display-" prefix
        2.5.1 Decision
     2.6 ggiPuts
        2.6.1 Decisions
     2.7 Alpha values
        2.7.1 Decision
     2.8 Auxiliary buffers
        2.8.1 Decision
     2.9 Frames
     2.10 ggiCrossBlit
        2.10.1 Decision
     2.11 Palettes
     2.12 Get/Put buffers: opaque or not?
        2.12.1 Decision
     2.13 Memory visual memory layout
        2.13.1 Decision
     2.14 Graphics context save/resore
     2.15 Behaviour on switch-away and switch-back
        2.15.1 What is this about?
        2.15.2 Decision


  ______________________________________________________________________

  1.  Pending issues

  Most API issues for the 1.5 definition have been resolved by now.

  1.1.  Mode negotiation and graphtypes


  1.1.1.  What is this about?

  The current Graphtype scheme is too inflexible for architectures other
  than VGA-related cards.

  1.1.2.  Recent comments

  1.1.2.1.  Andrew Apted, Jun 24























































  ______________________________________________________________________
  Let's make the graphtype consist of three components: depth, scheme, and
  sub-scheme, as follows :

      #define GT_SCHEME_MASK     0xff0000
      #define GT_SUBSCHEME_MASK  0x00ff00
      #define GT_DEPTH_MASK      0x0000ff

  The schemes would be :

      #define GT_RGB         0x010000
      #define GT_INDEXED     0x020000
      #define GT_GREYSCALE   0x030000
      #define GT_TEXT        0x040000

  The depth is just what you'd expect.

  The sub-scheme doesn't make any sense on its own.  Its only purpose
  would be to differentiate all the possible pixel formats within a
  particular scheme + depth combination.

  Here's how the current ggi_common_plb_setup values would be defined :

          ggi_common_plb_setup   scheme   sub-scheme   depth

          sp1a8lbl =            GT_INDEXED  |  1 << 8  |  1
          sp1a8hbl =            GT_INDEXED  |  2 << 8  |  1

          sp2a8lpl =            GT_INDEXED  |  1 << 8  |  2
          sp2a8hpl =            GT_INDEXED  |  2 << 8  |  2

          sp4a8lnl =            GT_INDEXED  |  1 << 8  |  4
          sp4a8hnl =            GT_INDEXED  |  2 << 8  |  4

          sp8a8i8  =            GT_INDEXED  |  1 << 8  |  8

          sp16a16r5g5b5A1 =     GT_RGB  |  1 << 8  |  16
          sp16a16r5g5b5A1rev =  GT_RGB  |  2 << 8  |  16
          sp16a16b5g5r5A1 =     GT_RGB  |  3 << 8  |  16
          sp16a16b5g5r5A1rev =  GT_RGB  |  4 << 8  |  16
          sp16a16r5g6b5 =       GT_RGB  |  5 << 8  |  16
          sp16a16r5g6b5rev =    GT_RGB  |  6 << 8  |  16
          sp16a16b5g6r5 =       GT_RGB  |  7 << 8  |  16
          sp16a16b5g6r5rev =    GT_RGB  |  8 << 8  |  16

          sp24a8b8g8r8 =        GT_RGB  |  1 << 8  |  24
          sp24a8r8g8b8 =        GT_RGB  |  2 << 8  |  24

          sp32a32b8g8r8A8 =     GT_RGB  |  1 << 8  |  32
          sp32a32b8g8r8A8rev =  GT_RGB  |  2 << 8  |  32
          sp32a32r8g8b8A8 =     GT_RGB  |  3 << 8  |  32
          sp32a32r8g8b8A8rev =  GT_RGB  |  4 << 8  |  32

  Here's how the current graphtypes would be defined :

          GT_1BIT = GT_INDEXED | 1
          GT_2BIT = GT_INDEXED | 2
          GT_4BIT = GT_INDEXED | 4
          GT_8BIT = GT_INDEXED | 8

          GT_16BIT = GT_RGB | 16
          GT_24BIT = GT_RGB | 24
          GT_32BIT = GT_RGB | 32

          GT_TEXT16 = GT_TEXT | 16
          GT_TEXT32 = GT_TEXT | 32
  Now, using zero in one of the fields has a special meaning, not unlike
  GGI_AUTO.  Usually a program will use ggiSetGraphMode() with something
  like GT_RGB | 16, leaving the sub-scheme field zero.  The display target
  then fills in that field with the actual pixel format (e.g. becoming
  GT_RGB | 5<<8 | 16 for a sp16a16r5g6b5 framebuffer).

  If a program really wanted a certain format (and this would be
  especially valid with the memory target), then it is free to call
  ggiSetGraphMode() with GT_RGB | 5<<8 | 16, for example.  If that
  particular format wasn't available, the setmode would just fail.

  Also, a program could use "GT_RGB" (leaving the depth 0), which would be
  interpreted as "give me the best RGB mode you've got", and the result
  could come back as GT_RGB | 1<<8 | 24 (== sp24a8b8g8r8).

  The full graphtype also [A] serves as the buffer format for ggiGetBox()
  and ggiPutBox() and others, and [B] serves as the pixel format for
  ggiGetPixel(), ggiPutPixel(), ggiSetGCForeground() and others.

  ______________________________________________________________________



  1.1.2.2.  Hartmut Niemann, Jun 24










































  ______________________________________________________________________
  The new graphtype is an integer with (currently) at least 32 bit.
  As users should use ggi_graphtype, they shouldn't be affected if
  we need to change this to 64 bits some day.

  bits 7-0 contain the bits per pixel actually used,
      this means: padding bits are not counted, a 15 bpp mode has 15 here.
      I would like to suggest to count the number of *foreground colours*
      possible, which makes most text modes ==4.

  bits 15:8 contain the bits per pixel occupied in memory. Marcus pointed
      out that one might want not to code that into the 'subtypes' field.

  bits 23:16 contain the subtypes.
       Subtype 0 always means: don't know/don't care.
       Other types are allocated as needed, together with a proper define
       along the 'old' common_plb_setup's.

  bit 24: 1 for text mode
  bit 25: 1 for indexed mode
   (think of it, you can specify an indexed text mode in YUV, and
  it makes some sense ...)

  bit 31:28 enumerated color space definitions: (are there more than 16?)
             1:RGB
          2: YUV
          3: ...
          4: RGB double precision floats ??
  (two spare bits :-)

  If everything is 'hidden' by defines, nobody will ever want to deal
  with that bitmap in detail anyway ...
  #define GT_TEXTMODE 0x01000000
  #define GT_INDEXED  0x02000000
  #define GT_RGB      0x10000000
  #define GT_YUV      0x20000000

  #define GT_MODE(x,bpp,consumed,sub) x+bpp+(consumed<<8)+(sub<<16)
  #define sp16a16r5g5b5A1rev GT_MODE(GT_RGB,15,16,1)
              /* 15 bit BGR 5/5/5 reverse endian */
  #define sp16a16b5g5r5A1 GT_MODE(GT_RGB,15,16,2)
              /* 15 bit RGB 5/5/5 native endian */

  int ggiModeBpp(graphtype g){return (g&&0xff)};
  ....
  ______________________________________________________________________



  1.1.2.3.  Marcus Sundberg, Jun 24
















  ______________________________________________________________________
  > bit 24: 1 for text mode
  > bit 25: 1 for indexed mode
  >  (think of it, you can specify an indexed text mode in YUV, and
  > it makes some sense ...)
  >
  > bit 31:28 enumerated color space definitions: (are there more than 16?)
  >            1:RGB
  >       2: YUV
  >       3: ...
  >       4: RGB double precision floats ??
  > (two spare bits :-)

  I would suggest:
  bit 24-25: enumerated colorspace definitions
          0: Don't care
          1: RGB
          2: YUV
          3: allocated when needed

  bit 26-29: allocated when we need them

  bit 30: 1 for indexed mode
  bit 31: 1 for text mode

  This will allow us to expand both the enumeration
  values and the flags when needed.
  ______________________________________________________________________



  1.1.2.4.  Thomas tanner, Jun 24


  ______________________________________________________________________
  Hartmut Niemann wrote:

  > The new graphtype is an integer with (currently) at least 32 bit.
  > As users should use ggi_graphtype, they shouldn't be affected if
  > we need to change this to 64 bits some day.

   Do we really need to save _so much_ memory for mode setting?
   If we change one bit we would get into trouble...
   Is this really necessary? I would suggest a simple mode struct.

  > bit 31:28 enumerated color space definitions: (are there more than 16?)
  >            1:RGB
  >         2: YUV
  >         3: ...
  >         4: RGB double precision floats ??
  > (two spare bits :-)

   indexed, greyscale, RGB, HSV, HLS, YUV, YCrCb, CMY, CYMK, CIE L*a*b*, CIE L*u*v
  ,
   CIE uvY, CIE xyY, CIE XYZ (most general) ...

   This are 14 color spaces, and with integer/double precision we have 28.

  > What do you think?

   Looks nice at the first glance but it would cause many problems in future.
  ______________________________________________________________________




  1.1.2.5.  Andrew Apted, Jun 24

































































  ______________________________________________________________________
  Hartmut writes:

  >  The new graphtype is an integer with (currently) at least 32 bit.
  >  As users should use ggi_graphtype, they shouldn't be affected if
  >  we need to change this to 64 bits some day.
  >
  >  bits 7-0 contain the bits per pixel actually used,
  >      this means: padding bits are not counted, a 15 bpp mode has 15 here.
  >      I would like to suggest to count the number of *foreground colours*
  >      possible, which makes most text modes ==4.

  Ok.  We can call it "color depth" to be really precise.  I also agree
  with using 4 for text modes.

  >  bits 15:8 contain the bits per pixel occupied in memory. Marcus pointed
  >      out that one might want not to code that into the 'subtypes' field.

  Ok.  We can call it "access" as in the DirectBuffer stuff.

  >  bits 23:16 contain the subtypes.
  >       Subtype 0 always means: don't know/don't care.

  Well, I'm saying that when it is 0, it will get filled out by ggiSetMode()
  (like the way GGI_AUTO works).  Is that what you meant too ?

  BTW, we also need a value that says "the subtype is private, so don't
  try to encode/decode the format, instead use ggiMapColor() and
  ggiUnmapPixel()".  I suggest using all ones (i.e. 0xff << 16).

  >  bit 24: 1 for text mode
  >  bit 25: 1 for indexed mode
  >   (think of it, you can specify an indexed text mode in YUV, and
  >  it makes some sense ...)

  This doesn't make sense to me... could you please explain what you had
  in mind ?

  I am yet to be convinced that having either TEXT or INDEXED as an "or'd
  option" would actually be useful.  For example, RGB | TEXT would imply
  that the text colors were encoded in the pixels with a mask for red,
  green and blue (e.g. rrggbbRRGGBBcccccccc), which is pretty silly IMHO.

  >  bit 31:28 enumerated color space definitions: (are there more than 16?)
  >             1:RGB
  >       2: YUV
  >       3: ...
  >       4: RGB double precision floats ??
  >  (two spare bits :-)

  We should think very carefully before adding *any* extra colorspaces
  other than RGB.  For example, just by including YUV we would need to
  change ggi_color to be a union, like this :

      typedef union ggi_color
      {
          struct { uint16 r, uint16 g, uint16 b, uint16 a } rgb;
          struct { uint16 y, uint16 u, uint16 v, uint16 a } yuv;

      } ggi_color;

  and while I'm not completely against this, I think it is a *big* step
  to take and needs to be discussed at length.

  >  #define GT_MODE(x,bpp,consumed,sub) x+bpp+(consumed<<8)+(sub<<16)
  >  #define sp16a16r5g5b5A1rev GT_MODE(GT_RGB,15,16,1)
  >              /* 15 bit BGR 5/5/5 reverse endian */
  >  #define sp16a16b5g5r5A1 GT_MODE(GT_RGB,15,16,2)
  >              /* 15 bit RGB 5/5/5 native endian */

  Ok, Take II :

  The masks would be :

      #define GT_SCHEME_MASK     0xff000000
      #define GT_SUBSCHEME_MASK  0x00ff0000
      #define GT_ACCESS_MASK     0x0000ff00
      #define GT_DEPTH_MASK      0x000000ff

      #define GT_MODE(scheme,sub,access,depth)  \
              (scheme + (sub << 16) + (access << 8) + depth)

  The schemes would be :

      #define GT_RGB         0x01000000
      #define GT_INDEXED     0x02000000
      #define GT_GREYSCALE   0x03000000
      #define GT_TEXT        0x04000000

      (possible future additions: GT_YUV, GT_CMYK, ...)

  Here's how the current ggi_common_plb_setup values would be defined :

          ggi_common_plb_setup   scheme   sub-scheme  access  depth

          sp1a8lbl =            GT_MODE(GT_INDEXED, 1, 8, 1)
          sp1a8hbl =            GT_MODE(GT_INDEXED, 2, 8, 1)

          sp2a8lpl =            GT_MODE(GT_INDEXED, 1, 8, 2)
          sp2a8hpl =            GT_MODE(GT_INDEXED, 2, 8, 2)

          sp4a8lnl =            GT_MODE(GT_INDEXED, 1, 8, 4)
          sp4a8hnl =            GT_MODE(GT_INDEXED, 2, 8, 4)

          sp8a8i8  =            GT_MODE(GT_INDEXED, 1, 8, 8)

          sp16a16r5g5b5A1 =     GT_MODE(GT_RGB, 1, 16, 15)
          sp16a16r5g5b5A1rev =  GT_MODE(GT_RGB, 2, 16, 15)
          sp16a16b5g5r5A1 =     GT_MODE(GT_RGB, 3, 16, 15)
          sp16a16b5g5r5A1rev =  GT_MODE(GT_RGB, 4, 16, 15)

          sp16a16r5g6b5 =       GT_MODE(GT_RGB, 5, 16, 16)
          sp16a16r5g6b5rev =    GT_MODE(GT_RGB, 6, 16, 16)
          sp16a16b5g6r5 =       GT_MODE(GT_RGB, 7, 16, 16)
          sp16a16b5g6r5rev =    GT_MODE(GT_RGB, 8, 16, 16)

          sp24a8b8g8r8 =        GT_MODE(GT_RGB, 1, 8, 24)
          sp24a8r8g8b8 =        GT_MODE(GT_RGB, 2, 8, 24)

          sp32a32b8g8r8A8 =     GT_MODE(GT_RGB, 1, 32, 24)
          sp32a32b8g8r8A8rev =  GT_MODE(GT_RGB, 2, 32, 24)
          sp32a32r8g8b8A8 =     GT_MODE(GT_RGB, 3, 32, 24)
           sp32a32r8g8b8A8rev =  GT_MODE(GT_RGB, 4, 32, 24)

  Here's how the current graphtypes would be defined :

          #define GT_1BIT  GT_MODE(GT_INDEXED, 0, 0, 1)
          #define GT_2BIT  GT_MODE(GT_INDEXED, 0, 0, 2)
          #define GT_4BIT  GT_MODE(GT_INDEXED, 0, 0, 4)
          #define GT_8BIT  GT_MODE(GT_INDEXED, 0, 0, 8)

          #define GT_15BIT  GT_MODE(GT_RGB, 0, 0,  15)
          #define GT_16BIT  GT_MODE(GT_RGB, 0, 0,  16)
          #define GT_24BIT  GT_MODE(GT_RGB, 0, 8,  24)
          #define GT_32BIT  GT_MODE(GT_RGB, 0, 32, 24)

          #define GT_TEXT16  GT_MODE(GT_TEXT, 0, 16, 4)
          #define GT_TEXT32  GT_MODE(GT_TEXT, 0, 32, 4)
  ______________________________________________________________________



  1.1.2.6.  Erich Schubert, Jun 26


  ______________________________________________________________________
  > bits 7-0 contain the bits per pixel actually used,
  >     this means: padding bits are not counted, a 15 bpp mode has 15 here.
  >     I would like to suggest to count the number of *foreground colours*
  >     possible, which makes most text modes ==4.

  Where do you put blinking?
  To take the number of foreground colours is ok.
  But you might want to say, the standard VGA Textmode is 1 bpp + 2 attributes.
  Well you have the basic 8 colors, and the attributes highlight and blink.
  Some cards might also have underline or something like this.

  Just think of this, your idea is more practicable, but someone
  might find a even better one.
  ______________________________________________________________________



  1.1.3.  Older Opinions


     Andrew Apted































        ________________________________________________________________
        Now that the fbdev target is coming along, there is a need for libggi to
        support 2 bit, 3 bit, 5 bit, 6 bit and possibly 7 bit modes.  The
        simplest thing would be to add GT_2BIT, GT_3BIT, GT_5BIT, GT_6BIT and
        GT_7BIT constants to the ggi_graphtype enum, but I think there is a
        better way.

        What I'd like to see is something like this :

            #define GT_BPP_MASK   0x00ff
            #define GT_TYPE_MASK  0xff00

            #define GT_INDEXED    0x0100
            #define GT_RGB        0x0200
            #define GT_TEXT       0x0300
            #define GT_GRAYSCALE  0x0400
            #define GT_YUV        0x0500

        where the lowest 8 bits is just the depth (e.g. 8, 16, or whatever), and
        the upper 8 bits is the type (only a rough indication).  The current
        values would be mapped as follows :

           GT_1BIT    ->  GT_INDEXED + 1
            GT_4BIT    ->  GT_INDEXED + 4
            GT_8BIT    ->  GT_INDEXED + 8
            GT_15BIT   ->  GT_RGB + 15
            GT_16BIT   ->  GT_RGB + 16
            GT_24BIT   ->  GT_RGB + 24
            GT_32BIT   ->  GT_RGB + 32
            GT_TEXT16  ->  GT_TEXT + 16
            GT_TEXT32  ->  GT_TEXT + 32
        ________________________________________________________________



     Hartmut Niemann
        (Me) pointed out that Andrews proposal does not completely
        satisfy needs for requesting a graph type.




























        ________________________________________________________________
        #define GT_BPP_ORMORE  0x0080
        #define GT_BPP_ORLESS  0x0040

        so I can check a mode GR_RGB + 15+ GT_BPP_ORMORE to get at least
        15 high colour.

        the standard GGI_AUTO will be GT_RGB + 63+ GT_BPP_ORLESS
        (highest available), but GT_RGB + 0 + GT_BPP_ORMORE will make perfect
        sense and will give the lowest unpalettised mode.

        >
        >     #define GT_INDEXED    0x0100
        >     #define GT_RGB        0x0200
        >     #define GT_TEXT       0x0300
        >     #define GT_GRAYSCALE  0x0400
        >     #define GT_YUV        0x0500
        If this is and enumeration instead of a bit field, we run into trouble.
        It would make sense to request GT_INDEXED | GT_RGB|GT_YUV, but then the values
        need to be 0x0100, 0x200, 0x400 ...

        I think your system is superiour to what we had and very well suited
        for defining a certain mode, but for requesting a mode some additions
        (for more flexibility) are needed.
        And if 16 bits are too small, let's make the mode a ggi_uint32.
        Then GT_BPP_ORLESS = 1 <<8, ORMORE 1<<9, GT_INDEXED 1<<10 ...
        Nobody should mess with the values and bits on his own anyway.
        ________________________________________________________________



     Marcus Sundberg

        ________________________________________________________________

        > Of course you can still do a 'simple-mode-init' that takes the graphtypes,
        > but it should use the enhanced scheme.

        are supporting other hardware than common VGAcards.
        (No real meaning as in doesn't separate an 8 bit indexed mode from an
        8 bit YUV mode)

        The "simple-mode-init" should IMO use something like the proposed scheme.

        One more thing about modes:
        As we're supporting an increasing number of diffrent mode-types the
        complexity of mode negotiation gets more complex.

        My suggestion is that the driver exports a structure that gives
        complete information of what modes it support and which it doesn't
        support. The driver will then only check the validity of requested
        modes, and all GGI_AUTO handling/suggesting modes will be handled
        in userspace.

        After all modenegotiation needn't be in the kernel, and therefore
        it shouldn't.
        ________________________________________________________________


     and on Massimilano's comment (which is below):






     ___________________________________________________________________
     > One thing I don't understand is: we say nowhere that GT_15BIT actually consume
     s
     > 16bits for a pixel. Also, GT_32BIT actually uses only 24bits on most cards.
     > Don't we need to clean the depth/bpp separation like in XFree86?
     > (one is the _consumed_ bits in the framebuffer, the other the _actually_used_
     > bits)

     I think we should have a SetMode function that does no GGI_AUTO expansion
     and no suggestions if the mode can't be set. This function should take a
     mode struct (just like the current ggiSetMode()) which can be passed on
     to kernel-drivers without modification. This struct should separate
     depth/bpp, and other things currently not separated.

     And as I suggested earlier drivers should export a struct that tells
     which modes it can handle and which it can not.

     If we have this a piece of cake to implement every possible mode
     setting/querying/negotiation, and thus there's no need for discussion
     and no decissions to be made. If someone want a certain type of
     modenegotiation he will just implement it and if it works it will
     go into libggu.
     ___________________________________________________________________




     Massimiliano Ghilardi

        ________________________________________________________________
        > After all modenegotiation needn't be in the kernel, and therefore
        > it shouldn't.

        This is probably an important point. Mode _validation_ and _setting_
        must be in the kernel, but complex handling of AUTO settings, weird
        interactions between the various card components and thus the whole mode
        negotiation routines could probably be moved to a general userspace library,
        unless they are so small and simple (which I doubt) that keeping them in the
        kernel harms noone. Even if it will turn out that there are many card-specific
        rules and tricks, a card-specific userspace library for mode negotiation looks
        useful.


        Also, I agree that the current GT_xBIT are a bit limited, but the ORMORE/ORLESS
        thing seems unnecessary to me. We already decided that when a certain
        mode can't be done, we use the rule "increase settings if possible, otherwise
        decrease", that can be applied happily to graphmode types too.

        The following splitting instead looks nice to me (except for the values of the
        #defines)
        >     #define GT_INDEXED    0x0100
        >     #define GT_RGB        0x0200
        >     #define GT_TEXT       0x0300
        >     #define GT_GRAYSCALE  0x0400
        >     #define GT_YUV        0x0500


        One thing I don't understand is: we say nowhere that GT_15BIT actually consumes
        16bits for a pixel. Also, GT_32BIT actually uses only 24bits on most cards.
        Don't we need to clean the depth/bpp separation like in XFree86?
        (one is the _consumed_ bits in the framebuffer, the other the _actually_used_
        bits)
        ________________________________________________________________



     Brian Julin

        ________________________________________________________________
        How about these for masks:

        GT_BPP_MASK      = 0x00000000000000ff
        GT_ACHAN_MASK    = 0x0000000000000f00
        GT_ZBUFF_MASK    = 0x000000000000f000
        GT_PIX_LAYO_MASK = 0x0000000fffff0000
         /* For RGB layout red mask = 0x0f000000, etc. == # of bits red per pixel
            For YUV layout yel mask = 0x0f000000, etc.
            For 2D/3D chipsets alpha mask = 0xf0000000
            For 3D chipsets z mask = 0xf00000000 */
        GT_PIX_TYPE_MASK = 0x000000f000000000
         GT_INDEXED      = 0x0000008000000000  /*Can be combined with RGB, YUV, etc */
         GT_RGB          = 0x0000000000000000
         GT_TEXT         = 0x0000001000000000
         GT_GRAYSCALE    = 0x0000002000000000
         GT_YUV          = 0x0000003000000000
        GT_FB_LAYO_MASK  = 0x0fffff0000000000
         GT_PACKED_MASK  = 0x0000ff0000000000 /* # of packed pixels per plane */
         GT_PLANES_MASK  = 0x00ff000000000000 /* # of planes */
         GT_CUSTOM_LAYO  = 0x0800000000000000 /* For strangeness like MDA */
                /* For alpha or x channels in separate buffers */
         GT_ACHAN_SEP    = 0x0100000000000000 /* For separate alpha "plane" */
         GT_ZBUF_SEP     = 0x0200000000000000 /* For separate z-buffer "plane" */

                /* Examples:
                   VGA_MODEX  =  0x0004808006660008
                   PLANAR8_RGB = 0x0008000003320008
                */

        I think teunis had something thought of here as well.  Of course
        basic KGI drivers/driver-libs don't break these apart and analyse
        them, they just know the ones for their own layouts.
        ________________________________________________________________


     and on Massimiliano's comment:



























     ___________________________________________________________________
     On Fri, 17 Apr 1998, Massimiliano Ghilardi wrote:
     > > After all modenegotiation needn't be in the kernel, and therefore
     > > it shouldn't.
     >
     > This is probably an important point. Mode _validation_ and _setting_
     > must be in the kernel, but complex handling of AUTO settings, weird
     > interactions between the various card components and thus the whole mode
     > negotiation routines could probably be moved to a general userspace library,

     Yes, this is the general arrangement I want for the mode negotiation stuff
     I have.  Note the kernel still has to "negotiate" text modes to grab
     VC's when the module is inserted but this can be a much more basic
     algorithm than the userspace one.

     The in-kernel functions will merely examine the structure sent in
     from userspace and validate that it is within their capability to
     produce this timing/layout, and flag the offending fields if they
     cannot.  This should be pretty small/fast.  They will also be able to
     take clues from the request since it will be based on a structure
     they passed to userspace before mode negotiation, so they won't
     e.g. have to check both packed and modex to see if either one can fit
     the request; they will know which to used based on the offset in their
     structure to which the request refers.

     I want to see Steffen's strategy for separating FB layout from timings,
     which is sort of what I was doing when working on this.  They can
     pretty much be cleanly separated AFAIHS.
     ___________________________________________________________________




  1.2.  Color depth reporting

  Some means is necessary to report the colour depth of a display.
  unsigned int  ggiVisualBpp(vis) was suggested, which returns the bits
  per pixel actually used, i.e. ld(number of colours).

  The question is whether to pass a visual, a mode or a graphtype to it.


  1.3.  CLUT restore

  It has been agreed on that neither libggi nor its targets try to
  handle a screen redraw themselves.

  It is still unclear whether restoring the palette is done by the
  application (along te redraw action), or by the libggi (target).  Most
  targets have a local copy of the palette anyway, so it would be rather
  easy.


  1.4.  Inactivated applications

  If an application loses the 'attention', it will receive a SIGSTP.

  Most applications will be stopped, but for some (POVRAY) it could make
  sense to work in the background, especially if they keep a backbuffer
  anyway.

  Should such application catch SIGSTP and stop issuing drawing commands
  (then: how?) or can the target be made ignore all drawing requests
  (ggiSetInfoFlags(vis,GGI_IGNOREWHENINACTIVE) ???)?


  2.  Resolved issues



  2.1.  ggiCircle

  Is this going to be completely removed?


  2.1.1.  Decision

  Yes. It has been moved to libggi2d.



  2.2.  Reporting internal state

  There is currently no way to report information like the timing
  information to a ggilib application. At least for some diagnostics
  this might be useful.


  2.2.1.  Decision

  There was some very good discussion, and the most interesting points
  were:

  o  There is no interesting libggi state.

  o  The driver state (KGI state) is interesting to some diagnostic
     programs, but not to 'normal' applications.

  o  a /proc/ or /dev/ggistat-based solution is not very portable, so it
     can not be the only choice. It would be handy for debugging though.
     (Think Windows here :-)

  There was only one remark in favor of putting this functionality into
  the libggi, and a valid one, that too many small libraries will be
  impractical, and that a larger lib is easier to handle.

  So the final word from The Lord Of The Library is:

  o  we will want some interface to the driver state

  o  this does not go into LibGGI. It is simply not needed widely enough
     to justify adding this call to this library.

  o  as soon as need arises, some portable solution (some LibGGItweak)
     has to be suggested, implemented and discussed.



  2.3.  ggiGetRayPos, ggiWaitRayPos

  These two have been implemented for the SVGAlib target, but nowhere
  else.  Should these really become part of the libggi API, or should
  they move somewhere else? What are they supposed to do?

  2.3.1.  Decision

  The RayPos functions are CRT specific and are moved from libggi to an
  extension, libggimisc.




  2.4.  extensionInit/extensionExit, ggiInit, ggiExit


  2.4.1.  Decision


  o  ggiInit() and ggiExit() will get counting behaviour, because
     multiple ggiInit invocations are needed for extension library
     initialisation.

  o  ggiExit() will return the number of 'open' ggiInit's, i.e. after
     two ggiInit invocations, the first ggiExit will return 1 and don't
     do anything else, the second ggiExit will shut down the library and
     return 0 (i.e.  success), the third will return -1.



  2.5.  Removing the "display-" prefix

  It was suggested to drop the "display-" prefix from all LIBGGI_DISPLAY
  parameters. There was a very easy solution suggested (editing
  libggi.conf), so it's the political question: with the prefix or not,
  allow both and recommend one, then which?


  2.5.1.  Decision

  Both ways are allowed. A string that does not contain a dash ('-') is
  considered an abbreviation of and equivalent to 'display-' plus this
  string, so 'KGI' is equivalent to 'display-KGI'.


  2.6.  ggiPuts

  How should ggiPuts behave (if the string does not fit into the line)?


  2.6.1.  Decisions



  o  Clip, i.e. obey the clipping area.

     1. ggiPuts() always draws the characters in a single line;
        formatting characters like tab, newline, etc. are not treated
        specially (Only '\000' is treated specially: end of string. But
        that's C :-)

     2. text is always clipped by the clipping region (of course)

     3. if the text origin specified to ggiPuts() is outside the
        visual's clipping area (in any direction), the text is displayed
        anyway, clipped properly.

  o  ggiPut* is documented to work in text and graphics mode.

  o  there is a function to query the char cell size:

     ggi_error ggiGetCharCellSize(vis, int * width, int * height);

     (Note: please remember that the char cell size is not a *mode*
     property, except for text mode, where it is 1x1 by definition!)

  o  The font is guaranteed to be at least 8x8 (fixed for all chars) and
     nobody is encouraged to implement something bigger, except for good
     (hardware) reasons.  (Note: Once again, the ggiPuts implementation
     is dependent on the frame buffer layout, not on it's *size*.)

  o  ggiPuts supports only the basic ASCII charset, characters 0x20 to
     0x7f. As it is meant for simple debug output ar very simple GUIs,
     using 'national' characters is not recommended.

  o  ggiPuts will not support loadable hardware charsets. This is VGA-
     centric anyway and of limited use, and shouldn't go into the base
     library.  A libggitext is the right place for these functions, as
     it is for loadable fonts in general.


  2.7.  Alpha values

  There was the suggestion to enhance ggi_color, which currently holds
  three shorts for r,g, and b, with an additional alpha value
  (transparency).


  2.7.1.  Decision

  The ggi_color struct will have a  short a added, but the libggi itself
  will not use it.


  2.8.  Auxiliary buffers

  Some cards support auxiliary buffers like Z-Buffers. There is
  currently no method for requesting them.


  2.8.1.  Decision

  This is going to be solved outside the base libggi. The new extension
  methos allow overriding mode setting functions, so this type of
  requests is going to be handled by an extension library to the
  lkibggi.



  2.9.  Frames

  These changes are done to support multiple frames (screen 'pages' of
  the same size).


  o  The frames field in the ggi_mode struct indicates the number of
     screen buffers requested. It will default to 1.

  o  Frames will be numbered 0 ... <frameno> -1

  o  After mode setting frame 0 is active for reading, writing and
     display.

  o  Three additional functions are required, to switch between these
     frames for drawing, reading back (ggiGet*) and for displaying,
     e.g.:

  o  ggiSetDisplayFrame(vis, int frameno);

  o  ggiSetWriteFrame(vis, int frameno);

  o  ggiSetReadFrame(vis, int frameno);

     These return 0 if they succeed, and -1 if they fail.

  o  Three functions are added to read back the current frame:

  o  int ggiGetDisplayFrame(vis);

  o  int ggiGetWriteFrame(vis);

  o  int ggiGetReadFrame(vis);

     These return the frame number or -1, if they fail.

     Side note: setting different frames for reading and writing the
     screen is necessary to be able to copy across the frames.
     Separating that into two function calls makes the Get function
     easier - a ggiSetDrawingFrames(vis, src,dest) would lead to a
     ggiGetDrawingFrames(vis,&src,&dest) ...  I like this better (HN).

  o  The current ggiSet*Mode calls will not be changed. So this feature
     will currently be only accessible thru changing the mode struct and
     using ggiSetMode.



  2.10.  ggiCrossBlit

  This function is supposed to transfer pictures between different
  visuals.  It has been decided that this function will move somewhere
  else.

  There was the proposal to include a 'small' version that will copy
  from one visual to another, but without stretching/shrinking, and
  possibly without colour conversion.


  2.10.1.  Decision

  The full crossblit will be moved to libggi2d.

  A version without stretching, i.e. one that copies a rectangular piece
  from one visual to another visual, will be included:

  int ggiSimpleCrossBlit(ggi_visual_t src,int sx,int sy,int sw,int sh,
  ggi_visual_t dst,int dx,int dy);

  This will do colour conversion as necessary.


  2.11.  Palettes


  Several topics have been discussed, this is the final word:

  o  No start-up palette is guaranteed. While a target should have some
     default setting, this is not required.

  o  The palette setting is not necessarily kept on a focus switch, so
     when an application needs to redraw the screen, it has to re-set
     the palette as well.

  o  A len==0 will be legal for ggiSetPalette and ggiGetPalette, and
     allow for easy checking the existence. With a len 0 the functions
     will return 0 if there is a palette that can be set and read out,
     respectively, without moving any actual data, i.e. the ggi_color
     pointer may be NULL.

  o  A target may implement only ggiGetPalette, but not ggiSetPalette,
     if that makes sense (CGA, maybe Borland BGI).
  o  A new function is introduced to request the bpp of a display.  It
     has to be discussed whether it should take a mode, a graphtype or a
     visual as it's argument.

  o  A start value of GGI_AUTO allows the placement of the CLUT entries
     chosen by the target.

     The decision algorithm can be as complicated as you want, but it
     will normally very simple, and I see good reason for this.

  o  normally you put all entries into the palette you want to have at
     startup, so each application sets the palette only once.

  o  For all those applications that set only one palette at startup, it
     usually doesn't matter where in the CLUT a certain value is, as
     long as ggiMapColor works as expected.

  o  For a fullscreen mode, there is nobody competing about the CLUT, so
     set s=0. If you don't want to implement it differently, too.

  o  On X it might be good to allocate from the end, to have the
     'general' colours not messed up.  Wouter (?) said he had code to
     copy the system-wide X palette into a private one and to allocate
     some colours there.

  o  and if someone thinks he needs a real 'allocation' scheme, he'll be
     able to build one.


     Side note: most targets will place all entries at the beginning of
     the CLUT, assuming s=0, but some (in windowing targets especially)
     will use other schemes.


     If you know at program startup, that you will need n different
     colours, you set these n colours in the palette and don't care
     where.  Only very few programs will set the palette more than once
     AND want to retain old values.  For a windowing environment it
     could very well make sense to assign positions 0 to 20 to the
     window manager, 30 to 100 to app1, and 101 to 200 to app2. So if we
     leave this assignment to the library, it *might* help.  And if
     someone doesnt want to implement fancy strategies, if (s==GGI_AUTO)
     s=0; is all enhancements necessary.

     This leads to the following change in semantics:

  o  ggiSetPalette returns the number of the first entry changed (or -1
     for failure).

     Side note: This allows to find out where GGI_AUTO'ed entries were
     put.



  2.12.  Get/Put buffers: opaque or not?


  2.12.1.  Decision

  The buffers used by the ggiGet* and ggiPut* functions will be
  guaranteed to have several properties:


  o  The pixel layout used for Get/PutHline and friends is guaranteed to
     be the same as for the frame buffer (if there is a frame buffer).
     Then (either the direct buffer or the enhanced) mode struct (see
     the (memory) visual memory layout and graphtype chapters) carry
     this information.

  o  one pixel consumes either k bytes (packed true colour) or 2**n bits
     (covering 1,2,4-bpp modes).  If the hardware has other sizes (like
     30 bits), they will be padded. (This is IMHO needed to reduce bit-
     shifting). The buffer is guaranteed to have a maximum size
     width*height*sizeof (ggi_pixel).

  o  the pixels are stored linearly on all targets, i.e. a rectangle
     with a width of three and a height of two will be stored pixel
     (0,0) (1,0) (2,0) (0,1) (1,1), (2,1) in that order.

     Note: We need to care for strange things like 5x7 rectangles in
     2bpp modes!  Does the stride need to be an integral byte count?


  o  the exact pixel layout will define

  o  how many bits per pixel

  o  what colour model

  o  what bits are where (rrrrgggg as oposed to ggggrrrr) and will be
     part of the mode struct.

  o  ggiPackColors and ggiUnpackPixels pack/unpack complete buffers
     from/to ggi_colors and/or ggi_pixels. Maybe these have to be
     renamed, made more consistent, and maybe have to be split into
     several calls for boxes, hlines and vlines?


  2.13.  Memory visual memory layout


  2.13.1.  Decision

  The mode struct will be enhanced to provide information about the
  exact pixel layout. This information is not only needed to request
  'suitable' memory displays minimising crossblit work, but for
  get/putbuffer access as well.

  The first candidate is a struct ggi_mode member pixelfmt of
  ggi_common_plb_setup type.

  The canonical way for getting a memory visual of the same type as the
  main visual will be:

  ______________________________________________________________________
  ggi_mode memmode;
  ggi_visual_t mainvis,memvis;
   ...
  ggiGetMode(mainvis,&memmode);
  memvis=ggiOpen("memory",NULL);
  ggiCheckMode(memvis,&memmode);
  ggiSetMode(memvis,&memmode);
  ______________________________________________________________________





  2.14.  Graphics context save/resore

  It seems to me that the application is guaranteed that all graphics
  state is saved and restored transparently (including the CLUT) except
  for the screen content itself, where the application is supposed to
  redraw after receiving an appropriate redraw event.


  2.15.  Behaviour on switch-away and switch-back



  2.15.1.  What is this about?

  What has to be done when a program is switched away (either the window
  (in X) becomes inactive, or the VT is switched), and on re-activation?

  This is currently not defined at all.

  What are the options for each case? What are pros/cons?  How can this
  be implemented?

  Is the application notified? How? Does it get a chance to save screen
  content, does it need to? Time limit for that?


  2.15.2.  Decision

  If an application is deactivated, depending on the target it may be
  stopped.

  An application can receive several events, for updating screen size,
  or redrawing or ... (I don't have a documentation about these events
  yet - HN).




































