#include <intuition/intuitionbase.h>
#include <graphics/displayinfo.h>
#include <graphics/gfxbase.h>
#include <clib/intuition_protos.h>
#include <clib/graphics_protos.h>
#include <clib/exec_protos.h>
#include <stdio.h>

struct IntuitionBase *IntuitionBase;
struct GfxBase       *GfxBase;
struct Screen        *Workbench;
struct BitMap        *BitMap;
struct DisplayInfo    DisplayInfo;
struct DimensionInfo  DimensionInfo;

ULONG                 DisplayID;
ULONG                 Flags;
ULONG                 BitMapDepth, BitMapWidth;
WORD                  MaxDepth;
UWORD                 NumSprites;

int main(void)
{
  if(IntuitionBase = (struct IntuitionBase *)
      OpenLibrary("intuition.library",37))
  {
    if(GfxBase = (struct GfxBase *)
        OpenLibrary("graphics.library",37))
    {
      if(Workbench = LockPubScreen("Workbench"))
      {
        DisplayID = GetVPModeID(&Workbench -> ViewPort);

        /*
         * Farbtiefe der Workbench bestimmen
         */

        if(GetDisplayInfoData(NULL, (APTR)&DimensionInfo,
            sizeof(struct DimensionInfo), DTAG_DIMS,
            DisplayID))
        {
            MaxDepth = DimensionInfo . MaxDepth;
            printf("Maximale Tiefe für 0x%08x = %d "
                   "(%d Farben)\n", DisplayID, MaxDepth,
                   1L << MaxDepth);
        }

        /*
         * Bittiefen der einzelnen Farben bestimmen
         */

        if(GetDisplayInfoData(NULL, (APTR)&DisplayInfo,
            sizeof(struct DisplayInfo), DTAG_DISP, DisplayID))
        {
          if(GfxBase -> LibNode . lib_Version < 39)
          { LONG i;
            for(i = 1 ; i < 16 ; i++)
            {  if(i * i * i >= DisplayInfo.PaletteRange)
                   break;
            }

            printf("Palette für 0x%08lx: %d × %d × %d = "
                   "%d Farbwerte\n",DisplayID,i,i,i,
                   DisplayInfo . PaletteRange);
          }
          else
          { printf("Palette für 0x%08lx: %d × %d × %d = "
                   "%d Farbwerte\n", DisplayID,
              1L << DisplayInfo . RedBits,
              1L << DisplayInfo . GreenBits,
              1L << DisplayInfo . BlueBits,
              (1L << DisplayInfo . RedBits)   *
              (1L << DisplayInfo . GreenBits) *
              (1L << DisplayInfo . BlueBits)    );
          }
        }

        /*
         * BitMap-Eigenschaften bestimmen
         *
         * Hinweis: Statt &Workbench->BitMap ist
         *                 Workbench->RastPort.BitMap vorzuziehen
         */

        BitMap = Workbench->RastPort.BitMap;
        Flags = GetBitMapAttr(BitMap,BMA_FLAGS);
        printf("BitMap-Eigenschaften des Workbench-Screens:\n");

        if(Flags & BMF_STANDARD)
            printf("Die Grafikdaten liegen als Bitplanes"
                   " im Chip-RAM vor.\n");
        else
            printf("Diese BitMap wurde vom Grafikkartentreiber"
                   " erzeugt.\n");

        /*
         * BitMap-Daten auslesen
         *
         * Wichtig: immer die BitMap aus dem RastPort des
         *      Screens verwenden, *niemals* Screen->BitMap. */

        BitMap = Workbench -> RastPort . BitMap;
        printf("Workbench im Modus 0x%08x, %d x %d\n",DisplayID,
            Workbench -> Width,Workbench -> Height);

        /* So sollte man es eigentlich nicht machen, aber
         * dieses Programmstück dient nur der Demonstration. */
        printf("BytesPerRow = %d Depth = %d\n",
                BitMap->BytesPerRow, BitMap -> Depth);

        /* So fragt man Informationen über die BitMap ab. */
        if(GfxBase -> LibNode . lib_Version >= 39)
        {
            BitMapDepth = GetBitMapAttr(BitMap,BMA_DEPTH);
            BitMapWidth = GetBitMapAttr(BitMap,BMA_WIDTH);
            printf("BitMap: Depth %d\n",BitMapDepth);
            printf("BitMap: Width %d\n",BitMapWidth);
        }

        /*
         * Größe des Bildschirmbereichs bestimmen
         */

        if(GetDisplayInfoData(NULL, (APTR)&DimensionInfo,
            sizeof(struct DimensionInfo), DTAG_DIMS, DisplayID))
        {
            printf("Minimale Größe für 0x%08x = %d x %d\n",
                    DisplayID, DimensionInfo.MinRasterWidth,
                               DimensionInfo.MinRasterHeight);

            printf("Maximale Größe für 0x%08x = %d x %d\n",
                    DisplayID, DimensionInfo.MaxRasterWidth,
                               DimensionInfo.MaxRasterHeight);
        }

        /*
         * Anzahl der verfügbaren Sprites bestimmen
         */

        if(GetDisplayInfoData(NULL,(APTR)&DisplayInfo,
            sizeof(struct DisplayInfo),DTAG_DISP, DisplayID))
        {
            NumSprites = DisplayInfo . NumStdSprites;
            printf("Anzahl Sprites für 0x%08x = %d\n",
                DisplayID,NumSprites);
        }

        UnlockPubScreen(NULL,Workbench);
      }
      CloseLibrary(GfxBase);
    }
  CloseLibrary(IntuitionBase);
  }
  return(0);
}
