home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 4 / FreshFish_May-June1994.bin / bbs / amigalib / d993 / muiffr.lha / MUIFFR / src / muiffr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-05  |  67.7 KB  |  1,989 lines

  1. /*
  2.  *    muiffr.c        © by Martin Steppler
  3.  *
  4.  */
  5.  
  6. #include "muiffr.h"
  7. #include "muiffr_locale.h"
  8.  
  9. #define PROGNAME "MUI Fido File Request"
  10. #define REVISION "1.1"
  11. #define REVDATE "17.02.94"
  12. #define PROGTITLE PROGNAME " " REVISION " (" REVDATE ")"
  13. #define VERSION "$VER: " PROGTITLE
  14. #define AUTHOR "Martin Steppler"
  15. #define COPYRIGHT "© 1994 " AUTHOR
  16. #define ADDRESS COPYRIGHT "\n\
  17. Internet: steppler@pool.informatik.rwth-aachen.de\n\
  18. ADSP: steppler@cookies.adsp.sub.org\n\
  19. Fido: 2:242/7.12 Martin_Steppler@mowgli.fido.de\n\
  20. FidoLite: 2:2452/107.12\n"
  21.  
  22. #define CATALOGNAME "muiffr.catalog"
  23.  
  24. #define SEARCH_DOWN 0
  25. #define SEARCH_UP 1
  26.  
  27. #define TO_UPPER(x) ((x >= 'a' && x <= 'z') ? (x - ' ') : (x))
  28.  
  29. __chip UWORD StopWatch[(1 + 16 + 1) * 2] =
  30. {
  31.     0x0000,0x0000,
  32.  
  33.     0x0400,0x07C0,
  34.     0x0000,0x07C0,
  35.     0x0100,0x0380,
  36.     0x0000,0x07E0,
  37.     0x07C0,0x1FF8,
  38.     0x1FF0,0x3FEC,
  39.     0x3FF8,0x7FDE,
  40.     0x3FF8,0x7FBE,
  41.     0x7FFC,0xFF7F,
  42.     0x7EFC,0xFFFF,
  43.     0x7FFC,0xFFFF,
  44.     0x3FF8,0x7FFE,
  45.     0x3FF8,0x7FFE,
  46.     0x1FF0,0x3FFC,
  47.     0x07C0,0x1FF8,
  48.     0x0000,0x07E0,
  49.  
  50.     0x0000,0x0000
  51. };
  52.  
  53. static int InitAll(void);
  54. static void CleanUp(void);
  55. static int DoOpenLibs(void);
  56. static void DoOpenCatalog(void);
  57. static void DoCloseCatalog(void);
  58. static int DoNewMenu(void);
  59. static void LVListDBClick(void);
  60. static int CreateReqFileName(int quiet);
  61. static void LoadReqFile(int quiet);
  62. static void BoyerMoore(int direction);
  63. static int MisCharSearch(UBYTE *list_str, int list_len, UBYTE *find_str, int len);
  64. static void DoOpenFont(int quiet);
  65. static int AppendPassword(void);
  66. static void SetWaitPointer(APTR *win_obj);
  67. static void ClearWaitPointer(APTR *win_obj);
  68.  
  69. struct IntuitionBase *IntuitionBase;
  70. struct GfxBase *GfxBase;
  71. struct LocaleBase *LocaleBase;
  72. struct DosLibrary *DosBase;
  73. struct Library *MUIMasterBase;
  74. struct Library *DiskfontBase;
  75. struct Library *XpkBase;
  76.  
  77. struct Application *app;
  78.  
  79. static enum
  80. {
  81.     ID_PROJECT, ID_OPEN, ID_SAVE, ID_LABEL1, ID_FIND, ID_LABEL2,
  82.     ID_CLIP_CUT, ID_CLIP_COPY, ID_CLIP_PASTE, ID_LABEL3,
  83.     ID_ABOUT, ID_LABEL4, ID_QUIT, ID_END,
  84.  
  85.     ID_LV_MAIN_LIST_DBCLICK,
  86.     ID_LV_MAIN_REQUESTLIST_DBCLICK,
  87.     ID_ST_MAIN_REQUEST_READY,
  88.     ID_BT_MAIN_ALIASES,
  89.     ID_ST_MAIN_ALIASES_READY,
  90.     ID_BT_MAIN_CONFIGURATION,
  91.     ID_BT_MAIN_PASSWORD,
  92.     ID_ST_MAIN_PASSWORD_READY,
  93.     ID_ST_MAIN_FIND_READY,
  94.     ID_ST_MAIN_FIND_CHANGED,
  95.     ID_BT_MAIN_FIND_NEXT,
  96.     ID_BT_MAIN_FIND_PREV,
  97.     ID_BT_MAIN_LOAD,
  98.     ID_BT_MAIN_INSERT,
  99.     ID_BT_MAIN_DELETE,
  100.     ID_BT_MAIN_SAVE,
  101.     ID_BT_MAIN_DOWNLOAD,
  102.  
  103.     ID_CONF_QUIT,
  104.     ID_LV_CONF_NODELIST_DBCLICK,
  105.     ID_ST_CONF_ALIAS_READY,
  106.     ID_ST_CONF_NODE_READY,
  107.     ID_ST_CONF_LIST_READY,
  108.     ID_ST_CONF_FONT_READY,
  109.     ID_ST_CONF_PHONE_READY,
  110.     ID_ST_CONF_PASSWORD_READY,
  111.     ID_ST_CONF_VIANUMBER_READY,
  112.     ID_ST_CONF_VIAPHONE_READY,
  113.     ID_ST_CONF_NODELIST_READY,
  114.     ID_BT_CONF_NEW_NODE,
  115.     ID_BT_CONF_DELETE_NODE,
  116.     ID_CYA_CONF_TERM_LF,
  117.     ID_CYA_CONF_TERM_CRLF,
  118.     ID_SL_CONF_FILENAMEPOS,
  119.     ID_BT_CONF_LOADCONFIG,
  120.     ID_BT_CONF_SAVECONFIG,
  121.  
  122.     ID_MENU_CONFIGURATION, ID_MENU_CONF_NODES, ID_MENU_CONF_GLOBAL_SETTINGS,
  123.     ID_MENU_CONF_LABEL1, ID_MENU_CONF_ABOUT, ID_MENU_CONF_LABEL2,
  124.     ID_MENU_CONF_QUIT, ID_MENU_CONF_END,
  125.  
  126.     ID_ALI_QUIT,
  127.     ID_LV_ALI_NODELIST_DBCLICK
  128.  
  129. };
  130.  
  131. static enum
  132. {
  133.     RGP_CONF_NODES, RGP_CONF_GLOBAL_SETTINGS
  134. };
  135.  
  136. int wbmain(struct WBStartup *wbs)
  137. {
  138.     return (main(0, (char **)wbs));
  139. }
  140.  
  141. int main(int argc, char *argv[])
  142. {
  143.     int return_ok = RETURN_FAIL;
  144.     int running = TRUE;
  145.     APTR vg_Conf;
  146.  
  147.     if (!InitAll())
  148.         goto abort;
  149.  
  150.     {
  151.         UBYTE programpath[256], *programname;
  152.         struct WBStartup *wbs;
  153.         BPTR lock;
  154.  
  155.         if (argc)
  156.             // shell startup
  157.             GetProgramName(programpath, 256);
  158.         else
  159.         {
  160.             // workbench startup
  161.             wbs = (struct WBStartup *)argv;
  162.             programname = wbs->sm_ArgList->wa_Name;
  163.             lock = Lock(programname, ACCESS_READ);
  164.             if (lock)
  165.             {
  166.                 NameFromLock(lock, programpath, 256);
  167.                 UnLock(lock);
  168.             }
  169.             else
  170.                 strcpy(programpath, programname);
  171.         }
  172.         // get diskobj
  173.         app->app_DiskObject = GetDiskObject(programpath);
  174.     }
  175.  
  176.     app->app_cya_Conf_Termination[CYA_CONF_TERM_LF] = GetCatStr(MSG_GAD_CYA_CONF_TERM_LF);
  177.     app->app_cya_Conf_Termination[CYA_CONF_TERM_CRLF] = GetCatStr(MSG_GAD_CYA_CONF_TERM_CRLF);
  178.     app->app_rgp_Conf[RGP_CONF_NODES] = GetCatStr(MSG_GAD_RGP_CONF_NODES);
  179.     app->app_rgp_Conf[RGP_CONF_GLOBAL_SETTINGS] = GetCatStr(MSG_GAD_RGP_CONF_GLOBAL_SETTINGS);
  180.  
  181.     app->app_st_Conf_List = KeyString(app->app_Conf_ListBuf, sizeof(app->app_Conf_ListBuf), GetCatHotKey(MSG_GAD_ST_CONF_LIST_KEY));
  182.     app->app_im_Conf_List = PopButton(MUII_PopFile);
  183.     app->app_st_Conf_Font = KeyString(app->app_Conf_FontBuf, sizeof(app->app_Conf_FontBuf), GetCatHotKey(MSG_GAD_ST_CONF_FONT_KEY));
  184.     app->app_im_Conf_Font = PopButton(MUII_PopUp);
  185.  
  186.     // Configuration Window
  187.     vg_Conf =  VGroup,
  188.         Child, app->app_rg_Conf = RegisterGroup(app->app_rgp_Conf),
  189.             MUIA_Register_Frame, TRUE,
  190.             Child, VGroup,
  191.                 Child, app->app_lv_Conf_NodeList = ListviewObject,
  192.                     MUIA_Listview_List , ListObject,
  193.                         InputListFrame,
  194.                         End,
  195.                     End,
  196.                 Child, HGroup,
  197.                     Child, VGroup,
  198.                         Child, KeyLabel2(GetCatStr(MSG_GAD_ST_CONF_ALIAS), GetCatHotKey(MSG_GAD_ST_CONF_ALIAS_KEY)),
  199.                         Child, KeyLabel2(GetCatStr(MSG_GAD_ST_CONF_NODE), GetCatHotKey(MSG_GAD_ST_CONF_NODE_KEY)),
  200.                         Child, KeyLabel2(GetCatStr(MSG_GAD_ST_CONF_LIST), GetCatHotKey(MSG_GAD_ST_CONF_LIST_KEY)),
  201.                         Child, KeyLabel2(GetCatStr(MSG_GAD_ST_CONF_FONT), GetCatHotKey(MSG_GAD_ST_CONF_FONT_KEY)),
  202.                         End,
  203.  
  204.                     Child, VGroup,
  205.                         Child, ColGroup(3),
  206.                             Child, app->app_st_Conf_Alias = KeyString(app->app_Conf_AliasBuf, sizeof(app->app_Conf_AliasBuf), GetCatHotKey(MSG_GAD_ST_CONF_ALIAS_KEY)),
  207.                             Child, KeyLabel2(GetCatStr(MSG_GAD_ST_CONF_PHONE), GetCatHotKey(MSG_GAD_ST_CONF_PHONE_KEY)),
  208.                             Child, app->app_st_Conf_Phone = StringObject,
  209.                                 StringFrame,
  210.                                 MUIA_String_Accept, "0123456789- ",
  211.                                 MUIA_String_Contents, app->app_Conf_PhoneBuf,
  212.                                 MUIA_String_MaxLen, sizeof(app->app_Conf_PhoneBuf),
  213.                                 MUIA_ControlChar, GetCatHotKey(MSG_GAD_ST_CONF_PHONE_KEY),
  214.                                 End,
  215.  
  216.                             Child, app->app_st_Conf_Node = StringObject,
  217.                                 StringFrame,
  218.                                 MUIA_String_Accept, "0123456789:/.",
  219.                                 MUIA_String_Contents, app->app_Conf_NodeBuf,
  220.                                 MUIA_String_MaxLen, sizeof(app->app_Conf_NodeBuf),
  221.                                 MUIA_ControlChar, GetCatHotKey(MSG_GAD_ST_CONF_NODE_KEY),
  222.                                 End,
  223.  
  224.                             Child, KeyLabel2(GetCatStr(MSG_GAD_ST_CONF_PASSWORD), GetCatHotKey(MSG_GAD_ST_CONF_PASSWORD_KEY)),
  225.                             Child, app->app_st_Conf_Password = StringObject,
  226.                                 StringFrame,
  227.                                 MUIA_String_Contents, app->app_Conf_PasswordBuf,
  228.                                 MUIA_String_MaxLen, sizeof(app->app_Conf_PasswordBuf),
  229.                                 MUIA_ControlChar, GetCatHotKey(MSG_GAD_ST_CONF_PASSWORD_KEY),
  230.                                 MUIA_String_Secret, TRUE,
  231.                                 End,
  232.                             End,
  233.  
  234.                         Child, app->app_pa_Conf_List = PopaslObject,
  235.                             MUIA_Popstring_String, app->app_st_Conf_List,
  236.                             MUIA_Popstring_Button, app->app_im_Conf_List,
  237.                             ASLFR_TitleText, GetCatStr(MSG_INFO_SELECT_LIST),
  238.                             End,
  239.  
  240.                         Child, app->app_pa_Conf_Font = PopaslObject,
  241.                             MUIA_Popstring_String, app->app_st_Conf_Font,
  242.                             MUIA_Popstring_Button, app->app_im_Conf_Font,
  243.                             MUIA_Popasl_Type, ASL_FontRequest,
  244.                             ASLFO_TitleText, GetCatStr(MSG_INFO_SELECT_FONT),
  245.                             End,
  246.                         End,
  247.                     End,
  248.                 Child, HGroup,
  249.                     GroupSpacing(0),
  250.                     Child, app->app_bt_Conf_NewNode = KeyButton(GetCatStr(MSG_GAD_BT_CONF_NEW_NODE), GetCatHotKey(MSG_GAD_BT_CONF_NEW_NODE_KEY)),
  251.                     Child, app->app_bt_Conf_DeleteNode = KeyButton(GetCatStr(MSG_GAD_BT_CONF_DELETE_NODE), GetCatHotKey(MSG_GAD_BT_CONF_DELETE_NODE_KEY)),
  252.                     End,
  253.                 End,
  254.  
  255.             Child, VGroup,
  256.                 Child, VGroup,
  257.                     GroupFrameT(GetCatStr(MSG_GAD_GP_CONF_SETTINGS_DOWNLOAD)),
  258.  
  259.                     Child, ColGroup(2),
  260.                         Child, KeyLabel2(GetCatStr(MSG_GAD_ST_CONF_VIANUMBER), GetCatHotKey(MSG_GAD_ST_CONF_VIANUMBER_KEY)),
  261.                         Child, app->app_st_Conf_ViaNumber = KeyString(app->app_Conf_ViaNumberBuf, sizeof(app->app_Conf_ViaNumberBuf), GetCatHotKey(MSG_GAD_ST_CONF_VIANUMBER_KEY)),
  262.  
  263.                         Child, KeyLabel2(GetCatStr(MSG_GAD_ST_CONF_VIANODE), GetCatHotKey(MSG_GAD_ST_CONF_VIANODE_KEY)),
  264.                         Child, app->app_st_Conf_ViaNode = KeyString(app->app_Conf_ViaNodeBuf, sizeof(app->app_Conf_ViaNodeBuf), GetCatHotKey(MSG_GAD_ST_CONF_VIANODE_KEY)),
  265.  
  266.                         Child, KeyLabel2(GetCatStr(MSG_GAD_ST_CONF_NODELIST), GetCatHotKey(MSG_GAD_ST_CONF_NODELIST_KEY)),
  267.                         Child, app->app_pa_Conf_NodeList = PopaslObject,
  268.                             MUIA_Popstring_String, app->app_st_Conf_NodeList = KeyString(app->app_Conf_NodeListBuf, sizeof(app->app_Conf_NodeListBuf), GetCatHotKey(MSG_GAD_ST_CONF_NODELIST_KEY)),
  269.                             MUIA_Popstring_Button, app->app_im_Conf_NodeList = PopButton(MUII_PopDrawer),
  270.                             ASLFR_TitleText, GetCatStr(MSG_INFO_SELECT_DIR),
  271.                             ASLFR_DrawersOnly, TRUE,
  272.                             End,
  273.                         End,
  274.                     End,
  275.  
  276.                 Child, VGroup,
  277.                     GroupFrameT(GetCatStr(MSG_GAD_GP_CONF_SETTINGS_MISC)),
  278.  
  279.                     Child, ColGroup(2),
  280.                         Child, KeyLabel2(GetCatStr(MSG_GAD_ST_CONF_OUTBOUND), GetCatHotKey(MSG_GAD_ST_CONF_OUTBOUND_KEY)),
  281.                         Child, app->app_pa_Conf_Outbound = PopaslObject,
  282.                             MUIA_Popstring_String, app->app_st_Conf_Outbound = KeyString(app->app_Conf_OutboundBuf, sizeof(app->app_Conf_OutboundBuf), GetCatHotKey(MSG_GAD_ST_CONF_OUTBOUND_KEY)),
  283.                             MUIA_Popstring_Button, app->app_im_Conf_Outbound = PopButton(MUII_PopDrawer),
  284.                             ASLFR_TitleText, GetCatStr(MSG_INFO_SELECT_DIR),
  285.                             ASLFR_DrawersOnly, TRUE,
  286.                             End,
  287.  
  288.                         Child, KeyLabel1(GetCatStr(MSG_GAD_CY_CONF_TERMINATION), GetCatHotKey(MSG_GAD_CY_CONF_TERMINATION_KEY)),
  289.                         Child, app->app_cy_Conf_Termination = KeyCycle(app->app_cya_Conf_Termination, GetCatHotKey(MSG_GAD_CY_CONF_TERMINATION_KEY)),
  290.  
  291.                         Child, KeyLabel1(GetCatStr(MSG_GAD_SL_CONF_FILENAMEPOS), GetCatHotKey(MSG_GAD_SL_CONF_FILENAMEPOS_KEY)),
  292.                         Child, app->app_sl_Conf_FileNamePos = KeySlider(1, MAX_FILENAMEPOS, 1, GetCatHotKey(MSG_GAD_SL_CONF_FILENAMEPOS_KEY)),
  293.                         End,
  294.                     End,
  295.                 End,
  296.             End,
  297.  
  298.         Child, HGroup,
  299.             GroupSpacing(0),
  300.             Child, app->app_bt_Conf_LoadConfig = KeyButton(GetCatStr(MSG_GAD_BT_CONF_LOADCONFIG), GetCatHotKey(MSG_GAD_BT_CONF_LOADCONFIG_KEY)),
  301.             Child, app->app_bt_Conf_SaveConfig = KeyButton(GetCatStr(MSG_GAD_BT_CONF_SAVECONFIG), GetCatHotKey(MSG_GAD_BT_CONF_SAVECONFIG_KEY)),
  302.             End,
  303.         End;
  304.  
  305.     app->app_Muiffr = ApplicationObject,
  306.         MUIA_Application_Title         , PROGNAME,
  307.         MUIA_Application_Version       , VERSION,
  308.         MUIA_Application_Copyright     , COPYRIGHT,
  309.         MUIA_Application_Author        , AUTHOR,
  310.         MUIA_Application_Description   , GetCatStr(MSG_ABOUT_DESCRIPTION),
  311.         MUIA_Application_Base          , "MUIFFR",
  312.         MUIA_Application_Menu          , app->app_NewMenu,
  313.         MUIA_Application_DiskObject    , app->app_DiskObject,
  314.  
  315.         SubWindow,
  316.             app->app_wi_Alias = WindowObject,
  317.             MUIA_Window_Title, GetCatStr(MSG_GAD_GP_ALI_ALIAS),
  318.             MUIA_Window_ID, MAKE_ID('A','L','I','A'),
  319.             MUIA_Window_Menu, MUIV_Window_Menu_NoMenu,
  320.             WindowContents, VGroup,
  321.                 Child, VGroup,
  322.                     GroupFrameT(GetCatStr(MSG_GAD_GP_ALI_SELECT)),
  323.                     Child, app->app_lv_Ali_NodeList = ListviewObject,
  324.                         MUIA_Listview_List , ListObject,
  325.                             InputListFrame,
  326.                             End,
  327.                         End,
  328.                     End,
  329.                 End,
  330.             End,
  331.  
  332.         SubWindow,
  333.             app->app_wi_Configuration = WindowObject,
  334.             MUIA_Window_Title, GetCatStr(MSG_GAD_GP_CONF_CONFIGURATION),
  335.             MUIA_Window_ID, MAKE_ID('C','O','N','F'),
  336.             MUIA_Window_Menu, app->app_Conf_NewMenu,
  337.             WindowContents, vg_Conf,
  338.             End,
  339.  
  340.         SubWindow,
  341.             app->app_wi_Main = WindowObject,
  342.             MUIA_Window_Title, PROGTITLE,
  343.             MUIA_Window_ID, MAKE_ID('F','F','R','Q'),
  344.  
  345.             WindowContents, VGroup,
  346.                 Child, HGroup,
  347.                     GroupFrameT(GetCatStr(MSG_GAD_GP_MAIN_LIST)),
  348.                     Child, app->app_lv_Main_List = ListviewObject,
  349.                         MUIA_Listview_List , ListObject,
  350.                             InputListFrame,
  351.                             End,
  352.                         MUIA_Font, MUIV_Font_Fixed,
  353.                         End,
  354.                     End,
  355.  
  356.                 Child, HGroup,
  357.                     Child, VGroup,
  358.                         GroupFrameT(GetCatStr(MSG_GAD_GP_MAIN_SELECTED)),
  359.                         GroupSpacing(0),
  360.                         Child, app->app_lv_Main_RequestList = ListviewObject,
  361.                             MUIA_Listview_List, ListObject,
  362.                                 InputListFrame,
  363.                                 End,
  364.                             MUIA_Font, MUIV_Font_Fixed,
  365.                             MUIA_Listview_MultiSelect, TRUE,
  366.                             End,
  367.                         Child, app->app_st_Main_Request = String(app->app_Main_RequestBuf, sizeof(app->app_Main_RequestBuf)),
  368.                         End,
  369.  
  370.                     Child, VGroup,
  371.                         Child, VGroup,
  372.                             GroupFrameT(GetCatStr(MSG_GAD_GP_MAIN_CONFIGURATION)),
  373.                             GroupSpacing(1),
  374.                             Child, HGroup,
  375.                                 GroupSpacing(0),
  376.                                 Child, app->app_bt_Main_Aliases = KeyButton(GetCatStr(MSG_GAD_BT_MAIN_ALIASES), GetCatHotKey(MSG_GAD_BT_MAIN_ALIASES_KEY)),
  377.                                 Child, app->app_bt_Main_Configuration = KeyButton(GetCatStr(MSG_GAD_BT_MAIN_CONFIGURATION), GetCatHotKey(MSG_GAD_BT_MAIN_CONFIGURATION_KEY)),
  378.                                 End,
  379.                             Child, app->app_st_Main_Aliases = StringObject,
  380.                                 StringFrame,
  381.                                 MUIA_String_Contents, app->app_Main_AliasesBuf,
  382.                                 MUIA_String_MaxLen, sizeof(app->app_Main_AliasesBuf),
  383.                                 MUIA_String_Format, MUIV_String_Format_Center,
  384.                                 End,
  385.                             End,
  386.  
  387.                         Child, VGroup,
  388.                             GroupFrame,
  389.                             GroupSpacing(1),
  390.                             Child, HGroup,
  391.                                 GroupSpacing(1),
  392.                                 Child, app->app_bt_Main_Password = KeyButton(GetCatStr(MSG_GAD_BT_MAIN_PASSWORD), GetCatHotKey(MSG_GAD_BT_MAIN_PASSWORD_KEY)),
  393.                                 Child, app->app_st_Main_Password = StringObject,
  394.                                     StringFrame,
  395.                                     MUIA_String_Contents, app->app_Main_PasswordBuf,
  396.                                     MUIA_String_MaxLen, sizeof(app->app_Main_PasswordBuf),
  397.                                     MUIA_String_Secret, TRUE,
  398.                                     End,
  399.                                 End,
  400.                             Child, HGroup,
  401.                                 Child, KeyLabel2(GetCatStr(MSG_GAD_ST_MAIN_FIND), GetCatHotKey(MSG_GAD_ST_MAIN_FIND_KEY)),
  402.                                 Child, app->app_st_Main_Find = KeyString(app->app_Main_FindBuf, sizeof(app->app_Main_FindBuf), GetCatHotKey(MSG_GAD_ST_MAIN_FIND_KEY)),
  403.                                 End,
  404.  
  405.                             Child, VGroup,
  406.                                 GroupSpacing(0),
  407.                                 Child, ColGroup(2),
  408.                                     GroupSpacing(0),
  409.                                     Child, app->app_bt_Main_FindNext = KeyButton(GetCatStr(MSG_GAD_BT_MAIN_FIND_NEXT), GetCatHotKey(MSG_GAD_BT_MAIN_FIND_NEXT_KEY)),
  410.                                     Child, app->app_bt_Main_FindPrev = KeyButton(GetCatStr(MSG_GAD_BT_MAIN_FIND_PREV), GetCatHotKey(MSG_GAD_BT_MAIN_FIND_PREV_KEY)),
  411.  
  412.                                     Child, app->app_bt_Main_Insert = KeyButton(GetCatStr(MSG_GAD_BT_MAIN_INSERT), GetCatHotKey(MSG_GAD_BT_MAIN_INSERT_KEY)),
  413.                                     Child, app->app_bt_Main_Delete = KeyButton(GetCatStr(MSG_GAD_BT_MAIN_DELETE), GetCatHotKey(MSG_GAD_BT_MAIN_DELETE_KEY)),
  414.                                     End,
  415.  
  416.                                 Child, HGroup,
  417.                                     GroupSpacing(0),
  418.                                     Child, app->app_bt_Main_Load = KeyButton(GetCatStr(MSG_GAD_BT_MAIN_LOAD), GetCatHotKey(MSG_GAD_BT_MAIN_LOAD_KEY)),
  419.                                     Child, app->app_bt_Main_Save = KeyButton(GetCatStr(MSG_GAD_BT_MAIN_SAVE), GetCatHotKey(MSG_GAD_BT_MAIN_SAVE_KEY)),
  420.                                     Child, app->app_bt_Main_Download = KeyButton(GetCatStr(MSG_GAD_BT_MAIN_DOWNLOAD), GetCatHotKey(MSG_GAD_BT_MAIN_DOWNLOAD_KEY)),
  421.                                     End,
  422.                                 End,
  423.                             End,
  424.                         End,
  425.                     End,
  426.                 End,
  427.             End,
  428.         End;
  429.  
  430.     if (!app->app_Muiffr)
  431.     {
  432.         puts("Unable to create application.");
  433.         goto abort;
  434.     }
  435.  
  436.     // Main Window
  437.     DoMethod(app->app_wi_Main, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, app->app_Muiffr, 2, MUIM_Application_ReturnID, ID_QUIT);
  438.     DoMethod(app->app_lv_Main_List, MUIM_Notify, MUIA_Listview_DoubleClick, TRUE, app->app_Muiffr, 2, MUIM_Application_ReturnID, ID_LV_MAIN_LIST_DBCLICK);
  439.     DoMethod(app->app_lv_Main_RequestList, MUIM_Notify, MUIA_Listview_DoubleClick, TRUE, app->app_Muiffr, 2, MUIM_Application_ReturnID, ID_LV_MAIN_REQUESTLIST_DBCLICK);
  440.     DoMethod(app->app_st_Main_Request, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, app->app_Muiffr, 2, MUIM_Application_ReturnID, ID_ST_MAIN_REQUEST_READY);
  441.     DoMethod(app->app_bt_Main_Aliases, MUIM_Notify, MUIA_Pressed, FALSE, app->app_Muiffr, 2, MUIM_Application_ReturnID, ID_BT_MAIN_ALIASES);
  442.     DoMethod(app->app_st_Main_Aliases, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, app->app_Muiffr, 2, MUIM_Application_ReturnID, ID_ST_MAIN_ALIASES_READY);
  443.     DoMethod(app->app_bt_Main_Configuration, MUIM_Notify, MUIA_Pressed, FALSE, app->app_Muiffr, 2, MUIM_Application_ReturnID, ID_BT_MAIN_CONFIGURATION);
  444.     DoMethod(app->app_bt_Main_Password, MUIM_Notify, MUIA_Pressed, FALSE, app->app_Muiffr, 2, MUIM_Application_ReturnID, ID_BT_MAIN_PASSWORD);
  445.     DoMethod(app->app_st_Main_Password, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, app->app_Muiffr, 2, MUIM_Application_ReturnID, ID_ST_MAIN_PASSWORD_READY);
  446.     DoMethod(app->app_st_Main_Find, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, app->app_Muiffr, 2, MUIM_Application_ReturnID, ID_ST_MAIN_FIND_READY);
  447.     DoMethod(app->app_st_Main_Find, MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, app->app_Muiffr, 2, MUIM_Application_ReturnID, ID_ST_MAIN_FIND_CHANGED);
  448.     DoMethod(app->app_bt_Main_FindNext, MUIM_Notify, MUIA_Pressed, FALSE, app->app_Muiffr, 2, MUIM_Application_ReturnID, ID_BT_MAIN_FIND_NEXT);
  449.     DoMethod(app->app_bt_Main_FindPrev, MUIM_Notify, MUIA_Pressed, FALSE, app->app_Muiffr, 2, MUIM_Application_ReturnID, ID_BT_MAIN_FIND_PREV);
  450.     DoMethod(app->app_bt_Main_Load, MUIM_Notify, MUIA_Pressed, FALSE, app->app_Muiffr, 2, MUIM_Application_ReturnID, ID_BT_MAIN_LOAD);
  451.     DoMethod(app->app_bt_Main_Insert, MUIM_Notify, MUIA_Pressed, FALSE, app->app_Muiffr, 2, MUIM_Application_ReturnID, ID_BT_MAIN_INSERT);
  452.     DoMethod(app->app_bt_Main_Delete, MUIM_Notify, MUIA_Pressed, FALSE, app->app_Muiffr, 2, MUIM_Application_ReturnID, ID_BT_MAIN_DELETE);
  453.     DoMethod(app->app_bt_Main_Save, MUIM_Notify, MUIA_Pressed, FALSE, app->app_Muiffr, 2, MUIM_Application_ReturnID, ID_BT_MAIN_SAVE);
  454.     DoMethod(app->app_bt_Main_Download, MUIM_Notify, MUIA_Pressed, FALSE, app->app_Muiffr, 2, MUIM_Application_ReturnID, ID_BT_MAIN_DOWNLOAD);
  455.  
  456.     DoMethod(app->app_wi_Main, MUIM_Window_SetCycleChain,
  457.              app->app_lv_Main_List,
  458.              app->app_lv_Main_RequestList,
  459.              app->app_st_Main_Request,
  460.              app->app_bt_Main_Aliases,
  461.              app->app_bt_Main_Configuration,
  462.              app->app_st_Main_Aliases,
  463.              app->app_bt_Main_Password,
  464.              app->app_st_Main_Password,
  465.              app->app_st_Main_Find,
  466.              app->app_bt_Main_FindNext,
  467.              app->app_bt_Main_FindPrev,
  468.              app->app_bt_Main_Insert,
  469.              app->app_bt_Main_Delete,
  470.              app->app_bt_Main_Load,
  471.              app->app_bt_Main_Save,
  472.              app->app_bt_Main_Download,
  473.              NULL);
  474.  
  475.     // Configuration Window
  476.     DoMethod(app->app_wi_Configuration, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, app->app_Muiffr, 2, MUIM_Application_ReturnID, ID_CONF_QUIT);
  477.     DoMethod(app->app_lv_Conf_NodeList, MUIM_Notify, MUIA_Listview_DoubleClick, TRUE, app->app_Muiffr, 2, MUIM_Application_ReturnID, ID_LV_CONF_NODELIST_DBCLICK);
  478.     DoMethod(app->app_st_Conf_Alias, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, app->app_Muiffr, 2, MUIM_Application_ReturnID, ID_ST_CONF_ALIAS_READY);
  479.     DoMethod(app->app_st_Conf_Phone, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, app->app_Muiffr, 2, MUIM_Application_ReturnID, ID_ST_CONF_PHONE_READY);
  480.     DoMethod(app->app_st_Conf_Node, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, app->app_Muiffr, 2, MUIM_Application_ReturnID, ID_ST_CONF_NODE_READY);
  481.     DoMethod(app->app_st_Conf_Password, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, app->app_Muiffr, 2, MUIM_Application_ReturnID, ID_ST_CONF_PASSWORD_READY);
  482.     DoMethod(app->app_st_Conf_List, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, app->app_Muiffr, 2, MUIM_Application_ReturnID, ID_ST_CONF_LIST_READY);
  483.     DoMethod(app->app_st_Conf_Font, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, app->app_Muiffr, 2, MUIM_Application_ReturnID, ID_ST_CONF_FONT_READY);
  484.     DoMethod(app->app_bt_Conf_NewNode, MUIM_Notify, MUIA_Pressed, FALSE, app->app_Muiffr, 2, MUIM_Application_ReturnID, ID_BT_CONF_NEW_NODE);
  485.     DoMethod(app->app_bt_Conf_DeleteNode, MUIM_Notify, MUIA_Pressed, FALSE, app->app_Muiffr, 2, MUIM_Application_ReturnID, ID_BT_CONF_DELETE_NODE);
  486.     DoMethod(app->app_cy_Conf_Termination, MUIM_Notify, MUIA_Cycle_Active, CYA_CONF_TERM_LF, app->app_Muiffr, 2, MUIM_Application_ReturnID, ID_CYA_CONF_TERM_LF);
  487.     DoMethod(app->app_cy_Conf_Termination, MUIM_Notify, MUIA_Cycle_Active, CYA_CONF_TERM_CRLF, app->app_Muiffr, 2, MUIM_Application_ReturnID, ID_CYA_CONF_TERM_CRLF);
  488.     DoMethod(app->app_sl_Conf_FileNamePos, MUIM_Notify, MUIA_Slider_Level, MUIV_EveryTime, app->app_Muiffr, 2, MUIM_Application_ReturnID, ID_SL_CONF_FILENAMEPOS);
  489.     DoMethod(app->app_bt_Conf_LoadConfig, MUIM_Notify, MUIA_Pressed, FALSE, app->app_Muiffr, 2, MUIM_Application_ReturnID, ID_BT_CONF_LOADCONFIG);
  490.     DoMethod(app->app_bt_Conf_SaveConfig, MUIM_Notify, MUIA_Pressed, FALSE, app->app_Muiffr, 2, MUIM_Application_ReturnID, ID_BT_CONF_SAVECONFIG);
  491.  
  492.     DoMethod(app->app_wi_Configuration, MUIM_Window_SetCycleChain,
  493.              app->app_lv_Conf_NodeList,
  494.              app->app_st_Conf_Alias,
  495.              app->app_st_Conf_Node,
  496.              app->app_st_Conf_Phone,
  497.              app->app_st_Conf_Password,
  498.              app->app_st_Conf_List,
  499.              app->app_im_Conf_List,
  500.              app->app_st_Conf_Font,
  501.              app->app_im_Conf_Font,
  502.              app->app_bt_Conf_NewNode,
  503.              app->app_bt_Conf_DeleteNode,
  504.              app->app_st_Conf_ViaNumber,
  505.              app->app_st_Conf_ViaNode,
  506.              app->app_st_Conf_NodeList,
  507.              app->app_im_Conf_NodeList,
  508.              app->app_st_Conf_Outbound,
  509.              app->app_im_Conf_Outbound,
  510.              app->app_cy_Conf_Termination,
  511.              app->app_sl_Conf_FileNamePos,
  512.              app->app_bt_Conf_LoadConfig,
  513.              app->app_bt_Conf_SaveConfig,
  514.              NULL);
  515.  
  516.     // Alias Window
  517.     DoMethod(app->app_wi_Alias, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, app->app_Muiffr, 2, MUIM_Application_ReturnID, ID_ALI_QUIT);
  518.     DoMethod(app->app_lv_Ali_NodeList, MUIM_Notify, MUIA_Listview_DoubleClick, TRUE, app->app_Muiffr, 2, MUIM_Application_ReturnID, ID_LV_ALI_NODELIST_DBCLICK);
  519.  
  520.     if (LoadConfig(TRUE))
  521.         LoadReqFile(TRUE);
  522.  
  523.     // default objects
  524.     set(app->app_wi_Main, MUIA_Window_DefaultObject, app->app_lv_Main_List);
  525.     set(app->app_wi_Configuration, MUIA_Window_DefaultObject, app->app_lv_Conf_NodeList);
  526.     set(app->app_wi_Alias, MUIA_Window_DefaultObject, app->app_lv_Ali_NodeList);
  527.  
  528.     // active object
  529.     set(app->app_wi_Main, MUIA_Window_ActiveObject, app->app_lv_Main_List);
  530.  
  531.     // open window
  532.     set(app->app_wi_Main, MUIA_Window_Open, TRUE);
  533.  
  534.     {
  535.         UBYTE *buf = " ";
  536.  
  537.         // in order to prevent a MUI bug
  538.         // (displaying the first element twice in a list at creation time,
  539.         // although there is only one physical entry)
  540.         // add and remove item
  541.         DoMethod(app->app_lv_Main_RequestList, MUIM_List_Insert,
  542.                  &buf, 1, MUIV_List_Insert_Bottom);
  543.         DoMethod(app->app_lv_Main_RequestList, MUIM_List_Remove, MUIV_List_Remove_Last);
  544.     }
  545.  
  546.     while (running)
  547.     {
  548.         ULONG signal, id;
  549.  
  550.         switch (id = DoMethod(app->app_Muiffr, MUIM_Application_Input, &signal))
  551.         {
  552.         case ID_CLIP_CUT:
  553.             CutClip();
  554.             break;
  555.  
  556.         case ID_CLIP_COPY:
  557.             CopyClip();
  558.             break;
  559.  
  560.         case ID_CLIP_PASTE:
  561.             PasteClip();
  562.             break;
  563.  
  564.         case ID_ABOUT:
  565.             MUI_Request(app->app_Muiffr, app->app_wi_Main, 0, NULL,
  566.                         GetCatStr(MSG_OKAY),
  567.                         "\33u%s\33n\n\n%s\n\n%s\n%s\n\n%s %s",
  568.                         PROGTITLE,
  569.                         GetCatStr(MSG_ABOUT_DESCRIPTION),
  570.                         ADDRESS,
  571.                         GetCatStr(MSG_ABOUT_COPYRIGHT),
  572.                         GetCatStr(MSG_ABOUT_MUI),
  573.                         "Stefan Stuntz.",
  574.                         TAG_END);
  575.             break;
  576.  
  577.         case MUIV_Application_ReturnID_Quit :
  578.         case ID_QUIT:
  579.             {
  580.                 LONG active;
  581.  
  582.                 get(app->app_pa_Conf_List, MUIA_Popasl_Active, &active);
  583.                 if (!active)
  584.                     get(app->app_pa_Conf_Font, MUIA_Popasl_Active, &active);
  585.                 if (!active)
  586.                     get(app->app_pa_Conf_Outbound, MUIA_Popasl_Active, &active);
  587.  
  588.                 if (active)
  589.                     DispError(MSG_ERROR_ASL_POPUPS, NULL);
  590.                 else
  591.                     running = FALSE;
  592.             }
  593.             break;
  594.  
  595.         case ID_LV_MAIN_LIST_DBCLICK:
  596.             LVListDBClick();
  597.             break;
  598.  
  599.         case ID_LV_MAIN_REQUESTLIST_DBCLICK:
  600.             {
  601.                 LONG pos;
  602.                 UBYTE *line;
  603.  
  604.                 // cursor position
  605.                 get(app->app_lv_Main_RequestList, MUIA_List_Active, &pos);
  606.  
  607.                 if (pos >= 0)
  608.                 {
  609.                     // get active line
  610.                     DoMethod(app->app_lv_Main_RequestList, MUIM_List_GetEntry, pos, &line);
  611.                     // set string
  612.                     set(app->app_st_Main_Request, MUIA_String_Contents, line);
  613.                 }
  614.             }
  615.             break;
  616.  
  617.         case ID_ST_MAIN_REQUEST_READY:
  618.         case ID_BT_MAIN_INSERT:
  619.             {
  620.                 UBYTE *buf;
  621.  
  622.                 get(app->app_st_Main_Request, MUIA_String_Contents, &buf);
  623.                 if (*buf)
  624.                 {
  625.                     AddListEntry(buf, FALSE);
  626.                     set(app->app_wi_Main, MUIA_Window_ActiveObject, app->app_st_Main_Request);
  627.                 }
  628.             }
  629.             break;
  630.  
  631.         case ID_BT_MAIN_ALIASES:
  632.             if (!app->app_NodeList)
  633.                 DispError(MSG_ERROR_NO_ALIAS, NULL);
  634.             else
  635.             {
  636.                 LONG pos = -1;
  637.                 struct NodeList *nl = app->app_NodeList;
  638.  
  639.                 set(app->app_wi_Configuration, MUIA_Window_Open, FALSE);
  640.                 get(app->app_lv_Conf_NodeList, MUIA_List_Active, &pos);
  641.  
  642.                 for (; nl; nl = nl->nl_Next)
  643.                     DoMethod(app->app_lv_Ali_NodeList, MUIM_List_Insert,
  644.                              &nl->nl_Alias, 1, MUIV_List_Insert_Bottom);
  645.                 set(app->app_lv_Ali_NodeList, MUIA_List_Active, pos);
  646.                 set(app->app_wi_Alias, MUIA_Window_ActiveObject, app->app_lv_Ali_NodeList);
  647.                 set(app->app_wi_Alias, MUIA_Window_Open, TRUE);
  648.                 set(app->app_bt_Main_Configuration, MUIA_Disabled, TRUE);
  649.                 set(app->app_bt_Main_Aliases, MUIA_Disabled, TRUE);
  650.             }
  651.             break;
  652.  
  653.         case ID_ST_MAIN_ALIASES_READY:
  654.             {
  655.                 LONG pos = 0, count = -1;
  656.                 struct NodeList *nl = app->app_NodeList;
  657.                 UBYTE *buf;
  658.  
  659.                 if (!nl)
  660.                     DispError(MSG_ERROR_NO_ALIAS, NULL);
  661.                 else
  662.                 {
  663.                     get(app->app_lv_Conf_NodeList, MUIA_List_Entries, &count);
  664.                     get(app->app_st_Main_Aliases, MUIA_String_Contents, &buf);
  665.  
  666.                     for (; pos < count; pos++, nl = nl->nl_Next)
  667.                         if (!strcmp(buf, nl->nl_Alias))
  668.                             break;
  669.  
  670.                     if (pos < count)
  671.                     {
  672.                         // refresh configuration window
  673.                         set(app->app_lv_Conf_NodeList, MUIA_List_Active, pos);
  674.                         NodeListDoubleClick();
  675.                         ReadList(FALSE);
  676.                     }
  677.                     else
  678.                         DispError(MSG_ERROR_UNKNOWN_ALIAS, buf);
  679.                 }
  680.             }
  681.             break;
  682.  
  683.         case ID_BT_MAIN_CONFIGURATION:
  684.             set(app->app_wi_Configuration, MUIA_Window_Open, TRUE);
  685.             set(app->app_bt_Main_Configuration, MUIA_Disabled, TRUE);
  686.             break;
  687.  
  688.         case ID_BT_MAIN_PASSWORD:
  689.         case ID_ST_MAIN_PASSWORD_READY:
  690.             AppendPassword();
  691.             break;
  692.  
  693.         case ID_FIND:
  694.             set(app->app_wi_Main, MUIA_Window_ActiveObject, app->app_st_Main_Find);
  695.             // no break;
  696.  
  697.         case ID_ST_MAIN_FIND_CHANGED:
  698.             app->app_Flags |= APP_FIND_CHANGED;
  699.             break;
  700.  
  701.         case ID_ST_MAIN_FIND_READY:
  702.         case ID_BT_MAIN_FIND_NEXT:
  703.             BoyerMoore(SEARCH_DOWN);
  704.             break;
  705.  
  706.         case ID_BT_MAIN_FIND_PREV:
  707.             BoyerMoore(SEARCH_UP);
  708.             break;
  709.  
  710.         case ID_BT_MAIN_LOAD:
  711.         case ID_OPEN:
  712.             LoadReqFile(FALSE);
  713.             break;
  714.  
  715.         case ID_BT_MAIN_DELETE:
  716.             DeleteListEntry();
  717.             break;
  718.  
  719.         case ID_BT_MAIN_SAVE:
  720.         case ID_SAVE:
  721.             SaveReqFile();
  722.             break;
  723.  
  724.         case ID_BT_MAIN_DOWNLOAD:
  725.             Download();
  726.             break;
  727.  
  728.         // Configuration Window
  729.         case ID_CONF_QUIT:
  730.             set(app->app_bt_Main_Configuration, MUIA_Disabled, FALSE);
  731.             set(app->app_wi_Configuration, MUIA_Window_Open, FALSE);
  732.             break;
  733.  
  734.         case ID_LV_CONF_NODELIST_DBCLICK:
  735.             NodeListDoubleClick();
  736.             break;
  737.  
  738.         case ID_ST_CONF_ALIAS_READY:
  739.             ConfAliasReady();
  740.             set(app->app_wi_Configuration, MUIA_Window_ActiveObject, app->app_st_Conf_Node);
  741.             break;
  742.  
  743.         case ID_ST_CONF_NODE_READY:
  744.             UpdateNodelist(NODE_BUF_NUM);
  745.             set(app->app_wi_Configuration, MUIA_Window_ActiveObject, app->app_st_Conf_Phone);
  746.             break;
  747.  
  748.         case ID_ST_CONF_PHONE_READY:
  749.             UpdateNodelist(PHONE_BUF_NUM);
  750.             set(app->app_wi_Configuration, MUIA_Window_ActiveObject, app->app_st_Conf_Password);
  751.             break;
  752.  
  753.         case ID_ST_CONF_PASSWORD_READY:
  754.             UpdateNodelist(PASSWORD_BUF_NUM);
  755.             set(app->app_wi_Configuration, MUIA_Window_ActiveObject, app->app_st_Conf_List);
  756.             break;
  757.  
  758.         case ID_ST_CONF_LIST_READY:
  759.             UpdateNodelist(LIST_BUF_NUM);
  760.             set(app->app_wi_Configuration, MUIA_Window_ActiveObject, app->app_st_Conf_Font);
  761.             break;
  762.  
  763.         case ID_ST_CONF_FONT_READY:
  764.             UpdateNodelist(FONT_BUF_NUM);
  765.             set(app->app_wi_Configuration, MUIA_Window_ActiveObject, app->app_st_Conf_Alias);
  766.             break;
  767.  
  768.         case ID_BT_CONF_NEW_NODE:
  769.             AddNodeListEntryInteractively();
  770.             set(app->app_wi_Configuration, MUIA_Window_ActiveObject, app->app_st_Conf_Alias);
  771.             break;
  772.  
  773.         case ID_BT_CONF_DELETE_NODE:
  774.             DeleteNodeListEntry();
  775.             set(app->app_wi_Configuration, MUIA_Window_ActiveObject, app->app_st_Conf_Alias);
  776.             break;
  777.  
  778.         case ID_CYA_CONF_TERM_LF:
  779.             app->app_Flags &= ~APP_CYA_CONF_TERM_CRLF;
  780.             break;
  781.  
  782.         case ID_CYA_CONF_TERM_CRLF:
  783.             app->app_Flags |= APP_CYA_CONF_TERM_CRLF;
  784.             break;
  785.  
  786.         case ID_SL_CONF_FILENAMEPOS:
  787.             break;
  788.  
  789.         case ID_BT_CONF_LOADCONFIG:
  790.             SetWaitPointer(app->app_wi_Configuration);
  791.             SetWaitPointer(app->app_wi_Main);
  792.             LoadConfig(FALSE);
  793.             ClearWaitPointer(app->app_wi_Configuration);
  794.             ClearWaitPointer(app->app_wi_Main);
  795.             break;
  796.  
  797.         case ID_BT_CONF_SAVECONFIG:
  798.             SaveConfig();
  799.             break;
  800.  
  801.         case ID_MENU_CONF_NODES:
  802.             set(app->app_rg_Conf, MUIA_Group_ActivePage, 0);
  803.             break;
  804.  
  805.         case ID_MENU_CONF_GLOBAL_SETTINGS:
  806.             set(app->app_rg_Conf, MUIA_Group_ActivePage, 1);
  807.             break;
  808.  
  809.         // Alias Window
  810.         case ID_ALI_QUIT:
  811.             set(app->app_bt_Main_Configuration, MUIA_Disabled, FALSE);
  812.             set(app->app_bt_Main_Aliases, MUIA_Disabled, FALSE);
  813.             set(app->app_wi_Alias, MUIA_Window_Open, FALSE);
  814.             DoMethod(app->app_lv_Ali_NodeList, MUIM_List_Clear, TAG_IGNORE);
  815.             break;
  816.  
  817.         case ID_LV_ALI_NODELIST_DBCLICK:
  818.             {
  819.                 LONG pos = -1, pos_bak;
  820.                 struct NodeList *nl = app->app_NodeList;
  821.  
  822.                 // close window
  823.                 set(app->app_wi_Alias, MUIA_Window_Open, FALSE);
  824.                 get(app->app_lv_Ali_NodeList, MUIA_List_Active, &pos);
  825.  
  826.                 SetWaitPointer(app->app_wi_Main);
  827.                 pos_bak = pos;
  828.                 if (pos >= 0)
  829.                 {
  830.                     // jump to selected entry
  831.                     while (pos > 0)
  832.                     {
  833.                         nl = nl->nl_Next;
  834.                         pos--;
  835.                     }
  836.                     // set alias str in main window
  837.                     strcpy(app->app_Main_AliasesBuf, nl->nl_Alias);
  838.                     set(app->app_st_Main_Aliases, MUIA_String_Contents, app->app_Main_AliasesBuf);
  839.                     // refresh configuration window
  840.                     set(app->app_lv_Conf_NodeList, MUIA_List_Active, pos_bak);
  841.                     NodeListDoubleClick();
  842.                     ReadList(FALSE);
  843.                 }
  844.                 set(app->app_bt_Main_Configuration, MUIA_Disabled, FALSE);
  845.                 set(app->app_bt_Main_Aliases, MUIA_Disabled, FALSE);
  846.                 DoMethod(app->app_lv_Ali_NodeList, MUIM_List_Clear, TAG_IGNORE);
  847.                 ClearWaitPointer(app->app_wi_Main);
  848.             }
  849.             break;
  850.  
  851.         default:
  852.             if (id)
  853.                 printf("ID: %d = %08lx\n", id, id);
  854.             break;
  855.         }
  856.  
  857.         if (running && signal)
  858.             Wait(signal);
  859.     }
  860.  
  861.     return_ok = RETURN_OK;
  862. abort:
  863.     CleanUp();
  864.     return (return_ok);
  865. }
  866.  
  867. static void CleanUp(void)
  868. {
  869.     if (app)
  870.     {
  871.         if (app->app_Muiffr)
  872.             MUI_DisposeObject(app->app_Muiffr);
  873.         if (app->app_DiskObject)
  874.             FreeDiskObject(app->app_DiskObject);
  875.         if (app->app_NewMenu)
  876.             FreeVec(app->app_NewMenu);
  877.         if (app->app_Conf_NewMenu)
  878.             FreeVec(app->app_Conf_NewMenu);
  879.         if (app->app_List)
  880.         {
  881.             UBYTE **list_bak = app->app_List;
  882.  
  883.             do
  884.             {
  885.                 // free strings
  886.                 if (*list_bak)
  887.                     FreeVec(*list_bak++);
  888.             }
  889.             while (*list_bak);
  890.             FreeVec(app->app_List);
  891.         }
  892.         if (app->app_RequestList)
  893.         {
  894.             struct RequestList *rl = app->app_RequestList, *rl_next;
  895.  
  896.             do
  897.             {
  898.                 if (rl->rl_Buffer)
  899.                     FreeVec(rl->rl_Buffer);
  900.                 rl_next = rl->rl_Next;
  901.                 FreeVec(rl);
  902.                 rl = rl_next;
  903.             }
  904.             while (rl);
  905.         }
  906.         ClearNodeList();
  907.         if (app->app_Font)
  908.             CloseFont(app->app_Font);
  909.     }
  910.     DoCloseCatalog();
  911.     if (app)
  912.         FreeVec(app);
  913.     if (MUIMasterBase)
  914.         CloseLibrary(MUIMasterBase);
  915.     if (IconBase)
  916.         CloseLibrary(IconBase);
  917.     if (DosBase)
  918.         CloseLibrary((struct Library *)DosBase);
  919.     if (GfxBase)
  920.         CloseLibrary((struct Library *)GfxBase);
  921.     if (IntuitionBase)
  922.         CloseLibrary((struct Library *)IntuitionBase);
  923. }
  924.  
  925. static int InitAll(void)
  926. {
  927.     int return_ok = FALSE;
  928.  
  929.     if (!DoOpenLibs())
  930.         goto abort;
  931.  
  932.     if (!(app = (struct Application *)AllocVec(sizeof(struct Application), MEMF_CLEAR)))
  933.     {
  934.         puts("Out of memory!");
  935.         goto abort;
  936.     }
  937.  
  938.     DoOpenCatalog();
  939.     if (!DoNewMenu())
  940.         goto abort;
  941.  
  942.     return_ok = TRUE;
  943. abort:
  944.     return (return_ok);
  945. }
  946.  
  947. static int DoOpenLibs(void)
  948. {
  949.     int return_ok = FALSE;
  950.  
  951.     if (!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 37)))
  952.     {
  953.         puts("Unable to open intuition.library.");
  954.         goto abort;
  955.     }
  956.  
  957.     if (!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 37)))
  958.     {
  959.         puts("Unable to open graphics.library.");
  960.         goto abort;
  961.     }
  962.  
  963.     if (!(DosBase = (struct DosLibrary *)OpenLibrary("dos.library", 37)))
  964.     {
  965.         puts("Unable to open dos.library.");
  966.         goto abort;
  967.     }
  968.  
  969.     if (!(IconBase = OpenLibrary("icon.library", 37)))
  970.     {
  971.         puts("Unable to open icon.library.");
  972.         goto abort;
  973.     }
  974.  
  975.     if (!(MUIMasterBase = OpenLibrary(MUIMASTER_NAME, MUIMASTER_VMIN)))
  976.     {
  977.         puts("Unable to open muimaster.library.");
  978.         goto abort;
  979.     }
  980.  
  981.     return_ok = TRUE;
  982. abort:
  983.     return (return_ok);
  984. }
  985.  
  986. static void DoOpenCatalog(void)
  987. {
  988.     if (LocaleBase = (struct LocaleBase *)OpenLibrary("locale.library", 38))
  989.     {
  990.         app->app_Catalog = OpenCatalog(NULL, (STRPTR)CATALOGNAME,
  991.                                   OC_BuiltInLanguage, (ULONG)"deutsch",
  992.                                   TAG_DONE);
  993.         if (!app->app_Catalog)
  994.         {
  995.             // use builtin language
  996.             CloseLibrary((struct Library *)LocaleBase);
  997.             LocaleBase = NULL;
  998.         }
  999.     }
  1000. }
  1001.  
  1002. static void DoCloseCatalog(void)
  1003. {
  1004.     if (LocaleBase)
  1005.     {
  1006.         if (app->app_Catalog)
  1007.             CloseCatalog(app->app_Catalog);
  1008.         app->app_Catalog = NULL;
  1009.         CloseLibrary((struct Library *)LocaleBase);
  1010.     }
  1011. }
  1012.  
  1013. // get localized string
  1014. UBYTE *GetCatStr(ULONG gad_id)
  1015. {
  1016.     if (LocaleBase)
  1017.         return (GetCatalogStr(app->app_Catalog, gad_id, CatCompArray[gad_id].cca_Str));
  1018.     else
  1019.         return (CatCompArray[gad_id].cca_Str);
  1020. }
  1021.  
  1022. // get localized hot key
  1023. UBYTE GetCatHotKey(ULONG gad_id)
  1024. {
  1025.     UBYTE *str;
  1026.  
  1027.     if (LocaleBase)
  1028.         str = GetCatalogStr(app->app_Catalog, gad_id, CatCompArray[gad_id].cca_Str);
  1029.     else
  1030.         str = CatCompArray[gad_id].cca_Str;
  1031.  
  1032.     return (*str);
  1033. }
  1034.  
  1035. static int DoNewMenu(void)
  1036. {
  1037.     int return_ok = FALSE;
  1038.  
  1039.     if (!(app->app_NewMenu = (struct NewMenu *)AllocVec((ID_END + 1) * sizeof(struct NewMenu), MEMF_CLEAR)))
  1040.     {
  1041.         puts("Out of memory!");
  1042.         goto abort;
  1043.     }
  1044.  
  1045.     if (!(app->app_Conf_NewMenu = (struct NewMenu *)AllocVec((ID_MENU_CONF_END - ID_MENU_CONFIGURATION + 1) * sizeof(struct NewMenu), MEMF_CLEAR)))
  1046.     {
  1047.         puts("Out of memory!");
  1048.         goto abort;
  1049.     }
  1050.  
  1051.     app->app_NewMenu[ID_PROJECT].nm_Type = NM_TITLE;
  1052.     app->app_NewMenu[ID_PROJECT].nm_Label = GetCatStr(MSG_MENU_PROJECT);
  1053.  
  1054.     app->app_NewMenu[ID_OPEN].nm_Type = NM_ITEM;
  1055.     app->app_NewMenu[ID_OPEN].nm_Label = GetCatStr(MSG_MENU_OPEN);
  1056.     app->app_NewMenu[ID_OPEN].nm_CommKey = GetCatStr(MSG_MENU_OPEN_KEY);
  1057.     app->app_NewMenu[ID_OPEN].nm_UserData = (APTR)ID_OPEN;
  1058.  
  1059.     app->app_NewMenu[ID_SAVE].nm_Type = NM_ITEM;
  1060.     app->app_NewMenu[ID_SAVE].nm_Label = GetCatStr(MSG_MENU_SAVE);
  1061.     app->app_NewMenu[ID_SAVE].nm_CommKey = GetCatStr(MSG_MENU_SAVE_KEY);
  1062.     app->app_NewMenu[ID_SAVE].nm_UserData = (APTR)ID_SAVE;
  1063.  
  1064.     app->app_NewMenu[ID_LABEL1].nm_Type = NM_ITEM;
  1065.     app->app_NewMenu[ID_LABEL1].nm_Label = NM_BARLABEL;
  1066.  
  1067.     app->app_NewMenu[ID_FIND].nm_Type = NM_ITEM;
  1068.     app->app_NewMenu[ID_FIND].nm_Label = GetCatStr(MSG_MENU_FIND);
  1069.     app->app_NewMenu[ID_FIND].nm_CommKey = GetCatStr(MSG_MENU_FIND_KEY);
  1070.     app->app_NewMenu[ID_FIND].nm_UserData = (APTR)ID_FIND;
  1071.  
  1072.     app->app_NewMenu[ID_LABEL2].nm_Type = NM_ITEM;
  1073.     app->app_NewMenu[ID_LABEL2].nm_Label = NM_BARLABEL;
  1074.  
  1075.     app->app_NewMenu[ID_CLIP_CUT].nm_Type = NM_ITEM;
  1076.     app->app_NewMenu[ID_CLIP_CUT].nm_Label = GetCatStr(MSG_MENU_CLIP_CUT);
  1077.     app->app_NewMenu[ID_CLIP_CUT].nm_CommKey = GetCatStr(MSG_MENU_CLIP_CUT_KEY);
  1078.     app->app_NewMenu[ID_CLIP_CUT].nm_UserData = (APTR)ID_CLIP_CUT;
  1079.  
  1080.     app->app_NewMenu[ID_CLIP_COPY].nm_Type = NM_ITEM;
  1081.     app->app_NewMenu[ID_CLIP_COPY].nm_Label = GetCatStr(MSG_MENU_CLIP_COPY);
  1082.     app->app_NewMenu[ID_CLIP_COPY].nm_CommKey = GetCatStr(MSG_MENU_CLIP_COPY_KEY);
  1083.     app->app_NewMenu[ID_CLIP_COPY].nm_UserData = (APTR)ID_CLIP_COPY;
  1084.  
  1085.     app->app_NewMenu[ID_CLIP_PASTE].nm_Type = NM_ITEM;
  1086.     app->app_NewMenu[ID_CLIP_PASTE].nm_Label = GetCatStr(MSG_MENU_CLIP_PASTE);
  1087.     app->app_NewMenu[ID_CLIP_PASTE].nm_CommKey = GetCatStr(MSG_MENU_CLIP_PASTE_KEY);
  1088.     app->app_NewMenu[ID_CLIP_PASTE].nm_UserData = (APTR)ID_CLIP_PASTE;
  1089.  
  1090.     app->app_NewMenu[ID_LABEL3].nm_Type = NM_ITEM;
  1091.     app->app_NewMenu[ID_LABEL3].nm_Label = NM_BARLABEL;
  1092.  
  1093.     app->app_NewMenu[ID_ABOUT].nm_Type = NM_ITEM;
  1094.     app->app_NewMenu[ID_ABOUT].nm_Label = GetCatStr(MSG_MENU_ABOUT);
  1095.     app->app_NewMenu[ID_ABOUT].nm_CommKey = GetCatStr(MSG_MENU_ABOUT_KEY);
  1096.     app->app_NewMenu[ID_ABOUT].nm_UserData = (APTR)ID_ABOUT;
  1097.  
  1098.     app->app_NewMenu[ID_LABEL4].nm_Type = NM_ITEM;
  1099.     app->app_NewMenu[ID_LABEL4].nm_Label = NM_BARLABEL;
  1100.  
  1101.     app->app_NewMenu[ID_QUIT].nm_Type = NM_ITEM;
  1102.     app->app_NewMenu[ID_QUIT].nm_Label = GetCatStr(MSG_MENU_QUIT);
  1103.     app->app_NewMenu[ID_QUIT].nm_CommKey = GetCatStr(MSG_MENU_QUIT_KEY);
  1104.     app->app_NewMenu[ID_QUIT].nm_UserData = (APTR)ID_QUIT;
  1105.  
  1106.     app->app_NewMenu[ID_END].nm_Type = NM_END;
  1107.  
  1108.     {
  1109.         int base = ID_MENU_CONFIGURATION;
  1110.  
  1111.         app->app_Conf_NewMenu[ID_MENU_CONFIGURATION - base].nm_Type = NM_TITLE;
  1112.         app->app_Conf_NewMenu[ID_MENU_CONFIGURATION - base].nm_Label = GetCatStr(MSG_GAD_GP_CONF_CONFIGURATION);
  1113.  
  1114.         app->app_Conf_NewMenu[ID_MENU_CONF_NODES - base].nm_Type = NM_ITEM;
  1115.         app->app_Conf_NewMenu[ID_MENU_CONF_NODES - base].nm_Label = GetCatStr(MSG_GAD_RGP_CONF_NODES);
  1116.         app->app_Conf_NewMenu[ID_MENU_CONF_NODES - base].nm_CommKey = "1";
  1117.         app->app_Conf_NewMenu[ID_MENU_CONF_NODES - base].nm_UserData = (APTR)ID_MENU_CONF_NODES;
  1118.  
  1119.         app->app_Conf_NewMenu[ID_MENU_CONF_GLOBAL_SETTINGS - base].nm_Type = NM_ITEM;
  1120.         app->app_Conf_NewMenu[ID_MENU_CONF_GLOBAL_SETTINGS - base].nm_Label = GetCatStr(MSG_GAD_RGP_CONF_GLOBAL_SETTINGS);
  1121.         app->app_Conf_NewMenu[ID_MENU_CONF_GLOBAL_SETTINGS - base].nm_CommKey = "2";
  1122.         app->app_Conf_NewMenu[ID_MENU_CONF_GLOBAL_SETTINGS - base].nm_UserData = (APTR)ID_MENU_CONF_GLOBAL_SETTINGS;
  1123.  
  1124.         app->app_Conf_NewMenu[ID_MENU_CONF_LABEL1 - base].nm_Type = NM_ITEM;
  1125.         app->app_Conf_NewMenu[ID_MENU_CONF_LABEL1 - base].nm_Label = NM_BARLABEL;
  1126.  
  1127.         app->app_Conf_NewMenu[ID_MENU_CONF_ABOUT - base].nm_Type = NM_ITEM;
  1128.         app->app_Conf_NewMenu[ID_MENU_CONF_ABOUT - base].nm_Label = GetCatStr(MSG_MENU_ABOUT);
  1129.         app->app_Conf_NewMenu[ID_MENU_CONF_ABOUT - base].nm_CommKey = GetCatStr(MSG_MENU_ABOUT_KEY);
  1130.         app->app_Conf_NewMenu[ID_MENU_CONF_ABOUT - base].nm_UserData = (APTR)ID_ABOUT;
  1131.  
  1132.         app->app_Conf_NewMenu[ID_MENU_CONF_LABEL2 - base].nm_Type = NM_ITEM;
  1133.         app->app_Conf_NewMenu[ID_MENU_CONF_LABEL2 - base].nm_Label = NM_BARLABEL;
  1134.  
  1135.         app->app_Conf_NewMenu[ID_MENU_CONF_QUIT - base].nm_Type = NM_ITEM;
  1136.         app->app_Conf_NewMenu[ID_MENU_CONF_QUIT - base].nm_Label = GetCatStr(MSG_MENU_QUIT);
  1137.         app->app_Conf_NewMenu[ID_MENU_CONF_QUIT - base].nm_CommKey = GetCatStr(MSG_MENU_QUIT_KEY);
  1138.         app->app_Conf_NewMenu[ID_MENU_CONF_QUIT - base].nm_UserData = (APTR)ID_QUIT;
  1139.  
  1140.         app->app_Conf_NewMenu[ID_MENU_CONF_END - base].nm_Type = NM_END;
  1141.     }
  1142.     return_ok = TRUE;
  1143. abort:
  1144.     return (return_ok);
  1145. }
  1146.  
  1147. int ReadList(int quiet)
  1148. {
  1149.     int return_ok = FALSE;
  1150.     char *buf;
  1151.     FILE *stream = NULL;
  1152.     UBYTE buffer[BUF_SIZE], dest[BUF_SIZE + 1];
  1153.     int buf_len = 0, buf_pos = 0, end_of_file = FALSE;
  1154.     int dest_pos = 0;
  1155.     UBYTE *stream_buffer = NULL;
  1156.     UBYTE **list = NULL;
  1157.     int lines = 0, space = 0;
  1158.     UBYTE *xpk_getoutbuf = NULL;
  1159.     long xpk_getoutlen, xpk_getoutbuflen, xpk_err = XPKERR_NOTPACKED;
  1160.     long xpk_bufpos = 0;
  1161.  
  1162.     get(app->app_st_Conf_List, MUIA_String_Contents, &buf);
  1163.  
  1164.     // first, try to decompress filelist
  1165.     if (XpkBase = OpenLibrary(XPKNAME, 0))
  1166.     {
  1167.         UBYTE xpk_errbuf[XPKERRMSGSIZE];
  1168.  
  1169.         xpk_err = XpkUnpackTags(XPK_InName, buf,
  1170.                                 XPK_GetOutBuf, &xpk_getoutbuf,
  1171.                                 XPK_GetOutBufLen, &xpk_getoutbuflen,
  1172.                                 XPK_GetOutLen, &xpk_getoutlen,
  1173.                                 XPK_GetError, xpk_errbuf,
  1174.                                 TAG_DONE);
  1175.  
  1176.         CloseLibrary(XpkBase);
  1177.  
  1178.         // an error occurred
  1179.         if (xpk_err != XPKERR_OK && xpk_err != XPKERR_NOTPACKED)
  1180.         {
  1181.             if (!quiet)
  1182.                 DispError(MSG_ERROR_XPK, xpk_errbuf);
  1183.  
  1184.             goto abort;
  1185.         }
  1186.     }
  1187.  
  1188.     // load not packed filelist
  1189.     if (xpk_err == XPKERR_NOTPACKED)
  1190.     {
  1191.         if (!(stream_buffer = malloc(STREAM_BUF_SIZE)))
  1192.         {
  1193.             if (!quiet)
  1194.                 DispError(MSG_ERROR_OUT_OF_MEMORY, NULL);
  1195.             goto abort;
  1196.         }
  1197.  
  1198.         get(app->app_st_Conf_List, MUIA_String_Contents, &buf);
  1199.         if (!(stream = fopen(buf, "r")))
  1200.         {
  1201.             if (!quiet)
  1202.                 DispError(MSG_ERROR_CANT_OPEN, buf);
  1203.             goto abort;
  1204.         }
  1205.         // use my own buffer
  1206.         setvbuf(stream, stream_buffer, _IOFBF, STREAM_BUF_SIZE);
  1207.     }
  1208.  
  1209.     for (;;)
  1210.     {
  1211.         // additional 1 for terminating NULL ptr
  1212.         if (lines + 1 >= space)
  1213.         {
  1214.             // make room
  1215.             UBYTE **new_list;
  1216.  
  1217.             if (!(new_list = (UBYTE **)AllocVec((space + 50) * sizeof(UBYTE *), MEMF_CLEAR)))
  1218.             {
  1219.                 if (!quiet)
  1220.                     DispError(MSG_ERROR_OUT_OF_MEMORY, NULL);
  1221.                 goto abort;
  1222.             }
  1223.             space += 50;
  1224.  
  1225.             if (lines)
  1226.                 // copy pointers from the old list to the new one
  1227.                 memcpy(new_list, list, lines * sizeof(UBYTE *));
  1228.             if (list)
  1229.                 FreeVec(list);
  1230.             list = new_list;
  1231.         }
  1232.  
  1233.         if (buf_pos + 1 >= buf_len)
  1234.         {
  1235.             if (end_of_file)
  1236.             {
  1237.                 UBYTE *str;
  1238.  
  1239.                 // flush buffer
  1240.                 if (dest_pos)
  1241.                 {
  1242.                     dest[dest_pos] = EOS;
  1243.                     if (!(str = (UBYTE *)AllocVec(strlen(dest) + 1, MEMF_CLEAR)))
  1244.                     {
  1245.                         if (!quiet)
  1246.                             DispError(MSG_ERROR_OUT_OF_MEMORY, NULL);
  1247.                         goto abort;
  1248.                     }
  1249.                     strcpy(str, dest);
  1250.                     list[lines++] = str;
  1251.                 }
  1252.                 break;
  1253.             }
  1254.  
  1255.             if (xpk_err == XPKERR_NOTPACKED)
  1256.             {
  1257.                 if ((buf_len = fread(buffer, 1, BUF_SIZE, stream)) != BUF_SIZE)
  1258.                 {
  1259.                     // reached EOF
  1260.                     if (!ferror(stream))
  1261.                         end_of_file = TRUE;
  1262.                     else
  1263.                     {
  1264.                         if (!quiet)
  1265.                             DispError(MSG_ERROR_WHILE_READING, buf);
  1266.                         goto abort;
  1267.                     }
  1268.                 }
  1269.             }
  1270.             else
  1271.             {
  1272.                 if (xpk_bufpos + BUF_SIZE >= xpk_getoutlen)
  1273.                 {
  1274.                     buf_len = xpk_getoutlen - xpk_bufpos;
  1275.                     end_of_file = TRUE;
  1276.                 }
  1277.                 else
  1278.                     buf_len = BUF_SIZE;
  1279.  
  1280.                 memcpy(buffer, &xpk_getoutbuf[xpk_bufpos], buf_len);
  1281.                 xpk_bufpos += buf_len;
  1282.             }
  1283.  
  1284.             buf_pos = 0;
  1285.         }
  1286.  
  1287.         while (buf_pos + 1 < buf_len)
  1288.         {
  1289.             // LF or destination buffer full
  1290.             // (no line must be longer than BUF_SIZE)
  1291.             if (buffer[buf_pos] == 10 || dest_pos == BUF_SIZE)
  1292.             {
  1293.                 UBYTE *str;
  1294.  
  1295.                 dest[dest_pos] = EOS;
  1296.                 if (!(str = (UBYTE *)AllocVec(strlen(dest) + 1, MEMF_CLEAR)))
  1297.                 {
  1298.                     if (!quiet)
  1299.                         DispError(MSG_ERROR_OUT_OF_MEMORY, NULL);
  1300.                     goto abort;
  1301.                 }
  1302.                 strcpy(str, dest);
  1303.                 list[lines++] = str;
  1304.                 buf_pos++;
  1305.                 dest_pos = 0;
  1306.                 break;
  1307.             }
  1308.             // tab stop
  1309.             else if (buffer[buf_pos] == 9)
  1310.             {
  1311.                 do
  1312.                 {
  1313.                     dest[dest_pos++] = 32;
  1314.                 }
  1315.                 while ((dest_pos & 7) && dest_pos < BUF_SIZE);
  1316.                 buf_pos++;
  1317.             }
  1318.             // illegal char
  1319.             else if (buffer[buf_pos] <= 31 ||
  1320.                     (buffer[buf_pos] >= 128 && buffer[buf_pos] <= 159))
  1321.             {
  1322.                 buf_pos++;
  1323.             }
  1324.             // copy legal char to destination buffer
  1325.             else
  1326.                 dest[dest_pos++] = buffer[buf_pos++];
  1327.         }
  1328.     }
  1329.  
  1330.     // everything worked fine
  1331.  
  1332.     // clear list
  1333.     DoMethod(app->app_lv_Main_List, MUIM_List_Clear, TAG_IGNORE);
  1334.  
  1335.     DoOpenFont(quiet);
  1336.  
  1337.     // free old list
  1338.     if (app->app_List)
  1339.     {
  1340.         UBYTE **list_bak = app->app_List;
  1341.  
  1342.         do
  1343.         {
  1344.             // free strings
  1345.             if (*list_bak)
  1346.                 FreeVec(*list_bak++);
  1347.         }
  1348.         while (*list_bak);
  1349.         FreeVec(app->app_List);
  1350.     }
  1351.     app->app_List = list;
  1352.     // set list
  1353.     set(app->app_lv_Main_List, MUIA_List_Quiet, TRUE);
  1354.     DoMethod(app->app_lv_Main_List, MUIM_List_Insert, app->app_List, -1,
  1355.              MUIV_List_Insert_Bottom);
  1356.     set(app->app_lv_Main_List, MUIA_List_Quiet, FALSE);
  1357.  
  1358.     return_ok = TRUE;
  1359. abort:
  1360.     if (stream)
  1361.         fclose(stream);
  1362.     if (stream_buffer)
  1363.         free (stream_buffer);
  1364.     // free mem allocated by XPK master
  1365.     if (xpk_getoutbuf)
  1366.         FreeMem(xpk_getoutbuf, xpk_getoutbuflen);
  1367.     if (!return_ok)
  1368.     {
  1369.         if (list)
  1370.         {
  1371.             UBYTE **list_bak = list;
  1372.  
  1373.             do
  1374.             {
  1375.                 // free strings
  1376.                 if (*list)
  1377.                     FreeVec(*list++);
  1378.             }
  1379.             while (*list);
  1380.             FreeVec(list_bak);
  1381.         }
  1382.     }
  1383.     return (return_ok);
  1384. }
  1385.  
  1386. static void LVListDBClick(void)
  1387. {
  1388.     LONG pos, filename_pos, cur_pos = 0;
  1389.     UBYTE *line;
  1390.     UBYTE buffer[BUF_SIZE + 1];
  1391.  
  1392.     // cursor position
  1393.     get(app->app_lv_Main_List, MUIA_List_Active, &pos);
  1394.  
  1395.     if (pos >= 0)
  1396.     {
  1397.         // get active line
  1398.         DoMethod(app->app_lv_Main_List, MUIM_List_GetEntry, pos, &line);
  1399.         // get filename_pos
  1400.         get(app->app_sl_Conf_FileNamePos, MUIA_Slider_Level, &filename_pos);
  1401.  
  1402.         // non empty line
  1403.         while (*line && cur_pos < filename_pos)
  1404.         {
  1405.             // strip blanks
  1406.             while (*line && *line == 32)
  1407.                 line++;
  1408.             if (*line)
  1409.             {
  1410.                 pos = 0;
  1411.                 // extract word until reaching next blank or eol
  1412.                 while (*line && *line != 32)
  1413.                 {
  1414.                     buffer[pos++] = *line++;
  1415.                 }
  1416.                 buffer[pos] = EOS;
  1417.  
  1418.                 // reached desired filename position
  1419.                 if (++cur_pos == filename_pos)
  1420.                     AddListEntry(buffer, FALSE);
  1421.             }
  1422.         }
  1423.     }
  1424. }
  1425.  
  1426. int AddListEntry(UBYTE *buffer, int quiet)
  1427. {
  1428.     int return_ok = FALSE;
  1429.     struct RequestList *rl = NULL;
  1430.     struct RequestList *rl_walk;
  1431.  
  1432.     if (!(rl = (struct RequestList *)AllocVec(sizeof(struct RequestList), MEMF_CLEAR)))
  1433.         goto abort;
  1434.     if (!(rl->rl_Buffer = (UBYTE *)AllocVec(strlen(buffer) + 1, MEMF_CLEAR)))
  1435.         goto abort;
  1436.     strcpy(rl->rl_Buffer, buffer);
  1437.  
  1438.     // append entry
  1439.     if (rl_walk = app->app_RequestList)
  1440.     {
  1441.         while (rl_walk->rl_Next)
  1442.             rl_walk = rl_walk->rl_Next;
  1443.         rl_walk->rl_Next = rl;
  1444.     }
  1445.     else
  1446.         app->app_RequestList = rl;
  1447.  
  1448.     // now add entry
  1449.     DoMethod(app->app_lv_Main_RequestList, MUIM_List_Insert,
  1450.              &rl->rl_Buffer, 1, MUIV_List_Insert_Bottom);
  1451.     set(app->app_lv_Main_RequestList, MUIA_List_Active, MUIV_List_Active_Bottom);
  1452.     // clear request string
  1453.     *app->app_Main_RequestBuf = EOS;
  1454.     set(app->app_st_Main_Request, MUIA_String_Contents, app->app_Main_RequestBuf);
  1455.  
  1456.     return_ok = TRUE;
  1457. abort:
  1458.     if (!return_ok)
  1459.     {
  1460.         if (rl)
  1461.             FreeVec(rl);
  1462.         if (!quiet)
  1463.             DispError(MSG_ERROR_OUT_OF_MEMORY, NULL);
  1464.     }
  1465.     return (return_ok);
  1466. }
  1467.  
  1468. void DeleteListEntry(void)
  1469. {
  1470.     // non empty list
  1471.     if (app->app_RequestList)
  1472.     {
  1473.         LONG pos = -1;
  1474.         LONG state = MUIV_List_Select_All;
  1475.         struct RequestList **rl = &app->app_RequestList, *rl_delete;
  1476.  
  1477.         do
  1478.         {
  1479.             DoMethod(app->app_lv_Main_RequestList, MUIM_List_NextSelected, &pos);
  1480.  
  1481.             if (pos != -1)
  1482.             {
  1483.                 // this is the active entry and
  1484.                 // no further entries are selected?
  1485.                 DoMethod(app->app_lv_Main_RequestList, MUIM_List_Select,
  1486.                          pos, MUIV_List_Select_Ask, &state);
  1487.  
  1488.                 DoMethod(app->app_lv_Main_RequestList, MUIM_List_Remove, pos);
  1489.  
  1490.                 // jump to selected entry
  1491.                 while (pos > 0)
  1492.                 {
  1493.                     rl = &(*rl)->rl_Next;
  1494.                     pos--;
  1495.                 }
  1496.  
  1497.                 // delete from chain and free mem
  1498.                 if (*rl)
  1499.                 {
  1500.                     rl_delete = *rl;
  1501.                     *rl = (*rl)->rl_Next;
  1502.                     if (rl_delete->rl_Buffer)
  1503.                         FreeVec(rl_delete->rl_Buffer);
  1504.                     FreeVec(rl_delete);
  1505.                 }
  1506.                 rl = &app->app_RequestList;
  1507.             }
  1508.         }
  1509.         while (pos != -1 && state != MUIV_List_Select_Off);
  1510.     }
  1511. }
  1512.  
  1513. static int CreateReqFileName(int quiet)
  1514. {
  1515.     int return_ok = FALSE;
  1516.     UBYTE *buf, req_file[PATHSIZE];
  1517.     int pos = 0;
  1518.  
  1519.     get(app->app_st_Conf_Node, MUIA_String_Contents, &buf);
  1520.     strcpy(req_file, buf);
  1521.  
  1522.     // replace all colons and slashes by dots
  1523.     while (req_file[pos])
  1524.     {
  1525.         if (req_file[pos] == ':' || req_file[pos] == '/')
  1526.             req_file[pos] = '.';
  1527.         pos++;
  1528.     }
  1529.     // append .REQ
  1530.     strcat(req_file, ".REQ");
  1531.  
  1532.     // create full filename
  1533.     get(app->app_st_Conf_Outbound, MUIA_String_Contents, &buf);
  1534.     strcpy(app->app_ReqFile, buf);
  1535.     if (!AddPart(app->app_ReqFile, req_file, PATHSIZE - 1))
  1536.         return (FALSE);
  1537.  
  1538.     return_ok = TRUE;
  1539. abort:
  1540.     if (!return_ok && !quiet)
  1541.         DispError(MSG_ERROR_INVALID_NODE_ADDRESS, NULL);
  1542.     return (return_ok);
  1543. }
  1544.  
  1545. int SaveReqFile(void)
  1546. {
  1547.     int return_ok = FALSE;
  1548.     FILE *stream = NULL;
  1549.     struct RequestList *rl = app->app_RequestList;
  1550.  
  1551.     if (!CreateReqFileName(FALSE))
  1552.         goto abort;
  1553.  
  1554.     if (!rl)
  1555.     {
  1556.         if (!remove(app->app_ReqFile))
  1557.             DispError(MSG_INFO_REQUESTFILE_DELETED, NULL);
  1558.         else
  1559.             DispError(MSG_ERROR_NO_REQUESTFILE, NULL);
  1560.         goto abort;
  1561.     }
  1562.  
  1563.     if (!(stream = fopen(app->app_ReqFile, "w")))
  1564.     {
  1565.         DispError(MSG_ERROR_CANT_OPEN, app->app_ReqFile);
  1566.         goto abort;
  1567.     }
  1568.  
  1569.     for (; rl; rl = rl->rl_Next)
  1570.     {
  1571.         fprintf(stream, "%s%s", rl->rl_Buffer, (app->app_Flags & APP_CYA_CONF_TERM_CRLF) ? "\r\n" : "\n");
  1572.         if (ferror(stream))
  1573.         {
  1574.             DispError(MSG_ERROR_WHILE_WRITING, app->app_ReqFile);
  1575.             goto abort;
  1576.         }
  1577.     }
  1578.  
  1579.     return_ok = TRUE;
  1580. abort:
  1581.     if (stream)
  1582.         fclose(stream);
  1583.     return (return_ok);
  1584. }
  1585.  
  1586. void DispError(int msg_id, UBYTE *buf)
  1587. {
  1588.     UBYTE buffer[BUF_SIZE];
  1589.  
  1590.     sprintf(buffer, GetCatStr(msg_id), buf);
  1591.     MUI_Request(app->app_Muiffr, app->app_wi_Main, 0, NULL,
  1592.                 GetCatStr(MSG_OKAY),
  1593.                 buffer,
  1594.                 TAG_END);
  1595. }
  1596.  
  1597. static void LoadReqFile(int quiet)
  1598. {
  1599.     int return_ok = FALSE;
  1600.     FILE *stream = NULL;
  1601.     struct RequestList *rl = app->app_RequestList;
  1602.     int end_of_file = FALSE;
  1603.     UBYTE buffer[BUF_SIZE];
  1604.  
  1605.     if (!CreateReqFileName(quiet))
  1606.         goto abort;
  1607.  
  1608.     if (!(stream = fopen(app->app_ReqFile, "r")))
  1609.     {
  1610.         if (!quiet)
  1611.             DispError(MSG_ERROR_CANT_OPEN, app->app_ReqFile);
  1612.         goto abort;
  1613.     }
  1614.  
  1615.     *app->app_Main_RequestBuf = EOS;
  1616.     set(app->app_st_Main_Request, MUIA_String_Contents, app->app_Main_RequestBuf);
  1617.     // clear list
  1618.     DoMethod(app->app_lv_Main_RequestList, MUIM_List_Clear, TAG_IGNORE);
  1619.     // quiet list
  1620.     set(app->app_lv_Main_RequestList, MUIA_List_Quiet, TRUE);
  1621.  
  1622.     if (rl)
  1623.     {
  1624.         struct RequestList *rl_next;
  1625.  
  1626.         do
  1627.         {
  1628.             if (rl->rl_Buffer)
  1629.                 FreeVec(rl->rl_Buffer);
  1630.             rl_next = rl->rl_Next;
  1631.             FreeVec(rl);
  1632.             rl = rl_next;
  1633.         }
  1634.         while (rl);
  1635.         app->app_RequestList = NULL;
  1636.     }
  1637.  
  1638.     while (!end_of_file)
  1639.     {
  1640.         if (fscanf(stream, "%199s", buffer) == -1)
  1641.         {
  1642.             // reached EOF
  1643.             if (!ferror(stream))
  1644.                 end_of_file = TRUE;
  1645.             else
  1646.             {
  1647.                 if (!quiet)
  1648.                     DispError(MSG_ERROR_WHILE_READING, app->app_ReqFile);
  1649.                 goto abort;
  1650.             }
  1651.         }
  1652.         else
  1653.         {
  1654.             int len = strlen(buffer);
  1655.  
  1656.             // remove CR
  1657.             if (buffer[len - 1] == '\r')
  1658.                 buffer[len - 1] = EOS;
  1659.  
  1660.             AddListEntry(buffer, quiet);
  1661.         }
  1662.     }
  1663.  
  1664. abort:
  1665.     if (stream)
  1666.         fclose(stream);
  1667.     set(app->app_lv_Main_RequestList, MUIA_List_Quiet, FALSE);
  1668.     set(app->app_lv_Main_RequestList, MUIA_List_Active, MUIV_List_Active_Bottom);
  1669. }
  1670.  
  1671. static void BoyerMoore(int direction)
  1672. {
  1673.     UBYTE *find_str;
  1674.     int len;
  1675.     int pattern_found = FALSE;
  1676.  
  1677.     if (!app->app_List)
  1678.     {
  1679.         DispError(MSG_ERROR_FIRST_LOAD_LIST, NULL);
  1680.         return;
  1681.     }
  1682.  
  1683.     get(app->app_st_Main_Find, MUIA_String_Contents, &find_str);
  1684.     if (!*find_str)
  1685.     {
  1686.         DispError(MSG_ERROR_NO_FIND_STRING, NULL);
  1687.         return;
  1688.     }
  1689.     len = strlen(find_str);
  1690.  
  1691.     if (app->app_Flags & APP_FIND_CHANGED)
  1692.     {
  1693.         int i;
  1694.  
  1695.         app->app_Flags &= ~(APP_FIND_CHANGED);
  1696.  
  1697.         // init skip table
  1698.         for (i = 0; i <= 255; i++)
  1699.             app->app_Skip[i] = len;
  1700.  
  1701.         for (i = 0; i < len; i++)
  1702.             app->app_Skip[find_str[i]] = len - 1 - i;
  1703.  
  1704.     }
  1705.  
  1706.     {
  1707.         UBYTE *list_str;
  1708.         long pos, num_lines;
  1709.         int list_len;
  1710.  
  1711.         get(app->app_lv_Main_List, MUIA_List_Active, &pos);
  1712.         get(app->app_lv_Main_List, MUIA_List_Entries, &num_lines);
  1713.  
  1714.         for ((direction == SEARCH_DOWN) ? (pos++) : (pos--);
  1715.              (direction == SEARCH_DOWN) ? (pos < num_lines) : (pos >= 0);
  1716.              (direction == SEARCH_DOWN) ? (pos++) : (pos--))
  1717.         {
  1718.             // get active line
  1719.             DoMethod(app->app_lv_Main_List, MUIM_List_GetEntry, pos, &list_str);
  1720.             list_len = strlen(list_str);
  1721.  
  1722.             if (MisCharSearch(list_str, list_len, find_str, len) < list_len)
  1723.             {
  1724.                 pattern_found = TRUE;
  1725.                 set(app->app_lv_Main_List, MUIA_List_Active, pos);
  1726.                 break;
  1727.             }
  1728.         }
  1729.     }
  1730.  
  1731. abort:
  1732.     if (!pattern_found)
  1733.         DispError(MSG_ERROR_PATTERN_NOT_FOUND, find_str);
  1734. }
  1735.  
  1736. static int MisCharSearch(UBYTE *list_str, int list_len, UBYTE *find_str, int len)
  1737. {
  1738.     int i, j, t;
  1739.  
  1740.     if (list_len < len)
  1741.         return list_len;
  1742.  
  1743.     for (i = len - 1, j = len - 1; j >= 0; i--, j--)
  1744.     {
  1745.         while (TO_UPPER(list_str[i]) != TO_UPPER(find_str[j]))
  1746.         {
  1747.             t = app->app_Skip[list_str[i]];
  1748.             i += (len - j > t) ? len - j : t;
  1749.  
  1750.             if (i >= list_len)
  1751.                 return list_len;
  1752.             j = len - 1;
  1753.         }
  1754.     }
  1755.  
  1756.     return i;
  1757. }
  1758.  
  1759. static void DoOpenFont(int quiet)
  1760. {
  1761.     int return_ok = FALSE;
  1762.     UBYTE *buf, buffer[PATHSIZE], *size;
  1763.     int ysize, force_display_change = FALSE;
  1764.  
  1765.     get(app->app_st_Conf_Font, MUIA_String_Contents, &buf);
  1766.     strcpy(buffer, buf);
  1767.  
  1768.     // same font already open
  1769.     if (!strcmp(buf, app->app_LastFontBuf))
  1770.         return;
  1771.  
  1772.     if (!*buffer)
  1773.     {
  1774.         quiet = TRUE;
  1775.         force_display_change = TRUE;
  1776.         goto abort;
  1777.     }
  1778.  
  1779.     if (size = strchr(buffer, '/'))
  1780.     {
  1781.         UBYTE *ptr;
  1782.         LONG only_digits = TRUE;
  1783.  
  1784.         *size++ = EOS;
  1785.         ptr = size;
  1786.  
  1787.         do
  1788.         {
  1789.             if (!isdigit(*ptr++))
  1790.             {
  1791.                 only_digits = FALSE;
  1792.                 break;
  1793.             }
  1794.         }
  1795.         while (*ptr);
  1796.  
  1797.         if (only_digits)
  1798.             ysize = atoi(size);
  1799.         else
  1800.             goto abort;
  1801.     }
  1802.     {
  1803.         struct TextFont *font;
  1804.         struct TextAttr ta;
  1805.  
  1806.         strcat(buffer, ".font");
  1807.         ta.ta_Name  = buffer;
  1808.         ta.ta_YSize = ysize;
  1809.         ta.ta_Style = 0;
  1810.         ta.ta_Flags = 0;
  1811.  
  1812.         font = OpenFont(&ta);
  1813.         if (!font || font->tf_YSize != ta.ta_YSize)
  1814.         {
  1815.             struct TextFont *font2;
  1816.  
  1817.             if (DiskfontBase = OpenLibrary("diskfont.library", 0))
  1818.             {
  1819.                 if (font2 = OpenDiskFont(&ta))
  1820.                 {
  1821.                     if (font)
  1822.                         CloseFont(font);
  1823.                     if (font->tf_YSize != ta.ta_YSize)
  1824.                     {
  1825.                         CloseFont(font2);
  1826.                         font2 = NULL;
  1827.                     }
  1828.                     font = font2;
  1829.                 }
  1830.                 CloseLibrary(DiskfontBase);
  1831.                 DiskfontBase = NULL;
  1832.             }
  1833.         }
  1834.         if (!font)
  1835.             goto abort;
  1836.  
  1837.         set(app->app_lv_Main_List, MUIA_Font, font);
  1838.  
  1839.         if (app->app_Font)
  1840.             CloseFont(app->app_Font);
  1841.         app->app_Font = font;
  1842.         // remember font
  1843.         strcpy(app->app_LastFontBuf, buf);
  1844.     }
  1845.  
  1846.     return_ok = TRUE;
  1847. abort:
  1848.     if (!return_ok)
  1849.     {
  1850.         if (!quiet)
  1851.             DispError(MSG_ERROR_CANT_OPEN, buf);
  1852.         set(app->app_lv_Main_List, MUIA_Font, MUIV_Font_Fixed);
  1853.         *app->app_LastFontBuf = EOS;
  1854.     }
  1855.     if (!quiet || force_display_change)
  1856.     {
  1857.         set(app->app_wi_Main, MUIA_Window_Open, FALSE);
  1858.         set(app->app_wi_Main, MUIA_Window_Open, TRUE);
  1859.         set(app->app_wi_Main, MUIA_Window_Activate, TRUE);
  1860.     }
  1861. }
  1862.  
  1863. static int AppendPassword(void)
  1864. {
  1865.     int return_ok = FALSE;
  1866.     struct RequestList *rl = app->app_RequestList;
  1867.     UBYTE buffer[BUF_SIZE];
  1868.     UBYTE *buf, *old_buf, *new_buf;
  1869.     LONG pos = -1, count = 0, pos_bak, buf_len;
  1870.     LONG state = MUIV_List_Select_All;
  1871.  
  1872.     get(app->app_st_Main_Password, MUIA_String_Contents, &buf);
  1873.     buf_len = strlen(buf);
  1874.  
  1875.     if (*buf && rl)
  1876.     {
  1877.         // clear request string gadget
  1878.         *app->app_Main_RequestBuf = EOS;
  1879.         set(app->app_st_Main_Request, MUIA_String_Contents, app->app_Main_RequestBuf);
  1880.         // quiet list
  1881.         set(app->app_lv_Main_RequestList, MUIA_List_Quiet, TRUE);
  1882.  
  1883.         // count entries
  1884.         for (; rl; rl = rl->rl_Next)
  1885.             count++;
  1886.  
  1887.         do
  1888.         {
  1889.             rl = app->app_RequestList;
  1890.             // next selected entry
  1891.             DoMethod(app->app_lv_Main_RequestList, MUIM_List_NextSelected, &pos);
  1892.  
  1893.             if (pos >= 0)
  1894.             {
  1895.  
  1896.                 // this is the active entry and
  1897.                 // no further entries are selected?
  1898.                 DoMethod(app->app_lv_Main_RequestList, MUIM_List_Select,
  1899.                          pos, MUIV_List_Select_Ask, &state);
  1900.  
  1901.                 pos_bak = pos;
  1902.                 // jump to selected entry
  1903.                 while (pos_bak > 0)
  1904.                 {
  1905.                     rl = rl->rl_Next;
  1906.                     pos_bak--;
  1907.                 }
  1908.  
  1909.                 // remember buffer
  1910.                 old_buf = rl->rl_Buffer;
  1911.  
  1912.                 // has password already been appended to entry?
  1913.                 {
  1914.                     LONG old_buf_len = strlen(old_buf);
  1915.  
  1916.                     if (old_buf_len >= buf_len)
  1917.                     {
  1918.                         // yes?
  1919.                         if (!strcmp(buf, &old_buf[old_buf_len - buf_len]))
  1920.                             continue;
  1921.                     }
  1922.                 }
  1923.  
  1924.                 // create new buffer
  1925.                 strcpy(buffer, rl->rl_Buffer);
  1926.                 // append password
  1927.                 strcat(buffer, buf);
  1928.  
  1929.                 if (!(new_buf = (UBYTE *)AllocVec(strlen(buffer) + 1, MEMF_CLEAR)))
  1930.                 {
  1931.                     DispError(MSG_ERROR_OUT_OF_MEMORY, NULL);
  1932.                     goto abort;
  1933.                 }
  1934.  
  1935.                 // remove entry
  1936.                 DoMethod(app->app_lv_Main_RequestList, MUIM_List_Remove, pos);
  1937.  
  1938.                 // copy new entry
  1939.                 strcpy(new_buf, buffer);
  1940.                 rl->rl_Buffer = new_buf;
  1941.  
  1942.                 // readd entry
  1943.                 DoMethod(app->app_lv_Main_RequestList, MUIM_List_Insert,
  1944.                          &rl->rl_Buffer, 1,
  1945.                          (pos + 1 == count) ? MUIV_List_Insert_Bottom : pos);
  1946.  
  1947.                 // free old buffer
  1948.                 FreeVec(old_buf);
  1949.             }
  1950.         }
  1951.         while (pos != -1 && state != MUIV_List_Select_Off);
  1952.     }
  1953.  
  1954.     // show changes
  1955.     set(app->app_lv_Main_RequestList, MUIA_List_Quiet, FALSE);
  1956.  
  1957.     return_ok = TRUE;
  1958. abort:
  1959.     return (return_ok);
  1960. }
  1961.  
  1962. static void SetWaitPointer(APTR *win_obj)
  1963. {
  1964.     struct Library *SysBase;
  1965.     struct Window *window;
  1966.  
  1967.     SysBase = *(struct Library **)4;
  1968.  
  1969.     get(win_obj, MUIA_Window_Window, &window);
  1970.     if (window)
  1971.     {
  1972.         if (SysBase->lib_Version >= 39)
  1973.             SetWindowPointer(window, WA_BusyPointer, TRUE,
  1974.                                   WA_PointerDelay, TRUE,
  1975.                                   TAG_DONE);
  1976.         else
  1977.             SetPointer(window, StopWatch, 16, 16, -6, 0);
  1978.     }
  1979. }
  1980.  
  1981. static void ClearWaitPointer(APTR *win_obj)
  1982. {
  1983.     struct Window *window;
  1984.  
  1985.     get(win_obj, MUIA_Window_Window, &window);
  1986.     if (window)
  1987.         ClearPointer(window);
  1988. }
  1989.