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

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