home *** CD-ROM | disk | FTP | other *** search
/ World of A1200 / World_Of_A1200.iso / programs / monitors / rsys / rsyssrc.lha / RSys.c < prev    next >
C/C++ Source or Header  |  1993-09-25  |  23KB  |  970 lines

  1. /*
  2. ***************************************************************************
  3. *
  4. * Datei:
  5. *      RSys.c
  6. *
  7. * Inhalt:
  8. *
  9. *      --- Globale Routinen ---
  10. *
  11. *    void About ( void );
  12. *    void HandleMainPort ( void );
  13. *    void main ( int argc , char **argv );
  14. *
  15. *      --- Lokale  Routinen ---
  16. *
  17. *    static int HandleArguments ( char **str );
  18. *    static int position ( int ch );
  19. *    static void HandleGadgets ( struct Gadget *gad );
  20. *    static void HandleIDPort ( void );
  21. *    static void HandleMenu ( ULONG code );
  22. *    static void HandleRawKeys ( ULONG code , ULONG qualifier );
  23. *    static void HandleVanillaKeys ( ULONG code , ULONG qualifier );
  24. *    static void Jump ( void );
  25. *    static void SelectGadget ( struct Gadget *Gadget );
  26. *    static void SetMainLVTop ( int top );
  27. *    static void UnSelectGadget ( struct Gadget *Gadget );
  28. *
  29. * Bemerkungen:
  30. *      Hauptprogramm und Handling-Routinen von RSys.
  31. *
  32. * Erstellungsdatum:
  33. *      07-Jan-93     Rolf Böhme
  34. *
  35. * Änderungen:
  36. *      07-Jan-93     Rolf Böhme      Erstellung
  37. *
  38. ***************************************************************************
  39. */
  40.  
  41. #include "RSys.h"
  42.  
  43. /*#define BETA 1*/
  44.  
  45.     /*
  46.      * Der Kennstring, der von dem DOS-Befehl Version
  47.      * gefunden wird
  48.      */
  49. const char *v = "\0$VER: " NAME " " VERSION " (" DATE " " TIME ") " COPYRIGHT " \n";
  50.  
  51.     /*
  52.      * Die Prozedur About() gibt eine Kurzinformation zum
  53.      * Programm RSys aus
  54.      */
  55. void
  56. About(void)
  57. {
  58.     UBYTE info[]= (UBYTE *)
  59.     "\n»»»»»»»»»»»» " NAME " " VERSION " ««««««««««««\n\n "
  60.     "    The Program was written by\n\n"
  61.     "            Rolf Böhme\n"
  62.     "           Stammestr. 48\n"
  63.     "         30459 Hannover 91\n"
  64.     "              Germany\n"
  65.     "     Z-NET: R.BOEHME@COPS.ZER\n"
  66.     "  FIDO: 2:241/37.2 (Rolf Boehme)\n\n"
  67. #ifdef BETA
  68.     "     !This is a BETA-RELEASE!\n"
  69.     "    Please do not redistribute!\n"
  70. #endif
  71.     "   It's placed in Public Domain\n"
  72.     "   under the terms of Giftware!\n"
  73.     "Please send small donations, gifts\n"
  74.     " or other little sweeties to me!!\n";
  75.  
  76.     DPOS;
  77.  
  78.    HandleHelp(MN_About);
  79.  
  80.     MyEasyRequest(SysWnd, (UBYTE *) NAME " Info (" DATE ", " TIME ")", 
  81.                  (UBYTE *) "Continue", info);
  82.     return;
  83. }
  84.  
  85.     /*
  86.      * Die Prozedur Jump() sucht den nächsten
  87.      * PublicScreen in der Systemliste, holt ihn nach
  88.      * vorn und öffnet auf ihm das RSys-Hauptfenster
  89.      */
  90. static void
  91. Jump(void)
  92. {
  93.     struct Screen *NewScr = NULL;
  94.     struct List *PSList = NULL;
  95.     struct Node *Node = NULL;
  96.     extern struct Screen *lastpubscreen;
  97.    char savenamebuffer[MAXPUBSCREENNAME + 1];
  98.    int openit;
  99.  
  100.    strcpy(savenamebuffer, (char *)namebuffer);
  101.         /*
  102.          * Sperren der Systemliste aller PubScreens
  103.          */
  104.     PSList = LockPubScreenList();
  105.  
  106.         /*
  107.          * Aktuellen Knoten finden, also den Screen auf dem sich
  108.          * RSys im Moment befindet
  109.          */
  110.     Forbid();
  111.     Node = FindName(PSList, namebuffer);
  112.     Permit();
  113.  
  114.     if (NOT(Node))
  115.     {
  116.         UnlockPubScreenList();
  117.         ErrorHandle((char *)namebuffer, SCREEN_ERR, FIND_FAIL, NO_KILL);
  118.     }
  119.    else
  120.    {
  121.        while (Node)
  122.        {
  123.                /*
  124.                 * Falls der gefundene PubScreen der letzte im System ist,
  125.                 * wird dieser gelocked
  126.                 */
  127.            if (NOT(Node->ln_Succ))
  128.            {
  129.                Node = PSList->lh_Head;
  130.                strcpy((char *)namebuffer, Node->ln_Name);
  131.                NewScr = LockPubScreen(namebuffer);
  132.  
  133.                break;
  134.            }
  135.            else
  136.                if (NewScr = LockPubScreen((UBYTE *)Node->ln_Succ->ln_Name))
  137.                {
  138.                    strcpy((char *)namebuffer, Node->ln_Succ->ln_Name);
  139.                    break;
  140.                }
  141.  
  142.                /*
  143.                 * Falls der Nachfolger-PubScreen nicht gesperrt werden konnte,
  144.                 * wird der nächste gesucht.
  145.                 */
  146.            Node = Node->ln_Succ;
  147.        }
  148.  
  149.        UnlockPubScreen(NULL, NewScr);
  150.  
  151.        UnlockPubScreenList();
  152.  
  153.        if (NewScr != lastpubscreen)
  154.        {
  155.            ScreenToFront(NewScr);
  156.  
  157.            CloseASysWindow(&SysWnd, &SysGList, &SysMenus);
  158.            CloseDownScreen();
  159.  
  160.          OpenMainWindow();
  161.            RefreshList(LastID);
  162.  
  163.          openit = CloseHelpOnScreen();
  164.          OpenHelpOnScreen(openit);
  165.  
  166.          ClearIntuiMsgPort(SysWnd);
  167.        }
  168.        else
  169.       {
  170.          strcpy((char *)namebuffer, savenamebuffer);
  171.          ErrorHandle("No more Public Screens", SCREEN_ERR, FIND_FAIL, NO_KILL);
  172.       }
  173.    }
  174.  
  175.     return;
  176. }
  177.  
  178.     /*
  179.      * Die Funktion position() gibt für die
  180.      * Gadget-Tastatturabfrage die Position des Zeichens
  181.      * ch in der Zeichenkette itemcode[] zurück
  182.      */
  183. static int
  184. position(int ch)
  185. {
  186.     char *itemcode = "TLMPVAFRIWSHYD J";
  187.  
  188.         /*
  189.          * Die Position des Zeichens errechnet sich aus der
  190.          * Differenz der Zeiger auf das gefundene Zeichen und
  191.          * dem auf die Zeichenkette itemcode
  192.          */
  193.     int    pos = (int)(strchr(itemcode, (int)ToUpper((ULONG) ch)) - itemcode);
  194.  
  195.     return ((pos < 0) ? ~0 : pos);
  196. }
  197.  
  198.     /*
  199.      * In diesem Feld stehen nach dem Aufruf die
  200.      * erwarteten Parameter. Im Falle der verwendeten
  201.      * Schalter steht im entsprechenden Feld opts[i] ein
  202.      * TRUE oder FALSE, jenachdem, ob der Schalter beim
  203.      * Aufruf angegeben wurde oder nicht
  204.      */
  205. LONG    opts[COUNT_FLAGS];
  206.  
  207.     /*
  208.      * Diese Funktion parst die Kommandozeile und gibt
  209.      * die Nummer des entsprechenden Schalters zurück.
  210.      * Defaultmäßig wird 12 (Systeminfo) zurückgegeben
  211.      */
  212. static int
  213. HandleArguments(char **str)
  214. {
  215.     int    ret = 12, j;
  216.     struct RDArgs *argsptr;
  217.  
  218.         /*
  219.          * Die Kommandozeile wird geparst. Falls ein Fehler
  220.          * beim Parsen auftrat, wird das Programm mit einer
  221.          * Fehlermeldung verlassen
  222.          */
  223.     if ((argsptr = ReadArgs(TEMPLATE, opts, NULL)) == NULL)
  224.         ErrorHandle("TemplateError", TASK_ERR, WRONG_FAIL, KILL);
  225.     else
  226.     {
  227.             /*
  228.              * Das Feld opts[] wird durchsucht, ob ein Flag
  229.              * gesetzt wurde. Falls eine gesetzte Option gefunden
  230.              * wurde, wird die Schleife abgebrochen und der
  231.              * entsprechende Rückgabewert gesetzt
  232.              */
  233.         for (j = 0; j < COUNT_FLAGS; j++)
  234.             if (opts[j])
  235.             {
  236.                 ret = j;
  237.                 break;
  238.             }
  239.  
  240.             /*
  241.              * Die Funktion ReadArgs() reserviert intern
  242.              * Speicherplatz für die Kommandoargumente.    Dieser
  243.              * Platz muß dem System mit der Prozedur FreeArgs()
  244.              * zurückgegeben werden
  245.              */
  246.         FreeArgs(argsptr);
  247.     }
  248.  
  249.     return (ret);
  250. }
  251.  
  252.     /*
  253.      * Die Prozedur HandleIDPort() wird aufgerufen, wenn RSys
  254.      * ein zweites Mal gestartet wird. Wird dabei ein Parameter
  255.      * übergeben, so wird dieser mit dem Message-System des
  256.      * AmigaDOS an den ID-Port des bereitsgestarteten Programms
  257.      * versendet und hier ausgewertet. Die Struktur SysMsg
  258.      * enthält neben der Standard-System-Message noch die ID
  259.      * der anzuzeigenden Liste.
  260.      */
  261. static void
  262. HandleIDPort(void)
  263. {
  264.     SysMsg *arrived_mess;
  265.     int    ID;
  266.  
  267.         /*
  268.          * Es werden alle Nachrichten ausgewertet, solange, bis
  269.          * die Message-Queue leer ist.
  270.          */
  271.     while (arrived_mess = (SysMsg *) GetMsg(SysIdPort))
  272.     {
  273.         ID = arrived_mess->sm_newtype;
  274.         ReplyMsg((struct Message *) arrived_mess);
  275.  
  276.            /*
  277.             * Falls  das RSys-Hauptfenster mit dem Zip-Gadget auf
  278.             * eine    kleine  Fenstergröße gebracht wurde, wird es
  279.             * jetzt  nach  vorne  geholt  und    auf normale Größe
  280.             * gebracht.
  281.             */
  282.        if (SysWnd->Flags & WFLG_ZOOMED)
  283.        {
  284.            WindowToFront(SysWnd);
  285.            ZipWindow(SysWnd);
  286.        }
  287.  
  288.            /*
  289.             * In jedem Fall wird das RSys-Hauptfenster aktiviert.
  290.             */
  291.        ActivateWindow(SysWnd);
  292.  
  293.            /*
  294.             * Ist die erhaltene Nachricht von einem zweiten
  295.             * RSys-Aufruf ohne Parameter abgesendet worden, steht
  296.             * das ID-Feld der SysMsg-Struktur auf SYSTEMINFO.
  297.             * Falls ein Parameter angegeben wurde, wird die
  298.             * Anzeigeliste mit dem neuen Parameter aktualisiert
  299.             * und in der globalen Variablen LastID gemerkt.
  300.             */
  301.        if (ID != SYSTEMINFO) RefreshList(LastID = ID);
  302.  
  303.            /*
  304.             * Während der ID-Port abgefragt wird, kann das
  305.             * Hauptfenster Nachrichten empfangen haben. Diese
  306.             * sollen nach dem Empfang der Nachricht vom zweiten
  307.             * Programmaufruf nicht ausgewertet werden. Deshalb
  308.             * werden jetzt die evtl. vorhandenen Nachrichten des
  309.             * Hauptfenster-Ports gelöscht.
  310.             */
  311.        ClearIntuiMsgPort(SysWnd);
  312.    }
  313.  
  314.     return;
  315. }
  316.  
  317. void
  318. SetMainLVTop(int top)
  319. {
  320.     GT_SetGadgetAttrs(SysGadgets[GD_ListeLV], SysWnd,
  321.                             NULL,
  322.                             GTLV_Top, top,
  323.                             TAG_DONE);
  324.  
  325.    return;
  326. }
  327.  
  328.     /*
  329.      * Die Procedure HandleRawKeys() wertet die
  330.      * Tastatureingaben des Hauptfensters aus. Dazu wird
  331.      * das Feld IntuiMessage->Code verwendet.
  332.      */
  333. static void
  334. HandleRawKeys(ULONG code, ULONG qualifier)
  335. {
  336.         /*
  337.          * Es werden bei einem Tastatur-Event zwei Messages
  338.          * an den Hauptfenster-Port versendet, wenn die Taste
  339.          * gedrückt und dann, wenn sie losgelassen wurde.
  340.          * Hier sollen nur die Events ausgewertet werden, die
  341.          * direkt nach dem Drücken einer Taste anliegen.
  342.          */
  343.    if(code & IECODE_UP_PREFIX) return;
  344.    if(qualifier & CTRLKEYS) return;
  345.  
  346.     switch (code)
  347.     {
  348.             /*
  349.              * Falls die "Cursor-Down"-Taste gedrückt wurde, wird
  350.              * der oberste Eintrag des ListViews aktualisiert und
  351.              * auf den nächsten Eintrag gesetzt, falls es nicht
  352.              * schon der letzte oberste Eintrag war. Der globale
  353.              * Zähler topentry wird dann um eins erhöht.
  354.              */
  355.         case CURSORDOWN:
  356.               if (topentry < (countentries - newlvh))
  357.            {
  358.                topentry++;
  359.                SetMainLVTop(topentry);
  360.  
  361.             actualfindnode = GetNode(&ListeLVList, topentry);
  362.             actualfindnodenum = topentry;
  363.               }
  364.             break;
  365.  
  366.             /*
  367.              * Falls die "Cursor-Up"-Taste gedrückt wurde, wird
  368.              * der oberste Eintrag des ListViews aktualisiert und
  369.              * auf den vorherigen Eintrag gesetzt, falls es nicht
  370.              * schon der erste Eintrag der Liste war. Der globale
  371.              * Zähler topentry wird dann um eins erniedrigt.
  372.              */
  373.         case CURSORUP:
  374.               if (topentry > 0)
  375.            {
  376.                topentry--;
  377.                SetMainLVTop(topentry);
  378.  
  379.             actualfindnode = GetNode(&ListeLVList, topentry);
  380.             actualfindnodenum = topentry;
  381.               }
  382.             break;
  383.  
  384.             /*
  385.              * Das ListView zeigt den Anfang der Liste. Der
  386.              * Zähler topentry wird auf Null gesetzt.
  387.              */
  388.         case CURSORLEFT:
  389.             if (topentry != 0)
  390.             {
  391.                 topentry = 0;
  392.                 SetMainLVTop(topentry);
  393.  
  394.             actualfindnode = GetNode(&ListeLVList, topentry);
  395.             actualfindnodenum = topentry;
  396.             }
  397.             break;
  398.  
  399.             /*
  400.              * Das ListView zeigt das Ende der Liste. Der
  401.              * Zähler topentry wird auf den Eintrag mit der
  402.              * Nummer (Anzahl der Einträge - Anzahl der
  403.              * sichtbaren Einträge) gesetzt.
  404.              */
  405.         case CURSORRIGHT:
  406.             if (topentry != (countentries - newlvh))
  407.             {
  408.                 topentry = (countentries - newlvh);
  409.                 SetMainLVTop(topentry);
  410.  
  411.             actualfindnode = GetNode(&ListeLVList, topentry);
  412.             actualfindnodenum = topentry;
  413.             }
  414.             break;
  415.  
  416.         default:
  417. /*            PrintStatistics();*/
  418.             break;
  419.     }
  420.  
  421.     return;
  422. }
  423.  
  424.     /*
  425.      * Die Funktion SelectGadget() simuliert den
  426.      * Gadget-Down-Klick eines Boolean-Gadgets.
  427.      */
  428. static void
  429. SelectGadget(struct Gadget *Gadget)
  430. {
  431.     UWORD oldpos;
  432.  
  433.         /*
  434.          * Dazu wird das Gadget aus der Gadget-Liste
  435.          * entfernt, das SELECTED-Flag gesetzt und das Gadget
  436.          * wieder an der gleichen Position in die Liste
  437.          * eingehängt.
  438.          */
  439.     oldpos = RemoveGadget(SysWnd, Gadget);
  440.     Gadget->Flags |= GFLG_SELECTED;
  441.     AddGadget(SysWnd, Gadget, (ULONG) oldpos);
  442.  
  443.         /*
  444.          * Nun wird das Gadget wieder aktualisiert und ein
  445.          * wenig gewartet.
  446.          */
  447.     RefreshGList(Gadget, SysWnd, NULL, 1);
  448.  
  449.     return;
  450. }
  451.  
  452.     /*
  453.      * Die Funktion UnSelectGadget() simuliert den
  454.      * Gadget-Up-Klick eines Boolean-Gadgets.
  455.      */
  456. static void
  457. UnSelectGadget(struct Gadget *Gadget)
  458. {
  459.     UWORD oldpos;
  460.  
  461.         /*
  462.          * Dazu wird das Gadget aus der Gadget-Liste
  463.          * entfernt, das SELECTED-Flag entfernt und das
  464.          * Gadget wieder an der gleichen Position in die
  465.          * Liste eingehängt.
  466.          */
  467.     oldpos = RemoveGadget(SysWnd, Gadget);
  468.     Gadget->Flags &= ~GFLG_SELECTED;
  469.     AddGadget(SysWnd, Gadget, (ULONG) oldpos);
  470.  
  471.         /*
  472.          * Nun wird das Gadget wieder aktualisiert.
  473.          */
  474.     RefreshGList(Gadget, SysWnd, NULL, 1);
  475.  
  476.     return;
  477. }
  478.  
  479.     /*
  480.      * Die Procedure HandleVanillaKeys() wertet die
  481.      * Tastatureingaben des Hauptfensters aus. Dazu wird
  482.      * das Feld IntuiMessage->Code verwendet.
  483.      */
  484. static void
  485. HandleVanillaKeys(ULONG code, ULONG qualifier)
  486. {
  487.     int    ID;
  488.  
  489.    if (qualifier & CTRLKEYS) return;
  490.  
  491.         /*
  492.          * Wurde die Esc-Taste gedrückt, werden zwei Fälle
  493.          * unterschieden. Wurde RSys von der WB gestartet,
  494.          * geht RSys in den AppIcon-Modus, wurde es von einem
  495.          * CLI gestartet, wird RSys beendet, indem das globale
  496.          * Flag Flags.quit_flag gesetzt wird.
  497.          */
  498.     if ((char)code == ESC && !Flags.wb_start)
  499.     {
  500.       Flags.quit_flag = 1;
  501.         return;
  502.     }
  503.  
  504.         /*
  505.          * Wurde RSys mit dem Zip-Gadget verkleinert, werden
  506.          * keine Vanillakeys ausgewertet.
  507.          */
  508.     if (SysWnd->Flags & WFLG_ZOOMED)     return;
  509.  
  510.    if((char)ToUpper(code) == 'N')
  511.    {
  512.           SelectGadget(SysGadgets[GD_NewGad]);
  513.       RefreshList(LastID);
  514.           UnSelectGadget(SysGadgets[GD_NewGad]);
  515.       return;
  516.    }
  517.         /*
  518.          * Nun wird die Listen-ID aus dem Code des Gadgets
  519.          * ermittelt, dessen entsprechende Taste gedrückt
  520.          * wurde.
  521.          */
  522.     ID = position((int)code);
  523.  
  524.         /*
  525.          * Entspricht die ID einer Gadget-ID, wird das
  526.          * entsprechende Gadget aktiviert und die
  527.          * entsprechende Aktion ausgeführt.  Dabei wird die
  528.          * ID des aktuellen ListView-Inhalts in LastID
  529.          * gemerkt.
  530.          */
  531.     if ((ID < GD_SaveListGad) && (ID != ~0))
  532.     {
  533.       HandleHelp((enum RSysNumbers)ID);
  534.  
  535.          LastID = ID;
  536.  
  537.           SelectGadget(SysGadgets[LastID]);
  538.           RefreshList(ID);
  539.           UnSelectGadget(SysGadgets[LastID]);
  540.  
  541.         return;
  542.     }
  543.  
  544.         /*
  545.          * Wurde das Jump-Gadget aktiviert, schließt RSys sein
  546.          * Hauptfenster und öffnet es auf dem vordersten
  547.          * PublicScreen.
  548.          */
  549.     if (ID == GD_JumpGad)
  550.     {
  551.           Jump();
  552.         return;
  553.     }
  554.  
  555.         /*
  556.          * Kommt das Programm bis hierhin, konnte der
  557.          * Tastenklick nicht erkannt werden. Es erfolgt eine
  558.          * entsprechende Nachricht im Message-Feld von RSys.
  559.          */
  560.     PrintStatistics();
  561.  
  562.     return;
  563. }
  564.  
  565.     /*
  566.      * Die Prozedur HandleGadgets() verarbeitet die
  567.      * Gadgetevents. Zu einem Parameter gad wird die
  568.      * entsprechende Aktion ausgelöst.
  569.      */
  570. static void
  571. HandleGadgets(struct Gadget *gad)
  572. {
  573.     char    fileout[MAXFULLNAME];
  574.     int    ID = (int)gad->GadgetID;
  575.  
  576.    HandleHelp((enum RSysNumbers)ID);
  577.  
  578.    if(ID == GD_NewGad)
  579.    {
  580.       RefreshList(LastID);
  581.       return;
  582.    }
  583.  
  584.         /*
  585.          * Falls die ListView-Liste abgespeichert werden
  586.          * soll, wird ein Asl-Requester angeboten und die
  587.          * Liste in eine ausgewählte Datei als Textdatei
  588.          * weggeschrieben.
  589.          */
  590.     if (ID == GD_SaveListGad)
  591.     {
  592.         sprintf(fileout, "RSys-%s.dat", EntryAttr[LastID].ea_type);
  593.  
  594.         if (GetFile(SysWnd, "RAM:", fileout, "#?.dat", "Select File for saving list", "Save"))
  595.             SaveList(SysWnd, (char *)_fullpath, EntryAttr[LastID].ea_type, &ListeLVList, TRUE);
  596.  
  597.         return;
  598.     }
  599.  
  600.         /*
  601.          * Handelt es sich um die anderen Gadgets, wird
  602.          * entsprechend der GadgetID das ListView
  603.          * aktualisiert.
  604.          */
  605.     if (ID < GD_SaveListGad)
  606.     {
  607.         LastID = ID;
  608.         RefreshList(ID);
  609.  
  610.         return;
  611.     }
  612.  
  613.         /*
  614.          * Wurde das Jump-Gadget aktiviert, schließt RSys sein
  615.          * Hauptfenster und öffnet es auf dem vordersten
  616.          * PublicScreen.
  617.          */
  618.     if (ID == GD_JumpGad) Jump();
  619.  
  620.     return;
  621. }
  622.  
  623.     /*
  624.      * Die Prozedur HandleMenu() verwaltet die
  625.      * Menu-Eingaben.
  626.      */
  627. static void
  628. HandleMenu(ULONG code)
  629. {
  630.     struct MenuItem *item;
  631.     USHORT nextcode = (USHORT) code;
  632.     void    (*fptr) (void);
  633.     extern int ReopenWindow;
  634.  
  635.     ReopenWindow = FALSE;
  636.  
  637.     DPOS;
  638.  
  639.         /*
  640.          * Falls ein Menüpunkt ausgewählt wurde, wird das
  641.          * entsprechende Menü-Item ermittelt. Aus dem
  642.          * UserData-Feld dieses Menüpunktes erhält man
  643.          * schließlich einen Zeiger auf die Funktion, die
  644.          * ausgeführt werden soll.
  645.          * Erweiterung: Werden mehrere Menüpunkte hintereinander
  646.          * angewählt, ohne das Menü zu desaktivieren, werden
  647.          * auch alle ausgewählt.
  648.          */
  649.     while (nextcode != MENUNULL && !ReopenWindow)
  650.     {
  651.         if ((item = ItemAddress(SysMenus, (long)nextcode)) != NULL)
  652.         {
  653.                 /*
  654.                  * Falls das UserData-Feld initialisiert wurde, wird
  655.                  * der dort eingetragene Zeiger als Zeiger auf eine
  656.                  * auszuführende Funktion genommen und ausgeführt.
  657.                  */
  658.             if (fptr = GTMENUITEM_USERDATA(item))
  659.                 (*fptr) ();
  660.         }
  661.         else break;
  662.  
  663.         nextcode = item->NextSelect;
  664.     }
  665.  
  666.     return;
  667. }
  668.  
  669.     /*
  670.      * HandleMainPort() bearbeitet die Nachrichten vom RSys-
  671.      * Hauptfenster und ruft die entsprechenden Unter-
  672.      * programme auf
  673.      */
  674. void
  675. HandleMainPort(void)
  676. {
  677.     register struct IntuiMessage *message;
  678.     ULONG class,
  679.             code,
  680.             qualifier;
  681.     APTR    object;
  682.     static int     refr = TRUE;
  683.     int GID;
  684.    static int oldh;
  685.  
  686.     while ((message = (struct IntuiMessage *) GT_GetIMsg(SysWnd->UserPort)) != NULL)
  687.     {
  688.             /*
  689.              * Die wichtigsten Daten werden aus der erhaltenen
  690.              * Nachricht kopiert.
  691.              */
  692.         object = message->IAddress;
  693.         class = message->Class;
  694.         code = message->Code;
  695.         qualifier = message->Qualifier;
  696.  
  697.             /*
  698.              * Die Nachricht wird sofort beantwortet, damit
  699.              * Intuition nicht länger als notwendig auf eine
  700.              * Antwort wartet.
  701.              */
  702.         GT_ReplyIMsg(message);
  703.  
  704.       if(!Flags.helpmode && ICONIFY_REQUESTED)
  705.       {
  706.          Iconify();
  707.          ClearIntuiMsgPort(SysWnd);
  708.  
  709.          return;
  710.       }
  711.  
  712.             /*
  713.              * Entsprechend der Art (der Klasse) der Nachricht
  714.              * werden die Aktionen ausgeführt.
  715.              */
  716.         switch (class)
  717.         {
  718.                 /*
  719.                  * Ist die Volumes-Liste im ListView aktiv und wurde
  720.                  * ein Diskettenwechsel in den Laufwerken erkannt,
  721.                  * wird die Liste automatisch aktualisiert.
  722.                  */
  723.             case IDCMP_DISKINSERTED:
  724.             case IDCMP_DISKREMOVED:
  725.                 if (LastID == VOLUMES) RefreshList(LastID);
  726.  
  727.                 break;
  728.  
  729.                 /*
  730.                  * Wurde eine Taste gedrückt, wird eine entsprechende
  731.                  * Aktion gestartet. Falls ein Qualifier (also einer
  732.                  * der Shift-, Amiga- und Control-Tasten oder eine
  733.                  * Kombination von diesen) erkannt wurde, wird keine
  734.                  * Aktion gestartet.
  735.                  */
  736.             case IDCMP_VANILLAKEY:
  737.                 HandleVanillaKeys(code, qualifier);
  738.                 break;
  739.  
  740.                 /*
  741.                  * Wurde eine Taste oder Sondertaste gedrückt, wird
  742.                  * eine entsprechende Aktion gestartet.  Falls ein
  743.                  * Qualifier (also einer der Shift-, Amiga- und
  744.                  * Control-Tasten oder eine Kombination von diesen)
  745.                  * erkannt wurde, wird keine Aktion gestartet.
  746.                  */
  747.             case RAWKEY:
  748.                HandleRawKeys(code, qualifier);
  749.                 break;
  750.  
  751.                 /*
  752.                  * Wird ein Gadget auf dem Hauptfenster angeklickt,
  753.                  * wird eine entsprechende Aktion gestartet.  Wurde
  754.                  * das ListView angeklickt, wird versucht, den
  755.                  * Eintrag zu modifizieren.
  756.                  */
  757.             case IDCMP_GADGETUP:
  758.             GID = ((struct Gadget *) object)->GadgetID;
  759.  
  760.                 if (GID == GD_ListeLV)
  761.             {
  762.                HandleHelp((enum RSysNumbers)GID);
  763.                       ModifyObject(LastID, code);
  764.             }
  765.                 else HandleGadgets((struct Gadget *) object);
  766.                 break;
  767.  
  768.                 /*
  769.                  * Wird das Hauptfenster gezipt, wird der Inhalt des
  770.                  * Fensters und das Hintergrundmuster erneuert.
  771.                  */
  772.             case IDCMP_CHANGEWINDOW:
  773.                 if (NOT(SysWnd->Flags & WFLG_ZOOMED))
  774.                 {
  775.                         /*
  776.                          * Das Fenster soll nur EINMAL refreshed werden.
  777.                          * Diese IDCMP-Message kommt aber auch dann, wenn ein
  778.                          * Fenster verschoben wurde, weshalb ein Flag extra
  779.                          * eingeführt wurde.
  780.                          */
  781.                     if (NOT(refr))
  782.                     {
  783.                         RefreshMainWindowPattern();
  784.  
  785.                         refr = TRUE;
  786.  
  787.                         if (Flags.autofront)
  788.                         {
  789.                             WindowToFront(SysWnd);
  790.                             ActivateWindow(SysWnd);
  791.                         }
  792.                     }
  793.                 }
  794.                 else refr = FALSE;
  795.                 break;
  796.  
  797.          case IDCMP_SIZEVERIFY:
  798.             oldh = SysWnd->Height;
  799.             break;
  800.  
  801.          case IDCMP_NEWSIZE:
  802.             if((SysWnd->Height - oldh) != 0) ResizeWindowRefresh();
  803.             break;
  804.  
  805.                 /*
  806.                  * Ein Menüpunkt wurde ausgewählt.
  807.                  */
  808.             case MENUPICK:
  809.                 HandleMenu(code);
  810.                 break;
  811.  
  812.                 /*
  813.                  * Das Closegadget des Hauptfensters wurde geklickt.
  814.                  * Nach einer Sicherheitsabfrage wird das Programm
  815.                  * beendet.
  816.                  */
  817.             case IDCMP_CLOSEWINDOW:
  818.                 quit(TRUE);
  819.                 break;
  820.  
  821.          default:
  822.             break;
  823.         }
  824.     }
  825.  
  826.     return;
  827. }
  828.  
  829.     /*
  830.      * Das Hauptprogramm. Hier werden alle
  831.      * Intuition-Events abgeholt und die entsprechenden
  832.      * Auswerteprozeduren aufgerufen.
  833.      */
  834. void
  835. main(int argc, char **argv)
  836. {
  837.     ULONG mask;
  838.  
  839.     DPOS;
  840.         /*
  841.          * Das Flag, daß die Beendung des Programms
  842.          * signalisiert wird initialisiert.
  843.          */
  844.     Flags.quit_flag = 0;
  845.  
  846.     InstallTrapHandlers();
  847.  
  848.         /*
  849.          * Falls RSys vom CLI aus gestartet wurde, erscheint
  850.          * eine kleine Infozeile im CLI. Dann wird die
  851.          * globale Variable Flags.wb_start auf FALSE gesetzt, da
  852.          * das Programm in diesem Fall nicht von der WB aus
  853.          * gestartet wurde.
  854.          */
  855.     if (argc)
  856.     {
  857.         PutStr((UBYTE *) &v[7]);
  858.         Flags.wb_start = 0;
  859.     }
  860.    else Flags.wb_start = 1;
  861.  
  862.         /*
  863.          * Falls bei einem CLI-Aufruf Parameter mit angegeben
  864.          * wurden, werden diese ausgewertet.
  865.          */
  866.     if (argc >= 2) LastID = HandleArguments(argv);
  867.  
  868.         /*
  869.          * Es wird festgestellt, ob das Programm bereits
  870.          * gestartet wurde. Wurde es bereits gestartet, wird
  871.          * das Programm beendet. Dabei werden die evtl.
  872.          * angegebenen und verarbeiteten Parameter an das
  873.          * bereits laufende Programm verschickt.
  874.          */
  875.     if (SysStarted(LastID)) CloseAll();
  876.  
  877.         /*
  878.          * Alle notwendigen Ressourcen (Libraries, RSys-Ports
  879.          * etc.) werden eröffnet und bereitgestellt.
  880.          */
  881.     OpenLibs();
  882.  
  883.         /*
  884.          * Der ID-Port wird erzeugt. An der Existenz dieses
  885.          * Ports kann bei einem zweiten Aufruf des Programms
  886.          * festgestellt werden, ob RSys bereits gestartet
  887.          * wurde.
  888.          */
  889.     if (!(SysIdPort = CreatePort(ID_PORT_NAME, 0)))
  890.       ErrorHandle((char *)ID_PORT_NAME, PORT_ERR, CREATE_FAIL, KILL);
  891.  
  892.         /*
  893.          * Das ListView wird initialisiert.
  894.          */
  895.     NewList(&ListeLVList);
  896.  
  897.         /*
  898.          * Falls der Aufruf von der WB aus geschah, wird RSys
  899.          * "iconifiziert", d.h. ein AppIcon wird auf der
  900.          * WB erzeugt. Andernfalls wird das Hauptfenster
  901.          * geöffnet und entsprechend der Nummer LastID das
  902.          * ListView aktualisiert.
  903.          */
  904.     if (Flags.wb_start) Iconify();
  905.     else
  906.     {
  907.         OpenMainWindow();
  908.         RefreshList(LastID);
  909.     }
  910.  
  911.         /*
  912.          * Schleifenbeginn.    Solange, bis ein
  913.          * Abbruchkriterium erkannt wurde (Flags.quit_flag ist
  914.          * TRUE), wird auf das Setzen der entsprechenden
  915.          * Flags gewartet.
  916.          */
  917.     do
  918.     {
  919.             /*
  920.              * Warten auf folgende Events:
  921.              * - ^C wurde eingegeben
  922.              * - Events vom Hauptfenster
  923.              * - Events vom ID-Port
  924.              * - Events vom Broker-Port.
  925.              */
  926.         mask = Wait(SIGBREAKF_CTRL_C |
  927.                         (1L << SysWnd->UserPort->mp_SigBit) |
  928.                         (1L << SysIdPort->mp_SigBit) |
  929.                         (1L << broker_mp->mp_SigBit));
  930.  
  931.             /*
  932.              * Falls ein ^C eingegeben wurde, wird das
  933.              * Programmbeendigungsflag gesetzt.
  934.              */
  935.         if (CTRL_C_RECEIVED) Flags.quit_flag = 1;
  936.  
  937.             /*
  938.              * Wenn das Programm ein zweitesmal aufgerufen wird,
  939.              * erhält der ID-Port eine Nachricht.
  940.              */
  941.         if (ID_PORT_SIG_RECEIVED) HandleIDPort();
  942.  
  943.             /*
  944.              * Falls von dem System-Programm Exchange ein Signal
  945.              * gesendet wurde, wird es hier verarbeitet.
  946.              */
  947.         if (BROKER_PORT_SIG_RECEIVED) HandleBrokerPort();
  948.  
  949.             /*
  950.              * Falls das Hauptfenster ein Signal erhalten hat,
  951.              * werden die Daten der Nachricht(en) gemerkt und
  952.              * weiterverarbeitet.
  953.              */
  954.         if (WINDOW_PORT_SIG_RECEIVED) HandleMainPort();
  955.     }
  956.         /*
  957.          * Das Programm läuft solange, bis das Flags.quit_flag
  958.          * gesetzt wurde.
  959.          */
  960.     while (NOT((Flags.quit_flag)));
  961.  
  962.         /*
  963.          * Die geöffneten Resourcen werden geschlossen und
  964.          * das Programm beendet.
  965.          */
  966.     CloseAll();
  967.  
  968.    return;
  969. }
  970.