/*
***************************************************************************
*
* Datei:
*    RSysGfxIntuiLists.c
*
* Inhalt:
*    void MakeFontList(void);
*    void MakeWindowList(void);
*    void MakeScreenList(void);
*    void SysPubScreenList(void);
*    void RSysGetDisplayModes(void);
*    void SysTOFWaitList(void);
*    void SysBlitterWaitList(void);
*
* Bemerkungen:
*    Listen der Graphics- und Intuition-Library.
*    (Teilweise ausgelagert aus RSysSpecialLists.c)
*
* Erstellungsdatum:
*    07-Jul-93    Rolf Böhme
*
* Änderungen:
*    07-Jul-93    Rolf Böhme    Erstellung
*
***************************************************************************
*/

#include "RSysFunc.h"
#include "RSysDebug.h"

   /*
    * MakeFontList() erzeugt eine Liste aller im System in der
    * GfxBase definierten Fonts
    */
void
MakeFontList(void)
{
   struct Node *node;
   struct TextFont *font;
   int   i = 0;

   DPOS;

   countentries = CountNodes(&GfxBase->TextFonts);

   if (NoEntries())
      return;

   Entries = AllocScrollEntries(countentries);

   Forbid();

   for (node = GfxBase->TextFonts.lh_Head;
        node->ln_Succ && (i < countentries); node = node->ln_Succ)
   {
      font = (struct TextFont *) node;

      Entries[i].se_obj_id.address = font;
      savestrcpy(Entries[i].se_obj_id.fullname, node,
                 MAXFULLNAME - 1, NT_FONT);

      sprintf(Entries[i].se_Entry, EntryAttr[FONTS].ea_dataformat,
              Entries[i].se_obj_id.fullname,
              ((font->tf_Flags & FPF_DISKFONT) ? "Disk" : "ROM"),
              font->tf_YSize,
              font->tf_XSize,
              font->tf_LoChar,
              font->tf_HiChar);

      i++;
   }

   countentries = i;

   Permit();

   CreateEntryList(SORT);

   return;
}

   /*
    * MakeWindowList() erzeugt eine Liste der offenen Windows im
    * System. Dazu werden alle geöffneten Screens durchsucht
    */
void
MakeWindowList(void)
{
   ULONG lock;
   struct Window *win;
   struct Screen *scr;
   char scrtitle[11];
   int   i = 0;

   DPOS;

   countentries = CountIntuiObjects((int)GD_WindowsGad);

   if (NoEntries())
      return;

   Entries = AllocScrollEntries(countentries);

   lock = LockIBase(NULL);

   for (scr = IntuitionBase->FirstScreen; scr && (i < countentries);
        scr = scr->NextScreen)
      for (win = scr->FirstWindow; win && (i < countentries);
           win = win->NextWindow)
      {
         Entries[i].se_obj_id.address = win;

         if ((char *)win->Title)
            strncpy(Entries[i].se_obj_id.fullname,
                    (char *)win->Title, MAXFULLNAME - 1);
         else
            strcpy(Entries[i].se_obj_id.fullname, field[NO_TITLE]);

         if ((char *)scr->DefaultTitle)
            strncpy(scrtitle, (char *)scr->DefaultTitle, 10);
         else
            strcpy(scrtitle, field[NO_TITLE]);

         sprintf(Entries[i].se_Entry, EntryAttr[WINDOWS].ea_dataformat,
                 Entries[i].se_obj_id.fullname,
                 win->Height,
                 win->Width,
                 win->LeftEdge,
                 win->TopEdge,
                 scrtitle);

         i++;
      }

   countentries = i;

   UnlockIBase(lock);

   CreateEntryList(SORT);

   return;
}

   /*
    * MakeScreenList() erzeugt eine Liste aller geöffneten Screens
    */
void
MakeScreenList(void)
{
   ULONG lock;
   struct Screen *scr;
   int   i = 0;
   char pub[5];

   DPOS;

   countentries = CountIntuiObjects((int)GD_ScreensGad);

   if (NoEntries())
      return;

   Entries = AllocScrollEntries(countentries);

   lock = LockIBase(NULL);

   for (scr = IntuitionBase->FirstScreen; scr && (i < countentries);
        scr = scr->NextScreen)
   {
      Entries[i].se_obj_id.address = scr;

      if (scr->Title)
         strncpy(Entries[i].se_obj_id.fullname, (char *)scr->Title, MAXFULLNAME - 1);
      else
         strcpy(Entries[i].se_obj_id.fullname, field[NO_TITLE]);

      strcpy(pub, "   ");

      if ((scr->Flags & WBENCHSCREEN) == WBENCHSCREEN)
         pub[0] = 'W';

      if ((scr->Flags & PUBLICSCREEN) == PUBLICSCREEN)
         pub[1] = 'P';

      if ((scr->Flags & CUSTOMSCREEN) == CUSTOMSCREEN)
         pub[2] = 'C';

      sprintf(Entries[i].se_Entry, EntryAttr[SCREENS].ea_dataformat,
              Entries[i].se_obj_id.fullname,
              scr->Height, scr->Width, scr->LeftEdge, scr->TopEdge,
              pub);

      i++;
   }

   countentries = i;

   UnlockIBase(lock);

   CreateEntryList(SORT);

   return;
}

   /*
    * SysPubScreenList() zeigt alle im System angemeldeten
    * Public Screens an
    */
void
SysPubScreenList(void)
{
   struct Node *node;
   struct Screen *scr;
   struct PubScreenNode *PSNodes;
   struct List *PSList = NULL;
   char name[20],taskname[16];
   int   i = 0;

   DPOS;

   PrintHeader(SYSPUBSCR, NULL);

   EmptyListView();

   PSList = LockPubScreenList();
   countentries = CountNodes(PSList);
   UnlockPubScreenList();

   if (NoEntries())
      return;

   PSNodes = (struct PubScreenNode *) MyAllocVec(countentries*sizeof(struct PubScreenNode),
                                               MEMF_ANY | MEMF_CLEAR, NO_KILL);

   if(!PSNodes)
      return;

   PSList = LockPubScreenList();

   for (node = PSList->lh_Head;
        node->ln_Succ && (i < countentries); node = node->ln_Succ)
      CopyMem(node,&PSNodes[i++],sizeof(struct PubScreenNode));

   UnlockPubScreenList();

   Entries = AllocScrollEntries(countentries);

   for (i = 0; i < countentries; i++)
   {
      scr = PSNodes[i].psn_Screen;

      savestrcpy(name,&(PSNodes[i].psn_Node),19, NT_UNKNOWN);

      Forbid();

      if(PSNodes[i].psn_SigTask)
         savestrcpy(taskname,&PSNodes[i].psn_SigTask->tc_Node, 15, NT_TASK);
      else
         strcpy(taskname,field[NO_TASK]);

      Permit();

      sprintf(Entries[i].se_Entry, EntryAttr[24].ea_dataformat,
              PSNodes[i].psn_Screen,
              name,
              PSNodes[i].psn_VisitorCount,
              taskname);
   }

   MyFreeVec(PSNodes);

   CreateEntryList(SORT);

   PrintStatistics();

   return;
}

void
RSysGetDisplayModes(void)
{
   struct DisplayInfo dinfo;
   struct NameInfo    ninfo;
   struct DisplayNode {
      struct Node          dn_Node;
      struct DisplayInfo   dn_dinfo;
      struct NameInfo      dn_ninfo;
      struct DimensionInfo dn_diminfo;
   }
   *dnode,*copydnode;
   struct Node *dispnode;
   struct List *DispList;
   ULONG modeID = INVALID_ID;
   struct Remember *DispKey = NULL;
   int i;

   DPOS;

   PrintHeader(DISPLAYMODES, NULL);

   EmptyListView();

   DispList = AllocRemember(&DispKey,sizeof(struct List),MEMF_CLEAR);
   if(DispList)
   {
      NewList(DispList);

      while ((modeID = NextDisplayInfo (modeID)) != INVALID_ID)
      {
         if (GetDisplayInfoData (NULL, (UBYTE *) &dinfo, sizeof(dinfo),
                                 DTAG_DISP,modeID))
         {
            if ((dinfo.NotAvailable == 0) && (modeID & MONITOR_ID_MASK))
            {
                  /*
                   * Hier gelangt das Programm nur dann hin, wenn
                   * der Modus verfügbar ist und nicht der
                   * Default-Monitor benötigt wird, sondern ein
                   * PAL-, NTSC- oder andere Monitore
                   */
               if (GetDisplayInfoData (NULL,(UBYTE *) &ninfo, sizeof(ninfo),
                                       DTAG_NAME,modeID))
               {
                  if(dnode = AllocRemember(&DispKey,sizeof(struct DisplayNode),
                                           MEMF_CLEAR|MEMF_PUBLIC))
                  {
                     if(dnode->dn_Node.ln_Name = AllocRemember(&DispKey,
                                                               strlen((char *)ninfo.Name) +1,
                                                               MEMF_CLEAR|MEMF_PUBLIC))
                     {
                        strcpy (dnode->dn_Node.ln_Name, (char *)ninfo.Name);

                        GetDisplayInfoData (NULL,(UBYTE *) &(dnode->dn_diminfo),
                                            sizeof(struct DimensionInfo),
                                            DTAG_DIMS, modeID);

                        GetDisplayInfoData (NULL, (UBYTE *) &(dnode->dn_dinfo),
                                            sizeof(struct DisplayInfo),
                                            DTAG_DISP, modeID);

                        AddTail(DispList, (struct Node *) dnode);
                     }
                  }
               }
            }
         }
      }

      countentries = CountNodes(DispList);

      if(!NoEntries())
      {
         Entries = AllocScrollEntries(countentries);

         for(dispnode = (struct Node *)DispList->lh_Head, i = 0;
             dispnode->ln_Succ && (i < countentries);
             dispnode = dispnode->ln_Succ)
         {
            copydnode = (struct DisplayNode *)dispnode;
            sprintf(Entries[i].se_Entry, EntryAttr[30].ea_dataformat,
                    copydnode->dn_Node.ln_Name,
                    copydnode->dn_diminfo.MaxDepth,
                    copydnode->dn_diminfo.MinRasterWidth,
                    copydnode->dn_diminfo.MinRasterHeight,
                    copydnode->dn_diminfo.MaxRasterWidth,
                    copydnode->dn_diminfo.MaxRasterHeight);

            i++;
         }

         CreateEntryList(SORT);
      }

      FreeRemember(&DispKey,TRUE);

      PrintStatistics();
   }
   else
      ErrorHandle(MEMORY_ERR, ALLOC_FAIL, KILL);

   return;
}

void
SysTOFWaitList(void)
{
   struct Node *node;
   struct Node *TWQNodes;
   char name[20];
   int   i = 0;

   DPOS;

   PrintHeader(TOFWAIT, NULL);

   EmptyListView();

   countentries = CountNodes(&GfxBase->TOF_WaitQ);

   if (NoEntries())
      return;

   TWQNodes = (struct Node *)MyAllocVec(countentries*sizeof(struct Node),
                                        MEMF_ANY | MEMF_CLEAR, NO_KILL);

   if(!TWQNodes)
      return;

   Disable();

   for (node = GfxBase->TOF_WaitQ.lh_Head;
        node->ln_Succ && (i < countentries); node = node->ln_Succ)
      CopyMem(node,&TWQNodes[i++],sizeof(struct Node));

   Enable();

   Entries = AllocScrollEntries(countentries);

   for (i = 0; i < countentries; i++)
   {
      savestrcpy(name,&TWQNodes[i],19, NT_TASK);

      sprintf(Entries[i].se_Entry, EntryAttr[24].ea_dataformat,
              name,
              TWQNodes[i].ln_Pri );
   }

   MyFreeVec(TWQNodes);

   CreateEntryList(SORT);

   PrintStatistics();

   return;
}

   /*
    * SysBlitterWaitList() erzeugt eine Liste aller Tasks,
    * die auf den Blitter warten. Diese Liste ist in der
    * GfxBase (graphics.library) zu finden
    */
void
SysBlitterWaitList(void)
{
   struct Node *node;
   struct Node *BWQNodes;
   char name[20];
   int   i = 0;

   DPOS;

   PrintHeader(BLITTERWAIT, NULL);

   EmptyListView();

   countentries = CountNodes(&GfxBase->BlitWaitQ);

   if (NoEntries())
      return;

   BWQNodes = (struct Node *) MyAllocVec(countentries*sizeof(struct Node),
                                         MEMF_ANY | MEMF_CLEAR, NO_KILL);

   if(!BWQNodes)
      return;

   Disable();

   for (node = GfxBase->BlitWaitQ.lh_Head;
        node->ln_Succ && (i < countentries); node = node->ln_Succ)
      CopyMem(node,&BWQNodes[i++],sizeof(struct Node));

   Enable();

   Entries = AllocScrollEntries(countentries);

   for (i = 0; i < countentries; i++)
   {
      savestrcpy(name,&BWQNodes[i],19, NT_TASK);

      sprintf(Entries[i].se_Entry, EntryAttr[24].ea_dataformat,
              name,
              BWQNodes[i].ln_Pri );
   }

   MyFreeVec(BWQNodes);

   CreateEntryList(SORT);

   PrintStatistics();

   return;
}

#define SETFLAG(gad,flag) ((((gad)->GadgetType)&(flag))==(flag))

static void
gadgetinfo(struct Gadget *gad, int i)
{
   char title[15], typ[7];

   if(gad->GadgetText && gad->GadgetText->IText)
      strncpy(title, (char *)(gad->GadgetText->IText), 15);
   else if(gad->GadgetRender || gad->SelectRender)
      strcpy(title, "<has image>");
   else
      strcpy(title, field[NO_FIELD]);

   if(SETFLAG(gad,GTYP_SYSGADGET))
      strcpy(typ,"SYS");
   else if(SETFLAG(gad,GTYP_SCRGADGET))
      strcpy(typ,"SCR");
   else if(SETFLAG(gad,GTYP_GZZGADGET))
      strcpy(typ,"GZZ");
   else if(SETFLAG(gad,GTYP_REQGADGET))
      strcpy(typ,"REQ");
   else
      strcpy(typ,"CUS");

   if(SETFLAG(gad, GTYP_WDRAGGING))
      strcat(typ,"WDR");
   else if(SETFLAG(gad, GTYP_SDRAGGING))
      strcat(typ,"SDR");
   else if(SETFLAG(gad, GTYP_WUPFRONT))
      strcat(typ,"WUP");
   else if(SETFLAG(gad, GTYP_SUPFRONT))
      strcat(typ,"SUP");
   else if(SETFLAG(gad, GTYP_WDOWNBACK))
      strcat(typ,"WDO");
   else if(SETFLAG(gad, GTYP_SDOWNBACK))
      strcat(typ,"SDO");
   else if(SETFLAG(gad, GTYP_CLOSE))
      strcat(typ,"CLO");
   else if(SETFLAG(gad, GTYP_BOOLGADGET))
      strcat(typ,"BOO");
   else if(SETFLAG(gad, GTYP_GADGET0002))
      strcat(typ,"G02");
   else if(SETFLAG(gad, GTYP_PROPGADGET))
      strcat(typ,"PRO");
   else if(SETFLAG(gad, GTYP_STRGADGET))
      strcat(typ,"STR");
   else if(SETFLAG(gad, GTYP_CUSTOMGADGET))
      strcat(typ,"CUS");
   else if(SETFLAG(gad, GTYP_SIZING))
      strcat(typ,"SIZ");
   else
      strcat(typ,"UNK");

   sprintf(Entries[i].se_Entry, EntryAttr[ALLGADGETS].ea_dataformat,
           title, typ, gad->LeftEdge, gad->TopEdge, gad->Width,
           gad->Height);

   return;
}
   /*
    * MakeWindowList() erzeugt eine Liste der offenen Windows im
    * System. Dazu werden alle geöffneten Screens durchsucht
    */
void
RSysGadgetList(void)
{
   ULONG lock;
   struct Window *win;
   struct Screen *scr;
   struct Gadget *gad;
   int   i = 0;

   DPOS;

   PrintHeader(ALLGADGETS, NULL);

   EmptyListView();

   countentries = 0;

   PrintInfo("Please wait! Lock Intuition...", NO_SPEAK, 0);

   lock = LockIBase(NULL);

   for (scr = IntuitionBase->FirstScreen; scr; scr = scr->NextScreen)
   {
      countentries++;

      for(gad = scr->FirstGadget; gad; gad = gad->NextGadget)
          countentries++;

      for (win = scr->FirstWindow; win; win = win->NextWindow)
      {
         countentries++;

         if(win->FirstRequest)
            for(gad = win->FirstRequest->ReqGadget; gad; gad = gad->NextGadget)
               countentries++;

         for(gad = win->FirstGadget; gad; gad = gad->NextGadget)
            countentries++;
      }
   }

   UnlockIBase(lock);

   if (NoEntries())
      return;

   Entries = AllocScrollEntries(countentries);

   PrintInfo("Please wait! Lock Intuition again...", NO_SPEAK, 0);

   lock = LockIBase(NULL);

   for (scr = IntuitionBase->FirstScreen; scr && (i < countentries); scr = scr->NextScreen)
   {
      if (scr->Title)
         sprintf(Entries[i++].se_Entry,"* SCR: %-20.20s", (char *)scr->Title);
      else
         sprintf(Entries[i++].se_Entry,"* SCR: %s", field[NO_TITLE]);

      for(gad = scr->FirstGadget; gad && (i < countentries); gad = gad->NextGadget)
         gadgetinfo(gad, i++);

      for (win = scr->FirstWindow; win && (i < countentries); win = win->NextWindow)
      {
         if ((char *)win->Title)
            sprintf(Entries[i++].se_Entry,"** WIN: %-20.20s", (char *)win->Title);
         else
            sprintf(Entries[i++].se_Entry,"** WIN: %-20.20s", field[NO_TITLE]);

         if(win->FirstRequest)
            for(gad = win->FirstRequest->ReqGadget; gad && (i < countentries);
                gad = gad->NextGadget)
               gadgetinfo(gad, i++);

         for(gad = win->FirstGadget; gad && (i < countentries); gad = gad->NextGadget)
            gadgetinfo(gad, i++);
      }
   }

   countentries = i;

   UnlockIBase(lock);

   CreateEntryList(NO_SORT);

   PrintStatistics();

   return;
}
