home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #1 / monster.zip / monster / WIN_BMP / FRCICN13.ZIP / SUPPORT.C < prev   
C/C++ Source or Header  |  1994-02-15  |  30KB  |  1,287 lines

  1. /*
  2. Auto:        smake ForceIcon
  3. */
  4.  
  5. /* $Revision Header built automatically *************** (do not edit) ************
  6. **
  7. ** ⌐ Copyright by GuntherSoft
  8. **
  9. ** File             : SnakeSYS:CPrgs/Utils/ForceIcon/Support.c
  10. ** Created on       : Friday, 22.10.93 16:38:41
  11. ** Created by       : Kai Iske
  12. ** Current revision : V1.0
  13. **
  14. **
  15. ** Purpose
  16. ** -------
  17. **   - Support-Routines for ForceIcon
  18. **
  19. ** Revision V1.0
  20. ** --------------
  21. ** created on Friday, 22.10.93 16:38:41  by  Kai Iske.   LogMessage :
  22. **     --- Initial release ---
  23. **
  24. *********************************************************************************/
  25.  
  26.  
  27.  
  28. /**********************************************************************/
  29. /*                      Routines for this module                      */
  30. /**********************************************************************/
  31. static UWORD ComputeX(UWORD value, UWORD FontX);
  32. static UWORD ComputeY(UWORD value, UWORD FontY);
  33. static void __stdargs ComputeFont(struct Screen *WorkScreen, UWORD width, UWORD height, struct TextAttr *Font, char *FontName, UWORD *OffX, UWORD *OffY, UWORD *FontX, UWORD *FontY);
  34. static void SetGadShortCut(UWORD Type, struct NewGadget *NewGad);
  35. static BOOL GetDosEntries(struct List *VolList, ULONG Mode);
  36. static void SortPartialList(struct List *VolList, UWORD Left, UWORD Right);
  37.  
  38.  
  39.  
  40. /**********************************************************************/
  41. /*                         External variables                         */
  42. /**********************************************************************/
  43. extern struct    ExecBase    *SysBase;
  44. extern struct    SignalSemaphore    MySemaphore;
  45. extern struct    List        VolumeList;
  46. extern struct    IClass        *GetFileClass;
  47.  
  48.  
  49. /**********************************************************************/
  50. /*                          Global variables                          */
  51. /**********************************************************************/
  52. static struct    RastPort    ComputeRPort;
  53.  
  54.  
  55.  
  56. /**********************************************************************/
  57. /*                       Vars for Busy-Pointer                        */
  58. /**********************************************************************/
  59. static UWORD __chip BusyPtr[] =
  60. {
  61.     0x0000,0x0000,0x0400,0x07C0,0x0000,0x07C0,
  62.     0x0100,0x0380,0x0000,0x07E0,0x07C0,0x1FF8,
  63.     0x1FF0,0x3FEC,0x3FF8,0x7FDE,0x3FF8,0x7FBE,
  64.     0x7FFC,0xFF7F,0x7EFC,0xFFFF,0x7FFC,0xFFFF,
  65.     0x3FF8,0x7FFE,0x3FF8,0x7FFE,0x1FF0,0x3FFC,
  66.     0x07C0,0x1FF8,0x0000,0x07E0,0x0000,0x0000
  67. };
  68.  
  69.  
  70.  
  71. /**********************************************************************/
  72. /*                          Calc X-Position                           */
  73. /**********************************************************************/
  74. static UWORD ComputeX(UWORD value, UWORD FontX)
  75. {
  76.     return((UWORD)(((FontX * value) + 2) / 8));
  77. }
  78.  
  79.  
  80.  
  81.  
  82.  
  83. /**********************************************************************/
  84. /*                          Calc Y-Position                           */
  85. /**********************************************************************/
  86. static UWORD ComputeY(UWORD value, UWORD FontY)
  87. {
  88.     return(( UWORD )((( FontY * value ) + 2 ) / 8 ));
  89. }
  90.  
  91.  
  92.  
  93.  
  94. /**********************************************************************/
  95. /*                  Calc resolution and correct font                  */
  96. /**********************************************************************/
  97. static void __stdargs ComputeFont(struct Screen *WorkScreen, UWORD width, UWORD height, struct TextAttr *Font, char *FontName, UWORD *OffX, UWORD *OffY, UWORD *FontX, UWORD *FontY)
  98. {
  99.         // Get Font-Structure
  100.  
  101.     strcpy(FontName, WorkScreen->RastPort.Font->tf_Message.mn_Node.ln_Name);
  102.  
  103.     Font->ta_Name    = FontName;
  104.     Font->ta_YSize    = *FontY = WorkScreen->RastPort.Font->tf_YSize;
  105.     Font->ta_Style    = FS_NORMAL;
  106.     Font->ta_Flags    = 0;
  107.  
  108.     *FontX        = WorkScreen->RastPort.Font->tf_XSize;
  109.  
  110.  
  111.         // Calc offsets
  112.  
  113.     *OffX = WorkScreen->WBorLeft;
  114.     *OffY = WorkScreen->RastPort.TxHeight + WorkScreen->WBorTop + 1;
  115.  
  116.  
  117.         // A Ok ???
  118.  
  119.     if(width && height)
  120.     {
  121.         if((ComputeX(width, *FontX) + *OffX + WorkScreen->WBorRight) > WorkScreen->Width)
  122.             goto UseTopaz;
  123.         if((ComputeY(height, *FontY) + *OffY + WorkScreen->WBorBottom) > WorkScreen->Height)
  124.             goto UseTopaz;
  125.     }
  126.     return;
  127.  
  128.         // FallBack to Topaz8
  129. UseTopaz:
  130.     strcpy(FontName, "topaz.font");
  131.     *FontX = *FontY = Font->ta_YSize = 8;
  132. }
  133.  
  134.  
  135.  
  136.  
  137. /**********************************************************************/
  138. /*              Open a window with a background pattern               */
  139. /**********************************************************************/
  140. BOOL OpenWin(
  141.             UWORD    Left,
  142.             UWORD    Top,
  143.             UWORD    Width,
  144.             UWORD    Height,
  145.             struct    Gadget        **BaseGadget,
  146.             UWORD    NumGads,
  147.             struct    _Object        **GetFile,
  148.             struct    NewGadget    *NewGads,
  149.             UWORD    *GTypes,
  150.             ULONG    *GTags,
  151.             struct    Gadget        **MyGads,
  152.             struct    Window        **Handle,
  153.             char    *Title,
  154.             ULONG    IDCMP,
  155.             ULONG    FLAGS,
  156.             UWORD    MLeft,
  157.             UWORD    MTop,
  158.             UWORD    MWidth,
  159.             UWORD    MHeight,
  160.             struct    TextAttr    *WinTxtAttr,
  161.             char            *WinTxtFontName,
  162.             struct    VisualInfo    **VisInfo)
  163. {
  164.     UWORD Raster[4] =
  165.     {
  166.         0xAAAA,
  167.         0x5555,
  168.     };
  169.     struct    Screen        *MyScreen;
  170.     struct    Rectangle    ScrRec;
  171.     struct    NewGadget    ng;
  172.     struct    Gadget        *g;
  173.     struct    TextFont    *MyFont = NULL;
  174.     UWORD    lc, tc;
  175.     UWORD    wleft, wtop, ww, wh, OffX, OffY, FontX, FontY,
  176.         swidth, sheight;
  177.  
  178.  
  179.     if(!(MyScreen = LockPubScreen("Workbench")))
  180.         return(FALSE);
  181.  
  182.     if(!(*VisInfo = GetVisualInfo(MyScreen, TAG_DONE)))
  183.         goto error;
  184.  
  185.         // Get Font and dimensions
  186.  
  187.     ComputeFont(MyScreen, Width, Height, WinTxtAttr, WinTxtFontName, &OffX, &OffY, &FontX, &FontY);
  188.  
  189.  
  190.         // Set RastPort Font
  191.  
  192.     InitRastPort(&ComputeRPort);
  193.     if(!(MyFont = OpenFont(WinTxtAttr)))
  194.     {
  195.         if(!(MyFont = OpenDiskFont(WinTxtAttr)))
  196.             goto error;
  197.     }
  198.     SetFont(&ComputeRPort, MyFont);
  199.  
  200.  
  201.         // Get size of window
  202.  
  203.     ww = ComputeX(Width, FontX);
  204.     wh = ComputeY(Height, FontY);
  205.  
  206.  
  207.         // Get info about Screenmode
  208.  
  209.     if(!QueryOverscan(GetVPModeID(&MyScreen->ViewPort), &ScrRec, OSCAN_TEXT))
  210.         goto error;
  211.  
  212.         // Center window
  213.  
  214.     swidth    = min((ScrRec.MaxX + 1), MyScreen->Width);
  215.     sheight    = min((ScrRec.MaxY + 1), MyScreen->Height);
  216.  
  217.     wleft    = ((swidth - ww - 1) >> 1) - ((MyScreen->LeftEdge < 0) ? MyScreen->LeftEdge : 0);
  218.     wtop    = ((sheight - wh - 1) >> 1) - ((MyScreen->TopEdge < 0) ? MyScreen->TopEdge : 0);
  219.  
  220.  
  221.         // Build GetFile image
  222.  
  223.     if(GetFile)
  224.     {
  225.         if(!(*GetFile = NewObject(GetFileClass, NULL, GT_VisualInfo, *VisInfo, IA_Width, ComputeX(20, FontX), IA_Height, ComputeY(14, FontY), TAG_DONE)))
  226.             goto error;
  227.     }
  228.  
  229.         // Create gadgets
  230.  
  231.     if(!(g = CreateContext(BaseGadget)))
  232.         goto error;
  233.  
  234.     for(lc = 0, tc = 0; lc < NumGads; lc++)
  235.     {
  236.         CopyMem((char *)&NewGads[lc], (char *)&ng, (long)sizeof(struct NewGadget));
  237.  
  238.         ng.ng_VisualInfo    = *VisInfo;
  239.         ng.ng_TextAttr        = WinTxtAttr;
  240.         ng.ng_LeftEdge        = OffX + ComputeX(ng.ng_LeftEdge, FontX);
  241.         ng.ng_TopEdge        = OffY + ComputeY(ng.ng_TopEdge, FontY);
  242.         ng.ng_Width        = ComputeX(ng.ng_Width, FontX);
  243.         ng.ng_Height        = ComputeY(ng.ng_Height, FontY);
  244.  
  245.             // Set gadget`s shortcut
  246.  
  247.         SetGadShortCut(GTypes[lc], &ng);
  248.  
  249.             // Check for ListView
  250.  
  251.         if(GTypes[lc] == LISTVIEW_KIND)
  252.         {
  253.             struct TagItem    *tmp;
  254.  
  255.             if(tmp = FindTagItem(GTLV_ShowSelected, (struct TagItem *)>ags[tc]))
  256.             {
  257.                 if(tmp->ti_Data)
  258.                     tmp->ti_Data = (ULONG)g;
  259.                 else
  260.                 {
  261.                         // With a normal ShowSelected,
  262.                         // adjust width according to version of OS
  263.  
  264.                     if(((struct Library *)SysBase)->lib_Version < 39)
  265.                         ng.ng_Height    -= 8;
  266.                 }
  267.             }
  268.         }
  269.  
  270.             // Create gadget
  271.  
  272.         MyGads[lc] = g = CreateGadgetA(GTypes[lc], g, &ng, (struct TagItem *)>ags[tc]);
  273.  
  274.             // Error ???
  275.  
  276.         if(!g)
  277.             goto error;
  278.  
  279.             // Set GetFile image
  280.  
  281.         if(GTypes[lc] == GENERIC_KIND && GetFile)
  282.         {
  283.             struct    TagItem    *tmp;
  284.             BOOL    Disabled = FALSE;
  285.  
  286.             if((tmp = FindTagItem(GA_Disabled, (struct TagItem *)>ags[tc])))
  287.                 Disabled = (BOOL)tmp->ti_Data;
  288.  
  289.             g->Flags        |= GFLG_GADGIMAGE | GFLG_GADGHIMAGE | ((Disabled) ? GFLG_DISABLED : 0);
  290.             g->Activation        |= GACT_RELVERIFY;
  291.             g->GadgetType        |= GTYP_BOOLGADGET;
  292.             g->GadgetRender        = (APTR)*GetFile;
  293.             g->SelectRender        = (APTR)*GetFile;
  294.         }
  295.  
  296.             // Patch String/Integer Gadgets
  297.  
  298.         if(GTypes[lc] == STRING_KIND || GTypes[lc] == INTEGER_KIND)
  299.         {
  300.             ((struct StringInfo *)g->SpecialInfo)->Extension->ActivePens[0] = 1;
  301.             ((struct StringInfo *)g->SpecialInfo)->Extension->ActivePens[1] = 2;
  302.         }
  303.  
  304.         while(GTags[tc])
  305.             tc += 2;
  306.         tc++;
  307.     }
  308.  
  309.         // Close Font
  310.  
  311.     CloseFont(MyFont);
  312.  
  313.         // Open window
  314.  
  315.     if(!(*Handle = OpenWindowTags(NULL,
  316.         WA_Left,        wleft,
  317.         WA_Top,            wtop,
  318.         WA_Width,        ww + OffX + MyScreen->WBorRight,
  319.         WA_Height,        wh + OffY + MyScreen->WBorBottom,
  320.         WA_IDCMP,        IDCMP,
  321.         WA_Flags,        FLAGS,
  322.         WA_Title,        Title,
  323.         WA_CustomScreen,    MyScreen,
  324.     TAG_DONE)))
  325.         goto error;
  326.  
  327.         // Clear userdata-field
  328.  
  329.     (*Handle)->UserData    = NULL;
  330.  
  331.         // Unlock Pub screen
  332.  
  333.     UnlockPubScreen(NULL, MyScreen);
  334.  
  335.     if(MLeft && MTop && MWidth && MHeight)
  336.     {
  337.             // Draw Raster
  338.  
  339.         SetAPen((*Handle)->RPort, 2);
  340.         SetAfPt((*Handle)->RPort, Raster, 1);
  341.         RectFill((*Handle)->RPort, (*Handle)->BorderLeft, (*Handle)->BorderTop, (*Handle)->Width - (*Handle)->BorderRight - 1, (*Handle)->Height - (*Handle)->BorderBottom - 1);
  342.         SetAfPt((*Handle)->RPort, NULL, 0);
  343.  
  344.             // Clear gadget areas and draw bevelbox
  345.  
  346.         SetAPen((*Handle)->RPort, 0);
  347.  
  348.         wleft    = OffX + ComputeX(MLeft, FontX);
  349.         wtop    = OffY + ComputeY(MTop, FontY);
  350.         RectFill((*Handle)->RPort, wleft, wtop, wleft + ComputeX(MWidth, FontX) - 1, wtop + ComputeY(MHeight, FontY) - 1);
  351.         DrawBevelBox((*Handle)->RPort, wleft, wtop,
  352.             ComputeX(MWidth, FontX),
  353.             ComputeY(MHeight, FontY),
  354.             GT_VisualInfo, *VisInfo, GTBB_Recessed, TRUE,
  355.         TAG_DONE);
  356.     }
  357.  
  358.         // Add gadgets and display them
  359.  
  360.     AddGList((*Handle), *BaseGadget, -1, -1, NULL);
  361.     RefreshGadgets(*BaseGadget, (*Handle), NULL);
  362.  
  363.     GT_RefreshWindow((*Handle), NULL );
  364.     return(TRUE);
  365.  
  366. error:
  367.     if(MyScreen)
  368.         UnlockPubScreen(NULL, MyScreen);
  369.     if(MyFont)
  370.         CloseFont(MyFont);
  371.     return(FALSE);
  372.  
  373. }
  374.  
  375.  
  376.  
  377.  
  378.  
  379. /**********************************************************************/
  380. /*                        Close a window again                        */
  381. /**********************************************************************/
  382. void CloseWin(struct Window **Handle, struct Gadget **MyGad, struct VisualInfo **VisInfo, struct _Object **GetFile)
  383. {
  384.     if(*Handle)
  385.     {
  386.         CloseWindow((*Handle));
  387.         *Handle = NULL;
  388.     }
  389.  
  390.     if(*MyGad)
  391.     {
  392.         FreeGadgets((*MyGad));
  393.         *MyGad = NULL;
  394.     }
  395.  
  396.     if(*VisInfo)
  397.     {
  398.         FreeVisualInfo(*VisInfo);
  399.         *VisInfo = NULL;
  400.     }
  401.  
  402.     if(GetFile && *GetFile)
  403.     {
  404.         DisposeObject(*GetFile);
  405.         *GetFile = NULL;
  406.     }
  407. }
  408.  
  409.  
  410.  
  411.  
  412.  
  413. /**********************************************************************/
  414. /*                      Set a gadget`s shortcut                       */
  415. /**********************************************************************/
  416. static void SetGadShortCut(UWORD Type, struct NewGadget *NewGad)
  417. {
  418.     char *UnderScore, MyChar;
  419.     ULONG EventType = 0;
  420.  
  421.         // Get char of ShortCut
  422.  
  423.     if(NewGad->ng_GadgetText && (UnderScore = (char *)strchr(NewGad->ng_GadgetText, '_')))
  424.     {
  425.         MyChar = *(UnderScore + 1);
  426.         NewGad->ng_UserData = (void *)ToUpper(MyChar);
  427.     }
  428.  
  429.         // Set type of event suited for Keystroke activation
  430.  
  431.     switch(Type)
  432.     {
  433.         case BUTTON_KIND :
  434.         case CYCLE_KIND :
  435.         case LISTVIEW_KIND :
  436.         case CHECKBOX_KIND :
  437.         {
  438.             EventType = IDCMP_GADGETUP;
  439.             break;
  440.         }
  441.         case STRING_KIND :
  442.         case INTEGER_KIND :
  443.         {
  444.             EventType = IDCMP_GADGETDOWN;
  445.             break;
  446.         }
  447.     }
  448.  
  449.     if(EventType)
  450.         NewGad->ng_UserData = (void *)((ULONG)NewGad->ng_UserData | (EventType << 8));
  451. }
  452.  
  453.  
  454.  
  455.  
  456.  
  457. /**********************************************************************/
  458. /*                    Get device and volume lists                     */
  459. /**********************************************************************/
  460. BOOL GetDevVolList(struct List *VolList)
  461. {
  462.     NewList(VolList);
  463.     VolList->lh_Type = 0;
  464.  
  465.     if(GetDosEntries(VolList, LDF_DEVICES))
  466.     {
  467.         if(GetDosEntries(VolList, LDF_VOLUMES))
  468.         {
  469.             SortList(VolList, FALSE);
  470.             return(TRUE);
  471.         }
  472.     }
  473.  
  474.     return(FALSE);
  475. }
  476.  
  477.  
  478.  
  479. /**********************************************************************/
  480. /*                     Collect available volumes                      */
  481. /**********************************************************************/
  482. static BOOL GetDosEntries(struct List *VolList, ULONG Mode)
  483. {
  484.     struct    DosList        *DList;
  485.     struct    VolEntry    *NewEntry;
  486.     BOOL    RetVal        = FALSE;
  487.  
  488.         // Lock DOS-List of Volumes
  489.  
  490.     if((DList = LockDosList(Mode|LDF_READ)))
  491.     {
  492.             // Loop for all entries
  493.  
  494.         while(DList)
  495.         {
  496.                 // Get next entry
  497.  
  498.             if(!(DList = NextDosEntry(DList, Mode|LDF_READ)))
  499.                 RetVal = TRUE;
  500.             else
  501.             {
  502.                 BOOL    DoGet = TRUE;
  503.  
  504.                 if(DList->dol_Type == DLT_DEVICE)
  505.                 {
  506.                     struct    FileSysStartupMsg *FSSM = (struct FileSysStartupMsg *)BADDR(DList->dol_misc.dol_handler.dol_Startup);
  507.                     DoGet = FALSE;
  508.  
  509.                     if(FSSM && TypeOfMem(FSSM) && TypeOfMem(BADDR(FSSM->fssm_Device)) && TypeOfMem(BADDR(FSSM->fssm_Environ)))
  510.                     {
  511.                         if(*((char *)BADDR(FSSM->fssm_Device)) != 255)
  512.                         {
  513.                             struct    DosEnvec    *DE = (struct DosEnvec *)BADDR(FSSM->fssm_Environ);
  514.  
  515.                             if(DE && TypeOfMem(DE))
  516.                             {
  517.                                 if(DE->de_Surfaces && DE->de_BlocksPerTrack)
  518.                                     DoGet = TRUE;
  519.                             }
  520.                         }
  521.                     }
  522.                 }
  523.  
  524.                 if(DoGet)
  525.                 {
  526.                         // Alloc memory for new entry
  527.  
  528.                     if((NewEntry = AllocVec(sizeof(struct VolEntry), MEMF_CLEAR)))
  529.                     {
  530.                             // Add to list
  531.  
  532.                         AddTail(VolList, (struct Node *)NewEntry);
  533.                         NewEntry->Link.ln_Name    = NewEntry->VolName;
  534.                         NewEntry->Link.ln_Type    = Mode;
  535.                         VolList->lh_Type++;
  536.  
  537.                         strcpy(NewEntry->VolName, ((char *)BADDR(DList->dol_Name) + 1));
  538.                     }
  539.                     else
  540.                         DList = NULL;
  541.                 }
  542.             }
  543.         }
  544.  
  545.             // Unlock DOS-List again
  546.  
  547.         UnLockDosList(Mode|LDF_READ);
  548.     }
  549.  
  550.     if(!RetVal)
  551.         DisplayError(ERR_NOTALL, NULL);
  552.  
  553.     return(RetVal);
  554. }
  555.  
  556.  
  557.  
  558.  
  559.  
  560.  
  561.  
  562. /**********************************************************************/
  563. /*                        Release Volume-Nodes                        */
  564. /**********************************************************************/
  565. void FreeDevVolList(struct List *VolList)
  566. {
  567.     struct    Node    *DelNode;
  568.  
  569.     while((DelNode = RemHead(VolList)))
  570.         FreeVec(DelNode);
  571. }
  572.  
  573.  
  574.  
  575.  
  576.  
  577.  
  578. /**********************************************************************/
  579. /*                     Check for gadget shortcuts                     */
  580. /**********************************************************************/
  581. void CheckKeys(ULONG *MsgClass, UWORD *MsgCode, UWORD *GadID, BOOL *KeyUse, struct Gadget **MsgGad, struct Gadget **EditGads, UWORD NumGads)
  582. {
  583.     register int i;
  584.  
  585.         // Key pressed ???
  586.  
  587.     if(*MsgClass == IDCMP_VANILLAKEY)
  588.     {
  589.             // Key released ???
  590.  
  591.         if(!(*MsgCode & IECODE_UP_PREFIX))
  592.         {
  593.                 // ESC hit ??? -> Return CLOSE WINDOW
  594.  
  595.             if(*MsgCode == ESCKEY)
  596.                 *MsgClass    = IDCMP_CLOSEWINDOW;
  597.  
  598.                 // On Return, search for the first String/Integer gadget
  599.  
  600.             else if(*MsgCode == 0x0d)
  601.             {
  602.                     // Search for gadget
  603.  
  604.                 for(i = 0; i < NumGads; i++)
  605.                 {
  606.                         // This is the one
  607.  
  608.                     if((EditGads[i]->GadgetType & GTYP_STRGADGET) && !(EditGads[i]->Flags & GFLG_DISABLED))
  609.                     {
  610.                             // Set flags and vars
  611.  
  612.                         *MsgGad        = EditGads[i];
  613.                         *MsgClass    = IDCMP_ACTSTRGAD;
  614.                         *KeyUse        = TRUE;
  615.                         break;
  616.                     }
  617.                 }
  618.             }
  619.             else
  620.             {
  621.                     // Get Char hit
  622.  
  623.                 *MsgCode = (UWORD)ToUpper((char)*MsgCode);
  624.  
  625.                     // Search for suited gadget
  626.  
  627.                 for(i = 0; i < NumGads; i++)
  628.                 {
  629.                     if(((ULONG)EditGads[i]->UserData & 0x000000ff) == (ULONG)*MsgCode)
  630.                     {
  631.                             // Set flags
  632.  
  633.                         *MsgGad        = EditGads[i];
  634.                         *GadID        = (*MsgGad)->GadgetID;
  635.                         *MsgClass    = ((ULONG)(*MsgGad)->UserData & 0x0000ff00) >> 8;
  636.                         *KeyUse        = TRUE;
  637.                         break;
  638.                     }
  639.                 }
  640.             }
  641.         }
  642.     }
  643.     else
  644.         *KeyUse = FALSE;
  645. }
  646.  
  647.  
  648.  
  649.  
  650.  
  651. /**********************************************************************/
  652. /*                      Handle a listview gadget                      */
  653. /**********************************************************************/
  654. ULONG HandleListViewGad(struct Gadget *Gad, struct Window *MsgWin, BOOL KeyUse, UWORD MsgCode, UWORD MsgQual, LONG Val, ULONG Min, ULONG Max)
  655. {
  656.     if(KeyUse)
  657.     {
  658.             // Key hit
  659.  
  660.         if(MsgQual & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
  661.         {
  662.                 // On SHIFT move up
  663.  
  664.             if((Val != Min) && (Val != -1))
  665.                 Val--;
  666.         }
  667.         else
  668.         {
  669.                 // On NON-SHIFT move down
  670.  
  671.             if(Val != Max)
  672.                 Val++;
  673.         }
  674.  
  675.             // Set gadget
  676.  
  677.         if(Val != -1)
  678.         {
  679.             GT_SetGadgetAttrs(Gad, MsgWin, NULL,
  680.                 GTLV_Selected,    Val,
  681.                 GTLV_Top,    Val,
  682.             TAG_DONE);
  683.         }
  684.     }
  685.     else
  686.             // Otherwiese simply get Message-Code
  687.  
  688.         Val = MsgCode;
  689.  
  690.  
  691.     return((ULONG)Val);
  692. }
  693.  
  694.  
  695.  
  696.  
  697. /**********************************************************************/
  698. /*                       Handle a cycle gadget                        */
  699. /**********************************************************************/
  700. ULONG HandleCycleGad(struct Gadget *Gad, struct Window *MsgWin, BOOL KeyUse, UWORD MsgCode, UWORD MsgQual, ULONG Val, ULONG Min, ULONG Max)
  701. {
  702.     if(KeyUse)
  703.     {
  704.             // Key hit
  705.  
  706.         if(MsgQual & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
  707.         {
  708.                 // On SHIFT move upward, on minimum jump to highest entry
  709.  
  710.             if(Val == Min)
  711.                 Val = Max;
  712.             else
  713.                 Val--;
  714.         }
  715.         else
  716.         {
  717.                 // On NON-SHIFT move downward, on maximum jump to lowest entry
  718.  
  719.             if(Val == Max)
  720.                 Val = Min;
  721.             else
  722.                 Val++;
  723.         }
  724.  
  725.             // Set gadget
  726.  
  727.         GT_SetGadgetAttrs(Gad, MsgWin, NULL,
  728.             GTCY_Active, Val,
  729.         TAG_DONE);
  730.     }
  731.     else
  732.             // Otherwise simply get MsgCode
  733.  
  734.         Val = MsgCode;
  735.  
  736.  
  737.     return(Val);
  738. }
  739.  
  740.  
  741.  
  742.  
  743. /**********************************************************************/
  744. /*                      Get an entry from a list                      */
  745. /**********************************************************************/
  746. APTR GetListEntry(struct List *List, WORD EntryNum)
  747. {
  748.     struct    Node    *ThisEntry = NULL, *CheckEntry;
  749.  
  750.         // Search list for entry
  751.  
  752.     if(!IsListEmpty((struct List *)List) && EntryNum >= 0)
  753.     {
  754.         CheckEntry = List->lh_Head;
  755.  
  756.         while(CheckEntry->ln_Succ && EntryNum)
  757.         {
  758.             CheckEntry    = CheckEntry->ln_Succ;
  759.             EntryNum--;
  760.         }
  761.  
  762.         if(!EntryNum)
  763.             ThisEntry    = CheckEntry;
  764.     }
  765.  
  766.     return(ThisEntry);
  767. }
  768.  
  769.  
  770.  
  771.  
  772. /**********************************************************************/
  773. /*                        Set a window to Busy                        */
  774. /**********************************************************************/
  775. void BusyWindow(struct Window *Window, struct Requester *MyReq)
  776. {
  777.     if(Window)
  778.     {
  779.             // Clear Requester structure
  780.  
  781.         setmem((void *)MyReq, sizeof(struct Requester), 0);
  782.  
  783.             // Open Requester and store address within UserData
  784.  
  785.         Window->UserData = (char *)Request(MyReq, Window);
  786.  
  787.             // Set Pointer
  788.  
  789.         if(SysBase->LibNode.lib_Version < 39)
  790.             SetPointer(Window, &BusyPtr[0],  16, 16, -6, 0);
  791.         else
  792.             SetWindowPointer(Window, WA_BusyPointer, TRUE, TAG_DONE);
  793.     }
  794. }
  795.  
  796.  
  797.  
  798.  
  799. /**********************************************************************/
  800. /*                          UnBusy a window                           */
  801. /**********************************************************************/
  802. void UnBusyWindow(struct Window *Window, struct Requester *MyReq)
  803. {
  804.     if(Window)
  805.     {
  806.             // Close Requester
  807.  
  808.         if(Window->UserData)
  809.             EndRequest(MyReq, Window);
  810.         Window->UserData = NULL;
  811.  
  812.             // Reset Pointer
  813.  
  814.         if(SysBase->LibNode.lib_Version < 39)
  815.             ClearPointer(Window);
  816.         else
  817.             SetWindowPointer(Window, TAG_DONE);
  818.     }
  819. }
  820.  
  821.  
  822.  
  823.  
  824.  
  825.  
  826.  
  827. /**********************************************************************/
  828. /*                       Save Prefs to disk/env                       */
  829. /**********************************************************************/
  830. BOOL SavePrefs(BOOL EnvMode)
  831. {
  832.         // On ENV: mode, simply save to ENV: only
  833.  
  834.     if(DoSavePrefs("ENV:ForceIcon_prefs.iff"))
  835.     {
  836.             // Otherwise write to envarc: as well
  837.  
  838.         if(!EnvMode)
  839.             return(DoSavePrefs("ENVARC:ForceIcon_prefs.iff"));
  840.         else
  841.             return(TRUE);
  842.     }
  843.     return(FALSE);
  844. }
  845. BOOL DoSavePrefs(char *PrefsName)
  846. {
  847.     struct    IFFHandle    *PrefsHandle;
  848.     LONG    Error;
  849.     BOOL    GoOn = FALSE;
  850.     UWORD    VersChunk[] =
  851.     {
  852.         VERNUM,
  853.         REVNUM
  854.     };
  855.  
  856.         // Get handle for IFF
  857.  
  858.     if((PrefsHandle = AllocIFF()))
  859.     {
  860.             // Open file for save
  861.  
  862.         if((PrefsHandle->iff_Stream = Open(PrefsName, MODE_NEWFILE)))
  863.         {
  864.                 // Init Handle
  865.  
  866.             InitIFFasDOS(PrefsHandle);
  867.  
  868.                 // Open Handle
  869.  
  870.             if(!(Error = OpenIFF(PrefsHandle, IFFF_WRITE)))
  871.             {
  872.                     // Write FORM chunk
  873.  
  874.                 if(!(Error = PushChunk(PrefsHandle, 'FOIC', 'FORM', IFFSIZE_UNKNOWN)))
  875.                 {
  876.                         // Write version chunk
  877.  
  878.                     if(!(Error = PushChunk(PrefsHandle, 'FOIC', 'VERS', IFFSIZE_UNKNOWN)))
  879.                     {
  880.                         if((Error = WriteChunkBytes(PrefsHandle, &VersChunk[0], (sizeof(UWORD) * 2))) == (sizeof(UWORD) * 2))
  881.                             Error = PopChunk(PrefsHandle);
  882.                         else
  883.                             Error = IoErr();
  884.                     }
  885.  
  886.                         // Write Prefs chunk
  887.  
  888.                     if(!Error && !(Error = PushChunk(PrefsHandle, 'FOIC', 'PREF', IFFSIZE_UNKNOWN)))
  889.                     {
  890.                         struct    VolEntry    *ThisEntry    = (struct VolEntry *)VolumeList.lh_Head;
  891.                         UWORD    NumEntries            = VolumeList.lh_Type;
  892.                         BOOL    NoErr = TRUE;
  893.  
  894.                                 // Write all entries of volume list
  895.  
  896.                         if((Error = WriteChunkBytes(PrefsHandle, &NumEntries, sizeof(UWORD))) == sizeof(UWORD))
  897.                         {
  898.                             while(NumEntries-- && NoErr)
  899.                             {
  900.                                 UWORD    EntryType = ThisEntry->Link.ln_Type;
  901.  
  902.                                 if((Error = WriteChunkBytes(PrefsHandle, &EntryType, sizeof(UWORD))) == sizeof(UWORD))
  903.                                 {
  904.                                     if((Error = WriteChunkBytes(PrefsHandle, &ThisEntry->VolName, 130)) == 130)
  905.                                     {
  906.                                         if((Error = WriteChunkBytes(PrefsHandle, &ThisEntry->IconName, 256)) == 256)
  907.                                         {
  908.                                             if((Error = WriteChunkBytes(PrefsHandle, &ThisEntry->Left, (sizeof(UWORD) * 4))) != (sizeof(UWORD) * 4))
  909.                                                 NoErr = FALSE;
  910.                                         }
  911.                                     }
  912.                                 }
  913.  
  914.                                 ThisEntry = (struct VolEntry *)ThisEntry->Link.ln_Succ;
  915.                             }
  916.  
  917.                             if(NoErr)
  918.                             {
  919.                                 if(!(Error = PopChunk(PrefsHandle)))
  920.                                     GoOn = TRUE;
  921.                             }
  922.                         }
  923.                     }
  924.                 }
  925.  
  926.                 if((Error = PopChunk(PrefsHandle)))
  927.                     GoOn = FALSE;
  928.  
  929.                 CloseIFF(PrefsHandle);
  930.             }
  931.  
  932.             Close(PrefsHandle->iff_Stream);
  933.         }
  934.         else
  935.             Error = IoErr();
  936.  
  937.         FreeIFF(PrefsHandle);
  938.     }
  939.     else
  940.         Error = ERR_NOMEM;
  941.  
  942.     if(!GoOn)
  943.         DisplayError(Error, (ULONG)PrefsName, NULL);
  944.  
  945.     return(GoOn);
  946. }
  947.  
  948.  
  949.  
  950.  
  951.  
  952.  
  953.  
  954. /**********************************************************************/
  955. /*                          Load in settings                          */
  956. /**********************************************************************/
  957. void LoadPrefs(void)
  958. {
  959.         // Try env: first, then envarc:
  960.     if(!DoLoadPrefs("ENV:ForceIcon_prefs.iff"))
  961.         DoLoadPrefs("ENVARC:ForceIcon_prefs.iff");
  962. }
  963. BOOL DoLoadPrefs(char *PrefsName)
  964. {
  965.     struct    IFFHandle    *PrefsHandle;
  966.     struct    StoredProperty    *SP;
  967.     UWORD    *VersCheck;
  968.     LONG    Error;
  969.     BOOL    GoOn = FALSE;
  970.  
  971.         // Initialize Lists first
  972.  
  973.     NewList(&VolumeList);
  974.     VolumeList.lh_Type = 0;
  975.  
  976.         // Get Prefs Handle
  977.  
  978.     if((PrefsHandle = AllocIFF()))
  979.     {
  980.             // Open file
  981.  
  982.         if((PrefsHandle->iff_Stream = Open(PrefsName, MODE_OLDFILE)))
  983.         {
  984.                 // Init handle
  985.  
  986.             InitIFFasDOS(PrefsHandle);
  987.  
  988.                 // Open Handle
  989.  
  990.             if(!(Error = OpenIFF(PrefsHandle, IFFF_READ)))
  991.             {
  992.                     // Search for version chunk
  993.  
  994.                 if(!(Error = PropChunk(PrefsHandle, 'FOIC', 'VERS')))
  995.                 {
  996.                         // Stop at prefs
  997.  
  998.                     if(!(Error = StopChunk(PrefsHandle, 'FOIC', 'PREF')))
  999.                     {
  1000.                             // Start parsing
  1001.  
  1002.                         if(!(Error = ParseIFF(PrefsHandle, IFFPARSE_SCAN)))
  1003.                         {
  1004.                                 // Try to find version chunk
  1005.  
  1006.                             if((SP = FindProp(PrefsHandle, 'FOIC', 'VERS')))
  1007.                             {
  1008.                                 VersCheck = (UWORD *)SP->sp_Data;
  1009.  
  1010.                                     // Check Version number
  1011.  
  1012.                                 if(((*VersCheck) <= VERNUM) && ((*(VersCheck+1)) <= REVNUM))
  1013.                                 {
  1014.                                     struct    VolEntry    *ThisEntry;
  1015.                                     UWORD    NumEntries, EntryType;
  1016.                                     BOOL    NoErr = TRUE;
  1017.  
  1018.                                         // Read in prefs
  1019.  
  1020.                                     if((Error = ReadChunkBytes(PrefsHandle, &NumEntries, sizeof(UWORD))) == sizeof(UWORD))
  1021.                                     {
  1022.                                         VolumeList.lh_Type = NumEntries;
  1023.  
  1024.                                         while(NumEntries-- && NoErr)
  1025.                                         {
  1026.                                             if((ThisEntry = AllocVec(sizeof(struct VolEntry), MEMF_CLEAR)))
  1027.                                             {
  1028.                                                 AddTail(&VolumeList, (struct Node *)ThisEntry);
  1029.                                                 ThisEntry->Link.ln_Name = ThisEntry->VolName;
  1030.  
  1031.                                                 if((Error = ReadChunkBytes(PrefsHandle, &EntryType, sizeof(UWORD))) == sizeof(UWORD))
  1032.                                                 {
  1033.                                                     ThisEntry->Link.ln_Type = EntryType;
  1034.  
  1035.                                                     if((Error = ReadChunkBytes(PrefsHandle, &ThisEntry->VolName, 130)) == 130)
  1036.                                                     {
  1037.                                                         if((Error = ReadChunkBytes(PrefsHandle, &ThisEntry->IconName, 256)) == 256)
  1038.                                                         {
  1039.                                                             if((Error = ReadChunkBytes(PrefsHandle, &ThisEntry->Left, (sizeof(UWORD) * 4))) != (sizeof(UWORD) * 4))
  1040.                                                                 NoErr = FALSE;
  1041.                                                         }
  1042.                                                     }
  1043.                                                 }
  1044.                                             }
  1045.                                             else
  1046.                                                 NoErr = FALSE;
  1047.                                         }
  1048.                                         GoOn = NoErr;
  1049.                                     }
  1050.  
  1051.                                     if(!NoErr)
  1052.                                         Error = IoErr();
  1053.                                 }
  1054.                             }
  1055.                         }
  1056.                     }
  1057.                 }
  1058.                 CloseIFF(PrefsHandle);
  1059.             }
  1060.  
  1061.             Close(PrefsHandle->iff_Stream);
  1062.         }
  1063.         else
  1064.             Error = IoErr();
  1065.  
  1066.         FreeIFF(PrefsHandle);
  1067.     }
  1068.     else
  1069.         Error = ERR_NOMEM;
  1070.  
  1071.     if(!GoOn && Error != ERROR_OBJECT_NOT_FOUND)
  1072.         DisplayError(Error, (ULONG)PrefsName);
  1073.  
  1074.  
  1075.     return(GoOn);
  1076. }
  1077.  
  1078.  
  1079.  
  1080.  
  1081.  
  1082.  
  1083.  
  1084. /**********************************************************************/
  1085. /*                           Get a filename                           */
  1086. /**********************************************************************/
  1087. BOOL GetFileName(struct Window *Window, char *Title, char *FileName)
  1088. {
  1089.     struct    Rectangle    ScrRec;
  1090.     struct    FileRequester    *FileReq;
  1091.     char    Drawer[256],
  1092.         File[256];
  1093.     UWORD    Left, Top, Width, Height, i;
  1094.     BOOL    Result = FALSE;
  1095.  
  1096.     if(QueryOverscan(GetVPModeID(&Window->WScreen->ViewPort), &ScrRec, OSCAN_TEXT))
  1097.     {
  1098.         Width    = ((ScrRec.MaxX - ScrRec.MinX + 1) * 45) / 100;
  1099.         Height    = ((ScrRec.MaxY - ScrRec.MinY + 1) * 8) / 10;
  1100.         Left    = (((ScrRec.MaxX + 1) - Width) >> 1) - Window->WScreen->LeftEdge;
  1101.         Top    = (((ScrRec.MaxY + 1) - Height) >> 1) - Window->WScreen->TopEdge;
  1102.  
  1103.             // Get initial path
  1104.  
  1105.         if(PathPart(FileName) != (UBYTE *)&FileName[0])
  1106.         {
  1107.             for(i = 0; i < 256; i++)
  1108.                 Drawer[i] = '\0';
  1109.             strncpy(Drawer, FileName, (PathPart(FileName) - FileName));
  1110.         }
  1111.         else
  1112.             strcpy(Drawer, "");
  1113.  
  1114.             // Get FileName
  1115.  
  1116.         strcpy(File, FilePart(FileName));
  1117.  
  1118.         if((FileReq = AllocAslRequestTags(ASL_FileRequest,
  1119.             ASLFR_Screen,        Window->WScreen,
  1120.             ASLFR_Window,        Window,
  1121.             ASLFR_PrivateIDCMP,    TRUE,
  1122.             ASLFR_SleepWindow,     TRUE,
  1123.             ASLFR_TitleText,    Title,
  1124.             ASLFR_InitialDrawer,    (ULONG)Drawer,
  1125.             ASLFR_InitialFile,    (ULONG)File,
  1126.             ASLFR_InitialLeftEdge,    Left,
  1127.             ASLFR_InitialTopEdge,    Top,
  1128.             ASLFR_InitialWidth,    Width,
  1129.             ASLFR_InitialHeight,    Height,
  1130.             ASLFR_InitialPattern,    "#?.info",
  1131.         TAG_DONE)))
  1132.         {
  1133.             if(AslRequest(FileReq, NULL) && (strlen(FileReq->fr_File)))
  1134.             {
  1135.                     // Remove filetypes
  1136.  
  1137.                 strcpy(FileName, "");
  1138.  
  1139.                 AddPart(FileName, FileReq->fr_Drawer, 256);
  1140.                 AddPart(FileName, FileReq->fr_File, 256);
  1141.  
  1142.                 Result = TRUE;
  1143.             }
  1144.  
  1145.             FreeAslRequest(FileReq);
  1146.         }
  1147.     }
  1148.  
  1149.     return(Result);
  1150. }
  1151.  
  1152.  
  1153.  
  1154. /**********************************************************************/
  1155. /*        Check for existance of a volume within the user list        */
  1156. /**********************************************************************/
  1157. BOOL CheckExists(char *Name)
  1158. {
  1159.     BOOL    RetVal = FALSE;
  1160.  
  1161.     ObtainSemaphore(&MySemaphore);
  1162.  
  1163.     if(!IsListEmpty(&VolumeList))
  1164.     {
  1165.         struct    VolEntry    *ThisEntry    = (struct VolEntry *)VolumeList.lh_Head;
  1166.  
  1167.         do
  1168.         {
  1169.             if(!stricmp(ThisEntry->VolName, Name))
  1170.                 RetVal = TRUE;
  1171.  
  1172.             ThisEntry = (struct VolEntry *)ThisEntry->Link.ln_Succ;
  1173.         } while(!RetVal && ThisEntry->Link.ln_Succ);
  1174.     }
  1175.  
  1176.     ReleaseSemaphore(&MySemaphore);
  1177.  
  1178.     return(RetVal);
  1179. }
  1180.  
  1181.  
  1182.  
  1183.  
  1184. /**********************************************************************/
  1185. /*             Sort the complete list of devices/volumes              */
  1186. /**********************************************************************/
  1187. void SortList(struct List *VolList, BOOL DisplayType)
  1188. {
  1189.     UWORD    First, Last;
  1190.  
  1191.     if(DisplayType)
  1192.     {
  1193.         First    = LDF_VOLUMES;
  1194.         Last    = LDF_DEVICES;
  1195.     }
  1196.     else
  1197.     {
  1198.         First    = LDF_DEVICES;
  1199.         Last    = LDF_VOLUMES;
  1200.     }
  1201.  
  1202.         // Sort partial lists within one list
  1203.  
  1204.     if(!IsListEmpty(VolList))
  1205.     {
  1206.         struct    VolEntry    *ThisEntry    = (struct VolEntry *)VolList->lh_Head;
  1207.         UWORD    NumEntries            = VolList->lh_Type;
  1208.         UWORD    Left = 0, Right = 0;
  1209.  
  1210.             // Find boundaries of first type of entries
  1211.  
  1212.         while(ThisEntry->Link.ln_Type == First && NumEntries)
  1213.         {
  1214.             Right++;
  1215.             NumEntries--;
  1216.             ThisEntry = (struct VolEntry *)ThisEntry->Link.ln_Succ;
  1217.         }
  1218.  
  1219.             // Sort`em
  1220.  
  1221.         if(Left < Right)
  1222.         {
  1223.             SortPartialList(VolList, Left, Right);
  1224.             Left = Right;
  1225.         }
  1226.  
  1227.             // Look for second type of entries
  1228.  
  1229.         while(ThisEntry->Link.ln_Type == Last && NumEntries)
  1230.         {
  1231.             Right++;
  1232.             NumEntries--;
  1233.             ThisEntry = (struct VolEntry *)ThisEntry->Link.ln_Succ;
  1234.         }
  1235.  
  1236.             // Sort`em
  1237.  
  1238.         if(Left < Right)
  1239.             SortPartialList(VolList, Left, Right);
  1240.     }
  1241. }
  1242.  
  1243.  
  1244.  
  1245. /**********************************************************************/
  1246. /*            Sort partial list, either devices or volumes            */
  1247. /**********************************************************************/
  1248. static void SortPartialList(struct List *VolList, UWORD Left, UWORD Right)
  1249. {
  1250.     UWORD    i, j;
  1251.  
  1252.         // This is a simply Insertion Sort
  1253.         // I don`t think that there will be too many entries,
  1254.         // so this algorithm will do it. (IMHO)
  1255.  
  1256.     for(i = Left + 1; i < Right; i++)
  1257.     {
  1258.         struct    VolEntry    Spare, *CheckEntry;
  1259.  
  1260.             j = i;
  1261.  
  1262.             Spare        = *((struct VolEntry *)GetListEntry(VolList, i));
  1263.             CheckEntry    = (struct VolEntry *)GetListEntry(VolList, j - 1);
  1264.  
  1265.             while(stricmp(CheckEntry->VolName, Spare.VolName) > 0 && j > Left)
  1266.             {
  1267.                 struct    VolEntry    *RightEntry = (struct VolEntry *)CheckEntry->Link.ln_Succ;
  1268.  
  1269.                 strcpy(RightEntry->VolName, CheckEntry->VolName);
  1270.                 strcpy(RightEntry->IconName, CheckEntry->IconName);
  1271.                 RightEntry->Left    = CheckEntry->Left;
  1272.                 RightEntry->Top        = CheckEntry->Top;
  1273.                 RightEntry->UseAlt    = CheckEntry->UseAlt;
  1274.  
  1275.                 j--;
  1276.                 CheckEntry = (struct VolEntry *)CheckEntry->Link.ln_Pred;
  1277.             }
  1278.  
  1279.             CheckEntry = (struct VolEntry *)GetListEntry(VolList, j);
  1280.             strcpy(CheckEntry->VolName, Spare.VolName);
  1281.             strcpy(CheckEntry->IconName, Spare.IconName);
  1282.             CheckEntry->Left    = Spare.Left;
  1283.             CheckEntry->Top        = Spare.Top;
  1284.             CheckEntry->UseAlt    = Spare.UseAlt;
  1285.     }
  1286. }
  1287.