 /**************************************************************************
 * Lattice-C-Compiler-V4.0-Tool V2.11                                      *
 * ----------------------------------                                      *
 *                                                                         *
 * (c) 1988 by Frank Langbein                                              *
 * Designed and Programed by Frank Langbein                                *
 *                                                                         *
 * Contact: Frank Langbein                                                 *
 *          Neuer Ring 21                                                  *
 *          8643 Kueps 4 (West Germany)                                    *
 *                                                                         *
 ***************************************************************************
 * Modification History:                                                   *
 * ---------------------                                                   *
 *                                                                         *
 * Date       |Author           |Comment                                   *
 *-------------------------------------------------------------------------*
 * 04-05-1988 |Frank Langbein   |Created this File (V1.0)                  *
 * 04-24-1988 |Frank Langbein   |LCT now uses Workbench-Screen (V1.1)      *
 * 06-22-1988 |Frank Langbein   |Debugging and some new things added       *
 *            |                 |              (V2.0)                      *
 * 12-24-1988 |Frank Langbein   |Debugging (V2.1)                          *
 * 05-01-1989 |Frank Langbein/Wa|Debugging (V2.11) 
*-------------------------------------------------------------------------*
 **************************************************************************/

#include "MyIncludes.h"    /* Variablen und Definitionen einlesen */

void main(argc,argv)
int argc;            /* Anzahl der eingegebenen Argumente */
char *argv[];        /* Argumente in der Reihenfolge ihrer Eingabe */

                     /* argv[0] enthaelt den Namen des aufgerufenen */
                     /* Programms */
{
   register FILE *fp;
   register int i,j;

   /* Argumente bei der Eingabe bearbeiten */

   if(argc > 5)    /* Zu viele Argumente bei der Eingabe */
   {
      printf("Too many Arguments!\n");
      exit(0);
   }
   if(argc != 0) 
      if(*argv[1] == '?') /* Beim Aufruf wurde ? eingegeben, um den Syntax */
      {                   /* zu erfahren */
         printf("%s [<Editor> [<WProcessor> [<Program> [<CLI>]]]]\n",argv[0]);
         exit(0);
      }
      else
      {
         if(argc > 1) /* Das erste Argument wird als Name fuer den Editor */
         {            /* verwendet */
            strcpy(&Editor[0],argv[1]);
            strcat(&Editor[0]," ");
         }
         if(argc > 2) /* Das zweite Argument wird als Name fuer das */
         {            /* Textvararbeitungssystem verwendet */
            strcpy(&WProcessor[0],argv[2]);
            strcat(&WProcessor[0]," ");
         }
         if(argc > 3) /* Das dritte Argument gibt das Programm an, das */
         {            /* ueber ein Gadget von LCT aufgerufen werden kann */
            strcpy(&Pref[0],argv[3]);
            i = strlen(&Pref[0])-17;
            if(i < 0)
               i = 0;
            TPref.IText = TTPref.IText = &Pref[i];
            TPref.LeftEdge = TTPref.LeftEdge = 78-(4*strlen(&Pref[i]));
         }
         if(argc > 4) /* Das vierte Argument gibt den Namen der Shell an,
                      /* die ueber CLI gestartet wird */
            strcpy(&CLIName[0],argv[4]);
      }

   /* Intuition- und Grafik-Bibliothek oeffnen */

   if((IntuitionBase = (struct IntuitionBase *)
                       OpenLibrary("intuition.library",0))==0)
      CleanUp("Can't open Intuition",0);
   if((GfxBase = (struct GfxBase *) OpenLibrary("graphics.library",0))==0)
      CleanUp("Can't open Graphics",1);

   /* Initialisierung */

   Init(); /* Bildschirmaufbau erstellen */
   if(access("LCT-ASSIGN",0) == 0) /* Definitionen fuer ASSIGN laden und  */
      Assign();                    /* definieren, wenn LCT-ASSIGN geladen */
                                   /* werden kann */
   ClearPointer(MainWindow);
   ls = quit = FALSE;
   lnc = -1;

   /* Hauptprogramm */

   while(quit == FALSE) /* Programm solange ausfuehren, bis QUIT */
                        /* angeklickt wurde */
   {
      Wait(1<<MainWindow->UserPort->mp_SigBit); /* Auf IntuitionMessage warten */
      while(message = (struct IntuiMessage *)GetMsg(MainWindow->UserPort))
      {
         if(message->Class == GADGETUP) /* Gadget wurde angeklickt */
         {
            SetPointer(MainWindow,WPointer,1,9,0,0); /* Neuer Mauszeiger */
            GID = ((struct Gadget *)message->IAddress)->GadgetID; /* Nummer des Gadgets */
            ReplyMsg((struct Message *)message); /* Nachricht an Intuition zurueckgeben */
            switch(GID) /* Routine fuer Gadget auswaehlen */
            {
               case 1:     /* File-StringGadget wurde angegklickt */
                  if(strcmp(lname[lnc],&BUFile[0]) != 0)
                     lnc = -1; /* Nummer in der File Liste auf -1 setzen, */
                               /* wenn der eingegebene Name nicht mit dem */
                               /* Namen des vorherigen Files in der Liste */
                               /* uebereinstimmt */
                  break;
               case 2:     /* Optionen-StringGadget wurde angeklickt   */
                  if(lnc != -1)  /* Wenn das File in der Liste steht, */
                                 /* werden die Optionen in der Liste  */
                                 /* fuer dieses File geaendert        */
                  {
                     strcpy(lopt[lnc],&BUOpt[0]);
                     ls = FALSE;
                     ShowList();
                  }
                  break;
               case 3:     /* Programm-StringGadget wurde angeklickt */
                  if(strcmp(lprog[lnc],&BUProg[0]) != 0)
                     lnc = -1;   /* Stimmt der alte Programmname nicht */
                                 /* mit dem neuen ueberein, wird die   */
                                 /* Verbindung zwischen StringGadgets  */
                                 /* und Liste aufgeloest */
                  break;
                case 4:     /* Linkfile-StringGadget wurde angeklickt */
                  if(access(&BULink[0],0) != 0)     /* Existiert das LinkFile     */
                     StartEditor(&Editor[0],&SLink);/* nicht, wird der Editor     */
                                                    /* fuer dieses File gestartet */
                  break;
               case 7:     /* Output-Gadget wurde angeklickt */
                  Type("LCT.output");  /* LCT.output anzeigen */
                  break;
               case 8:     /* Compile All-Gadget wurde angeklickt */
                  if(SProg.NumChars != 0 && size != 0)
                     /* Es Existiert eine Programmliste und ein Programmname */
                     /* im Programm-Stringgadget */
                  {
                     if(BoolRequest("Copy Files to RAM: ?","",MainWindow,
                                  234,102,172,50,2,1,4,0) == TRUE)
                        i = TRUE;   /* Benutzer ueber Request fragen, ob */
                     else           /* er die Files im RAM compilieren   */
                        i = FALSE;  /* will */
                     PrintText(MainWindow->RPort,"Options:",4,250,2,0);
                     BUI[0] = '\0';
                     SmallInput(); /* Allgemeine Optionen fuer Compiler */
                                   /* eingeben */
                     CompStart();  /* Alles fuer Compile-Vorgang vorbereiten */
                     /* Programmliste nach Programmnamen durchsuchen */
                     for(j=0;j<size;j++)
                        if(strcmp(lprog[j],&BUProg[0]) == 0)
                           /* Name mit dem im Programm-Gadget identisch */
                        {
                           if(i == TRUE && strncmp("RAM:",lname[j],4) != 0)
                             /* File ins RAM-kopieren, wenn Benutzer dies will */
                           {
                              strsfn(lname[j],&a[0],&b[0],&c[0],&d[0]);
                              strmfn(&UB[0],"RAM:",0,&c[0],&d[0]);
                              Copy(lname[j],&UB[0]); /* File kopieren */
                           }
                           else
                              /* File auf Disk lassen */
                           {
                              i = FALSE;
                              strcpy(&UB[0],lname[j]);
                           }
                           /* Compileraufruf vorbereiten */
                           strcpy(&Buffer[0],&BUI[0]);
                           strcat(&Buffer[0]," ");
                           strcat(&Buffer[0],lopt[j]);
                           Comp(&UB[0],&Buffer[0]); /* Compiler starten */
                           if(i == TRUE)
                           {
                              /* File aus dem RAM zurueck auf Diskette */
                              /* kopieren und aus dem RAM loeschen */
                              strcpy(&Buffer[0],&UB[0]);
                              strmfe(&comand[0],&UB[0],"o");
                              strmfe(&UB[0],lname[j],"o");
                              if(access(&comand[0],0) == 0)
                              {
                                 Copy(&comand[0],&UB[0]);
                                 DeleteFile(&comand[0]);
                              }
                              if(access(&Buffer[0],0) == 0)
                                 DeleteFile(&Buffer[0]);
                           }
                        }
                     CompEnd();  /* Compile-Vorgang beenden */
                  }
                  break;
               case 9: /* Compile One-Gadget wurde angeklickt */
                  if(SFile.NumChars != 0) /* Steht ein Name im Gadget fuer */
                  {                       /* den Filenamen? */
                     if(strncmp("RAM:",lname[i],4) != 0 && 
                        BoolRequest("Copy File to RAM: ?","",MainWindow,
                                  238,102,164,50,2,1,4,0) == TRUE)
                        /* File soll im RAM compiliert werden */
                     {
                        i = TRUE;
                        strsfn(&BUFile[0],&a[0],&b[0],&c[0],&d[0]);
                        strmfn(&UB[0],"RAM:",0,&c[0],&d[0]);
                        Copy(&BUFile[0],&UB[0]);
                     }
                     else
                        /* File nicht ins RAM kopieren */
                     {
                        i = FALSE;
                        strcpy(&UB[0],&BUFile[0]);
                     }
                     CompStart();   /* Compilieren vorbereiten */
                     Comp(&UB[0],&BUOpt[0]); /* File Compilieren */
                     CompEnd();     /* Compiliervorgang beenden */
                     if(i == TRUE)
                     {
                        /* compiliertes File wieder auf Diskette kopieren */
                        /* und im RAM loeschen */
                        strcpy(&Buffer[0],&UB[0]);
                        strmfe(&comand[0],&UB[0],"o");
                        strmfe(&UB[0],&BUFile[0],"o");
                        if(access(&comand[0],0) == 0)
                        {
                           Copy(&comand[0],&UB[0]);
                           DeleteFile(&comand[0]);
                        }
                        if(access(&Buffer[0],0) == 0)
                           DeleteFile(&Buffer[0]);
                     }
                  }
                  break;
               case 10: /* Link-Gadget wurde angeklickt */
                  if(SLink.NumChars != 0) /* LinkFile vorhanden? */
                  {
                     /* LINK-Befehl zusammenstellen */
                     strcpy(&comand[0],"BLINK >LCT.output BATCH WITH ");
                     strcat(&comand[0],&BULink[0]);
                     CallSystem(&comand[0]); /* Linker starten */
                  }
                  break;
               case 11: /* Eidt LinkFile-Gadget wurde angeklickt */
                  StartEditor(&Editor[0],&SLink); /* Editor starten */
                  break;
               case 12: /* Edit File-Gadget wurde angeklickt */
                  StartEditor(&Editor[0],&SFile); /* Editor starten */
                  break;
               case 13: /* Add to List-Gadget wurde angeklickt */
                  if(SFile.NumChars != 0 && size < LIST_SIZE && lnc == -1 &&
                     (lname[size] = getmem(SFile.NumChars+1)) != 0 &&
                     (lopt[size]  = getmem(SOpt.NumChars+1))  != 0 &&
                     (lprog[size] = getmem(SProg.NumChars+1)) != 0)
                     /* File ist nicht in der Liste, Liste ist noch nicht */
                     /* voll, File steht in dem StringGadget und es ist  */
                     /* genuegend Speicher vorhanden */
                  {
                     if(SProg.NumChars == 0)
                     {
                        /* Wenn kein Programmname angegeben wurde, wird */
                        /* No Name verwendet */
                        rlsmem(lprog[size],1);
                        lprog[size] = getmem(8);
                        strcpy(&BUProg[0],"No Name");
                        RefreshGadgets(&GLink,MainWindow,0);
                     }
                     /* File in Programmliste schreiben */
                     strcpy(lname[size],&BUFile[0]);
                     strcpy(lprog[size],&BUProg[0]);
                     strcpy(lopt[size],&BUOpt[0]);
                     lnc = size;
                     size += 1;
                     ls = FALSE;
                     ShowList();
                  }
                  break;
               case 14:    /* OMD-Gadget wurde angeklickt */
                  if(SFile.NumChars != 0)
                  {
                     /* OMD-Befehl zusammenstellen */
                     strcpy(&comand[0],"OMD >");
                     strmfe(&UB[0],&BUFile[0],"lst");
                     strcat(&comand[0],&UB[0]);
                     strcat(&comand[0]," ");
                     if(InputG() == TRUE) /* Befehle fuer OMD eingeben */
                     {
                        strcat(&comand[0],&BUI[0]);
                        strcat(&comand[0]," ");
                     }
                     strmfe(&UB[0],&BUFile[0],"o");
                     strcat(&comand[0],&UB[0]);
                     strcat(&comand[0]," ");
                     strcat(&comand[0],&BUFile[0]);
                     CallSystem(&comand[0]); /* OMD starten */
                  }
                  break;
               case 15: /* Copy File to RAM-Gadget wurde angeklickt */
                  if(access(&BUFile[0],0) == 0 && BUFile[0] != '\0' &&
                     strncmp("RAM:",&BUFile[0],4) != 0)
                     /* File existiert, Filename wurde angegeben und File */
                     /* steht nicht im RAM */
                  {
                     /* Neuen Filenamen ermitteln */
                     strsfn(&BUFile[0],&a[0],&b[0],&c[0],&d[0]);
                     strmfn(&Buffer[0],"RAM:",0,&c[0],&d[0]);
                     /* File kopieren */
                     Copy(&BUFile[0],&Buffer[0]);
                     /* Neuen Namen ins Gadget schreiben */
                     strcpy(&BUFile[0],&Buffer[0]);
                     RefreshGadgets(&GLink,MainWindow,0);
                     if(lnc != -1)
                     {
                        /* Wenn File in Liste steht, auch dort Namen */
                        /* durch neuen ersetzen */
                        rlsmem(lname[lnc],strlen(lprog[lnc])+1);
                        lname[lnc] = getmem(strlen(&Buffer[0])+1);
                        strcpy(lname[lnc],&Buffer[0]);
                        ls = FALSE;
                        ShowList();
                     }
                  }
                  break;
               case 16: /* Print File-Gadget wurde angeklickt */
                  PrintFile(&BUFile[0]); /* File drucken */
                  break;
               case 17:    /* Del from List-Gadget wurde angeklickt */
                  if(size > 0 && SFile.NumChars != 0 && SProg.NumChars != 0
                     && lnc != -1)
                     /* Liste noch nicht leer, File- und Programmname */
                     /* angegeben und in Liste vorhanden */
                  {
                     /* Speicher zurueckgeben */
                     rlsmem(lprog[lnc],strlen(lprog[lnc])+1);
                     rlsmem(lname[lnc],strlen(lname[lnc])+1);
                     rlsmem(lopt[lnc],strlen(lopt[lnc])+1);
                     size -= 1;
                     /* Liste neu ordnen */
                     for(i=lnc;i<size;i++)
                     {
                        lprog[i] = lprog[i+1];
                        lname[i] = lname[i+1];
                        lopt[i] = lopt[i+1];
                     }
                     lnc = -1;
                     ls = FALSE;
                     ShowList();
                  }
                  break;
               case 18:    /* OML-Gadget wurde angeklickt */
                  /* OML-Befehl zusammenstellen */
                  strcpy(&comand[0],"OML >LCT.output ");
                  strcat(&comand[0],&BUOpt[0]);
                  strcat(&comand[0]," ");
                  strcat(&comand[0],&BUProg[0]);
                  if(InputG() == TRUE) /* Befehle fuer OML eingeben */
                  {
                     strcat(&comand[0]," ");
                     strcat(&comand[0],&BUI[0]);
                  }
                  CallSystem(&comand[0]); /* OML aufrufen */
                  break;
               case 19: /* Assign-Gadget wurde angeklickt */
                  if((fp = fopen("LCT-ASSIGN","wb")) != 0)
                  {
                     /* Neue Definitionen fuer LCT-ASSIGN eingeben und */
                     /* speichern */
                     for(i=0;i<4;i++)
                     {
                        strcpy(&BUI[0],&As[i][0]);
                        PrintText(MainWindow->RPort,&EV[i][0],4,250,2,0);
                        SmallInput();
                        fputs(&BUI[0],fp);
                        fputs("\n",fp);
                     }
                     fclose(fp);
                     Assign(); /* Definitionen fuer Assign setzen */
                  }
                  break;
               case 21: /* Packer-Gadget wurde angeklickt */
                  if(SFile.NumChars != 0 && InputG() == TRUE)
                     /* File im File-StringGadget vorhanden und */
                     /* Ausgabefile eingegeben */
                  {
                     /* Packer-Befehl zusammenstellen */
                     strcpy(&comand[0],"lcompact <");
                     strcat(&comand[0],&BUFile[0]);
                     strcat(&comand[0]," >");
                     strcat(&comand[0],&BUI[0]);
                     CallSystem(&comand[0]); /* Packer aufrufen */
                  }
                  break;
               case 22: /* Save-Gadget wurde angeklickt */
                  if(InputG() == TRUE) /* Eingabe des Filenamens */
                     if((fp = fopen(&BUI[0],"wb")) != 0)
                     {
                        /* LinkFile speichern */
                        fputs(SLink.Buffer,fp);
                        fputs("\n",fp);
                        /* Groesse speichern */
                        fputc(size,fp);
                        /* angezeigtes File speichern */
                        fputc(lfirst,fp);
                        /* Programmliste speichern */
                        for(i=0;i<size;i++)
                        {
                           fputs(lprog[i],fp);
                           fputs("\n",fp);
                           fputs(lname[i],fp);
                           fputs("\n",fp);
                           fputs(lopt[i],fp);
                           fputs("\n",fp);
                        }
                        fclose(fp);
                        ls = TRUE;
                     }
                  break;
               case 23: /* Load List-Gadget wurde angeklickt */
                  if(InputG() == TRUE) /* Eingabe des File-Namens */
                     if((fp = fopen(&BUI[0],"rb")) != 0)
                     {
                        /* Alte Programmliste loeschen */
                        for(i=0;i<size;i++)
                        {
                           rlsmem(lprog[i],strlen(lprog[i])+1);
                           rlsmem(lname[i],strlen(lname[i])+1);
                           rlsmem(lopt[i],strlen(lopt[i])+1);
                        }
                        /* Name des LinkFiles einlesen */
                        fgets(SLink.Buffer,101,fp);
                        *(SLink.Buffer+strlen(SLink.Buffer)-1) = '\0';
                        SLink.NumChars = strlen(SLink.Buffer);
                        RefreshGadgets(&GLink,MainWindow,0);
                        size = fgetc(fp); /* Anzahl der Eintraege */
                        lfirst = fgetc(fp); /* angezeigtes File */
                        /* Programmliste laden */
                        for(i=0;i<size;i++)
                        {
                           fgets(&comand[0],101,fp);
                           comand[strlen(&comand[0])-1] = '\0';
                           lprog[i] = getmem(strlen(&comand[0])+1);
                           strcpy(lprog[i],&comand[0]);
                           fgets(&comand[0],101,fp);
                           comand[strlen(&comand[0])-1] = '\0';
                           lname[i] = getmem(strlen(&comand[0])+1);
                           strcpy(lname[i],&comand[0]);
                           fgets(&comand[0],101,fp);
                           comand[strlen(&comand[0])-1] = '\0';
                           lopt[i] = getmem(strlen(&comand[0])+1);
                           strcpy(lopt[i],&comand[0]);
                        }
                        fclose(fp);
                        ls = TRUE;
                        ShowList();
                     }
                  break;
               case 6:  /* Editor-StringGadget wurde angeklickt */
               case 24: /* Editor-Gadget wurde angeklickt */
                  StartEditor(&Editor[0],&SEdN); /* Editor starten */
                  break;
               case 5:  /* Word Processor-StringGadget wurde angeklickt */
               case 25: /* Word Processor-Gadget wurde angeklickt */
                  /* Textverarbeitungssystem starten */
                  StartEditor(&WProcessor[0],&SWpN);
                  break;
               case 26: /* CLI-Gadget wurde angeklickt */
                  CallSystem(&CLIName[0]); /* CLI-Programm starten */
                  break;
               case 27: /* Start Program-Gadget wurde angeklickt */
                  if(InputG() == TRUE) /* Eingabe des Programmnamens */
                     CallSystem(&BUI[0]); /* Aufruf des Programms */
                  break;
               case 28: /* Execute-Gadget wurde angeklickt */
                  if(InputG() == TRUE) /* Eingabe des Batch-Files */
                  {
                     /* Execute Befehl zusammenstellen */
                     strcpy(&comand[0],"Execute >LCT.output ");
                     strcat(&comand[0],&BUI[0]);
                     CallSystem(&comand[0]); /* Execute aufrufen */
                  }
                  break;
               case 29: /* Programm aufrufen */
                  CallSystem(&Pref[0]); /* Programm starten */
                  /* Farben von LCT wieder setzen */
                  LoadRGB4(&MainScreen->ViewPort,&colormap[0],8);
                  break;
               case 30: /* Print-Gadget wurde aufgerufen */
                  if(InputG() == TRUE) /* Eingabe des Filenamens */
                     PrintFile(&BUI[0]); /* File drucken */
                  break;
               case 31: /* Catalog-Gadget wurde angeklickt */
                  InputG();   /* Eingabe des Directorynamens */
                  Dir(&BUI[0]); /* Directory anzeigen */
                  break;
               case 32: /* Set Date-Gadget wurde angeklickt */
                  if(InputG() == TRUE) /* Eingabe des Datums */
                  {
                     strcpy(&comand[0],"date "); /* Date zusammenstellen */
                     strcat(&comand[0],&BUI[0]);
                     CallSystem(&comand[0]); /* Date aufrufen */
                  }
                  break;
               case 33: /* Type-Gadget wurde angeklickt */
                  if(InputG() == TRUE) /* Eingabe des Filenamens */
                     Type(&BUI[0]); /* Ausgabe des Files */
                  break;
               case 34: /* Pfeil nach oben wurde angeklickt */
                  if(lfirst > 0)
                  {
                     lfirst -= 1; /* Liste um 1 nach unten schieben */
                     ShowList();
                  }
                  break;
               case 35: /* Pfeil nach unten wurde angeklickt */
                  if(lfirst < size-1)  /* Ende der Liste? */
                  {
                     lfirst += 1; /* Liste um 1 nach oben schieben */
                     ShowList();
                  }
                  break;
                case 20: /* Quit-Gadget wurde angeklickt */
                  if(size != 0 && ls == FALSE)  /* Liste wurde nicht gespeichert */
                     quit = BoolRequest("List not saved !","Really quit ?",
                                        MainWindow,238,97,164,60,2,1,4,0);
                  else
                     quit = TRUE;
                  break;
            }
            ClearPointer(MainWindow);
         }
         else if(message->Class == MOUSEBUTTONS && message->Code == SELECTUP
                 && message->MouseY > 13 && message->MouseY < 48)
            /* Programm aus der Liste wurde angeklickt */
         {
            i = lfirst+(message->MouseY-14)/9; /* Nummer des Files in der */
            if(i < size)                       /* Liste */
            {
               strcpy(&BUFile[0],lname[i]); /* File in die Gadgets kopieren */
               strcpy(&BUProg[0],lprog[i]);
               strcpy(&BUOpt[0],lopt[i]);
               RefreshGadgets(&GLink,MainWindow,0); /* Gadgets erneuern */
               lnc = i; /* Ausgewaehltes File */
            }
            ReplyMsg((struct Message *)message);
         }
         else
            ReplyMsg((struct Message *)message);
      }
   }

   CleanUp("End",7); /* Programm beenden */
}

/* CLI-Befehl aufrufen */

void CallSystem(c)
char *c;
{
   register int i;

   if((i = system(c)) != 0)   /* Befehl aufrufen */
      ReqError((i<0)?_OSERR:i); /* Fehler anzeigen */
   return;
}

/* Text mit Schatten ausgeben */

void PrintText(rp,str,x,y,c1,c2)
struct RastPort *rp;
char *str;
USHORT x,y,c1,c2;
{
   register UBYTE l;
   register SHORT i;

   l = strlen(str);  /* Laenge */
   SetDrMd(rp,JAM1); /* Zeichenmodus */
   SetAPen(rp,c2);   /* Farbe */
   for(i=1;i>-1;i--) /* Zuerst Schatten, dann Text ausgeben */
   {
      Move(rp,x+i,y+i);
      Text(rp,str,l);
      SetAPen(rp,c1);
   }
   return;
}

/* Fehlermeldung anzeigen */

void ReqError(num)
int num;
{
   char err_str[81];

   switch(num)
   {
      case -4:
         strcpy(&err_str[0],"Can't open Window");
         break;
      case -3:
         strcpy(&err_str[0],"Too many file names");
         break;
      case -2:
         strcpy(&err_str[0],"Can't find File");
         break;
      case 103:
         strcpy(&err_str[0],"Insufficient free store");
         break;
      case 104:
         strcpy(&err_str[0],"Task table full");
         break;
      case 120:
         strcpy(&err_str[0],"Argument line invalid or too long");
         break;
      case 121:
         strcpy(&err_str[0],"File is not an object module");
         break;
      case 122:
         strcpy(&err_str[0],"Invalid resident library during load");
         break;
      case 202:
         strcpy(&err_str[0],"Object in use");
         break;
      case 203:
         strcpy(&err_str[0],"Object already exists");
         break;
      case 204:
         strcpy(&err_str[0],"Directory not found");
         break;
      case 205:
         strcpy(&err_str[0],"Object not found");
         break;
      case 206:
         strcpy(&err_str[0],"Invalid window");
         break;
      case 209:
         strcpy(&err_str[0],"Packet request type unknown");
         break;
      case 210:
         strcpy(&err_str[0],"Invalid stream componen name");
         break;
      case 211:
         strcpy(&err_str[0],"Invalid object lock");
         break;
      case 212:
         strcpy(&err_str[0],"Object not of required type");
         break;
      case 213:
         strcpy(&err_str[0],"Disk not validated");
         break;
      case 214:
         strcpy(&err_str[0],"Disk write protected");
         break;
      case 215:
         strcpy(&err_str[0],"Rename across devices attempted");
         break;
      case 216:
         strcpy(&err_str[0],"Directory not empty");
         break;
      case 218:
         strcpy(&err_str[0],"Device not mounted");
         break;
      case 219:
         strcpy(&err_str[0],"Seek error");
         break;
      case 220:
         strcpy(&err_str[0],"Comment too big");
         break;
      case 221:
         strcpy(&err_str[0],"Disk full");
         break;
      case 222:
         strcpy(&err_str[0],"File is protected from deletion");
         break;
      case 223:
         strcpy(&err_str[0],"File is protected from writing");
         break;
      case 224:
         strcpy(&err_str[0],"File is protected from reading");
         break;
      case 225:
         strcpy(&err_str[0],"Not a DOS disk");
         break;
      case 226:
         strcpy(&err_str[0],"No disk in drive");
         break;
      case 232:
         strcpy(&err_str[0],"No more entries in directory");
         break;
      case 65535:
         strcpy(&err_str[0],"Lattice failed");
         break;
      case 16745390:
         strcpy(&err_str[0],"OML failed");
         break;
      default: /* Keine besondere Meldung vorhanden */
         strcpy(&err_str[0],"Errornumber:                 ");
         stci_d(&err_str[13],num);
         break;
   }
   strcat(&err_str[0],"!");
   /* Ausgabe der Fehlermeldung vorbereiten */
   BT3.IText = BT4.IText = &err_str[0];
   BT3.LeftEdge = (640-strlen(BT3.IText)*8)/2;
   BT4.LeftEdge = BT3.LeftEdge+1;
   if(GfxBase->ActiView->ViewPort->RasInfo->BitMap->Depth == 1L)
      BT4.IText = 0;
   /* Bildschirm nach oben schieben */
   MoveScreen(MainScreen,0,-MainScreen->TopEdge);
   /* Fehlermeldung ueber Requester anzeigen */
   AutoRequest(IntuitionBase->ActiveWindow,&BodyText,0,
               &ReqNegativeText,0,0,640,50);
   return;
}

/* Eingabe ueber ein StringGadget am unteren Rand des Windows */

BOOL InputG()
{
   register struct IntuiMessage *m;
   register BOOL q;

   q = FALSE;
   BUI[0] = '\0';
   AddGadget(MainWindow,&GInput,-1);      /* Gadget zur Liste hinzufuegen */
   RefreshGadgets(&GInput,MainWindow,0);  /* Gadget anzeigen */
   ActivateGadget(&GInput,MainWindow,0);  /* Gadget aktivieren */
   while(!q)   /* Wiederhole, bis Gadget verlassen wurde */
   {
      Wait(1<<MainWindow->UserPort->mp_SigBit); /* Auf Nachricht warten */
      /* Nachricht lesen */
      while(m = (struct IntuiMessage *)GetMsg(MainWindow->UserPort))
      {
         if(m->Class == GADGETUP &&
            ((struct Gadget *)message->IAddress)->GadgetID == 99)
            q = TRUE; /* StringGadget wurde verlassen */
         ReplyMsg((struct Message *)m); /* Nachricht zurueckgeben */
      }
   }
   RemoveGadget(MainWindow,&GInput);   /* Gadget aus Liste entfernen */
   SetAPen(MainWindow->RPort,5); /* Gadget auf dem Bildschirm loeschen */
   RectFill(MainWindow->RPort,3,243,636,253);
   if(StrI.NumChars == 0)  /* Wenn keine Eingabe gemacht wurde, mit FALSE */
      return(FALSE);       /* Funktion verlassen */
   return(TRUE);  /* Es wurde eine Eingabe gemacht */
}

/* Programm beenden */

void CleanUp(str,n)
char *str;
UBYTE n;
{
   struct Preferences P;
   register int i;

   switch(n)
   {
      case 7:
         for(i=0;i<size;i++)  /* Speicher fuer die Programmliste zurueckgeben */
         {
            rlsmem(lprog[i],strlen(lprog[i])+1);
            rlsmem(lname[i],strlen(lname[i])+1);
            rlsmem(lopt[i],strlen(lopt[i])+1);
         }
         FreeMem((BYTE *)DUp,60); /* Speicher fuer Pfeil nach oben zurueckgeben */
      case 6:
         FreeMem((BYTE *)DDo,60); /* Speicher fuer Pfeil nach unten zurueckgeben */
      case 5:
         FreeMem((BYTE *)WPointer,12); /* Speicher fuer Mauszeiger zurueckgeben */
      case 4:
         CloseWindow(MainWindow); /* Window schliessen */
      case 3:
         MakeRasters(2L);  /* 2 Bitplanes fuer den Workbench-Screen */
         GetPrefs(&P,sizeof(struct Preferences)); /* Preferences lesen */
         colormap[0] = P.color0;    /* Farben wieder in ihren Urzustand */
         colormap[1] = P.color1;    /* zurueckversetzen */
         colormap[2] = P.color2;
         colormap[3] = P.color3;
         LoadRGB4(&MainScreen->ViewPort,&colormap[0],4);
       case 2:
         CloseLibrary((struct Library *)GfxBase); /* Intuition schliessen */
       case 1:
         CloseLibrary((struct Library *)IntuitionBase); /* Grafik schliessen */
   }
   if(CHIPf == TRUE && n < 5) /* Wenn Speicher fuer Mauszeiger und Pfeile */
   {                          /* noch nicht zurueckgegeben wurden, dann   */
      FreeMem((BYTE *)DUp,60);/* ihn hier sofort zurueckgeben */
      FreeMem((BYTE *)DDo,60);
      FreeMem((BYTE *)WPointer,12);
   }
   /* Wenn ASSIGN in den RAM-kopiert wurde, dann ASSIGN loeschen */
   if(access("RAM:ASSIGN",0) == 0 && ASSIGNC == TRUE)
      DeleteFile("RAM:ASSIGN");
   /* Fehlermeldung ausgeben */
   printf("%s!\n",str);
   if(n != 4)
      exit(-100-n);
   exit(0);
}

/* Bildschirmaufbau erstellen */

void Init()
{
   register int i,j;

   MakeRasters(3L); /* 3 BitPlanes fuer Workbench-Screen*/
   MainScreen = IntuitionBase->ActiveScreen; /* Bildschirm fuer Window */
   RemakeDisplay();
   ClearScreen(IntuitionBase->ActiveWindow->RPort); /* Bildschirm loeschen */
   RefreshWindowFrame(IntuitionBase->ActiveWindow); /* CLI-Windowrand erneuern */
   LoadRGB4(&MainScreen->ViewPort,&colormap[0],8); /* Farben setzen */
   NewMainWindow.Screen = MainScreen;
   if((MainWindow = OpenWindow(&NewMainWindow)) == 0) /* Window oeffnen */
      CleanUp("Can't open Window",3);
   if(CHIPf == FALSE)   /* Daten fuer Mauszeiger und Pfeil-Gadgets       */
   {                    /* in den CHIP_MEM verlegen, wenn sie noch nicht */
      CHIPf = TRUE;     /* da sind */
      /* Speicher holen */
      if((WPointer = (USHORT *) AllocMem(12,MEMF_CHIP)) == 0) /* Mauszeiger */
         CleanUp("Not enough Memory",4);
      if((DDo = (SHORT *) AllocMem(60,MEMF_CHIP)) == 0) /* Pfeil nach unten */
         CleanUp("Not enough Memory",5);
      if((DUp = (SHORT *) AllocMem(60,MEMF_CHIP)) == 0) /* Pfeil nach oben */
         CleanUp("Not enough Memory",6);
      /* Daten kopieren */
      for(i=0;i<6;i++)    /* Mauszeiger */
         *(WPointer+i) = WaitPointer[i];
      for(i=0;i<30;i++)    /* Pfeile */
      {
         *(DDo+i) = DataDo[i];
         *(DUp+i) = DataUp[i];
      }
   }
   IDo.ImageData = DDo;
   IUp.ImageData = DUp;
   puts("\n");
   SetPointer(MainWindow,WPointer,1,9,0,0);

   /* Bildschirmaufbau ausgeben */
   SetDrMd(MainWindow->RPort,JAM2);
   SetAPen(MainWindow->RPort,7);
   RectFill(MainWindow->RPort,1,10,638,175);
   SetAPen(MainWindow->RPort,5);
   RectFill(MainWindow->RPort,1,176,638,254);
   SetAPen(MainWindow->RPort,0);
   RectFill(MainWindow->RPort,53,54,304,65);
   RectFill(MainWindow->RPort,311,54,562,65);
   RectFill(MainWindow->RPort,81,69,332,80);
   RectFill(MainWindow->RPort,422,69,631,80);
   SetAPen(MainWindow->RPort,6);
   Move(MainWindow->RPort,0,174);
   Draw(MainWindow->RPort,640,174);
   RectFill(MainWindow->RPort,3,12,621,49);
   SetAPen(MainWindow->RPort,1);
   Move(MainWindow->RPort,0,173);
   Draw(MainWindow->RPort,640,173);
   Move(MainWindow->RPort,0,175);
   Draw(MainWindow->RPort,640,175);
   RectFill(MainWindow->RPort,5,13,619,48);
   SetAPen(MainWindow->RPort,4);
   RectFill(MainWindow->RPort,6,14,618,47);
   RectFill(MainWindow->RPort,567,52,631,65);
   for(i=0;i<4;i++)
      for(j=0;j<4;j++)
      {
         RectFill(MainWindow->RPort,4+i*158,88+j*21,160+i*158,107+j*21);
         if(j<3)
            RectFill(MainWindow->RPort,4+i*158,180+j*21,160+i*158,199+j*21);
      }
   RefreshGadgets(&GLink,MainWindow,0);
   PrintText(MainWindow->RPort,"File:",6,61,2,0);
   PrintText(MainWindow->RPort,"Program:",6,76,2,0);
   PrintText(MainWindow->RPort,"Link File:",337,76,2,0);
   return;
}

/* Editor aufrufen */

void StartEditor(e_nam,SIP)
char *e_nam;
struct StringInfo *SIP;
{
   if(SIP->NumChars != 0)  /* Steht ein Name in SIP? */
   {
      strcpy(&comand[0],e_nam);   /* Aufruf fuer Editor zusammenstellen */
      strcat(&comand[0],SIP->Buffer);
      SetRGB4(&MainScreen->ViewPort,1,0,10,0);/* Schriftfarbe: Gruen */
      CallSystem(&comand[0]);                 /* Editor aufrufen */
      SetRGB4(&MainScreen->ViewPort,1,0,0,12);/* Schriftfarbe: Blau */
   }
   return;
}

/* Directory anzeigen */

void Dir(dirnam)
char *dirnam;
{
   struct FILEINFO info;
   register USHORT i,j,y;

   if((DirWindow = OpenWindow(&NewDirWindow)) != 0) /* Window oeffnen */
   {
      /* Directorynamen fuer dfind() veraendern */
      strcat(dirnam,"/");
      strsfn(dirnam,&a[0],&b[0],&c[0],&d[0]);
      if(c[0] == '\0' && d[0] == '\0')
      {
         if(b[0] != '\0')
            strcpy(&c[0],"/");
         strcpy(&c[0],"#?");
      }
      strmfn(&comand[0],&a[0],&b[0],&c[0],&d[0]);
      if(dfind(&info,&comand[0],1) == 0) /* Directory 'oeffnen' */
      {
         j = 0;
         while(j == 0)
         {
            for(i=0;i<29;i++)
            {
               /* Directoryeintrag ausgeben */
               y = 16+i*8;
               PrintText(DirWindow->RPort,&info.fib_FileName[0],5,y,3,4);
               if(info.fib_DirEntryType > 0) /* Eintrag war Directory */
                  PrintText(DirWindow->RPort,"DIR",443,y,3,4);
               /* Flags ausgeben */
               strcpy(&comand[0],"-----");
               if((info.fib_Protection&1) == 0)
                  comand[0] = 'D';
               if((info.fib_Protection&2) == 0)
                  comand[1] = 'E';
               if((info.fib_Protection&4) == 0)
                  comand[2] = 'W';
               if((info.fib_Protection&8) == 0)
                  comand[3] = 'R';
               if((info.fib_Protection&16) == 0)
                  comand[4] = 'A';
               PrintText(DirWindow->RPort,&comand[0],475,y,3,4);
               /* Groesse ausgeben */
               stcl_d(&comand[0],info.fib_Size);
               PrintText(DirWindow->RPort,&comand[0],530,y,3,4);
               if(dnext(&info) != 0) /* naechsten Eintrag lesen */
                  /* Keine weiteren Eintraege */
                  j = i = 100;
            }
            /* Auf den Druck einer Maustaste warten */
            WaitMessage();
            WaitMessage();
            SetAPen(DirWindow->RPort,0);
            RectFill(DirWindow->RPort,5,10,635,253);
         }
      }
      else
         ReqError(204);
      CloseWindow(DirWindow);
   }
   else
      ReqError(-4);
   return;
}

/* File drucken */

void PrintFile(fnam)
char *fnam;
{
   if(access(fnam,0) == 0) /* Existiert File ? */
   {
      strcpy(&comand[0],"TYPE ");   /* Aufruf fuer TYPE zusammenstellen */
      strcat(&comand[0],fnam);
      if(BoolRequest("Hexdump ?","",MainWindow,238,102,164,50,
         2,1,4,0) == TRUE) /* Ausgabe als Hexdump ? */
         strcat(&comand[0]," OPT H");
      else if(BoolRequest("Linenumbering ?","",MainWindow,238,102,164,50,
              2,1,4,0) == TRUE)  /* Ausgabe mit Zeilennummern? */
         strcat(&comand[0]," OPT N");
      strcat(&comand[0]," TO PRT:");
      CallSystem(&comand[0]); /* TYPE aufrufen */
   }
   return;
}

/* File auf Bildschirm anzeigen */

void Type(fnam)
char *fnam;
{
   register struct IntuiMessage *m;
   register FILE *fp;
   register int c,z,s;

   if(access(fnam,4) != 0)
         /* File Existiert nicht */
   {
      ReqError(-2);
      return;
   }
   if((DirWindow = OpenWindow(&NewDirWindow)) != 0) /* Window oeffnen */
   {
      fp = fopen(fnam,"rb");  /* File oeffnen */
      z = s = 0;
      while((c = getc(fp)) != EOF && z != -1) /* wiederhole, bis Fileende  */
                                              /* erreicht oder rechte      */
                                              /* Maustaste gedrueckt wurde */
         if(s > 77 || c == '\0' || c == '\n' || c == 10)
            /* Ende der Zeile */
         {
            if(s > 77 && c != '\0' && c != '\n' && c != 10)
            /* Zeile im File laenger als 77 Zeichen, deswegen neue Zeile */
            {
               comand[s] = (char) c; /* Zeichen an Zeile anhaengen */
               s += 1;
            }
            /* Zeile ausgeben */
            comand[s] = '\0';
            PrintText(DirWindow->RPort,&comand[0],4,(USHORT)(16+z*8),3,0);
            /* Neue Zeile */
            s = 0;
            z += 1;
            if(z > 29)
               /* Seitenende erreicht */
            {
               z = 0;
               /* Auf Maustaste warten */
               WaitMessage();
               Wait(1<<DirWindow->UserPort->mp_SigBit);
               m = (struct IntuiMessage *)GetMsg(DirWindow->UserPort);
               if(m->Code == MENUUP)
                  /* Rechte Maustaste gedrueckt => Abbruch */
                  z = -1;
               ReplyMsg((struct Message *)m);
               /* Bildschirm loeschen */
               SetAPen(DirWindow->RPort,0);
               RectFill(DirWindow->RPort,4,10,635,253);
            }
         }
         else
         {
            /* Zeichen an aktuelle Zeile anhaengen */
            comand[s] = (char) c;
            s += 1;
         }
      fclose(fp); /* File schliessen */
      if(z != -1)
         /* nicht durch rechte Maustaste abgebrochen */
      {
         /* letzte Zeile ausgeben */
         comand[s] = '\0';
         PrintText(DirWindow->RPort,&comand[0],4,(USHORT)(16+z*8),3,0);
         /* Auf Maustaste warten */
         WaitMessage();
         WaitMessage();
      }
      CloseWindow(DirWindow); /* Window schliessen */
   }
   else
      ReqError(-4);
   return;
}

/* Auf IntuitionMessage warten */

void WaitMessage()
{
   struct IntuiMessage *ime;

   Wait(1<<DirWindow->UserPort->mp_SigBit);  /* Warten auf das Auftreten */
                                             /* einer Nachricht */
   /* Nachricht lesen und zurueckgeben */
   ime = (struct IntuiMessage *)GetMsg(DirWindow->UserPort);
   ReplyMsg((struct Message *)ime);

   return;
}

/* Definitionen fuer Assign lesen und definieren */

void Assign()
{
   register FILE *fp;
   register int i;

   if(access("RAM:ASSIGN",0) != 0) /* Wenn RAM:ASSIGN nicht existiert, */
   {                               /* dann Assign ins RAM kopieren */
      ASSIGNC = TRUE;
      Copy("C:ASSIGN","RAM:ASSIGN");
   }
   fp = fopen("LCT-ASSIGN","rb");   /* LCT-ASSIGN oeffnen und */
   for(i=0;i<4;i++)                 /* Definitionen einlesen  */
   {
      fgets(&As[i][0],101,fp);
      As[i][strlen(&As[i][0])-1] = '\0';
   }
   fclose(fp);
   for(i=0;i<4;i++)  /* Definitionen setzen */
   {
      strcpy(&comand[0],"RAM:ASSIGN ");   /* ASSIGN_Befehl zusammenstellen */ 
      strcat(&comand[0],&EV[i][0]);
      strcat(&comand[0]," ");
      strcat(&comand[0],&As[i][0]);
      CallSystem(&comand[0]);             /* ASSIGN aufrufen */
   }
   return;
}

/* Programmliste auf Bildschirm ausgeben */

void ShowList()
{
   register int i;

   SetAPen(MainWindow->RPort,4);            /* Kasten loeschen */
   RectFill(MainWindow->RPort,6,14,617,47);
   for(i=0;i<4;i++)        /* Die 4 Files, die in dem Kasten Platz haben,*/
      if(lfirst+i<size)    /* ausgeben, solange die Liste noch Eintraege */
      {                    /* hat */
         stccpy(&comand[0],lname[lfirst+i],37);
         PrintText(MainWindow->RPort,&comand[0],8,(USHORT)(21+i*8),3,4);
         stccpy(&comand[0],lprog[lfirst+i],37);
         PrintText(MainWindow->RPort,&comand[0],306,(USHORT)(21+i*8),3,4);
      }
      else
         i = 4;
   return;
}

/* Alles vorbereiten zum Compilieren */

void CompStart()
{
   CloseWindow(MainWindow);   /* Window schliessen */
   MakeRasters(1L);  /* Anzahl der Bitplanes des WB-Screens auf */
   return;           /* 1 reduzieren */
}

/* File compilieren */

void Comp(cfile,copt)
char *cfile,*copt;
{
   if(access(cfile,0) != 0)   /* Existiert File? */
      return;
   if(*(cfile+strlen(&cfile[0])-1) == 'c' || /* Ist das File ein C- oder */
      *(cfile+strlen(&cfile[0])-1) == 'C')   /* ein Assembler-Listing? */
      strcpy(&comand[0],"LC");   /* Lattice-C-Compiler verwenden */
   else
      strcpy(&comand[0],"ASM");  /* Lattice-Assembler verwenden */
   strcat(&comand[0]," >LCT.output "); /* Ausgabe der Fehler auf LCT.output */
   if(strlen(copt) != 0)   /* Falls Optionen vorhanden sind, diese angeben */
   {
      strcat(&comand[0],copt);
      strcat(&comand[0]," ");
   }
   strcat(&comand[0],cfile);  /* Name des Files angeben */
   CallSystem(&comand[0]);    /* Compilieren bzw. Assemblieren */
   CallSystem("type LCT.output"); /* LCT.output ausgeben */
   return;
}

/* Beenden des Compilierens */

void CompEnd()
{
   Init();     /* Bildschirmaufbau erstellen */
   ShowList(); /* Programmliste anzeigen */
   return;
}

/* Requester aufrufen */

BOOL BoolRequest(str1,str2,w,x,y,width,height,c0,c1,c2,c3)
char *str1,*str2;
struct Window *w;
SHORT x,y,width,height,c0,c1,c2,c3;
{
   register struct IntuiMessage *im;
   register struct Gadget *G;
   register BOOL f;

   /* Strukturen fuer Requester und Gadgets definieren */
   BoolReqG.BackFill = c0;    /* Hintergrundfarbe fuer das Requester */
   BOK.FrontPen = BYES.FrontPen = c3; /* Randfarbe fuer die Gadgets */
   ITNO.FrontPen = ITYES.FrontPen = c2; /* Schriftfarbe fuer die Gadgets */
   ITB1Req.FrontPen = ITB2Req.FrontPen= c1; /* Schriftfarbe fuer Text */
   XYReqBorder[2] = XYReqBorder[4] = width-4; /* Koordinaten fuer den */
   XYReqBorder[5] = XYReqBorder[7] = height-2;/* Kasten um das Requester */
   BoolReqG.LeftEdge = x; /* x-Position des Requesters */
   BoolReqG.TopEdge = y;  /* y-Position des Requesters */
   BoolReqG.Width = width; /* Breite des Requesters */
   BoolReqG.Height = height; /* Hoehe des Reqeusters */
   GNO.LeftEdge = width-31; /* x-Position des NO-Gadgets */
   GYES.LeftEdge = 10; /* x-Position des YES-Gadgets */
   GNO.TopEdge = GYES.TopEdge = height-18; /* y-Position der Gadgets */
   ITB1Req.IText = str2;   /* Text 1 */
   ITB2Req.IText = str1;   /* Text 2 */

   ClearPointer(MainWindow);
   Request(&BoolReqG,w);   /* Requester aufrufen */
   /* Auf das Anklicken eines Gadgets warten */
   Wait(1<<MainWindow->UserPort->mp_SigBit);
   im = (struct IntuiMessage *) GetMsg(w->UserPort);
   G = (struct Gadget*)im->IAddress;
   ReplyMsg((struct Message *)im);
   if(G->GadgetID == 1)       /* YES-Gadget wurde angeklickt */
      f = TRUE;
   else if(G->GadgetID == 2)  /* NO-Gadget wurde angeklickt */
      f = FALSE;
   EndRequest(&BoolReqG,w);   /* Beenden des Requesters */
   SetPointer(MainWindow,WPointer,1,9,0,0);
   return(f);
}

/* File kopieren */

BOOL Copy(source,dest)
char *source,*dest;
{
   register FILE *fps,*fpd;
   register int c;

   if((fps = fopen(source,"rb")) == 0) /* Quellfile oeffnen */
   {
      ReqError(_OSERR);    /* File liess sich nicht oeffnen */
      return(FALSE);
   }
   if((fpd = fopen(dest,"wb")) == 0)   /* Zielfile oeffnen */
   {
      fclose(fps);      /* File liess sich nicht oeffnen */
      ReqError(_OSERR);
      return(FALSE);
   }
   while((c=fgetc(fps)) != EOF)  /* Solange nicht EOF erreicht wurde, */
      if(fputc(c,fpd) == EOF)    /* Zeichen einlesen */
      {
         ReqError(_OSERR);       /* Zielfile konnte nicht beschrieben */
         fclose(fps);            /* werden */
         fclose(fpd);
         DeleteFile(dest);
         return(FALSE);
      }
   fclose(fps);
   fclose(fpd);
   return(TRUE);
}

/* Eingabe ueber StringGadget am unteren Rand des Windows */

void SmallInput()
{
   register struct IntuiMessage *message;
   register BOOL q;

   q = FALSE;
   AddGadget(MainWindow,&GA,-1);       /* Gadget oeffnen */
   RefreshGadgets(&GA,MainWindow,0);   /* Gadget anzeigen */
   ActivateGadget(&GA,MainWindow,0);   /* Gadget aktivieren */
   while(!q)      /* Wiederhole, bis GADGETUP von Intuition kommt */
   {
      Wait(1<<MainWindow->UserPort->mp_SigBit); /* Auf Nachricht warten */
      /* Nachricht holen */
      while(message = (struct IntuiMessage *)GetMsg(MainWindow->UserPort))
      {
         if(message->Class == GADGETUP &&
            ((struct Gadget *)message->IAddress)->GadgetID == 99)
            q = TRUE;               /* Eingabegadget wurde verlassen */
         ReplyMsg((struct Message *)message); /* Nachricht zurueckgeben */
      }
   }
   RemoveGadget(MainWindow,&GA); /* Gadget aus Gadgetliste entfernen */
   SetAPen(MainWindow->RPort,5); /* Gadget auf dem Bildschirm loeschen */
   RectFill(MainWindow->RPort,3,243,636,253);
   return;
}

/* Anzahl der BitPlanes des Workbench-Screens aendern */

void MakeRasters(Planes)
long Planes;
{
   register int i,j;

   /* Anzahl der BitPlanes erniedrigen */
   if(GfxBase->ActiView->ViewPort->RasInfo->BitMap->Depth > Planes)
   {
      /* Anzahl der BitPlanes, die entfernt werden sollen */
      j = GfxBase->ActiView->ViewPort->RasInfo->BitMap->Depth-Planes;
      /* Neue Anzhal der BitPlanes setzen */
      GfxBase->ActiView->ViewPort->RasInfo->BitMap->Depth = Planes;
      RemakeDisplay(); /* Anzeigen erneuern */
      /* Ueberfluessige BitPlanes an das System zurueckgeben */
      for(i=Planes;i<Planes+j;i++)
         FreeRaster(GfxBase->ActiView->ViewPort->RasInfo->BitMap->
                    Planes[i],640L,256L);
   }
   /* Anzahl der Bitplanes erhoehen */
   else if(GfxBase->ActiView->ViewPort->RasInfo->BitMap->Depth < Planes)
   {
      /* Anzahl der BitPlanes, die geoeffnet werden sollen */
      j = Planes-GfxBase->ActiView->ViewPort->RasInfo->BitMap->Depth;
      /* BitPlanes vom System holen */
      for(i=GfxBase->ActiView->ViewPort->RasInfo->BitMap->Depth;
          i<GfxBase->ActiView->ViewPort->RasInfo->BitMap->Depth+j;i++)
         GfxBase->ActiView->ViewPort->RasInfo->BitMap->Planes[i] =
          (PLANEPTR) AllocRaster(640L,256L);
      /* Neue Anzahl der BitPlanes setzen */
      GfxBase->ActiView->ViewPort->RasInfo->BitMap->Depth = Planes;
      RemakeDisplay(); /* Anzeige erneuern */
   }
   return;
}
