home *** CD-ROM | disk | FTP | other *** search
/ Amiga Times / AmigaTimes.iso / demos / programme / AmigaWriter-Demo / StormScreenManager / source / StormScreenManager.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-10-06  |  66.0 KB  |  2,441 lines

  1. /*
  2.  
  3. StormScreenManager (SSM) Version 2.0
  4.  
  5. */
  6.  
  7. #include "ScreenManager.h"
  8. #include <dos/dos.h>
  9. #include <exec/memory.h>
  10. #include <intuition/gadgetclass.h>
  11. #include <intuition/imageclass.h>
  12. #include <libraries/asl.h>
  13. #include <libraries/commodities.h>
  14. #include <libraries/wizard.h>
  15. #include <rexx/errors.h>
  16. #include <workbench/workbench.h>
  17.  
  18. #include <clib/alib_protos.h>
  19. #include <clib/asl_protos.h>
  20. #include <clib/commodities_protos.h>
  21. #include <clib/diskfont_protos.h>
  22. #include <clib/dos_protos.h>
  23. #include <clib/exec_protos.h>
  24. #include <clib/graphics_protos.h>
  25. #include <clib/icon_protos.h>
  26. #include <clib/intuition_protos.h>
  27. #include <clib/locale_protos.h>
  28. #include <clib/rexxsyslib_protos.h>
  29. #include <clib/utility_protos.h>
  30. #include <clib/wb_protos.h>
  31. #include <clib/wizard_protos.h>
  32.  
  33. #include <string.h>
  34. #include <stdio.h>
  35. #include <ctype.h>
  36.  
  37. #define WBSTART_LIKE_SAS
  38. #include <wbstartup.h>
  39.  
  40. #define CATCOMP_NUMBERS
  41. #define CATCOMP_STRINGS
  42. #include "ScreenManagerAll.h"
  43.  
  44. #define EVT_HOTKEY 1
  45.  
  46. struct Screen *GlbScreenP;     // Open SSM User Interface on this screen
  47. struct Catalog *GlbCatalogP;   // SSM User Interface catalog
  48. APTR GlbSurfaceP;              // Wizard Interface Descriptor
  49. struct MsgPort *GlbIDCMPortP;  // Shared IDCM Port for all windows
  50. LONG GlbScreenSignal;          // All public screens use the same signal
  51. BPTR GlbCurrentDir;            // Backup of current directory
  52. STRPTR GlbProgramNameP;        // Name of Program
  53. BOOL GlbExitSoonF;             // Exit as soon as every screen is closed
  54.  
  55. extern UBYTE WizardSurface[];  // Wizard resource is linked to executable
  56.  
  57. // main window variables
  58. struct WizardWindowHandle *GlbManagerWindowHandleP;
  59. struct NewWindow *GlbManagerNewWindowP;
  60. struct Window *GlbManagerWindowP;
  61. struct Gadget *GlbManagerGadgets[MANAGERWIN_ID_GADGETS];
  62.  
  63. // property window variables
  64. struct WizardWindowHandle *GlbPropertiesWindowHandleP;
  65. struct NewWindow *GlbPropertiesNewWindowP;
  66. struct Window *GlbPropertiesWindowP;
  67. struct Gadget *GlbPropertiesGadgets[PROPERTIESWIN_ID_GADGETS];
  68. BOOL GlbOpenPropertiesF;
  69.  
  70. // asl font requester
  71. struct // loaded parameters
  72. {
  73.     BOOL Set;
  74.     ULONG Left, Top;
  75.     ULONG Width, Height;
  76. } GlbFontGeometry;
  77. struct FontRequester *GlbFontRequesterP;
  78.  
  79. // asl screen mode requester
  80. struct // loaded parameters
  81. {
  82.     BOOL Set;
  83.     ULONG Left, Top;
  84.     ULONG Width, Height;
  85.     BOOL InfoSet;
  86.     BOOL InfoOpened;              // InfoOpened, InfoWidth, InfoHeight are not
  87.     ULONG InfoLeft, InfoTop;      // supported to be set by AllocAslRequest()
  88.     ULONG InfoWidth, InfoHeight;  // so it is "future expansion"
  89. } GlbScreenModeGeometry;
  90. struct ScreenModeRequester *GlbScreenModeRequesterP;
  91.  
  92. // some global screen flags
  93. BOOL GlbShanghaiF;
  94. BOOL GlbAutoPopupF;
  95.  
  96. // commodity variables
  97. CxObj *GlbBrokerP;
  98. struct MsgPort *GlbBrokerPortP;
  99. BOOL GlbStartPopupF;
  100. LONG GlbCXPriority;
  101. BOOL GlbCXPopkeyF;
  102. UBYTE GlbCXPopkey[256];  // hot key description string
  103. BOOL GlbDisableF;
  104.  
  105. // rexx interface variables
  106. struct MsgPort *GlbRexxPortP;
  107.  
  108. // *************************************************************
  109. // ***
  110. // *** NAME      getlocalestr
  111. // *** FUNCTION  Simplify GetCatalogStr from locale.library
  112. // ***
  113. // *************************************************************
  114.  
  115. extern struct Library *LocaleBase;
  116.  
  117. STRPTR getlocalestr(ULONG id, STRPTR dflt)
  118. {
  119.     if (!LocaleBase)
  120.         return dflt;
  121.     return GetCatalogStr(GlbCatalogP,id,dflt);
  122. }
  123.  
  124. // *************************************************************
  125. // ***
  126. // *** NAME      ScreenNode
  127. // *** FUNCTION  Structure to store the screen parameters
  128. // ***
  129. // *************************************************************
  130.  
  131. struct ScreenNode
  132. {
  133.     struct WizardNode Node; // this is a node for wizard listviews
  134.     struct WizardNodeEntry Entries[6]; // 6 columns in my list
  135.     // work data
  136.     BOOL StormScreenF;   // TRUE : Screen is managed by StormScreenManager
  137.     BOOL OpenF;            // TRUE : Screen is currently open
  138.     BOOL CloseSoonF;     // TRUE : Close screen ASAP
  139.     BOOL OpenSoonF;      // TRUE : Open screen ASAP
  140.     struct Screen *Screen;      // pointer to screen, valid if OpenF == TRUE
  141.     struct Window *CloseGadget; // pointer to window showing the close gadget
  142.     STRPTR DefaultTitle;        // the old default title
  143.     // screen description
  144.     UBYTE Name[MAXPUBSCREENNAME]; // screen name
  145.     ULONG ModeID;          // display mode id
  146.     ULONG Depth;
  147.     ULONG Height;
  148.     ULONG Width;
  149.     UWORD Overscan;        // OSCAN_#?
  150.     BOOL AutoScrollF;
  151.     struct TextAttr Font;
  152.     BOOL OpenBehindF;
  153.     // more properties
  154.     BOOL CloseGadgetF;     // make a close gadget for this screen
  155.     BOOL QuietF;
  156.     UBYTE Title[256]; // if (strlen(Title) == 0) use pubscreen name
  157.     ULONG SysFont;    // 0 = custom font, 1 = system font, 2 = workbench font
  158.     UWORD Pens[15];   // currently not configurable, Pens[0] == ~0
  159.     BOOL LikeWorkbenchF;
  160.     BOOL DraggableF;
  161.     BOOL ExclusiveF;
  162.     struct            // colors are currently not configurable
  163.     {
  164.         struct loadrgb;
  165.         ULONG colors[3*256];
  166.     } colors32;
  167.     // buffers for listview texts
  168.     UBYTE ModeName[DISPLAYNAMELEN];
  169.     UBYTE FontText[64];
  170.     // more buffers
  171.     UBYTE FontName[64];     // Font.ta_Name points to this array
  172.     UBYTE ScreenTitle[280]; // the actual screen title is stored here
  173. };
  174.  
  175. struct MinList ScreenList;
  176. struct ScreenNode HeaderNode;    // the header node for the listview
  177. struct ScreenNode *ActiveNodeP;  // actual selected node
  178. struct ScreenNode *DefaultScreenNodeP; // this screen is the default screen
  179.  
  180. // *************************************************************
  181. // ***
  182. // *** NAME      AllocScreenNode
  183. // *** FUNCTION  Allocates a new ScreenNode entry and initializes it
  184. // ***
  185. // *************************************************************
  186. struct ScreenNode *AllocScreenNode(STRPTR Name)
  187. {
  188.     struct ScreenNode *node = (struct ScreenNode *) AllocVec(sizeof(struct ScreenNode),MEMF_CLEAR);
  189.     if (node)
  190.     {
  191.         strcpy(node->Name,Name);
  192.         node->CloseGadgetF = TRUE;
  193.         node->Pens[0] = ~0;
  194.         WZ_InitNode(&node->Node,6,       // 6 columns
  195.             TAG_END);
  196.         WZ_InitNodeEntry(&node->Node,0,  // Initialize each column
  197.             WENTRYA_Type,WNE_TEXT,
  198.             WENTRYA_TextPen,WZRD_TEXTPEN,
  199.             WENTRYA_TextSPen,WZRD_TEXTPEN,
  200.             WENTRYA_TextString,"",
  201.             TAG_END);
  202.         WZ_InitNodeEntry(&node->Node,1,
  203.             WENTRYA_Type,WNE_TEXT,
  204.             WENTRYA_TextPen,WZRD_TEXTPEN,
  205.             WENTRYA_TextSPen,WZRD_TEXTPEN,
  206.             WENTRYA_TextString,&node->Name,
  207.             TAG_END);
  208.         WZ_InitNodeEntry(&node->Node,2,
  209.             WENTRYA_Type,WNE_VIMAGE,
  210.             WENTRYA_VImageType,10,
  211.             TAG_END);
  212.         WZ_InitNodeEntry(&node->Node,3,
  213.             WENTRYA_Type,WNE_TEXT,
  214.             WENTRYA_TextPen,WZRD_TEXTPEN,
  215.             WENTRYA_TextSPen,WZRD_TEXTPEN,
  216.             WENTRYA_TextString,"",
  217.             TAG_END);
  218.         WZ_InitNodeEntry(&node->Node,4,
  219.             WENTRYA_Type,WNE_VIMAGE,
  220.             WENTRYA_VImageType,10,
  221.             TAG_END);
  222.         WZ_InitNodeEntry(&node->Node,5,
  223.             WENTRYA_Type,WNE_TEXT,
  224.             WENTRYA_TextPen,WZRD_TEXTPEN,
  225.             WENTRYA_TextSPen,WZRD_TEXTPEN,
  226.             WENTRYA_TextString,"",
  227.             TAG_END);
  228.     }
  229.     return node;
  230. }
  231.  
  232. // *************************************************************
  233. // ***
  234. // *** NAME      FreeScreenNode
  235. // *** FUNCTION  frees a screen node and release allocated resources
  236. // ***           (currently none)
  237. // ***
  238. // *************************************************************
  239. void FreeScreenNode(struct ScreenNode *node)
  240. {
  241.     FreeVec(node);
  242. }
  243.  
  244. // *************************************************************
  245. // ***
  246. // *** NAME      FreeScreenList
  247. // *** FUNCTION  remove and free all ScreenNodes from the global list
  248. // ***
  249. // *************************************************************
  250. void FreeScreenList()
  251. {
  252.     struct ScreenNode *node;
  253.     while (node = (struct ScreenNode *) RemHead((struct List *) &ScreenList))
  254.         FreeScreenNode(node);
  255. }
  256.  
  257. // *************************************************************
  258. // ***
  259. // *** NAME      InitHeaderNode
  260. // *** FUNCTION  Initialize the header node used for the listview
  261. // ***
  262. // *************************************************************
  263. void InitHeaderNode()
  264. {
  265.     struct ScreenNode *node = &HeaderNode;
  266.     WZ_InitNode(&node->Node,6,      // 6 columns
  267.         TAG_END);
  268.     WZ_InitNodeEntry(&node->Node,0, // initialize each column
  269.         WENTRYA_Type,WNE_TEXT,
  270.         WENTRYA_TextPen,WZRD_TEXTPEN,
  271.         WENTRYA_TextSPen,WZRD_TEXTPEN,
  272.         WENTRYA_TextStyle,FSF_BOLD,
  273.         WENTRYA_TextString,"·",
  274.         TAG_END);
  275.     WZ_InitNodeEntry(&node->Node,1,
  276.         WENTRYA_Type,WNE_TEXT,
  277.         WENTRYA_TextPen,WZRD_TEXTPEN,
  278.         WENTRYA_TextSPen,WZRD_TEXTPEN,
  279.         WENTRYA_TextStyle,FSF_BOLD,
  280.         WENTRYA_TextString,getlocalestr(MSG_NAME_ID,MSG_NAME_ID_STR),
  281.         TAG_END);
  282.     WZ_InitNodeEntry(&node->Node,2, // this feature is new for the latest
  283.         WENTRYA_Type,WNE_VIMAGE,     // wizard.library. If you have not the
  284.         WENTRYA_VImageType,10,       // newest version you will not see the
  285.         TAG_END);                    // vertical bars
  286.     WZ_InitNodeEntry(&node->Node,3,
  287.         WENTRYA_Type,WNE_TEXT,
  288.         WENTRYA_TextPen,WZRD_TEXTPEN,
  289.         WENTRYA_TextSPen,WZRD_TEXTPEN,
  290.         WENTRYA_TextStyle,FSF_BOLD,
  291.         WENTRYA_TextString,getlocalestr(MSG_DISPLAYMODE_ID,MSG_DISPLAYMODE_ID_STR),
  292.         TAG_END);
  293.     WZ_InitNodeEntry(&node->Node,4,
  294.         WENTRYA_Type,WNE_VIMAGE,
  295.         WENTRYA_VImageType,10,
  296.         TAG_END);
  297.     WZ_InitNodeEntry(&node->Node,5,
  298.         WENTRYA_Type,WNE_TEXT,
  299.         WENTRYA_TextPen,WZRD_TEXTPEN,
  300.         WENTRYA_TextSPen,WZRD_TEXTPEN,
  301.         WENTRYA_TextStyle,FSF_BOLD,
  302.         WENTRYA_TextString,getlocalestr(MSG_FONT_ID,MSG_FONT_ID_STR),
  303.         TAG_END);
  304. }
  305.  
  306. // *************************************************************
  307. // ***
  308. // *** NAME      SetScreenName
  309. // *** FUNCTION  Set the screen name for the given node
  310. // ***
  311. // *************************************************************
  312. void SetScreenName(struct ScreenNode *node, STRPTR Name)
  313. {
  314.     strcpy(node->Name,Name);
  315.     WZ_InitNodeEntry(&node->Node,1,
  316.         WENTRYA_TextString,&node->Name,
  317.         TAG_END);
  318. }
  319.  
  320. // *************************************************************
  321. // ***
  322. // *** NAME      SetScreenMode
  323. // *** FUNCTION  Set display mode and some values from the asl requester
  324. // ***
  325. // *************************************************************
  326. void SetScreenMode(struct ScreenNode *node, ULONG modeid,
  327.     ULONG depth, ULONG height, ULONG width, UWORD overscan, BOOL autoscroll)
  328. {
  329.     struct NameInfo nameinfo;
  330.     if (GetDisplayInfoData(NULL,(UBYTE *) &nameinfo,sizeof(struct NameInfo),DTAG_NAME,modeid))
  331.     {
  332.         strcpy(node->ModeName,nameinfo.Name);
  333.         WZ_InitNodeEntry(&node->Node,3,
  334.             WENTRYA_TextString,&node->ModeName,
  335.             TAG_END);
  336.     }
  337.     else
  338.     {
  339.         WZ_InitNodeEntry(&node->Node,3,
  340.             WENTRYA_TextString,getlocalestr(MSG_UNKNOWN_ID,MSG_UNKNOWN_ID_STR),
  341.             TAG_END);
  342.     }
  343.     node->ModeID = modeid;
  344.     node->Depth = depth;
  345.     node->Height = height;
  346.     node->Width = width;
  347.     node->Overscan = overscan;
  348.     node->AutoScrollF = autoscroll;
  349. }
  350.  
  351. // *************************************************************
  352. // ***
  353. // *** NAME      SetScreenFont
  354. // *** FUNCTION  Set the screen font from the asl requester
  355. // ***
  356. // *************************************************************
  357. void SetScreenFont(struct ScreenNode *node, struct TextAttr *tattr)
  358. {
  359.     sprintf(node->FontText,getlocalestr(MSG_FONTTEXT_ID,MSG_FONTTEXT_ID_STR),
  360.         tattr->ta_Name,tattr->ta_YSize);
  361.     WZ_InitNodeEntry(&node->Node,5,
  362.         WENTRYA_TextString,&node->FontText,
  363.         TAG_END);
  364.     strcpy(node->FontName,tattr->ta_Name);
  365.     node->Font = *tattr;
  366.     node->Font.ta_Name = node->FontName;
  367.     node->Font.ta_Style &= ~FSF_TAGGED; // for safety
  368. }
  369.  
  370. // *************************************************************
  371. // ***
  372. // *** NAME      AddScreenNode
  373. // *** FUNCTION  Add node to list, alphanumerical sorted
  374. // ***
  375. // *************************************************************
  376. void AddScreenNode(struct ScreenNode *node)
  377. {
  378.     struct ScreenNode *n;
  379.     for (n = (struct ScreenNode *) ScreenList.mlh_Head;
  380.         n->Node.Node.mln_Succ;
  381.         n = (struct ScreenNode *) n->Node.Node.mln_Succ)
  382.     {
  383.         if (Stricmp(n->Name,node->Name) > 0)
  384.         {
  385.             Insert((struct List *) &ScreenList, (struct Node *) &node->Node.Node,
  386.                 (struct Node *) n->Node.Node.mln_Pred);
  387.             return;
  388.         }
  389.     }
  390.     AddTail((struct List *) &ScreenList, (struct Node *) &node->Node.Node);
  391. }
  392.  
  393. // *************************************************************
  394. // ***
  395. // *** NAME      RemScreenNode
  396. // *** FUNCTION  Remove a screen node from its list
  397. // ***
  398. // *************************************************************
  399. void RemScreenNode(struct ScreenNode *node)
  400. {
  401.     Remove((struct Node *) &node->Node.Node);
  402. }
  403.  
  404. // *************************************************************
  405. // ***
  406. // *** NAME      FindScreenNode
  407. // *** FUNCTION  Find a screen node with the given name
  408. // ***
  409. // *************************************************************
  410. struct ScreenNode *FindScreenNode(STRPTR Name)
  411. {
  412.     struct ScreenNode *node;
  413.     for (node = (struct ScreenNode *) ScreenList.mlh_Head;
  414.         node->Node.Node.mln_Succ;
  415.         node = (struct ScreenNode *) node->Node.Node.mln_Succ)
  416.     {
  417.         if (Stricmp(node->Name,Name) == 0)
  418.             return node;
  419.     }
  420.     return NULL;
  421. }
  422.  
  423. // *************************************************************
  424. // ***
  425. // *** NAME      GetScreenNode
  426. // *** FUNCTION  Find a screen node with the given index
  427. // ***
  428. // *************************************************************
  429. struct ScreenNode *GetScreenNode(ULONG index)
  430. {
  431.     ULONG i = 0;
  432.     struct ScreenNode *node;
  433.     for (node = (struct ScreenNode *) ScreenList.mlh_Head;
  434.         node->Node.Node.mln_Succ;
  435.         node = (struct ScreenNode *) node->Node.Node.mln_Succ)
  436.     {
  437.         if (index == i)
  438.             return node;
  439.         i++;
  440.     }
  441.     return NULL;
  442. }
  443.  
  444. // *************************************************************
  445. // ***
  446. // *** NAME      GetScreenNodeIndex
  447. // *** FUNCTION  COunt the index for a given screen node
  448. // ***
  449. // *************************************************************
  450. ULONG GetScreenNodeIndex(struct ScreenNode *n)
  451. {
  452.     ULONG i = 0;
  453.     struct ScreenNode *node;
  454.     for (node = (struct ScreenNode *) ScreenList.mlh_Head;
  455.         node->Node.Node.mln_Succ;
  456.         node = (struct ScreenNode *) node->Node.Node.mln_Succ)
  457.     {
  458.         if (node == n)
  459.             return i;
  460.         i++;
  461.     }
  462.     return ~0;
  463. }
  464.  
  465. // *************************************************************
  466. // ***
  467. // *** NAME      LengthOfScreenList
  468. // *** FUNCTION  Calculate the number of ScreenNodes in the list
  469. // ***
  470. // *************************************************************
  471. ULONG LengthOfScreenList()
  472. {
  473.     ULONG i = 0;
  474.     struct ScreenNode *node;
  475.     for (node = (struct ScreenNode *) ScreenList.mlh_Head;
  476.         node->Node.Node.mln_Succ;
  477.         node = (struct ScreenNode *) node->Node.Node.mln_Succ)
  478.     {
  479.         i++;
  480.     }
  481.     return i;
  482. }
  483.  
  484. // *************************************************************
  485. // ***
  486. // *** NAME      ScanOpenPubScreens
  487. // *** FUNCTION  Scan the list of public screens and add to list
  488. // ***
  489. // *************************************************************
  490. void ScanOpenPubScreens()
  491. {
  492.     struct ScreenNode *node, *succ;
  493.     for (node = (struct ScreenNode *) ScreenList.mlh_Head;
  494.         succ = (struct ScreenNode *) node->Node.Node.mln_Succ;
  495.         node = succ)
  496.     {
  497.         if (!node->StormScreenF)
  498.         {
  499.             RemScreenNode(node);
  500.             FreeScreenNode(node);
  501.         }
  502.     }
  503.     struct List *pubscreens = LockPubScreenList();
  504.     struct PubScreenNode *snode;
  505.     for (snode = (struct PubScreenNode *) pubscreens->lh_Head;
  506.         snode->psn_Node.ln_Succ;
  507.         snode = (struct PubScreenNode *) snode->psn_Node.ln_Succ)
  508.     {
  509.         if ((snode->psn_Flags & PSNF_PRIVATE) == 0)
  510.         {
  511.             if (!FindScreenNode(snode->psn_Node.ln_Name))
  512.             {
  513.                 struct ScreenNode *n = AllocScreenNode(snode->psn_Node.ln_Name);
  514.                 if (n)
  515.                 {
  516.                     AddScreenNode(n);
  517.                     n->OpenF = TRUE;
  518.                 }
  519.             }
  520.         }
  521.     }
  522.     UnlockPubScreenList()
  523. }
  524.  
  525. // *************************************************************
  526. // ***
  527. // *** NAME      SetDefaultScreenNode
  528. // *** FUNCTION  Make the given screen node the default public screen
  529. // ***
  530. // *************************************************************
  531. void SetDefaultScreenNode(struct ScreenNode *node)
  532. {
  533.     if (node->OpenF)
  534.     {
  535.         if (DefaultScreenNodeP)
  536.         {
  537.             WZ_InitNodeEntry(&DefaultScreenNodeP->Node,0,
  538.                 WENTRYA_TextString,"",
  539.                 TAG_END);
  540.             DefaultScreenNodeP = NULL;
  541.         }
  542.         DefaultScreenNodeP = node;
  543.         SetDefaultPubScreen(node->Name);
  544.         WZ_InitNodeEntry(&DefaultScreenNodeP->Node,0,
  545.             WENTRYA_TextString,"·",
  546.             TAG_END);
  547.     }
  548. }
  549.  
  550. // *************************************************************
  551. // ***
  552. // *** NAME      GetDefaultScreenNode
  553. // *** FUNCTION  Get the default public screen and reset it in the list
  554. // ***
  555. // *************************************************************
  556. struct ScreenNode *GetDefaultScreenNode()
  557. {
  558.     UBYTE Name[MAXPUBSCREENNAME];
  559.     GetDefaultPubScreen(Name);
  560.     struct ScreenNode *node = FindScreenNode(Name);
  561.     if (node)
  562.         SetDefaultScreenNode(node);
  563.     return node;
  564. }
  565.  
  566. // *************************************************************
  567. // ***
  568. // *** NAME      IsAnyScreenOpen
  569. // *** FUNCTION  Returns TRUE if any screen is opened by SSM
  570. // ***
  571. // *************************************************************
  572. BOOL IsAnyScreenOpen()
  573. {
  574.     struct ScreenNode *node;
  575.     for (node = (struct ScreenNode *) ScreenList.mlh_Head;
  576.         node->Node.Node.mln_Succ;
  577.         node = (struct ScreenNode *) node->Node.Node.mln_Succ)
  578.     {
  579.         if (node->StormScreenF && node->OpenF)
  580.             return TRUE;
  581.     }
  582.     return FALSE;
  583. }
  584.  
  585. // *************************************************************
  586. // ***
  587. // *** NAME      Save
  588. // *** FUNCTION  Save the screen list and interface parameters to
  589. // ***           a workbench icon
  590. // ***
  591. // *************************************************************
  592. STRPTR Save(STRPTR Name)
  593. {
  594.     struct DiskObject *diskobj;
  595.     STRPTR ToolTypes[64];
  596.     UBYTE *Buffer;
  597.     if (!(Buffer = (UBYTE *) AllocVec(16384,MEMF_CLEAR)))
  598.         return getlocalestr(MSG_OUT_OF_MEMORY_ID,MSG_OUT_OF_MEMORY_ID_STR);
  599.     if (diskobj = GetDiskObject(Name))
  600.     {
  601.     }
  602.     else if (diskobj = GetDefDiskObject(WBTOOL))
  603.     {
  604.         diskobj->do_CurrentX = NO_ICON_POSITION;
  605.         diskobj->do_CurrentY = NO_ICON_POSITION;
  606.     }
  607.     else
  608.     {
  609.         FreeVec(Buffer);
  610.         return getlocalestr(MSG_UNABLE_TO_READ_ICON_ID,MSG_UNABLE_TO_READ_ICON_ID_STR);
  611.     }
  612.     // copy some tooltypes that are not configurable by SSM
  613.     STRPTR cxpriority = FindToolType((UBYTE **) diskobj->do_ToolTypes,"CX_PRIORITY");
  614.     STRPTR cxpopup = FindToolType((UBYTE **) diskobj->do_ToolTypes,"CX_POPUP");
  615.     if (!cxpopup)
  616.         cxpopup = "NO";
  617.     STRPTR cxpopkey = FindToolType((UBYTE **) diskobj->do_ToolTypes,"CX_POPKEY");
  618.     if (!cxpopkey)
  619.         cxpopkey = "control alt p";
  620.  
  621.     // set the standard tooltypes
  622.     ULONG i = 0;
  623.     STRPTR Buf = Buffer;
  624.     Buf += sprintf(ToolTypes[i++] = Buf,"DONOTWAIT") + 1;
  625.     if (cxpriority)
  626.         Buf += sprintf(ToolTypes[i++] = Buf,"CX_PRIORITY=%s",cxpriority) + 1;
  627.     Buf += sprintf(ToolTypes[i++] = Buf,"CX_POPUP=%s",cxpopup) + 1;
  628.     Buf += sprintf(ToolTypes[i++] = Buf,"CX_POPKEY=%s",cxpopkey) + 1;
  629.  
  630.     // save the global parameters
  631.     Buf += sprintf(ToolTypes[i++] = Buf,"SHANGHAI=%s",GlbShanghaiF ? "ON" : "OFF") + 1;
  632.     Buf += sprintf(ToolTypes[i++] = Buf,"AUTOPOPUP=%s",GlbAutoPopupF ? "ON" : "OFF") + 1;
  633.     if (DefaultScreenNodeP)
  634.         Buf += sprintf(ToolTypes[i++] = Buf,"DEFAULTSCREEN=%s",DefaultScreenNodeP->Name) + 1;
  635.  
  636.     // save the screen list
  637.     struct ScreenNode *node;
  638.     for (node = (struct ScreenNode *) ScreenList.mlh_Head;
  639.         node->Node.Node.mln_Succ;
  640.         node = (struct ScreenNode *) node->Node.Node.mln_Succ)
  641.     {
  642.         if (node->StormScreenF)
  643.         {
  644.             Buf += sprintf(ToolTypes[i++] = Buf,
  645.                 "SCREEN=%s/%ld/%ld/%ld/0x%lx/%s/%ld/%s/%ld/%ld/%ld/%ld/%ld/%s/%ld/%ld/%ld/%ld",
  646.                 node->Name,
  647.                 node->Width,
  648.                 node->Height,
  649.                 node->Depth,
  650.                 node->ModeID,
  651.                 node->Font.ta_Name,
  652.                 node->Font.ta_YSize,
  653.                 node->OpenF ? "on" : "off",
  654.                 node->OpenBehindF,
  655.                 node->CloseGadgetF,
  656.                 node->AutoScrollF,
  657.                 node->Overscan,
  658.                 node->QuietF,
  659.                 node->Title,
  660.                 node->SysFont,
  661.                 node->LikeWorkbenchF,
  662.                 node->DraggableF,
  663.                 node->ExclusiveF
  664.                 ) + 1;
  665.         }
  666.     }
  667.  
  668.     // save the interface parameters like window geometry etc
  669.     if (GlbManagerWindowP)
  670.     {
  671.         Buf += sprintf(ToolTypes[i++] = Buf,"WINDOW=%ld/%ld/%ld/%ld",
  672.             GlbManagerWindowP->LeftEdge,
  673.             GlbManagerWindowP->TopEdge,
  674.             GlbManagerWindowP->Width,
  675.             GlbManagerWindowP->Height) + 1;
  676.     }
  677.     else
  678.     {
  679.         Buf += sprintf(ToolTypes[i++] = Buf,"WINDOW=%ld/%ld/%ld/%ld",
  680.             GlbManagerNewWindowP->LeftEdge,
  681.             GlbManagerNewWindowP->TopEdge,
  682.             GlbManagerNewWindowP->Width,
  683.             GlbManagerNewWindowP->Height) + 1;
  684.     }
  685.     if (GlbPropertiesWindowP)
  686.     {
  687.         Buf += sprintf(ToolTypes[i++] = Buf,"PROPERTIES=%ld/%ld/%ld/%ld/on",
  688.             GlbPropertiesWindowP->LeftEdge,
  689.             GlbPropertiesWindowP->TopEdge,
  690.             GlbPropertiesWindowP->Width,
  691.             GlbPropertiesWindowP->Height) + 1;
  692.     }
  693.     else
  694.     {
  695.         Buf += sprintf(ToolTypes[i++] = Buf,"PROPERTIES=%ld/%ld/%ld/%ld/off",
  696.             GlbPropertiesNewWindowP->LeftEdge,
  697.             GlbPropertiesNewWindowP->TopEdge,
  698.             GlbPropertiesNewWindowP->Width,
  699.             GlbPropertiesNewWindowP->Height) + 1;
  700.     }
  701.     Buf += sprintf(ToolTypes[i++] = Buf,"SCREENMODEREQ=%ld/%ld/%ld/%ld",
  702.         GlbScreenModeRequesterP->sm_LeftEdge,
  703.         GlbScreenModeRequesterP->sm_TopEdge,
  704.         GlbScreenModeRequesterP->sm_Width,
  705.         GlbScreenModeRequesterP->sm_Height) + 1;
  706.     Buf += sprintf(ToolTypes[i++] = Buf,"SCREENMODEINFO=%ld/%ld/%ld/%ld/%ld",
  707.         GlbScreenModeRequesterP->sm_InfoLeftEdge,
  708.         GlbScreenModeRequesterP->sm_InfoTopEdge,
  709.         GlbScreenModeRequesterP->sm_InfoWidth,
  710.         GlbScreenModeRequesterP->sm_InfoHeight,
  711.         GlbScreenModeRequesterP->sm_InfoOpened) + 1;
  712.     Buf += sprintf(ToolTypes[i++] = Buf,"FONTREQ=%ld/%ld/%ld/%ld",
  713.         GlbFontRequesterP->fo_LeftEdge,
  714.         GlbFontRequesterP->fo_TopEdge,
  715.         GlbFontRequesterP->fo_Width,
  716.         GlbFontRequesterP->fo_Height) + 1;
  717.     ToolTypes[i] = NULL;
  718.  
  719.     // write icon to file
  720.     STRPTR *tooltypes = diskobj->do_ToolTypes;
  721.     diskobj->do_ToolTypes = ToolTypes;
  722.     if (!PutDiskObject(Name,diskobj))
  723.     {
  724.         diskobj->do_ToolTypes = tooltypes;
  725.         FreeDiskObject(diskobj);
  726.         FreeVec(Buffer);
  727.         return getlocalestr(MSG_UNABLE_TO_WRITE_ICON_ID,MSG_UNABLE_TO_WRITE_ICON_ID_STR);
  728.     }
  729.     diskobj->do_ToolTypes = tooltypes;
  730.     FreeDiskObject(diskobj);
  731.     FreeVec(Buffer);
  732.     return NULL; // no error string
  733. }
  734.  
  735. // *************************************************************
  736. // ***
  737. // *** NAME      Load
  738. // *** FUNCTION  Load a screen list and many parameters from a wb icon
  739. // ***
  740. // *************************************************************
  741. STRPTR Load(STRPTR Name)
  742. {
  743.     struct DiskObject *diskobj;
  744.     if (!(diskobj = GetDiskObject(Name)))
  745.         return NULL;
  746.     STRPTR v;
  747.  
  748.     // load some standard parameters
  749.     v = FindToolType((UBYTE **) diskobj->do_ToolTypes,"CX_PRIORITY");
  750.     if (v)
  751.     {
  752.         sscanf(v,"%ld",&GlbCXPriority);
  753.         if (GlbCXPriority > 127)
  754.             GlbCXPriority = 127;
  755.         else if (GlbCXPriority < -128)
  756.             GlbCXPriority = -128;
  757.     }
  758.     v = FindToolType((UBYTE **) diskobj->do_ToolTypes,"CX_POPUP");
  759.     if (v && (MatchToolValue(v,"ON") || MatchToolValue(v,"TRUE") || strlen(v) == 0))
  760.         GlbStartPopupF = TRUE;
  761.     v = FindToolType((UBYTE **) diskobj->do_ToolTypes,"CX_POPKEY");
  762.     if (v)
  763.     {
  764.         GlbCXPopkeyF = TRUE;
  765.         strcpy(GlbCXPopkey,v);
  766.     }
  767.  
  768.     // load some global variables
  769.     v = FindToolType((UBYTE **) diskobj->do_ToolTypes,"SHANGHAI");
  770.     if (v && (MatchToolValue(v,"ON") || MatchToolValue(v,"TRUE") || strlen(v) == 0))
  771.         GlbShanghaiF = TRUE;
  772.     v = FindToolType((UBYTE **) diskobj->do_ToolTypes,"AUTOPOPUP");
  773.     if (v && (MatchToolValue(v,"ON") || MatchToolValue(v,"TRUE") || strlen(v) == 0))
  774.         GlbAutoPopupF = TRUE;
  775.  
  776.     // build the screen list
  777.     STRPTR *ToolTypes = diskobj->do_ToolTypes;
  778.     while (*ToolTypes)
  779.     {
  780.         STRPTR ToolType = *ToolTypes;
  781.         UBYTE Name[MAXPUBSCREENNAME];
  782.         ULONG Width, Height, Depth, ModeID;
  783.         struct TextAttr Font;
  784.         UBYTE FontName[64];
  785.         UBYTE OpenF[6];
  786.         ULONG OpenBehindF = FALSE, CloseGadgetF = FALSE, AutoScrollF = FALSE;
  787.         ULONG Overscan = OSCAN_TEXT, QuietF = FALSE;
  788.         UBYTE Title[256] = { };
  789.         ULONG SysFont = 0, LikeWorkbenchF = FALSE, DraggableF = FALSE;
  790.         ULONG ExclusiveF = FALSE;
  791.         LONG parameters;
  792.         if (parameters = sscanf(ToolType,
  793.             "SCREEN=%[^/]/%ld/%ld/%ld/%lx/%[^/]/%hd/%[^/]/%ld/%ld/%ld/%ld/%ld/%[^/]/%ld/%ld/%ld/%ld",
  794.             Name,
  795.             &Width,
  796.             &Height,
  797.             &Depth,
  798.             &ModeID,
  799.             FontName,
  800.             &Font.ta_YSize,
  801.             OpenF,
  802.             &OpenBehindF,
  803.             &CloseGadgetF,
  804.             &AutoScrollF,
  805.             &Overscan,
  806.             &QuietF,
  807.             Title,
  808.             &SysFont,
  809.             &LikeWorkbenchF,
  810.             &DraggableF,
  811.             &ExclusiveF
  812.             ) >= 8)
  813.         {
  814.             struct ScreenNode *node;
  815.             if (node = AllocScreenNode(Name))
  816.             {
  817.                 node->StormScreenF = TRUE;
  818.                 SetScreenMode(node,ModeID,Depth,Height,Width,OSCAN_TEXT,TRUE);
  819.                 Font.ta_Name = FontName;
  820.                 SetScreenFont(node,&Font);
  821.                 node->OpenSoonF = (Stricmp(OpenF,"on") == 0); // screens will be opened later
  822.                 node->OpenBehindF = OpenBehindF;
  823.                 node->CloseGadgetF = CloseGadgetF;
  824.                 node->AutoScrollF = AutoScrollF;
  825.                 node->Overscan = Overscan;
  826.                 node->QuietF = QuietF;
  827.                 strcpy(node->Title,Title);
  828.                 node->SysFont = SysFont;
  829.                 node->LikeWorkbenchF = LikeWorkbenchF;
  830.                 node->DraggableF = DraggableF;
  831.                 node->ExclusiveF = ExclusiveF;
  832.                 AddScreenNode(node);
  833.             }
  834.             else
  835.             {
  836.                 FreeDiskObject(diskobj);
  837.                 return getlocalestr(MSG_OUT_OF_MEMORY_ID,MSG_OUT_OF_MEMORY_ID_STR);
  838.             }
  839.         }
  840.         ToolTypes++
  841.     }
  842.     v = FindToolType((UBYTE **) diskobj->do_ToolTypes,"DEFAULTSCREEN");
  843.     if (v)
  844.     {
  845.         DefaultScreenNodeP = FindScreenNode(v);
  846.     }
  847.  
  848.     // load interface parameters
  849.     v = FindToolType((UBYTE **) diskobj->do_ToolTypes,"WINDOW");
  850.     sscanf(v,"%hd/%hd/%hd/%hd",
  851.         &GlbManagerNewWindowP->LeftEdge,
  852.         &GlbManagerNewWindowP->TopEdge,
  853.         &GlbManagerNewWindowP->Width,
  854.         &GlbManagerNewWindowP->Height);
  855.     v = FindToolType((UBYTE **) diskobj->do_ToolTypes,"PROPERTIES");
  856.     UBYTE onoff[10];
  857.     sscanf(v,"%hd/%hd/%hd/%hd/%[^/]",
  858.         &GlbPropertiesNewWindowP->LeftEdge,
  859.         &GlbPropertiesNewWindowP->TopEdge,
  860.         &GlbPropertiesNewWindowP->Width,
  861.         &GlbPropertiesNewWindowP->Height,
  862.         &onoff);
  863.     GlbOpenPropertiesF = (Stricmp(onoff,"on") == 0);
  864.     v = FindToolType((UBYTE **) diskobj->do_ToolTypes,"SCREENMODEREQ");
  865.     GlbScreenModeGeometry.Set = (sscanf(v,"%ld/%ld/%ld/%ld",
  866.         &GlbScreenModeGeometry.Left,
  867.         &GlbScreenModeGeometry.Top,
  868.         &GlbScreenModeGeometry.Width,
  869.         &GlbScreenModeGeometry.Height) == 4);
  870.     v = FindToolType((UBYTE **) diskobj->do_ToolTypes,"SCREENMODEINFO");
  871.     GlbScreenModeGeometry.InfoSet = (sscanf(v,"%ld/%ld/%ld/%ld/%hd",
  872.         &GlbScreenModeGeometry.InfoLeft,
  873.         &GlbScreenModeGeometry.InfoTop,
  874.         &GlbScreenModeGeometry.InfoWidth,
  875.         &GlbScreenModeGeometry.InfoHeight,
  876.         &GlbScreenModeGeometry.InfoOpened) == 5);
  877.     v = FindToolType((UBYTE **) diskobj->do_ToolTypes,"FONTREQ");
  878.     GlbFontGeometry.Set = (sscanf(v,"%ld/%ld/%ld/%ld",
  879.         &GlbFontGeometry.Left,
  880.         &GlbFontGeometry.Top,
  881.         &GlbFontGeometry.Width,
  882.         &GlbFontGeometry.Height) == 4);
  883.     FreeDiskObject(diskobj);
  884.     return NULL;
  885. }
  886.  
  887. // *************************************************************
  888. // ***
  889. // *** NAME      StripIDCMPMessages
  890. // *** FUNCTION  Reply messages before closing a window (should be in amiga.lib)
  891. // ***
  892. // *************************************************************
  893. void StripIDCMPMessages(struct Window *WinP)
  894. {
  895.     Forbid();
  896.     struct IntuiMessage *msg;
  897.     struct Node *succ;
  898.     msg = (struct IntuiMessage *) WinP->UserPort->mp_MsgList.lh_Head;
  899.     while (succ = msg->ExecMessage.mn_Node.ln_Succ)
  900.     {
  901.         if (msg->IDCMPWindow == WinP)
  902.         {
  903.             Remove(&msg->ExecMessage.mn_Node);
  904.             ReplyMsg(&msg->ExecMessage);
  905.         }
  906.         msg = (struct IntuiMessage *) succ;
  907.     }
  908.     WinP->UserPort = NULL;
  909.     ModifyIDCMP(WinP,0);
  910.     Permit();
  911. }
  912.  
  913. // *************************************************************
  914. // ***
  915. // *** NAME      error
  916. // *** FUNCTION  show error message, cleanup and exit
  917. // ***
  918. // *************************************************************
  919. void error(char *s)
  920. {
  921.     if (s)
  922.     {
  923.         if (GlbSurfaceP)
  924.         {
  925.             WZ_LockWindows(GlbSurfaceP);
  926.             WZ_EasyRequestArgs(GlbSurfaceP,GlbManagerWindowP,REQ_ERROR_ID,&s);
  927.             WZ_UnlockWindows(GlbSurfaceP);
  928.         }
  929.     }
  930.     if (GlbPropertiesWindowP)
  931.     {
  932.         StripIDCMPMessages(GlbPropertiesWindowP);
  933.         WZ_CloseWindow(GlbPropertiesWindowHandleP);
  934.     }
  935.     if (GlbManagerWindowP)
  936.     {
  937.         StripIDCMPMessages(GlbManagerWindowP);
  938.         WZ_CloseWindow(GlbManagerWindowHandleP);
  939.     }
  940.     if (GlbIDCMPortP)
  941.         DeleteMsgPort(GlbIDCMPortP);
  942.     if (GlbRexxPortP)
  943.     {
  944.         RemPort(GlbRexxPortP);
  945.         struct RexxMsg *msg;
  946.         while (msg = (struct RexxMsg *) GetMsg(GlbRexxPortP))
  947.         {
  948.             msg->rm_Result1 = RC_FATAL;
  949.             ReplyMsg(&msg->rm_Node);
  950.         }
  951.         DeleteMsgPort(GlbRexxPortP);
  952.     }
  953.     if (GlbScreenSignal != ~0)
  954.         FreeSignal(GlbScreenSignal);
  955.     if (GlbPropertiesWindowHandleP)
  956.         WZ_FreeWindowHandle(GlbPropertiesWindowHandleP);
  957.     if (GlbManagerWindowHandleP)
  958.         WZ_FreeWindowHandle(GlbManagerWindowHandleP);
  959.     if (GlbSurfaceP)
  960.         WZ_CloseSurface(GlbSurfaceP);
  961.     if (GlbScreenP)
  962.         UnlockPubScreen(NULL,GlbScreenP);
  963.     if (GlbFontRequesterP)
  964.         FreeAslRequest(GlbFontRequesterP);
  965.     if (GlbScreenModeRequesterP)
  966.         FreeAslRequest(GlbScreenModeRequesterP);
  967.     FreeScreenList();
  968.     if (GlbBrokerP)
  969.     {
  970.         DeleteCxObjAll(GlbBrokerP);
  971.     }
  972.     if (GlbBrokerPortP)
  973.     {
  974.         CxMsg *msg;
  975.         while (msg = (CxMsg *) GetMsg(GlbBrokerPortP))
  976.             ReplyMsg((struct Message *) msg);
  977.         DeletePort(GlbBrokerPortP);
  978.     }
  979.     if (GlbCatalogP)
  980.         CloseCatalog(GlbCatalogP);
  981.     if (GlbCurrentDir)
  982.         UnLock(CurrentDir(GlbCurrentDir));
  983.     exit(s ? 20 : 0)
  984. }
  985.  
  986. // *************************************************************
  987. // ***
  988. // *** NAME      setselected
  989. // *** FUNCTION  Set all gadgets that reflect a screen node
  990. // ***
  991. // *************************************************************
  992. void setselected()
  993. {
  994.     ULONG selected;
  995.     GetAttr(WLISTVIEWA_Selected,GlbManagerGadgets[GAD_MAN_LIST_ID],&selected);
  996.     ActiveNodeP = GetScreenNode(selected);
  997.     if (ActiveNodeP)
  998.     {
  999.         BOOL v = (!ActiveNodeP->StormScreenF) || ActiveNodeP->OpenF;
  1000.         SetGadgetAttrs(GlbManagerGadgets[GAD_MAN_NAME_ID],GlbManagerWindowP,NULL,
  1001.             GA_Disabled,v,
  1002.             WSTRINGA_String,ActiveNodeP->Name,
  1003.             TAG_END);
  1004.         SetGadgetAttrs(GlbManagerGadgets[GAD_MAN_DELETE_ID],GlbManagerWindowP,NULL,
  1005.             GA_Disabled,v,
  1006.             TAG_END);
  1007.         SetGadgetAttrs(GlbManagerGadgets[GAD_MAN_MODE_ID],GlbManagerWindowP,NULL,
  1008.             GA_Disabled,v,
  1009.             TAG_END);
  1010.         SetGadgetAttrs(GlbManagerGadgets[GAD_MAN_FONT_ID],GlbManagerWindowP,NULL,
  1011.             GA_Disabled,v,
  1012.             TAG_END);
  1013.         SetGadgetAttrs(GlbManagerGadgets[GAD_MAN_OPEN_ID],GlbManagerWindowP,NULL,
  1014.             GA_Disabled,!ActiveNodeP->StormScreenF,
  1015.             WTOGGLEA_Checked,ActiveNodeP->OpenF,
  1016.             TAG_END);
  1017.         SetGadgetAttrs(GlbManagerGadgets[GAD_MAN_OPENBEHIND_ID],GlbManagerWindowP,NULL,
  1018.             GA_Disabled,!ActiveNodeP->StormScreenF,
  1019.             WCHECKBOXA_Checked,ActiveNodeP->OpenBehindF,
  1020.             TAG_END);
  1021.         SetGadgetAttrs(GlbPropertiesGadgets[GAD_PRP_COLORNUM_ID],GlbPropertiesWindowP,NULL,
  1022.             WARGSA_Format,ActiveNodeP->StormScreenF ? "%ld" : "",
  1023.             WARGSA_Arg0,1L << ActiveNodeP->Depth,
  1024.             TAG_END);
  1025.         SetGadgetAttrs(GlbPropertiesGadgets[GAD_PRP_WIDTH_ID],GlbPropertiesWindowP,NULL,
  1026.             WARGSA_Format,ActiveNodeP->StormScreenF ? "%ld" : "",
  1027.             WARGSA_Arg0,ActiveNodeP->Width,
  1028.             TAG_END);
  1029.         SetGadgetAttrs(GlbPropertiesGadgets[GAD_PRP_HEIGHT_ID],GlbPropertiesWindowP,NULL,
  1030.             WARGSA_Format,ActiveNodeP->StormScreenF ? "%ld" : "",
  1031.             WARGSA_Arg0,ActiveNodeP->Height,
  1032.             TAG_END);
  1033.         SetGadgetAttrs(GlbPropertiesGadgets[GAD_PRP_FONT_ID],GlbPropertiesWindowP,NULL,
  1034.             GA_Disabled,v,
  1035.             WCYCLEA_Active,ActiveNodeP->SysFont,
  1036.             TAG_END);
  1037.         SetGadgetAttrs(GlbPropertiesGadgets[GAD_PRP_TITLE_ID],GlbPropertiesWindowP,NULL,
  1038.             GA_Disabled,v,
  1039.             WSTRINGA_String,ActiveNodeP->Title,
  1040.             TAG_END);
  1041.         SetGadgetAttrs(GlbPropertiesGadgets[GAD_PRP_LIKEWB_ID],GlbPropertiesWindowP,NULL,
  1042.             GA_Disabled,v,
  1043.             WCHECKBOXA_Checked,ActiveNodeP->LikeWorkbenchF,
  1044.             TAG_END);
  1045.         SetGadgetAttrs(GlbPropertiesGadgets[GAD_PRP_CLOSEGADGET_ID],GlbPropertiesWindowP,NULL,
  1046.             GA_Disabled,v,
  1047.             WCHECKBOXA_Checked,ActiveNodeP->CloseGadgetF,
  1048.             TAG_END);
  1049.         SetGadgetAttrs(GlbPropertiesGadgets[GAD_PRP_DRAGGABLE_ID],GlbPropertiesWindowP,NULL,
  1050.             GA_Disabled,v,
  1051.             WCHECKBOXA_Checked,ActiveNodeP->DraggableF,
  1052.             TAG_END);
  1053.         SetGadgetAttrs(GlbPropertiesGadgets[GAD_PRP_QUIET_ID],GlbPropertiesWindowP,NULL,
  1054.             GA_Disabled,v,
  1055.             WCHECKBOXA_Checked,ActiveNodeP->QuietF,
  1056.             TAG_END);
  1057.         SetGadgetAttrs(GlbPropertiesGadgets[GAD_PRP_EXCLUSIVE_ID],GlbPropertiesWindowP,NULL,
  1058.             GA_Disabled,v,
  1059.             WCHECKBOXA_Checked,ActiveNodeP->ExclusiveF,
  1060.             TAG_END);
  1061.     }
  1062.     else
  1063.     {
  1064.         SetGadgetAttrs(GlbManagerGadgets[GAD_MAN_NAME_ID],GlbManagerWindowP,NULL,
  1065.             GA_Disabled,TRUE,
  1066.             WSTRINGA_String,"",
  1067.             TAG_END);
  1068.         SetGadgetAttrs(GlbManagerGadgets[GAD_MAN_DELETE_ID],GlbManagerWindowP,NULL,
  1069.             GA_Disabled,TRUE,
  1070.             TAG_END);
  1071.         SetGadgetAttrs(GlbManagerGadgets[GAD_MAN_MODE_ID],GlbManagerWindowP,NULL,
  1072.             GA_Disabled,TRUE,
  1073.             TAG_END);
  1074.         SetGadgetAttrs(GlbManagerGadgets[GAD_MAN_FONT_ID],GlbManagerWindowP,NULL,
  1075.             GA_Disabled,TRUE,
  1076.             TAG_END);
  1077.         SetGadgetAttrs(GlbManagerGadgets[GAD_MAN_OPEN_ID],GlbManagerWindowP,NULL,
  1078.             GA_Disabled,TRUE,
  1079.             WCHECKBOXA_Checked,FALSE,
  1080.             TAG_END);
  1081.         SetGadgetAttrs(GlbManagerGadgets[GAD_MAN_OPENBEHIND_ID],GlbManagerWindowP,NULL,
  1082.             GA_Disabled,TRUE,
  1083.             WCHECKBOXA_Checked,FALSE,
  1084.             TAG_END);
  1085.         SetGadgetAttrs(GlbPropertiesGadgets[GAD_PRP_COLORNUM_ID],GlbPropertiesWindowP,NULL,
  1086.             WARGSA_Format,"",
  1087.             TAG_END);
  1088.         SetGadgetAttrs(GlbPropertiesGadgets[GAD_PRP_WIDTH_ID],GlbPropertiesWindowP,NULL,
  1089.             WARGSA_Format,"",
  1090.             TAG_END);
  1091.         SetGadgetAttrs(GlbPropertiesGadgets[GAD_PRP_HEIGHT_ID],GlbPropertiesWindowP,NULL,
  1092.             WARGSA_Format,"",
  1093.             TAG_END);
  1094.         SetGadgetAttrs(GlbPropertiesGadgets[GAD_PRP_FONT_ID],GlbPropertiesWindowP,NULL,
  1095.             GA_Disabled,TRUE,
  1096.             WCYCLEA_Active,0,
  1097.             TAG_END);
  1098.         SetGadgetAttrs(GlbPropertiesGadgets[GAD_PRP_TITLE_ID],GlbPropertiesWindowP,NULL,
  1099.             GA_Disabled,TRUE,
  1100.             WSTRINGA_String,"",
  1101.             TAG_END);
  1102.         SetGadgetAttrs(GlbPropertiesGadgets[GAD_PRP_LIKEWB_ID],GlbPropertiesWindowP,NULL,
  1103.             GA_Disabled,TRUE,
  1104.             WCHECKBOXA_Checked,FALSE,
  1105.             TAG_END);
  1106.         SetGadgetAttrs(GlbPropertiesGadgets[GAD_PRP_CLOSEGADGET_ID],GlbPropertiesWindowP,NULL,
  1107.             GA_Disabled,TRUE,
  1108.             WCHECKBOXA_Checked,FALSE,
  1109.             TAG_END);
  1110.         SetGadgetAttrs(GlbPropertiesGadgets[GAD_PRP_DRAGGABLE_ID],GlbPropertiesWindowP,NULL,
  1111.             GA_Disabled,TRUE,
  1112.             WCHECKBOXA_Checked,FALSE,
  1113.             TAG_END);
  1114.         SetGadgetAttrs(GlbPropertiesGadgets[GAD_PRP_QUIET_ID],GlbPropertiesWindowP,NULL,
  1115.             GA_Disabled,TRUE,
  1116.             WCHECKBOXA_Checked,FALSE,
  1117.             TAG_END);
  1118.         SetGadgetAttrs(GlbPropertiesGadgets[GAD_PRP_EXCLUSIVE_ID],GlbPropertiesWindowP,NULL,
  1119.             GA_Disabled,TRUE,
  1120.             WCHECKBOXA_Checked,FALSE,
  1121.             TAG_END);
  1122.     }
  1123. }
  1124.  
  1125. // *************************************************************
  1126. // ***
  1127. // *** NAME      setshanghai
  1128. // *** FUNCTION  set the global Shaghai flag
  1129. // ***
  1130. // *************************************************************
  1131. void setshanghai(BOOL checked)
  1132. {
  1133.     GlbShanghaiF = checked;
  1134.     ULONG mode = SetPubScreenModes(0);
  1135.     if (checked)
  1136.         SetPubScreenModes(mode | SHANGHAI);
  1137.     else
  1138.         SetPubScreenModes(mode & ~SHANGHAI);
  1139.     SetGadgetAttrs(GlbManagerGadgets[GAD_MAN_SHANGHAI_ID],GlbManagerWindowP,NULL,
  1140.         WCHECKBOXA_Checked,GlbShanghaiF,
  1141.         TAG_END);
  1142. }
  1143.  
  1144. // *************************************************************
  1145. // ***
  1146. // *** NAME      setautopopup
  1147. // *** FUNCTION  set the global AutoPopup flag
  1148. // ***
  1149. // *************************************************************
  1150. void setautopopup(BOOL checked)
  1151. {
  1152.     GlbAutoPopupF = checked;
  1153.     ULONG mode = SetPubScreenModes(0);
  1154.     if (checked)
  1155.         SetPubScreenModes(mode | POPPUBSCREEN);
  1156.     else
  1157.         SetPubScreenModes(mode & ~POPPUBSCREEN);
  1158.     SetGadgetAttrs(GlbManagerGadgets[GAD_MAN_AUTOPOPUP_ID],GlbManagerWindowP,NULL,
  1159.         WCHECKBOXA_Checked,GlbAutoPopupF,
  1160.         TAG_END);
  1161. }
  1162.  
  1163. // *************************************************************
  1164. // ***
  1165. // *** NAME      openscreen
  1166. // *** FUNCTION  open a public screen, close gadget etc
  1167. // ***
  1168. // *************************************************************
  1169. void openscreen(struct ScreenNode *node)
  1170. {
  1171.     struct TextFont *font = NULL;
  1172.     strcpy(node->ScreenTitle,strlen(node->Title) ? node->Title : node->Name);
  1173.     if (node->SysFont == 0)
  1174.         font = OpenDiskFont(&node->Font);
  1175.     if (node->Screen = OpenScreenTags(NULL,
  1176.             SA_Type,PUBLICSCREEN,
  1177.             SA_PubName,node->Name,
  1178.             SA_PubSig,GlbScreenSignal,
  1179.             SA_PubTask,NULL,
  1180.  
  1181.             SA_LikeWorkbench, node->LikeWorkbenchF,
  1182.             node->LikeWorkbenchF ? TAG_SKIP : TAG_IGNORE, 11,
  1183.             SA_DisplayID,node->ModeID,
  1184.             SA_Depth,node->Depth,
  1185.             SA_Overscan,node->Overscan,
  1186.             SA_Width,node->Width,
  1187.             SA_Height,node->Height,
  1188.             SA_FullPalette,TRUE,
  1189.             SA_Interleaved,TRUE,
  1190.             SA_Pens,node->Pens,
  1191.             node->SysFont == 0 ? SA_Font : TAG_IGNORE, &node->Font,
  1192.             node->SysFont != 0 ? SA_SysFont : TAG_IGNORE, node->SysFont-1,
  1193.             SA_SharePens,TRUE,
  1194.  
  1195.             SA_Title,node->CloseGadgetF ? "" : node->ScreenTitle,
  1196.             SA_AutoScroll,node->AutoScrollF,
  1197.             SA_Behind,node->OpenBehindF,
  1198.             SA_ShowTitle,FALSE,
  1199.             SA_Quiet,node->QuietF,
  1200.             SA_Exclusive,node->ExclusiveF,
  1201.             SA_Draggable,node->DraggableF,
  1202.             TAG_END))
  1203.     {
  1204.         node->OpenF = TRUE;
  1205.         if (node->CloseGadgetF)
  1206.         {
  1207.             struct DrawInfo *drawinfo = GetScreenDrawInfo(node->Screen);
  1208.             if (drawinfo)
  1209.             {
  1210.                 struct Image *closeimage = (struct Image *) NewObject(NULL,SYSICLASS,
  1211.                     SYSIA_DrawInfo,drawinfo,
  1212.                     SYSIA_Size,SYSISIZE_HIRES,
  1213.                     SYSIA_Which,CLOSEIMAGE,
  1214.                     font ? IA_Height : TAG_IGNORE, font ? font->tf_YSize+2 : 0,
  1215.                     TAG_END);
  1216.                 if (closeimage)
  1217.                 {
  1218.                     ULONG screenmodes;
  1219.                     // calculate Screentitle
  1220.                     #define SPACES "                            "
  1221.                     struct TextExtent textextent;
  1222.                     ULONG count = TextFit(&node->Screen->RastPort,
  1223.                         SPACES,strlen(SPACES),
  1224.                         &textextent,NULL,1,
  1225.                         closeimage->Width + 4, 1000);
  1226.                     sprintf(node->ScreenTitle,"%s%s",
  1227.                         SPACES+strlen(SPACES)-count,strlen(node->Title) == 0 ? node->Name : node->Title);
  1228.                     node->DefaultTitle = node->Screen->DefaultTitle;
  1229.                     node->Screen->DefaultTitle = node->ScreenTitle;
  1230.                     #undef SPACES
  1231.                     screenmodes = SetPubScreenModes(0);
  1232.                     SetPubScreenModes(screenmodes & ~(POPPUBSCREEN|SHANGHAI));
  1233.                     struct Window *win = OpenWindowTags(NULL,
  1234.                         WA_Activate,TRUE,
  1235.                         WA_Left,0,
  1236.                         WA_Top,0,
  1237.                         WA_Width,1,
  1238.                         WA_Height,1,
  1239.                         WA_Borderless,TRUE,
  1240.                         WA_PubScreen,node->Screen,
  1241.                         WA_ScreenTitle,node->ScreenTitle,
  1242.                         TAG_END);
  1243.                     if (win)
  1244.                         CloseWindow(win);
  1245.                     if (node->CloseGadget = OpenWindowTags(NULL,
  1246.                         WA_Activate,FALSE,
  1247.                         WA_Backdrop,TRUE,
  1248.                         WA_Borderless,TRUE,
  1249.                         WA_CloseGadget,TRUE,
  1250.                         WA_DepthGadget,FALSE,
  1251.                         WA_DragBar,FALSE,
  1252.                         WA_Left,0,
  1253.                         WA_Top,0,
  1254.                         WA_Width,closeimage->Width,
  1255.                         WA_Height,closeimage->Height,
  1256.                         WA_IDCMP,0,
  1257.                         WA_NoCareRefresh,TRUE,
  1258.                         WA_RMBTrap,TRUE,
  1259.                         WA_SimpleRefresh,TRUE,
  1260.                         WA_SizeGadget,FALSE,
  1261.                         WA_Title,NULL,
  1262.                         WA_ScreenTitle,node->ScreenTitle,
  1263.                         WA_PubScreen,node->Screen,
  1264.                         TAG_END))
  1265.                     {
  1266.                         node->CloseGadget->UserPort = GlbIDCMPortP;
  1267.                         ModifyIDCMP(node->CloseGadget,IDCMP_CLOSEWINDOW);
  1268.                     }
  1269.                     SetPubScreenModes(screenmodes);
  1270.                     DisposeObject(closeimage);
  1271.                 }
  1272.                 FreeScreenDrawInfo(node->Screen,drawinfo);
  1273.             }
  1274.         }
  1275.         PubScreenStatus(node->Screen,0);
  1276.     }
  1277.     else
  1278.     {
  1279.         STRPTR err = node->Name;
  1280.         WZ_LockWindows(GlbSurfaceP);
  1281.         WZ_EasyRequestArgs(GlbSurfaceP,GlbManagerWindowP,REQ_SCREENOPENERR_ID,&err);
  1282.         WZ_UnlockWindows(GlbSurfaceP);
  1283.     }
  1284.     if (font)
  1285.         CloseFont(font);
  1286. }
  1287.  
  1288. // *************************************************************
  1289. // ***
  1290. // *** NAME      closescreen
  1291. // *** FUNCTION  close a public screen
  1292. // ***
  1293. // *************************************************************
  1294. void closescreen(struct ScreenNode *node)
  1295. {
  1296.     if (node->CloseGadget)
  1297.     {
  1298.         StripIDCMPMessages(node->CloseGadget);
  1299.         CloseWindow(node->CloseGadget);
  1300.         node->CloseGadget = NULL;
  1301.     }
  1302.     if (node->Screen)
  1303.     {
  1304.         node->Screen->DefaultTitle = node->DefaultTitle;
  1305.         if (CloseScreen(node->Screen))
  1306.         {
  1307.             node->OpenF = FALSE;
  1308.             node->CloseSoonF = FALSE;
  1309.         }
  1310.         else
  1311.         {
  1312.             node->CloseSoonF = TRUE;
  1313.         }
  1314.     }
  1315. }
  1316.  
  1317. // *************************************************************
  1318. // ***
  1319. // *** NAME      closeproperties
  1320. // *** FUNCTION  close properties window
  1321. // ***
  1322. // *************************************************************
  1323. void closeproperties()
  1324. {
  1325.     if (GlbPropertiesWindowP)
  1326.     {
  1327.         StripIDCMPMessages(GlbPropertiesWindowP);
  1328.         WZ_CloseWindow(GlbPropertiesWindowHandleP);
  1329.         GlbPropertiesWindowP = NULL;
  1330.     }
  1331. }
  1332.  
  1333. // *************************************************************
  1334. // ***
  1335. // *** NAME      openproperties
  1336. // *** FUNCTION  open properties window
  1337. // ***
  1338. // *************************************************************
  1339. void openproperties(BOOL activate)
  1340. {
  1341.     if (!GlbPropertiesWindowP)
  1342.     {
  1343.         struct NewWindow *nw = GlbPropertiesNewWindowP;
  1344.         if (nw->Width < nw->MinWidth)
  1345.             nw->Width = nw->MinWidth;
  1346.         nw->Height = nw->MaxHeight = nw->MinHeight;
  1347.         if (!(GlbPropertiesWindowP = WZ_OpenWindow(GlbPropertiesWindowHandleP,GlbPropertiesNewWindowP,
  1348.             WA_IDCMP,0,
  1349.             WA_AutoAdjust,TRUE,
  1350.             WA_Activate,activate,
  1351.             TAG_END)))
  1352.         {
  1353.             error(getlocalestr(MSG_FATAL_ID,MSG_FATAL_ID_STR));
  1354.         }
  1355.         GlbPropertiesWindowP->UserPort = GlbIDCMPortP;
  1356.         ModifyIDCMP(GlbPropertiesWindowP,GlbPropertiesNewWindowP->IDCMPFlags);
  1357.     }
  1358.     else
  1359.     {
  1360.         WindowToFront(GlbPropertiesWindowP);
  1361.         if (activate)
  1362.             ActivateWindow(GlbPropertiesWindowP);
  1363.     }
  1364. }
  1365.  
  1366. // *************************************************************
  1367. // ***
  1368. // *** NAME      hide
  1369. // *** FUNCTION  hide user interface, remember state of properties window
  1370. // ***
  1371. // *************************************************************
  1372. void hide()
  1373. {
  1374.     if (GlbPropertiesWindowP)
  1375.         GlbOpenPropertiesF = TRUE;
  1376.     closeproperties();
  1377.     if (GlbManagerWindowP)
  1378.     {
  1379.         StripIDCMPMessages(GlbManagerWindowP);
  1380.         WZ_CloseWindow(GlbManagerWindowHandleP);
  1381.         GlbManagerWindowP = NULL;
  1382.     }
  1383. }
  1384.  
  1385. // *************************************************************
  1386. // ***
  1387. // *** NAME      show
  1388. // *** FUNCTION  show user interface, open properties window?
  1389. // ***
  1390. // *************************************************************
  1391. void show()
  1392. {
  1393.     if (!GlbManagerWindowP)
  1394.     {
  1395.         struct NewWindow *nw = GlbPropertiesNewWindowP;
  1396.         if (nw->Width < nw->MinWidth)
  1397.             nw->Width = nw->MinWidth;
  1398.         if (nw->Height < nw->MinHeight)
  1399.             nw->Height = nw->MinHeight;
  1400.         if (!(GlbManagerWindowP = WZ_OpenWindow(GlbManagerWindowHandleP,GlbManagerNewWindowP,
  1401.             WA_IDCMP,0,
  1402.             WA_AutoAdjust,TRUE,
  1403.             TAG_END)))
  1404.         {
  1405.             error(getlocalestr(MSG_FATAL_ID,MSG_FATAL_ID_STR));
  1406.         }
  1407.         GlbManagerWindowP->UserPort = GlbIDCMPortP;
  1408.         ModifyIDCMP(GlbManagerWindowP,GlbManagerNewWindowP->IDCMPFlags);
  1409.     }
  1410.     else
  1411.     {
  1412.         WindowToFront(GlbManagerWindowP);
  1413.         ActivateWindow(GlbManagerWindowP);
  1414.     }
  1415.     if (GlbOpenPropertiesF)
  1416.         openproperties(FALSE);
  1417. }
  1418.  
  1419. // *************************************************************
  1420. // ***
  1421. // *** NAME      handlemanagerwindow
  1422. // *** FUNCTION  handle all IDCMP messages for the main window
  1423. // ***
  1424. // *************************************************************
  1425. BOOL handlemanagerwindow(struct IntuiMessage *msg)
  1426. {
  1427.     BOOL retval = FALSE;
  1428.     switch (msg->Class)
  1429.     {
  1430.         case IDCMP_IDCMPUPDATE:
  1431.             switch (GetTagData(GA_ID,-1,(struct TagItem *) msg->IAddress))
  1432.             {
  1433.                 case GAD_MAN_LIST_ID:
  1434.                     if (GetTagData(WLISTVIEWA_DoubleClick,FALSE,(struct TagItem *) msg->IAddress))
  1435.                     {
  1436.                         SetGadgetAttrs(GlbManagerGadgets[GAD_MAN_LIST_ID],NULL,NULL,
  1437.                             WLISTVIEWA_List,NULL,
  1438.                             TAG_END);
  1439.                         SetDefaultScreenNode(ActiveNodeP);
  1440.                         SetGadgetAttrs(GlbManagerGadgets[GAD_MAN_LIST_ID],GlbManagerWindowP,NULL,
  1441.                             WLISTVIEWA_List,&ScreenList,
  1442.                             TAG_END);
  1443.                     }
  1444.                     else
  1445.                         setselected();
  1446.                     break;
  1447.                 case GAD_MAN_NAME_ID:
  1448.                 {
  1449.                     STRPTR name;
  1450.                     GetAttr(WSTRINGA_String,GlbManagerGadgets[GAD_MAN_NAME_ID],(ULONG *) &name);
  1451.                     if (ActiveNodeP)
  1452.                     {
  1453.                         SetGadgetAttrs(GlbManagerGadgets[GAD_MAN_LIST_ID],NULL,NULL,
  1454.                             WLISTVIEWA_List,NULL,
  1455.                             TAG_END);
  1456.                         SetScreenName(ActiveNodeP,name);
  1457.                         SetGadgetAttrs(GlbManagerGadgets[GAD_MAN_LIST_ID],GlbManagerWindowP,NULL,
  1458.                             WLISTVIEWA_List,&ScreenList,
  1459.                             TAG_END);
  1460.                     }
  1461.                     break;
  1462.                 }
  1463.                 case GAD_MAN_NEW_ID:
  1464.                 {
  1465.                     struct ScreenNode *node;
  1466.                     UBYTE Name[MAXPUBSCREENNAME];
  1467.                     ULONG i = 1;
  1468.                     strcpy(Name,"StormScreen");
  1469.                     while (FindScreenNode(Name))
  1470.                     {
  1471.                         sprintf(Name,"StormScreen.%ld",i);
  1472.                         i++;
  1473.                     }
  1474.                     if (node = AllocScreenNode(Name))
  1475.                     {
  1476.                         node->StormScreenF = TRUE;
  1477.                         struct Screen *screen = LockPubScreen(NULL);
  1478.                         SetScreenMode(node,GetVPModeID(&screen->ViewPort),
  1479.                             screen->RastPort.BitMap->Depth,
  1480.                             screen->Height,
  1481.                             screen->Width,
  1482.                             OSCAN_TEXT,
  1483.                             TRUE);
  1484.                         SetScreenFont(node,screen->Font);
  1485.                         UnlockPubScreen(NULL,screen);
  1486.                         SetGadgetAttrs(GlbManagerGadgets[GAD_MAN_LIST_ID],NULL,NULL,
  1487.                             WLISTVIEWA_List,NULL,
  1488.                             TAG_END);
  1489.                         AddScreenNode(node);
  1490.                         SetGadgetAttrs(GlbManagerGadgets[GAD_MAN_LIST_ID],GlbManagerWindowP,NULL,
  1491.                             WLISTVIEWA_List,&ScreenList,
  1492.                             WLISTVIEWA_Selected,GetScreenNodeIndex(node),
  1493.                             TAG_END);
  1494.                         setselected();
  1495.                     }
  1496.                     break;
  1497.                 }
  1498.                 case GAD_MAN_DELETE_ID:
  1499.                     if (ActiveNodeP)
  1500.                     {
  1501.                         SetGadgetAttrs(GlbManagerGadgets[GAD_MAN_LIST_ID],NULL,NULL,
  1502.                             WLISTVIEWA_List,NULL,
  1503.                             TAG_END);
  1504.                         RemScreenNode(ActiveNodeP);
  1505.                         FreeScreenNode(ActiveNodeP);
  1506.                         SetGadgetAttrs(GlbManagerGadgets[GAD_MAN_LIST_ID],GlbManagerWindowP,NULL,
  1507.                             WLISTVIEWA_List,&ScreenList,
  1508.                             WLISTVIEWA_Selected,-1,
  1509.                             TAG_END);
  1510.                         setselected();
  1511.                     }
  1512.                     break;
  1513.                 case GAD_MAN_MODE_ID:
  1514.                     if (ActiveNodeP)
  1515.                     {
  1516.                         WZ_LockWindows(GlbSurfaceP);
  1517.                         if (AslRequestTags(GlbScreenModeRequesterP,
  1518.                             ASLSM_InitialDisplayDepth,ActiveNodeP->Depth,
  1519.                             ASLSM_InitialDisplayHeight,ActiveNodeP->Height,
  1520.                             ASLSM_InitialDisplayWidth,ActiveNodeP->Width,
  1521.                             ASLSM_InitialDisplayID,ActiveNodeP->ModeID,
  1522.                             ASLSM_InitialOverscanType,ActiveNodeP->Overscan,
  1523.                             ASLSM_DoAutoScroll,TRUE,
  1524.                             ASLSM_DoDepth,TRUE,
  1525.                             ASLSM_DoHeight,TRUE,
  1526.                             ASLSM_DoWidth,TRUE,
  1527.                             ASLSM_DoOverscanType,TRUE,
  1528.                             TAG_END))
  1529.                         {
  1530.                             SetGadgetAttrs(GlbManagerGadgets[GAD_MAN_LIST_ID],NULL,NULL,
  1531.                                 WLISTVIEWA_List,NULL,
  1532.                                 TAG_END);
  1533.                             SetScreenMode(ActiveNodeP,
  1534.                                 GlbScreenModeRequesterP->sm_DisplayID,
  1535.                                 GlbScreenModeRequesterP->sm_DisplayDepth,
  1536.                                 GlbScreenModeRequesterP->sm_DisplayHeight,
  1537.                                 GlbScreenModeRequesterP->sm_DisplayWidth,
  1538.                                 GlbScreenModeRequesterP->sm_OverscanType,
  1539.                                 GlbScreenModeRequesterP->sm_AutoScroll);
  1540.                             SetGadgetAttrs(GlbManagerGadgets[GAD_MAN_LIST_ID],GlbManagerWindowP,NULL,
  1541.                                 WLISTVIEWA_List,&ScreenList,
  1542.                                 TAG_END);
  1543.                         }
  1544.                         WZ_UnlockWindows(GlbSurfaceP);
  1545.                     }
  1546.                     break;
  1547.                 case GAD_MAN_FONT_ID:
  1548.                     if (ActiveNodeP)
  1549.                     {
  1550.                         WZ_LockWindows(GlbSurfaceP);
  1551.                         if (AslRequestTags(GlbFontRequesterP,
  1552.                             ASLFO_InitialName,ActiveNodeP->Font.ta_Name,
  1553.                             ASLFO_InitialSize,ActiveNodeP->Font.ta_YSize,
  1554.                             TAG_END))
  1555.                         {
  1556.                             SetGadgetAttrs(GlbManagerGadgets[GAD_MAN_LIST_ID],NULL,NULL,
  1557.                                 WLISTVIEWA_List,NULL,
  1558.                                 TAG_END);
  1559.                             SetScreenFont(ActiveNodeP,&GlbFontRequesterP->fo_Attr);
  1560.                             SetGadgetAttrs(GlbManagerGadgets[GAD_MAN_LIST_ID],GlbManagerWindowP,NULL,
  1561.                                 WLISTVIEWA_List,&ScreenList,
  1562.                                 TAG_END);
  1563.                         }
  1564.                         WZ_UnlockWindows(GlbSurfaceP);
  1565.                     }
  1566.                     break;
  1567.                 case GAD_MAN_OPEN_ID:
  1568.                     if (ActiveNodeP)
  1569.                     {
  1570.                         ULONG openf;
  1571.                         GetAttr(WTOGGLEA_Checked,GlbManagerGadgets[GAD_MAN_OPEN_ID],&openf);
  1572.                         if (openf && !ActiveNodeP->OpenF)
  1573.                         {
  1574.                             openscreen(ActiveNodeP);
  1575.                             GlbExitSoonF = FALSE;
  1576.                         }
  1577.                         else if (!openf && ActiveNodeP->OpenF)
  1578.                         {
  1579.                             closescreen(ActiveNodeP);
  1580.                         }
  1581.                         SetGadgetAttrs(GlbManagerGadgets[GAD_MAN_LIST_ID],NULL,NULL,
  1582.                             WLISTVIEWA_List,NULL,
  1583.                             TAG_END);
  1584.                         GetDefaultScreenNode();
  1585.                         SetGadgetAttrs(GlbManagerGadgets[GAD_MAN_LIST_ID],GlbManagerWindowP,NULL,
  1586.                             WLISTVIEWA_List,&ScreenList,
  1587.                             TAG_END);
  1588.                         setselected();
  1589.                     }
  1590.                     break;
  1591.                 case GAD_MAN_OPENBEHIND_ID:
  1592.                     if (ActiveNodeP)
  1593.                     {
  1594.                         ULONG checked;
  1595.                         GetAttr(WCHECKBOXA_Checked,GlbManagerGadgets[GAD_MAN_OPENBEHIND_ID],&checked);
  1596.                         ActiveNodeP->OpenBehindF = checked;
  1597.                     }
  1598.                     break;
  1599.                 case GAD_MAN_PROPERTIES_ID:
  1600.                     openproperties(TRUE);
  1601.                     break;
  1602.                 case GAD_MAN_SHANGHAI_ID:
  1603.                 {
  1604.                     ULONG checked;
  1605.                     GetAttr(WCHECKBOXA_Checked,GlbManagerGadgets[GAD_MAN_SHANGHAI_ID],&checked);
  1606.                     setshanghai(checked);
  1607.                     break;
  1608.                 }
  1609.                 case GAD_MAN_AUTOPOPUP_ID:
  1610.                 {
  1611.                     ULONG checked;
  1612.                     GetAttr(WCHECKBOXA_Checked,GlbManagerGadgets[GAD_MAN_AUTOPOPUP_ID],&checked);
  1613.                     setautopopup(checked);
  1614.                     break;
  1615.                 }
  1616.             }
  1617.             break;
  1618.         case IDCMP_VANILLAKEY:
  1619.             if (!WZ_GadgetKeyA(GlbManagerWindowHandleP,msg->Code,msg->Qualifier,NULL))
  1620.             {
  1621.                 switch (msg->Code)
  1622.                 {
  1623.                     case 0x1b: // ESC
  1624.                         hide();
  1625.                         msg = NULL;
  1626.                         break;
  1627.                 }
  1628.             }
  1629.             break;
  1630.         case IDCMP_RAWKEY:
  1631.             switch (msg->Code)
  1632.             {
  1633.                 case 0x4c: // cursor up
  1634.                 {
  1635.                     ULONG selected;
  1636.                     GetAttr(WLISTVIEWA_Selected,GlbManagerGadgets[GAD_MAN_LIST_ID],&selected);
  1637.                     ULONG l = LengthOfScreenList();
  1638.                     if (l > 0)
  1639.                     {
  1640.                         if (selected == ~0)
  1641.                             selected = 0;
  1642.                         else if (selected > 0)
  1643.                             selected--;
  1644.                         else
  1645.                             selected = LengthOfScreenList() - 1;
  1646.                     }
  1647.                     SetGadgetAttrs(GlbManagerGadgets[GAD_MAN_LIST_ID],GlbManagerWindowP,NULL,
  1648.                         WLISTVIEWA_Selected,selected,
  1649.                         TAG_END);
  1650.                     setselected();
  1651.                     break;
  1652.                 }
  1653.                 case 0x4d: // cursor down
  1654.                 {
  1655.                     ULONG selected;
  1656.                     GetAttr(WLISTVIEWA_Selected,GlbManagerGadgets[GAD_MAN_LIST_ID],&selected);
  1657.                     ULONG l = LengthOfScreenList();
  1658.                     if (l > 0)
  1659.                     {
  1660.                         if (selected == ~0)
  1661.                             selected = 0;
  1662.                         else if (selected < l - 1)
  1663.                             selected++;
  1664.                         else
  1665.                             selected = 0;
  1666.                     }
  1667.                     SetGadgetAttrs(GlbManagerGadgets[GAD_MAN_LIST_ID],GlbManagerWindowP,NULL,
  1668.                         WLISTVIEWA_Selected,selected,
  1669.                         TAG_END);
  1670.                     setselected();
  1671.                     break;
  1672.                 }
  1673.                 case 0x44: // return == double click
  1674.                     SetGadgetAttrs(GlbManagerGadgets[GAD_MAN_LIST_ID],NULL,NULL,
  1675.                         WLISTVIEWA_List,NULL,
  1676.                         TAG_END);
  1677.                     SetDefaultScreenNode(ActiveNodeP);
  1678.                     SetGadgetAttrs(GlbManagerGadgets[GAD_MAN_LIST_ID],GlbManagerWindowP,NULL,
  1679.                         WLISTVIEWA_List,&ScreenList,
  1680.                         TAG_END);
  1681.                     break;
  1682.             }
  1683.             break;
  1684.         case IDCMP_CLOSEWINDOW:
  1685.             hide();
  1686.             msg = NULL;
  1687.             break;
  1688.         case IDCMP_MENUPICK:
  1689.         {
  1690.             UWORD code = msg->Code;
  1691.             while (code != MENUNULL)
  1692.             {
  1693.                 switch (code)
  1694.                 {
  1695.                     case PROJECT_SAVE_ID:
  1696.                     {
  1697.                         STRPTR err = Save(GlbProgramNameP);
  1698.                         if (err)
  1699.                             error(err);
  1700.                         break;
  1701.                     }
  1702.                     case PROJECT_ABOUT_ID:
  1703.                         WZ_LockWindows(GlbSurfaceP);
  1704.                         WZ_EasyRequestArgs(GlbSurfaceP,GlbManagerWindowP,REQ_ABOUT_ID,NULL);
  1705.                         WZ_UnlockWindows(GlbSurfaceP);
  1706.                         break;
  1707.                     case PROJECT_HIDE_ID:
  1708.                         hide();
  1709.                         msg = NULL;
  1710.                         break;
  1711.                     case PROJECT_QUIT_ID:
  1712.                         retval = TRUE;
  1713.                         break;
  1714.                 }
  1715.                 if (!msg)
  1716.                     break;
  1717.                 code = ItemAddress(GlbManagerWindowP->MenuStrip,code)->NextSelect;
  1718.             }
  1719.             break;
  1720.         }
  1721.     }
  1722.     if (msg)
  1723.         ReplyMsg(&msg->ExecMessage);
  1724.     return retval;
  1725. }
  1726.  
  1727. // *************************************************************
  1728. // ***
  1729. // *** NAME      handlepropertieswindow
  1730. // *** FUNCTION  handle all IDCMP messages for the properties window
  1731. // ***
  1732. // *************************************************************
  1733. BOOL handlepropertieswindow(struct IntuiMessage *msg)
  1734. {
  1735.     BOOL retval = FALSE;
  1736.     switch (msg->Class)
  1737.     {
  1738.         case IDCMP_IDCMPUPDATE:
  1739.             switch (GetTagData(GA_ID,-1,(struct TagItem *) msg->IAddress))
  1740.             {
  1741.                 case GAD_PRP_FONT_ID:
  1742.                     if (ActiveNodeP)
  1743.                     {
  1744.                         ULONG selected;
  1745.                         GetAttr(WCYCLEA_Active,GlbPropertiesGadgets[GAD_PRP_FONT_ID],&selected);
  1746.                         ActiveNodeP->SysFont = selected;
  1747.                     }
  1748.                     break;
  1749.                 case GAD_PRP_TITLE_ID:
  1750.                     if (ActiveNodeP)
  1751.                     {
  1752.                         STRPTR str;
  1753.                         GetAttr(WSTRINGA_String,GlbPropertiesGadgets[GAD_PRP_TITLE_ID],(ULONG *) &str);
  1754.                         strcpy(ActiveNodeP->Title,str);
  1755.                     }
  1756.                     break;
  1757.                 case GAD_PRP_LIKEWB_ID:
  1758.                     if (ActiveNodeP)
  1759.                     {
  1760.                         ULONG checked;
  1761.                         GetAttr(WCHECKBOXA_Checked,GlbPropertiesGadgets[GAD_PRP_LIKEWB_ID],&checked);
  1762.                         ActiveNodeP->LikeWorkbenchF = checked;
  1763.                     }
  1764.                     break;
  1765.                 case GAD_PRP_CLOSEGADGET_ID:
  1766.                     if (ActiveNodeP)
  1767.                     {
  1768.                         ULONG checked;
  1769.                         GetAttr(WCHECKBOXA_Checked,GlbPropertiesGadgets[GAD_PRP_CLOSEGADGET_ID],&checked);
  1770.                         ActiveNodeP->CloseGadgetF = checked;
  1771.                     }
  1772.                     break;
  1773.                 case GAD_PRP_DRAGGABLE_ID:
  1774.                     if (ActiveNodeP)
  1775.                     {
  1776.                         ULONG checked;
  1777.                         GetAttr(WCHECKBOXA_Checked,GlbPropertiesGadgets[GAD_PRP_DRAGGABLE_ID],&checked);
  1778.                         ActiveNodeP->DraggableF = checked;
  1779.                     }
  1780.                     break;
  1781.                 case GAD_PRP_QUIET_ID:
  1782.                     if (ActiveNodeP)
  1783.                     {
  1784.                         ULONG checked;
  1785.                         GetAttr(WCHECKBOXA_Checked,GlbPropertiesGadgets[GAD_PRP_QUIET_ID],&checked);
  1786.                         ActiveNodeP->QuietF = checked;
  1787.                     }
  1788.                     break;
  1789.                 case GAD_PRP_EXCLUSIVE_ID:
  1790.                     if (ActiveNodeP)
  1791.                     {
  1792.                         ULONG checked;
  1793.                         GetAttr(WCHECKBOXA_Checked,GlbPropertiesGadgets[GAD_PRP_EXCLUSIVE_ID],&checked);
  1794.                         ActiveNodeP->ExclusiveF = checked;
  1795.                     }
  1796.                     break;
  1797.             }
  1798.             break;
  1799.         case IDCMP_VANILLAKEY:
  1800.             if (!WZ_GadgetKeyA(GlbPropertiesWindowHandleP,msg->Code,msg->Qualifier,NULL))
  1801.             {
  1802.                 switch (msg->Code)
  1803.                 {
  1804.                     case 0x1b: // ESC
  1805.                         closeproperties();
  1806.                         GlbOpenPropertiesF = FALSE;
  1807.                         msg = NULL;
  1808.                         break;
  1809.                 }
  1810.             }
  1811.             break;
  1812.         case IDCMP_CLOSEWINDOW:
  1813.             closeproperties();
  1814.             GlbOpenPropertiesF = FALSE;
  1815.             msg = NULL;
  1816.             break;
  1817.     }
  1818.     if (msg)
  1819.         ReplyMsg(&msg->ExecMessage);
  1820.     return retval;
  1821. }
  1822.  
  1823. // *************************************************************
  1824. // ***
  1825. // *** NAME      handleintuimsg
  1826. // *** FUNCTION  handle all IDCMP messages
  1827. // ***
  1828. // *************************************************************
  1829. BOOL handleintuimsg(struct IntuiMessage *msg)
  1830. {
  1831.     BOOL retval = FALSE;
  1832.     if (msg->IDCMPWindow == GlbManagerWindowP)
  1833.         retval = handlemanagerwindow(msg);
  1834.     else if (msg->IDCMPWindow == GlbPropertiesWindowP)
  1835.         retval = handlepropertieswindow(msg);
  1836.     else // close gadget pressed?
  1837.     {
  1838.         struct ScreenNode *node;
  1839.         for (node = (struct ScreenNode *) ScreenList.mlh_Head;
  1840.             node->Node.Node.mln_Succ;
  1841.             node = (struct ScreenNode *) node->Node.Node.mln_Succ)
  1842.         {
  1843.             if (msg->IDCMPWindow == node->CloseGadget)
  1844.             {
  1845.                 switch (msg->Class)
  1846.                 {
  1847.                     case IDCMP_CLOSEWINDOW:
  1848.                         closescreen(node);
  1849.                         msg = NULL;
  1850.                         break;
  1851.                 }
  1852.                 if (msg)
  1853.                     ReplyMsg(&msg->ExecMessage);
  1854.             }
  1855.         }
  1856.     }
  1857.     return retval;
  1858. }
  1859.  
  1860. // *************************************************************
  1861. // ***
  1862. // *** NAME      readtok
  1863. // *** FUNCTION  read next token from a REXX command string
  1864. // ***
  1865. // *************************************************************
  1866. STRPTR readtok(STRPTR *cmdbuf)
  1867. {
  1868.     STRPTR cmd = *cmdbuf;
  1869.     while (isspace(*cmd))
  1870.         cmd++;
  1871.     if (!*cmd)
  1872.     {
  1873.         *cmdbuf = cmd;
  1874.         return NULL;
  1875.     }
  1876.     STRPTR command = cmd;
  1877.     UBYTE delim = '\0';
  1878.     UBYTE ch = *cmd;
  1879.     if (*cmd == '\"' || *cmd == '\'')
  1880.     {
  1881.         delim = ch;
  1882.         cmd++;
  1883.         for (;;)
  1884.         {
  1885.             while (*cmd && *cmd != delim)
  1886.                 cmd++;
  1887.             if (!*cmd)
  1888.             {
  1889.                 *cmdbuf = cmd;
  1890.                 return command; // last token must not stop with delim
  1891.             }
  1892.             if (*(cmd+1) != delim)
  1893.                 break;
  1894.             cmd += 2;
  1895.         }
  1896.     }
  1897.     else
  1898.     {
  1899.         while (*cmd && !isspace(*cmd))
  1900.             cmd++;
  1901.         if (!*cmd)
  1902.         {
  1903.             *cmdbuf = cmd;
  1904.             return command;
  1905.         }
  1906.     }
  1907.     *cmd++ = '\0';
  1908.     *cmdbuf = cmd;
  1909.     return command;
  1910. }
  1911.  
  1912. // *************************************************************
  1913. // ***
  1914. // *** NAME      handlerexxmsg
  1915. // *** FUNCTION  handle REXX messages
  1916. // ***
  1917. // *************************************************************
  1918. BOOL handlerexxmsg(struct RexxMsg *msg)
  1919. {
  1920.     BOOL retval = FALSE;
  1921.     if ((msg->rm_Action & RXCODEMASK) == RXCOMM)
  1922.     {
  1923.         UBYTE cmdbuf[256];
  1924.         strncpy(cmdbuf,msg->rm_Args[0],255);
  1925.         cmdbuf[255] = '\0';
  1926.         STRPTR cmd = cmdbuf;
  1927.         STRPTR command = readtok(&cmd);
  1928.         if (Stricmp(command,"OPEN") == 0) // OPEN <screenname>
  1929.         {
  1930.             STRPTR name = readtok(&cmd);
  1931.             if (name)
  1932.             {
  1933.                 if (!readtok(&cmd))
  1934.                 {
  1935.                     struct ScreenNode *node = FindScreenNode(name);
  1936.                     if (node)
  1937.                     {
  1938.                         if (node->StormScreenF && !node->OpenF)
  1939.                         {
  1940.                             openscreen(node);
  1941.                             node->CloseSoonF = TRUE;
  1942.                         }
  1943.                         else
  1944.                             msg->rm_Result1 = RC_WARN;
  1945.                     }
  1946.                     else
  1947.                         msg->rm_Result1 = RC_ERROR;
  1948.                 }
  1949.                 else
  1950.                     msg->rm_Result1 = RC_ERROR;
  1951.             }
  1952.             else
  1953.                 msg->rm_Result1 = RC_ERROR;
  1954.         }
  1955.         else if (Stricmp(command,"CLOSE") == 0) // CLOSE <screenname>
  1956.         {
  1957.             STRPTR name = readtok(&cmd);
  1958.             if (name)
  1959.             {
  1960.                 if (!readtok(&cmd))
  1961.                 {
  1962.                     struct ScreenNode *node = FindScreenNode(name);
  1963.                     if (node)
  1964.                     {
  1965.                         if (node->StormScreenF && node->OpenF)
  1966.                             closescreen(node);
  1967.                         else
  1968.                             msg->rm_Result1 = RC_WARN;
  1969.                     }
  1970.                     else
  1971.                         msg->rm_Result1 = RC_ERROR;
  1972.                 }
  1973.                 else
  1974.                     msg->rm_Result1 = RC_ERROR;
  1975.             }
  1976.             else
  1977.                 msg->rm_Result1 = RC_ERROR;
  1978.         }
  1979.         else if (Stricmp(command,"SCREENTOFRONT") == 0) // SCREENTOFRONT <screenname>
  1980.         {
  1981.             STRPTR name = readtok(&cmd);
  1982.             if (name)
  1983.             {
  1984.                 if (!readtok(&cmd))
  1985.                 {
  1986.                     struct ScreenNode *node = FindScreenNode(name);
  1987.                     if (node)
  1988.                     {
  1989.                         if (node->StormScreenF && node->OpenF)
  1990.                             ScreenToFront(node->Screen);
  1991.                         else
  1992.                             msg->rm_Result1 = RC_WARN;
  1993.                     }
  1994.                     else
  1995.                         msg->rm_Result1 = RC_ERROR;
  1996.                 }
  1997.                 else
  1998.                     msg->rm_Result1 = RC_ERROR;
  1999.             }
  2000.             else
  2001.                 msg->rm_Result1 = RC_ERROR;
  2002.         }
  2003.         else if (Stricmp(command,"SCREENTOBACK") == 0) // SCREENTOBACK <screenname>
  2004.         {
  2005.             STRPTR name = readtok(&cmd);
  2006.             if (name)
  2007.             {
  2008.                 if (!readtok(&cmd))
  2009.                 {
  2010.                     struct ScreenNode *node = FindScreenNode(name);
  2011.                     if (node)
  2012.                     {
  2013.                         if (node->StormScreenF && node->OpenF)
  2014.                             ScreenToBack(node->Screen);
  2015.                         else
  2016.                             msg->rm_Result1 = RC_WARN;
  2017.                     }
  2018.                     else
  2019.                         msg->rm_Result1 = RC_ERROR;
  2020.                 }
  2021.                 else
  2022.                     msg->rm_Result1 = RC_ERROR;
  2023.             }
  2024.             else
  2025.                 msg->rm_Result1 = RC_ERROR;
  2026.         }
  2027.         else if (Stricmp(command,"SETDEFSCREEN") == 0) // SETDEFSCREEN <screenname>
  2028.         {
  2029.             STRPTR name = readtok(&cmd);
  2030.             if (name)
  2031.             {
  2032.                 if (!readtok(&cmd))
  2033.                 {
  2034.                     struct ScreenNode *node = FindScreenNode(name);
  2035.                     if (node)
  2036.                     {
  2037.                         SetDefaultScreenNode(node);
  2038.                         if (DefaultScreenNodeP != node)
  2039.                             msg->rm_Result1 = RC_WARN;
  2040.                     }
  2041.                     else
  2042.                         msg->rm_Result1 = RC_ERROR;
  2043.                 }
  2044.                 else
  2045.                     msg->rm_Result1 = RC_ERROR;
  2046.             }
  2047.             else
  2048.                 msg->rm_Result1 = RC_ERROR;
  2049.         }
  2050.         else if (Stricmp(command,"SHANGHAI") == 0) // SHANGHAI ON/OFF
  2051.         {
  2052.             STRPTR value = readtok(&cmd);
  2053.             if (value)
  2054.             {
  2055.                 if (!readtok(&cmd))
  2056.                 {
  2057.                     if (Stricmp(value,"ON") == 0)
  2058.                         setshanghai(TRUE);
  2059.                     else if (Stricmp(value,"OFF") == 0)
  2060.                         setshanghai(FALSE);
  2061.                     else
  2062.                         msg->rm_Result1 = RC_ERROR;
  2063.                 }
  2064.                 else
  2065.                     msg->rm_Result1 = RC_ERROR;
  2066.             }
  2067.             else
  2068.                 msg->rm_Result1 = RC_ERROR;
  2069.         }
  2070.         else if (Stricmp(command,"AUTOPOPUP") == 0) // AUTOPOPUP ON/OFF
  2071.         {
  2072.             STRPTR value = readtok(&cmd);
  2073.             if (value)
  2074.             {
  2075.                 if (!readtok(&cmd))
  2076.                 {
  2077.                     if (Stricmp(value,"ON") == 0)
  2078.                         setautopopup(TRUE);
  2079.                     else if (Stricmp(value,"OFF") == 0)
  2080.                         setautopopup(FALSE);
  2081.                     else
  2082.                         msg->rm_Result1 = RC_ERROR;
  2083.                 }
  2084.                 else
  2085.                     msg->rm_Result1 = RC_ERROR;
  2086.             }
  2087.             else
  2088.                 msg->rm_Result1 = RC_ERROR;
  2089.         }
  2090.         else if (Stricmp(command,"HIDE") == 0) // HIDE
  2091.         {
  2092.             if (!readtok(&cmd))
  2093.                 hide();
  2094.             else
  2095.                 msg->rm_Result1 = RC_ERROR;
  2096.         }
  2097.         else if (Stricmp(command,"SHOW") == 0) // SHOW
  2098.         {
  2099.             if (!readtok(&cmd))
  2100.                 show();
  2101.             else
  2102.                 msg->rm_Result1 = RC_ERROR;
  2103.         }
  2104.         else if (Stricmp(command,"QUIT") == 0) // QUIT
  2105.         {
  2106.             if (!readtok(&cmd))
  2107.                 retval = TRUE;
  2108.             else
  2109.                 msg->rm_Result1 = RC_ERROR;
  2110.         }
  2111.         else
  2112.         {
  2113.             msg->rm_Result1 = RC_FATAL; // unknown command
  2114.         }
  2115.         ReplyMsg(&msg->rm_Node)
  2116.     }
  2117.     return retval;
  2118. }
  2119.  
  2120. // *************************************************************
  2121. // ***
  2122. // *** NAME      main
  2123. // *** FUNCTION
  2124. // ***
  2125. // *************************************************************
  2126. void main(int argc, char *argv[])
  2127. {
  2128.     NewList((struct List *) &ScreenList);
  2129.  
  2130.     // set the current directory
  2131.     if (argc == 0) // started from WB
  2132.     {
  2133.         GlbCurrentDir = CurrentDir(DupLock(((struct WBStartup *) argv)->sm_ArgList[0].wa_Lock));
  2134.         GlbProgramNameP = ((struct WBStartup *) argv)->sm_ArgList[0].wa_Name;
  2135.     }
  2136.     else
  2137.     {
  2138.         GlbCurrentDir = CurrentDir(Lock("PROGDIR:",SHARED_LOCK));
  2139.         GlbProgramNameP = argv[0];
  2140.     }
  2141.  
  2142.     // open locale catalog
  2143.     if (LocaleBase)
  2144.     {
  2145.         GlbCatalogP = OpenCatalog(NULL,"StormScreenManager.catalog",
  2146.             OC_Version,0,
  2147.             TAG_END);
  2148.     }
  2149.  
  2150.     // open user interface
  2151.     if (!(GlbScreenP = LockPubScreen(NULL)))
  2152.         error(getlocalestr(MSG_FATAL_ID,MSG_FATAL_ID_STR));
  2153.     if (!(GlbSurfaceP = WZ_OpenSurface(NULL,WizardSurface,
  2154.         SFH_Catalog,GlbCatalogP,
  2155.         TAG_END)))
  2156.     {
  2157.         error(getlocalestr(MSG_UNABLE_TO_OPEN_WIZARD_FILE_ID,MSG_UNABLE_TO_OPEN_WIZARD_FILE_ID_STR));
  2158.     }
  2159.     if (!(GlbManagerWindowHandleP = WZ_AllocWindowHandle(GlbScreenP,0,GlbSurfaceP,
  2160.         TAG_END)))
  2161.     {
  2162.         error(getlocalestr(MSG_OUT_OF_MEMORY_ID,MSG_OUT_OF_MEMORY_ID_STR));
  2163.     }
  2164.     if (!(GlbManagerNewWindowP = WZ_CreateWindowObj(GlbManagerWindowHandleP,MANAGERWIN_ID,
  2165.         WWH_GadgetArray,GlbManagerGadgets,
  2166.         TAG_END)))
  2167.     {
  2168.         error(getlocalestr(MSG_FATAL_ID,MSG_FATAL_ID_STR));
  2169.     }
  2170.     if (!(GlbPropertiesWindowHandleP = WZ_AllocWindowHandle(GlbScreenP,0,GlbSurfaceP,
  2171.         TAG_END)))
  2172.     {
  2173.         error(getlocalestr(MSG_OUT_OF_MEMORY_ID,MSG_OUT_OF_MEMORY_ID_STR));
  2174.     }
  2175.     if (!(GlbPropertiesNewWindowP = WZ_CreateWindowObj(GlbPropertiesWindowHandleP,PROPERTIESWIN_ID,
  2176.         WWH_GadgetArray,GlbPropertiesGadgets,
  2177.         TAG_END)))
  2178.     {
  2179.         error(getlocalestr(MSG_FATAL_ID,MSG_FATAL_ID_STR));
  2180.     }
  2181.     if (!(GlbIDCMPortP = CreateMsgPort()))
  2182.     {
  2183.         error(getlocalestr(MSG_FATAL_ID,MSG_FATAL_ID_STR));
  2184.     }
  2185.  
  2186.     // allocate signal for public screens
  2187.     if ((GlbScreenSignal = AllocSignal(~0)) == ~0)
  2188.     {
  2189.         error(getlocalestr(MSG_FATAL_ID,MSG_FATAL_ID_STR));
  2190.     }
  2191.  
  2192.     // create REXX msg port
  2193.     if (!(GlbRexxPortP = CreateMsgPort()))
  2194.     {
  2195.         error(getlocalestr(MSG_FATAL_ID,MSG_FATAL_ID_STR));
  2196.     }
  2197.     Forbid();
  2198.     if (FindPort("StormScreenManager"))
  2199.     {
  2200.         Permit();
  2201.         DeleteMsgPort(GlbRexxPortP);
  2202.         GlbRexxPortP = NULL;
  2203.         error(getlocalestr(MSG_REXXPORT_IN_USE_ID,MSG_REXXPORT_IN_USE_ID_STR));
  2204.     }
  2205.     GlbRexxPortP->mp_Node.ln_Name = "StormScreenManager";
  2206.     AddPort(GlbRexxPortP);
  2207.     Permit();
  2208.  
  2209.     STRPTR err = Load(GlbProgramNameP);
  2210.     if (err)
  2211.         error(err);
  2212.  
  2213.     // initialize asl requesters using the loaded geometries
  2214.     struct TagItem ScreenModeInfoTags[] =
  2215.     {
  2216.         { ASLSM_InitialInfoLeftEdge, GlbScreenModeGeometry.InfoLeft },
  2217.         { ASLSM_InitialInfoTopEdge, GlbScreenModeGeometry.InfoTop },
  2218. //        { ASLSM_InitialInfoWidth, GlbScreenModeGeometry.InfoWidth },
  2219. //        { ASLSM_InitialInfoHeight, GlbScreenModeGeometry.InfoHeight },
  2220.         { TAG_END }
  2221.     };
  2222.     struct TagItem ScreenModeTags[] =
  2223.     {
  2224.         { ASLSM_InitialLeftEdge, GlbScreenModeGeometry.Left },
  2225.         { ASLSM_InitialTopEdge, GlbScreenModeGeometry.Top },
  2226.         { ASLSM_InitialWidth, GlbScreenModeGeometry.Width },
  2227.         { ASLSM_InitialHeight, GlbScreenModeGeometry.Height },
  2228.         { GlbScreenModeGeometry.InfoSet ? TAG_MORE : TAG_END, (ULONG) ScreenModeInfoTags }
  2229.     };
  2230.     if (!(GlbScreenModeRequesterP = (struct ScreenModeRequester *) AllocAslRequestTags(ASL_ScreenModeRequest,
  2231.         ASLSM_PrivateIDCMP,TRUE,
  2232.         ASLSM_Screen,GlbScreenP,
  2233.         ASLSM_TitleText,getlocalestr(MSG_SELECT_SCREEN_MODE_ID,MSG_SELECT_SCREEN_MODE_ID_STR),
  2234.         GlbScreenModeGeometry.Set ? TAG_MORE : TAG_END, ScreenModeTags)))
  2235.     {
  2236.         error(getlocalestr(MSG_FATAL_ID,MSG_FATAL_ID_STR));
  2237.     }
  2238.     struct TagItem FontReqTags[] =
  2239.     {
  2240.         { ASLFO_InitialLeftEdge, GlbFontGeometry.Left },
  2241.         { ASLFO_InitialTopEdge, GlbFontGeometry.Top },
  2242.         { ASLFO_InitialWidth, GlbFontGeometry.Width },
  2243.         { ASLFO_InitialHeight, GlbFontGeometry.Height },
  2244.         { TAG_END }
  2245.     };
  2246.     if (!(GlbFontRequesterP = (struct FontRequester *) AllocAslRequestTags(ASL_FontRequest,
  2247.         ASLFO_PrivateIDCMP,TRUE,
  2248.         ASLFO_Screen,GlbScreenP,
  2249.         ASLFO_TitleText,getlocalestr(MSG_SELECT_FONT_ID,MSG_SELECT_FONT_ID_STR),
  2250.         GlbFontGeometry.Set ? TAG_MORE : TAG_END, FontReqTags)))
  2251.     {
  2252.         error(getlocalestr(MSG_FATAL_ID,MSG_FATAL_ID_STR));
  2253.     }
  2254.  
  2255.     // initialize commodity
  2256.     if (!(GlbBrokerPortP = CreateMsgPort()))
  2257.         error(getlocalestr(MSG_FATAL_ID,MSG_FATAL_ID_STR));
  2258.     struct NewBroker newbroker =
  2259.     {
  2260.         NB_VERSION,
  2261.         "StormScreenManager",
  2262.         getlocalestr(MSG_BROKER_TITLE_ID,MSG_BROKER_TITLE_ID_STR),
  2263.         getlocalestr(MSG_BROKER_DESCRIP_ID,MSG_BROKER_DESCRIP_ID_STR),
  2264.         NBU_UNIQUE|NBU_NOTIFY,
  2265.         COF_SHOW_HIDE,
  2266.         GlbCXPriority,
  2267.         GlbBrokerPortP
  2268.     };
  2269.     LONG brokererr;
  2270.     if (!(GlbBrokerP = CxBroker(&newbroker,&brokererr)))
  2271.     {
  2272.         error(brokererr != CBERR_DUP ? getlocalestr(MSG_UNABLE_TO_INSTALL_COMMODITY_ID,MSG_UNABLE_TO_INSTALL_COMMODITY_ID_STR) : NULL);
  2273.     }
  2274.     if (GlbCXPopkeyF)
  2275.     {
  2276.         CxObj *filter, *sender, *translate;
  2277.         filter = CxFilter(GlbCXPopkey);
  2278.         sender = CxSender(GlbBrokerPortP,EVT_HOTKEY);
  2279.         translate = CxTranslate(NULL);
  2280.         AttachCxObj(GlbBrokerP,filter);
  2281.         AttachCxObj(filter,sender);
  2282.         AttachCxObj(filter,translate);
  2283.         if (CxObjError(GlbBrokerP) || CxObjError(filter))
  2284.             error(getlocalestr(MSG_FATAL_ID,MSG_FATAL_ID_STR));
  2285.     }
  2286.     ActivateCxObj(GlbBrokerP,1);
  2287.  
  2288.     // final stage: init header, open screens, init listview
  2289.     InitHeaderNode();
  2290.     ScanOpenPubScreens();
  2291.     struct ScreenNode *node;
  2292.     for (node = (struct ScreenNode *) ScreenList.mlh_Head;
  2293.         node->Node.Node.mln_Succ;
  2294.         node = (struct ScreenNode *) node->Node.Node.mln_Succ)
  2295.     {
  2296.         if (node->StormScreenF && node->OpenSoonF)
  2297.         {
  2298.             openscreen(node);
  2299.         }
  2300.     }
  2301.     if (DefaultScreenNodeP)
  2302.         SetDefaultScreenNode(DefaultScreenNodeP);
  2303.     GetDefaultScreenNode();
  2304.     setshanghai(GlbShanghaiF);
  2305.     setautopopup(GlbAutoPopupF);
  2306.     SetGadgetAttrs(GlbManagerGadgets[GAD_MAN_LIST_ID],NULL,NULL,
  2307.         WLISTVIEWA_HeaderNode,&HeaderNode,
  2308.         WLISTVIEWA_List,&ScreenList,
  2309.         WLISTVIEWA_Columns,6,
  2310.         TAG_END);
  2311.     setselected();
  2312.  
  2313.     // popup user interface?
  2314.     if (GlbStartPopupF)
  2315.         show();
  2316.  
  2317.     // the main loop
  2318.     ULONG mask = (1L << GlbIDCMPortP->mp_SigBit)
  2319.         | (1L << GlbScreenSignal)
  2320.         | (1L << GlbBrokerPortP->mp_SigBit)
  2321.         | (1L << GlbRexxPortP->mp_SigBit)
  2322.         | SIGBREAKF_CTRL_C;
  2323.     BOOL exitloop = FALSE;
  2324.     GlbExitSoonF = FALSE;
  2325.     while (!exitloop)
  2326.     {
  2327.         ULONG signals = Wait(mask);
  2328.  
  2329.         // Ctrl-C
  2330.         if (signals & SIGBREAKF_CTRL_C)
  2331.             GlbExitSoonF = TRUE;
  2332.  
  2333.         // IDCMP messages
  2334.         struct IntuiMessage *msg;
  2335.         while (msg = (struct IntuiMessage *) GetMsg(GlbIDCMPortP))
  2336.         {
  2337.             if (handleintuimsg(msg))
  2338.             {
  2339.                 GlbExitSoonF = TRUE;
  2340.                 break;
  2341.             }
  2342.         }
  2343.  
  2344.         // screen signals are sent if the last window is closed
  2345.         if (signals & (1L << GlbScreenSignal))
  2346.         {
  2347.             struct ScreenNode *node;
  2348.             for (node = (struct ScreenNode *) ScreenList.mlh_Head;
  2349.                 node->Node.Node.mln_Succ;
  2350.                 node = (struct ScreenNode *) node->Node.Node.mln_Succ)
  2351.             {
  2352.                 if (node->CloseSoonF && node->OpenF)
  2353.                 {
  2354.                     if (CloseScreen(node->Screen))
  2355.                     {
  2356.                         node->CloseSoonF = FALSE;
  2357.                         node->OpenF = FALSE;
  2358.                         node->Screen = NULL;
  2359.                     }
  2360.                 }
  2361.             }
  2362.             setselected();
  2363.         }
  2364.  
  2365.         // commodity messages
  2366.         CxMsg *cxmsg;
  2367.         while (cxmsg = (CxMsg *) GetMsg(GlbBrokerPortP))
  2368.         {
  2369.             ULONG msgid = CxMsgID(cxmsg);
  2370.             ULONG msgtype = CxMsgType(cxmsg);
  2371.             ReplyMsg((struct Message *) cxmsg);
  2372.             switch (msgtype)
  2373.             {
  2374.                 case CXM_IEVENT:
  2375.                     switch (msgid)
  2376.                     {
  2377.                         case EVT_HOTKEY: // hotkey pressed
  2378.                             show();
  2379.                             break;
  2380.                     }
  2381.                     break;
  2382.                 case CXM_COMMAND:
  2383.                     switch (msgid)
  2384.                     {
  2385.                         case CXCMD_DISABLE:
  2386.                             GlbDisableF = TRUE;
  2387.                             ActivateCxObj(GlbBrokerP,0);
  2388.                             break;
  2389.                         case CXCMD_ENABLE:
  2390.                             GlbDisableF = FALSE;
  2391.                             ActivateCxObj(GlbBrokerP,1);
  2392.                             break;
  2393.                         case CXCMD_APPEAR:
  2394.                         case CXCMD_UNIQUE: // SSM is started second time
  2395.                             show();
  2396.                             break;
  2397.                         case CXCMD_DISAPPEAR:
  2398.                             hide();
  2399.                             break;
  2400.                         case CXCMD_KILL:
  2401.                             GlbExitSoonF = TRUE; // exit as soon as possible
  2402.                             break;
  2403.                     }
  2404.                     break;
  2405.             }
  2406.         }
  2407.  
  2408.         // handle REXX messages
  2409.         struct RexxMsg *rxmsg;
  2410.         while (rxmsg = (struct RexxMsg *) GetMsg(GlbRexxPortP))
  2411.         {
  2412.             if (handlerexxmsg(rxmsg))
  2413.             {
  2414.                 GlbExitSoonF = TRUE;
  2415.                 break;
  2416.             }
  2417.         }
  2418.  
  2419.         // try to exit
  2420.         if (GlbExitSoonF)
  2421.         {
  2422.             exitloop = TRUE;
  2423.             struct ScreenNode *node;
  2424.             for (node = (struct ScreenNode *) ScreenList.mlh_Head;
  2425.                 node->Node.Node.mln_Succ;
  2426.                 node = (struct ScreenNode *) node->Node.Node.mln_Succ)
  2427.             {
  2428.                 if (node->StormScreenF && node->OpenF)
  2429.                 {
  2430.                     // try to close the screen
  2431.                     closescreen(node);
  2432.                     if (node->OpenF) // couldn't close the screen
  2433.                         exitloop = FALSE; // -> cannot exit
  2434.                 }
  2435.             }
  2436.             setselected(); // some screens may be closed
  2437.         }
  2438.     }
  2439.     error(NULL); // exit gracefully
  2440. }
  2441.