home *** CD-ROM | disk | FTP | other *** search
/ The Best of Mecomp Multimedia 1 / Mecomp-CD.iso / amiga / tools / system / shutdown / libcode.c < prev    next >
C/C++ Source or Header  |  1993-03-01  |  19KB  |  925 lines

  1. /*
  2. **    Shutdown 2.0 package, LibCode.c module
  3. **
  4. **    Copyright © 1992 by Olaf `Olsen' Barthel
  5. **        All Rights Reserved
  6. */
  7.  
  8. #include "ShutdownGlobal.h"
  9.  
  10.     /* Gadget IDs... */
  11.  
  12. enum    {    GAD_LIST, GAD_RETURN, GAD_SHUTDOWN };
  13.  
  14.     /* User interface data. */
  15.  
  16. STATIC struct Window            *Window;
  17. STATIC struct Screen            *Screen;
  18. STATIC APTR                 VisualInfo;
  19. STATIC struct Gadget            *GadgetList,
  20.                     *GadgetArray[GAD_SHUTDOWN + 1];
  21. STATIC struct RastPort            *RPort;
  22.  
  23. STATIC struct List             FileList;
  24.  
  25. STATIC BYTE                 Blocking    = FALSE,
  26.                      Accessing    = FALSE,
  27.                      WindowMode;
  28.  
  29. STATIC UWORD                 ButtonWidth,
  30.                      DisplayWidth,
  31.                      FontHeight,
  32.                      WindowWidth,
  33.                      WindowHeight;
  34.  
  35. STATIC BYTE DisplayStrings[7] =
  36. {
  37.     MSG_TURNOFF_TXT, MSG_WAIT_A_MINUTE_TXT, MSG_FILESOPEN1_TXT,
  38.     MSG_FILESOPEN2_TXT, MSG_WORKING1_TXT, MSG_WORKING2_TXT,
  39.     MSG_RESET_TXT
  40. };
  41.  
  42. STATIC struct TextAttr *DisplayFont;
  43.  
  44. STATIC struct IntuiText ResetText =
  45. {
  46.     1,0,
  47.     JAM1,
  48.     0,0,
  49.     NULL,
  50.     NULL,
  51.     NULL
  52. };
  53.  
  54. STATIC UWORD __chip BlankSprite[(2 + 1) * 2] =
  55. {
  56.     0x0000,0x0000,
  57.  
  58.     0x0000,0x0000,
  59.  
  60.     0x0000,0x0000
  61. };
  62.  
  63. STATIC UWORD __chip Stopwatch[(2 + 16) * 2] =
  64. {
  65.     0x0000,0x0000,
  66.  
  67.     0x0400,0x07C0,
  68.     0x0000,0x07C0,
  69.     0x0100,0x0380,
  70.     0x0000,0x07E0,
  71.     0x07C0,0x1FF8,
  72.     0x1FF0,0x3FEC,
  73.     0x3FF8,0x7FDE,
  74.     0x3FF8,0x7FBE,
  75.     0x7FFC,0xFF7F,
  76.     0x7EFC,0xFFFF,
  77.     0x7FFC,0xFFFF,
  78.     0x3FF8,0x7FFE,
  79.     0x3FF8,0x7FFE,
  80.     0x1FF0,0x3FFC,
  81.     0x07C0,0x1FF8,
  82.     0x0000,0x07E0,
  83.  
  84.     0x0000,0x0000
  85. };
  86.  
  87.     /* Local routines for this module. */
  88.  
  89. STATIC VOID __regargs        CloseDown(BYTE Fast);
  90. STATIC VOID __regargs        ClearList(struct List *List);
  91. STATIC struct Node * __regargs    CreateNode(STRPTR Name);
  92. STATIC VOID __regargs        ShowText(STRPTR String);
  93. STATIC BYTE __regargs        OpenShutdownWindow(BYTE Mode);
  94. STATIC struct Gadget *        CreateAllGadgets(struct Gadget **GadgetArray,struct Gadget **GadgetList,BYTE UseList);
  95. STATIC VOID            CloseAll(VOID);
  96.  
  97. STATIC VOID __regargs
  98. CloseDown(BYTE Fast)
  99. {
  100.     STATIC struct Requester Requester;
  101.  
  102.     struct FileInfo        *Node,
  103.                 *Next;
  104.  
  105.     struct ShutdownInfo    *Info,
  106.                 *NextInfo;
  107.  
  108.     STRPTR             Message;
  109.  
  110.     ReleaseSemaphore(&GlobalBase -> DevBlockLock);
  111.  
  112.     ObtainSemaphore(&DeviceWatchSemaphore);
  113.  
  114.     if(DeviceInUse)
  115.         Message = GetString(MSG_WAIT_A_MINUTE_TXT);
  116.     else
  117.     {
  118.         if(!Fast)
  119.             Message = GetString(MSG_TURNOFF_TXT);
  120.         else
  121.             Message = NULL;
  122.     }
  123.  
  124.     ReleaseSemaphore(&DeviceWatchSemaphore);
  125.  
  126.     if(Message)
  127.         ShowText(Message);
  128.  
  129.     if(!Fast)
  130.         SetPointer(Window,&Stopwatch[0],16,16,-6,0);
  131.  
  132.     memset(&Requester,0,sizeof(struct Requester));
  133.  
  134.     Request(&Requester,Window);
  135.  
  136.     ObtainSemaphore(&GlobalBase -> AccessLock);
  137.  
  138.     GlobalBase -> Closing = TRUE;
  139.  
  140.     Info = (struct ShutdownInfo *)GlobalBase -> ShutdownList . mlh_Head;
  141.  
  142.     ReleaseSemaphore(&GlobalBase -> AccessLock);
  143.  
  144.     if(Info -> sdi_Node . mln_Succ)
  145.     {
  146.         ULONG Mode;
  147.  
  148.         GlobalBase -> Shutdown = FALSE;
  149.  
  150.         ReleaseSemaphore(&GlobalBase -> BlockLock);
  151.  
  152.         while(NextInfo = (struct ShutdownInfo *)Info -> sdi_Node . mln_Succ)
  153.         {
  154.             Mode = SD_EXIT;
  155.  
  156.             if(Fast)
  157.                 CallHook(Info -> sdi_Hook,&Mode,SDF_RESET);
  158.             else
  159.                 CallHook(Info -> sdi_Hook,&Mode,NULL);
  160.  
  161.             Info = NextInfo;
  162.         }
  163.  
  164.         ObtainSemaphore(&GlobalBase -> BlockLock);
  165.  
  166.         GlobalBase -> Shutdown = TRUE;
  167.     }
  168.  
  169.     ObtainSemaphore(&GlobalBase -> AccessLock);
  170.  
  171.     Node = (struct FileInfo *)GlobalBase -> AccessList . mlh_Head;
  172.  
  173.     while(Next = (struct FileInfo *)Node -> Node . mln_Succ)
  174.     {
  175.         if(Node -> Accesses && Node -> Handle)
  176.             Flush(Node -> Handle);
  177.  
  178.         Node = Next;
  179.     }
  180.  
  181.     ReleaseSemaphore(&GlobalBase -> AccessLock);
  182.  
  183.     ObtainSemaphore(&DeviceWatchSemaphore);
  184.  
  185.     if(DeviceInUse)
  186.         Message = GetString(MSG_WAIT_A_MINUTE_TXT);
  187.     else
  188.     {
  189.         if(Fast)
  190.             Message = GetString(MSG_RESET_TXT);
  191.         else
  192.             Message = GetString(MSG_TURNOFF_TXT);
  193.     }
  194.  
  195.     ReleaseSemaphore(&DeviceWatchSemaphore);
  196.  
  197.     ShowText(Message);
  198.  
  199.     Forbid();
  200.  
  201.     GlobalBase -> DevShutdown = TRUE;
  202.  
  203.     Wait(SIG_NOTIFY);
  204.  
  205.     ObtainSemaphore(&GlobalBase -> DevBlockLock);
  206.  
  207.     if(Fast)
  208.         ShowText(GetString(MSG_RESET_TXT));
  209.     else
  210.         ShowText(GetString(MSG_TURNOFF_TXT));
  211.  
  212.     TimeDelay(UNIT_VBLANK,1,0);
  213.  
  214.     ColdReboot();
  215. }
  216.  
  217. STATIC VOID __regargs
  218. ClearList(struct List *List)
  219. {
  220.     struct Node    *Node,
  221.             *Next;
  222.  
  223.     Node = List -> lh_Head;
  224.  
  225.     while(Next = Node -> ln_Succ)
  226.     {
  227.         Remove(Node);
  228.  
  229.         FreeVec(Node);
  230.  
  231.         Node = Next;
  232.     }
  233. }
  234.  
  235. STATIC struct Node * __regargs
  236. CreateNode(STRPTR Name)
  237. {
  238.     struct Node *Node;
  239.  
  240.     if(Node = (struct Node *)AllocVec(sizeof(struct Node) + strlen(Name) + 1,MEMF_ANY | MEMF_CLEAR))
  241.     {
  242.         Node -> ln_Name = (STRPTR)(Node + 1);
  243.  
  244.         strcpy(Node -> ln_Name,Name);
  245.     }
  246.  
  247.     return(Node);
  248. }
  249.  
  250. STATIC VOID __regargs
  251. ShowText(STRPTR String)
  252. {
  253.     ResetText . ITextFont    = DisplayFont;
  254.     ResetText . IText    = String;
  255.  
  256.     ClipBlit(Window -> RPort,0,0,Window -> RPort,Screen -> WBorLeft + INTERWIDTH + 2,Screen -> WBorTop + INTERHEIGHT + 1,DisplayWidth - 4,INTERHEIGHT + FontHeight + INTERHEIGHT,0x00);
  257.  
  258.     PrintIText(Window -> RPort,&ResetText,(Window -> Width - IntuiTextLength(&ResetText)) / 2,Screen -> WBorTop + INTERHEIGHT + 1 + INTERHEIGHT);
  259. }
  260.  
  261. STATIC BYTE __regargs
  262. OpenShutdownWindow(BYTE Mode)
  263. {
  264.     STRPTR Message;
  265.  
  266.     WindowWidth = Screen -> WBorLeft + INTERWIDTH + DisplayWidth + INTERWIDTH + Screen -> WBorRight;
  267.  
  268.     switch(Mode)
  269.     {
  270.         case MODE_SHUTDOWN:    WindowHeight = Screen -> WBorTop + INTERHEIGHT + 1 + INTERHEIGHT + FontHeight + INTERHEIGHT + 1 + INTERHEIGHT + 2 + FontHeight + 2 + INTERHEIGHT + Screen -> WBorBottom;
  271.                     break;
  272.  
  273.         case MODE_RESET:
  274.         case MODE_FASTRESET:    WindowHeight = Screen -> WBorTop + INTERHEIGHT + 1 + INTERHEIGHT + FontHeight + INTERHEIGHT + 1 + INTERHEIGHT + Screen -> WBorBottom;
  275.                     break;
  276.  
  277.         default:        WindowHeight = Screen -> WBorTop + INTERHEIGHT + 1 + INTERHEIGHT + FontHeight + INTERHEIGHT + 1 + INTERHEIGHT + 2 + 16 * FontHeight + 2 + INTERHEIGHT + 2 + FontHeight + 2 + INTERHEIGHT + Screen -> WBorBottom;
  278.                     break;
  279.     }
  280.  
  281.     if(WindowWidth > Screen -> Width || WindowHeight > Screen -> Height)
  282.         return(FALSE);
  283.  
  284.     WindowMode = Mode;
  285.  
  286.     switch(Mode)
  287.     {
  288.         case MODE_SHUTDOWN:    if(!CreateAllGadgets(&GadgetArray[0],&GadgetList,FALSE))
  289.                     {
  290.                         FreeGadgets(GadgetList);
  291.  
  292.                         return(FALSE);
  293.                     }
  294.                     else
  295.                         break;
  296.  
  297.         case MODE_LIST:
  298.         case MODE_NAME:        if(!CreateAllGadgets(&GadgetArray[0],&GadgetList,TRUE))
  299.                     {
  300.                         FreeGadgets(GadgetList);
  301.  
  302.                         return(FALSE);
  303.                     }
  304.                     else
  305.                         break;
  306.  
  307.         default:        GadgetList = NULL;
  308.                     break;
  309.     }
  310.  
  311.     if(!(Window = OpenWindowTags(NULL,
  312.         WA_Left,        (Screen -> Width - WindowWidth) / 2,
  313.         WA_Top,            (Screen -> Height - WindowHeight) / 2,
  314.         WA_Width,        WindowWidth,
  315.         WA_Height,        WindowHeight,
  316.         WA_IDCMP,        IDCMP_VANILLAKEY | BUTTONIDCMP | LISTVIEWIDCMP,
  317.         WA_RMBTrap,        TRUE,
  318.         WA_CustomScreen,    Screen,
  319.     TAG_DONE)))
  320.         return(FALSE);
  321.  
  322.     ScreenToFront(Screen);
  323.  
  324.     switch(Mode)
  325.     {
  326.         case MODE_SHUTDOWN:    ObtainSemaphore(&DeviceWatchSemaphore);
  327.  
  328.                     if(DeviceInUse)
  329.                         Message = GetString(MSG_WAIT_A_MINUTE_TXT);
  330.                     else
  331.                         Message = GetString(MSG_TURNOFF_TXT);
  332.  
  333.                     ReleaseSemaphore(&DeviceWatchSemaphore);
  334.  
  335.                     break;
  336.  
  337.         case MODE_LIST:        if(FileList . lh_Head -> ln_Succ -> ln_Succ)
  338.                         Message = GetString(MSG_FILESOPEN2_TXT);
  339.                     else
  340.                         Message = GetString(MSG_FILESOPEN1_TXT);
  341.  
  342.                     break;
  343.  
  344.         case MODE_NAME:        if(FileList . lh_Head -> ln_Succ -> ln_Succ)
  345.                         Message = GetString(MSG_WORKING2_TXT);
  346.                     else
  347.                         Message = GetString(MSG_WORKING1_TXT);
  348.  
  349.                     break;
  350.  
  351.         case MODE_RESET:    Message = GetString(MSG_RESET_TXT);
  352.  
  353.                     SetPointer(Window,BlankSprite,1,16,0,0);
  354.  
  355.                     break;
  356.  
  357.         case MODE_FASTRESET:    ObtainSemaphore(&DeviceWatchSemaphore);
  358.  
  359.                     if(DeviceInUse)
  360.                         Message = GetString(MSG_WAIT_A_MINUTE_TXT);
  361.                     else
  362.                         Message = GetString(MSG_RESET_TXT);
  363.  
  364.                     ReleaseSemaphore(&DeviceWatchSemaphore);
  365.  
  366.                     SetPointer(Window,BlankSprite,1,16,0,0);
  367.  
  368.                     break;
  369.     }
  370.  
  371.     if(GadgetList)
  372.     {
  373.         AddGList(Window,GadgetList,(UWORD)-1,(UWORD)-1,NULL);
  374.         RefreshGList(GadgetList,Window,NULL,(UWORD)-1);
  375.         GT_RefreshWindow(Window,NULL);
  376.     }
  377.  
  378.     DrawBevelBox(Window -> RPort,Screen -> WBorLeft + INTERWIDTH,Screen -> WBorTop + INTERHEIGHT,DisplayWidth,1 + INTERHEIGHT + FontHeight + INTERHEIGHT + 1,
  379.         GTBB_Recessed,    TRUE,
  380.         GT_VisualInfo,    VisualInfo,
  381.     TAG_DONE);
  382.  
  383.     ShowText(Message);
  384.  
  385.     return(TRUE);
  386. }
  387.  
  388. STATIC struct Gadget *
  389. CreateAllGadgets(struct Gadget **GadgetArray,struct Gadget **GadgetList,BYTE UseList)
  390. {
  391.     struct Gadget        *Gadget;
  392.     struct NewGadget     NewGadget;
  393.     UWORD             Counter;
  394.  
  395.     memset(&NewGadget,0,sizeof(struct NewGadget));
  396.  
  397.     if(Gadget = CreateContext(GadgetList))
  398.     {
  399.         NewGadget . ng_TextAttr        = DisplayFont;
  400.         NewGadget . ng_VisualInfo    = VisualInfo;
  401.         NewGadget . ng_Flags        = NULL;
  402.  
  403.         if(UseList)
  404.         {
  405.             Counter = 0;
  406.  
  407.             NewGadget . ng_LeftEdge        = Screen -> WBorLeft + INTERWIDTH;
  408.             NewGadget . ng_TopEdge        = Screen -> WBorTop + INTERHEIGHT + 1 + INTERHEIGHT + FontHeight + INTERHEIGHT + 1 + INTERHEIGHT;
  409.             NewGadget . ng_GadgetID        = Counter;
  410.             NewGadget . ng_Width        = DisplayWidth;
  411.             NewGadget . ng_Height        = 2 + 16 * FontHeight + 2;
  412.  
  413.             GadgetArray[Counter++] = Gadget = CreateGadget(LISTVIEW_KIND,Gadget,&NewGadget,
  414.                 GTLV_Labels,    &FileList,
  415.                 GTLV_ReadOnly,    TRUE,
  416.             TAG_DONE);
  417.  
  418.             NewGadget . ng_TopEdge        = NewGadget . ng_TopEdge + NewGadget . ng_Height + INTERHEIGHT;
  419.         }
  420.         else
  421.         {
  422.             Counter = GAD_RETURN;
  423.  
  424.             NewGadget . ng_LeftEdge        = Screen -> WBorLeft + INTERWIDTH;
  425.             NewGadget . ng_TopEdge        = Screen -> WBorTop + INTERHEIGHT + 1 + INTERHEIGHT + FontHeight + INTERHEIGHT + 1 + INTERHEIGHT;
  426.         }
  427.  
  428.         NewGadget . ng_GadgetText    = GetString(MSG_RETURN_TXT);
  429.         NewGadget . ng_GadgetID        = Counter;
  430.         NewGadget . ng_Width        = ButtonWidth;
  431.         NewGadget . ng_Height        = 2 + FontHeight + 2;
  432.  
  433.         GadgetArray[Counter++] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
  434.             GT_Underscore,    '_',
  435.         TAG_DONE);
  436.  
  437.         NewGadget . ng_GadgetText    = GetString(MSG_RESTART_TXT);
  438.         NewGadget . ng_GadgetID        = Counter;
  439.         NewGadget . ng_LeftEdge        = WindowWidth - (Screen -> WBorLeft + INTERWIDTH + NewGadget . ng_Width);
  440.  
  441.         GadgetArray[Counter] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
  442.             GT_Underscore,    '_',
  443.         TAG_DONE);
  444.     }
  445.  
  446.     return(Gadget);
  447. }
  448.  
  449. STATIC VOID
  450. CloseAll()
  451. {
  452.     MainProcess = NULL;
  453.  
  454.     if(NotifySignal)
  455.     {
  456.         SetSignal(0,SIG_NOTIFY);
  457.  
  458.         FreeSignal(NotifySignal);
  459.     }
  460.  
  461.     if(Window)
  462.         CloseWindow(Window);
  463.  
  464.     if(Screen)
  465.         CloseScreen(Screen);
  466.  
  467.     if(GadgetList)
  468.         FreeGadgets(GadgetList);
  469.  
  470.     if(VisualInfo)
  471.         FreeVisualInfo(VisualInfo);
  472.  
  473.     ClearList(&FileList);
  474.  
  475.     if(Blocking)
  476.     {
  477.         Forbid();
  478.  
  479.         GlobalBase -> Shutdown = FALSE;
  480.  
  481.         ReleaseSemaphore(&GlobalBase -> BlockLock);
  482.         ReleaseSemaphore(&GlobalBase -> DevBlockLock);
  483.  
  484.         Permit();
  485.     }
  486.  
  487.     if(Accessing)
  488.         ReleaseSemaphore(&GlobalBase -> AccessLock);
  489. }
  490.  
  491. BYTE
  492. OpenAll(BYTE Mode)
  493. {
  494.     struct Screen    *PublicScreen;
  495.     ULONG         DisplayID;
  496.     UWORD         Dummy = (UWORD)~0,Depth;
  497.     BYTE         Done = TRUE;
  498.     UBYTE         Char;
  499.     UWORD         MaxWidth = 0,
  500.              Width,
  501.              i;
  502.     STRPTR         String;
  503.  
  504.     NewList(&FileList);
  505.  
  506.     if(!(PublicScreen = LockPubScreen(NULL)))
  507.         return(FALSE);
  508.  
  509.     DisplayID = GetVPModeID(&PublicScreen -> ViewPort);
  510.  
  511.     if((Depth = PublicScreen -> RastPort . BitMap -> Depth) > 2)
  512.         Depth = 2;
  513.  
  514.     UnlockPubScreen(NULL,PublicScreen);
  515.  
  516.     if(!(Screen = OpenScreenTags(NULL,
  517.         SA_Behind,                TRUE,
  518.         SA_Quiet,                TRUE,
  519.         SA_DisplayID,                DisplayID,
  520.         SA_Depth,                Depth,
  521.         SA_Overscan,                OSCAN_TEXT,
  522.         Depth > 1 ? SA_Pens : TAG_IGNORE,    &Dummy,
  523.         SA_SysFont,                1,
  524.     TAG_DONE)))
  525.         return(FALSE);
  526.  
  527.     RPort = &Screen -> RastPort;
  528.  
  529.     DisplayFont = Screen -> Font;
  530.  
  531.     for(i = 32 ; i < 127 ; i++)
  532.     {
  533.         Char = i;
  534.  
  535.         if((Width = TextLength(RPort,&Char,1)) > MaxWidth)
  536.             MaxWidth = Width;
  537.     }
  538.  
  539.     for(i = 160 ; i < 256 ; i++)
  540.     {
  541.         Char = i;
  542.  
  543.         if((Width = TextLength(RPort,&Char,1)) > MaxWidth)
  544.             MaxWidth = Width;
  545.     }
  546.  
  547.     ButtonWidth = TextLength(RPort,GetString(MSG_RETURN_TXT),strlen(GetString(MSG_RETURN_TXT)));
  548.  
  549.     if((Width = TextLength(RPort,GetString(MSG_RESTART_TXT),strlen(GetString(MSG_RESTART_TXT)))) > ButtonWidth)
  550.         ButtonWidth = Width;
  551.  
  552.     DisplayWidth = 4 + 32 * MaxWidth + 4 + 16;
  553.  
  554.     for(i = 0 ; i < 7 ; i++)
  555.     {
  556.         String = GetString(DisplayStrings[i]);
  557.  
  558.         if((Width = TextLength(RPort,String,strlen(String))) > DisplayWidth)
  559.             DisplayWidth = Width;
  560.     }
  561.  
  562.     ButtonWidth    += 2 * INTERWIDTH;
  563.     DisplayWidth    += 2 * INTERWIDTH;
  564.  
  565.     if(2 * ButtonWidth + INTERWIDTH > DisplayWidth)
  566.         DisplayWidth = 2 * ButtonWidth + INTERWIDTH;
  567.  
  568.     FontHeight = RPort -> Font -> tf_YSize;
  569.  
  570.     if(!(VisualInfo = GetVisualInfo(Screen,TAG_DONE)))
  571.         return(FALSE);
  572.  
  573.     if((NotifySignal = AllocSignal(-1)) == -1)
  574.         return(FALSE);
  575.  
  576.     switch(Mode)
  577.     {
  578.         case MODE_RESET:
  579.  
  580.             if(!OpenShutdownWindow(MODE_RESET))
  581.                 return(FALSE);
  582.             else
  583.                 break;
  584.  
  585.         case MODE_FASTRESET:
  586.  
  587.             Blocking = TRUE;
  588.  
  589.             ObtainSemaphore(&GlobalBase -> BlockLock);
  590.  
  591.             ObtainSemaphore(&GlobalBase -> DevBlockLock);
  592.  
  593.             GlobalBase -> Shutdown = TRUE;
  594.  
  595.             if(!OpenShutdownWindow(MODE_FASTRESET))
  596.                 return(FALSE);
  597.             else
  598.                 break;
  599.  
  600.         default:
  601.  
  602.             Blocking = Accessing = TRUE;
  603.  
  604.             ObtainSemaphore(&GlobalBase -> AccessLock);
  605.  
  606.             ObtainSemaphore(&GlobalBase -> BlockLock);
  607.  
  608.             ObtainSemaphore(&GlobalBase -> DevBlockLock);
  609.  
  610.             GlobalBase -> Shutdown = TRUE;
  611.  
  612.             if(GlobalBase -> ShutdownList . mlh_Head -> mln_Succ)
  613.             {
  614.                 struct ShutdownInfo    *Info,
  615.                             *NextInfo;
  616.  
  617.                 struct Node        *Node;
  618.                 ULONG             Mode;
  619.  
  620.                 Info = (struct ShutdownInfo *)GlobalBase -> ShutdownList . mlh_Head;
  621.  
  622.                 while(NextInfo = (struct ShutdownInfo *)Info -> sdi_Node . mln_Succ)
  623.                 {
  624.                     Mode = SD_CHECK;
  625.  
  626.                     if(!CallHook(Info -> sdi_Hook,&Mode,NULL))
  627.                     {
  628.                         if(Node = CreateNode(Info -> sdi_Name))
  629.                             AddTail(&FileList,Node);
  630.  
  631.                         Done = FALSE;
  632.                     }
  633.  
  634.                     Info = NextInfo;
  635.                 }
  636.             }
  637.  
  638.             if(Done)
  639.             {
  640.                 if(GlobalBase -> OpenCount)
  641.                 {
  642.                     struct Node     *New;
  643.                     struct FileInfo    *Node,
  644.                             *Next;
  645.  
  646.                     Node = (struct FileInfo *)GlobalBase -> AccessList . mlh_Head;
  647.  
  648.                     while(Next = (struct FileInfo *)Node -> Node . mln_Succ)
  649.                     {
  650.                         if(Node -> Accesses && !Node -> Ignore)
  651.                         {
  652.                             if(New = CreateNode(Node -> Name))
  653.                                 AddTail(&FileList,New);
  654.                         }
  655.  
  656.                         Node = Next;
  657.                     }
  658.  
  659.                     if(FileList . lh_Head -> ln_Succ)
  660.                     {
  661.                         if(!OpenShutdownWindow(MODE_LIST))
  662.                             return(FALSE);
  663.                     }
  664.                     else
  665.                     {
  666.                         if(!OpenShutdownWindow(MODE_SHUTDOWN))
  667.                             return(FALSE);
  668.                     }
  669.                 }
  670.                 else
  671.                 {
  672.                     if(!OpenShutdownWindow(MODE_SHUTDOWN))
  673.                         return(FALSE);
  674.                 }
  675.             }
  676.             else
  677.             {
  678.                 if(!OpenShutdownWindow(MODE_NAME))
  679.                     return(FALSE);
  680.             }
  681.  
  682.             ReleaseSemaphore(&GlobalBase -> AccessLock);
  683.  
  684.             Accessing = FALSE;
  685.  
  686.             break;
  687.     }
  688.  
  689.     ScreenToFront(Screen);
  690.     ActivateWindow(Window);
  691.  
  692.     return(TRUE);
  693. }
  694.  
  695. LONG __saveds __asm
  696. RexxDispatch(register __a0 struct RexxMsg *Message)
  697. {
  698.     STRPTR    Arg    = NULL;
  699.     LONG    Result    = RC_OK;
  700.  
  701.     if(GlobalBase -> Child)
  702.     {
  703.         if(!Stricmp(Message -> rm_Args[0],"shutdown"))
  704.         {
  705.             if(Message -> rm_Args[1])
  706.             {
  707.                 if(!Stricmp(Message -> rm_Args[1],"immediately"))
  708.                 {
  709.                     if(!Shutdown(SHUTDOWN_FAST))
  710.                         Result = RC_ERROR;
  711.                 }
  712.                 else
  713.                 {
  714.                     if(!Shutdown(SHUTDOWN_NORMAL))
  715.                         Result = RC_ERROR;
  716.                     else
  717.                         Arg = CreateArgstring("aborted",7);
  718.                 }
  719.             }
  720.             else
  721.             {
  722.                 if(!Shutdown(SHUTDOWN_NORMAL))
  723.                     Result = RC_ERROR;
  724.                 else
  725.                     Arg = CreateArgstring("aborted",7);
  726.             }
  727.         }
  728.         else
  729.             Result = 1;
  730.     }
  731.  
  732.     putreg(REG_A0,(LONG)Arg);
  733.  
  734.     return(Result);
  735. }
  736.  
  737. LONG __saveds __asm
  738. Shutdown(register __d0 ULONG Mode)
  739. {
  740.     if(!GlobalBase -> Child)
  741.         return(FALSE);
  742.     else
  743.     {
  744.         if(!AttemptSemaphore(&GlobalBase -> ShutdownLock))
  745.             return(FALSE);
  746.         else
  747.         {
  748.             if(Mode == SHUTDOWN_FAST)
  749.             {
  750.                 if(!OpenAll(MODE_FASTRESET))
  751.                 {
  752.                     CloseAll();
  753.  
  754.                     ReleaseSemaphore(&GlobalBase -> ShutdownLock);
  755.  
  756.                     return(FALSE);
  757.                 }
  758.                 else
  759.                 {
  760.                     MainProcess = (struct Process *)SysBase -> ThisTask;
  761.  
  762.                     CloseDown(TRUE);
  763.                 }
  764.             }
  765.  
  766.             if(Mode == SHUTDOWN_NORMAL)
  767.             {
  768.                 if(!OpenAll(MODE_SHUTDOWN))
  769.                 {
  770.                     CloseAll();
  771.  
  772.                     ReleaseSemaphore(&GlobalBase -> ShutdownLock);
  773.  
  774.                     return(FALSE);
  775.                 }
  776.                 else
  777.                 {
  778.                     struct IntuiMessage    *Massage;
  779.                     ULONG             InputClass,
  780.                                  Code,
  781.                                  SignalSet;
  782.                     struct Gadget        *Gadget;
  783.                     BYTE             Terminated = FALSE;
  784.  
  785.                     MainProcess = (struct Process *)SysBase -> ThisTask;
  786.  
  787.                     while(!Terminated)
  788.                     {
  789.                         SignalSet = Wait(SIG_WINDOW | SIG_NOTIFY);
  790.  
  791.                         if(SignalSet & SIG_NOTIFY)
  792.                         {
  793.                             if(WindowMode == MODE_SHUTDOWN)
  794.                             {
  795.                                 STRPTR Message;
  796.  
  797.                                 if(DeviceProbablyInUse)
  798.                                     Message = GetString(MSG_WAIT_A_MINUTE_TXT);
  799.                                 else
  800.                                     Message = GetString(MSG_TURNOFF_TXT);
  801.  
  802.                                 ShowText(Message);
  803.                             }
  804.                         }
  805.  
  806.                         if(SignalSet & SIG_WINDOW)
  807.                         {
  808.                             while(Massage = GT_GetIMsg(Window -> UserPort))
  809.                             {
  810.                                 InputClass    = Massage -> Class;
  811.                                 Code        = Massage -> Code;
  812.                                 Gadget        = (struct Gadget *)Massage -> IAddress;
  813.  
  814.                                 GT_ReplyIMsg(Massage);
  815.  
  816.                                 if(InputClass == IDCMP_VANILLAKEY)
  817.                                 {
  818.                                     UBYTE    *W_Code    = GetString(MSG_RETURN_SHORTCUT),
  819.                                         *R_Code    = GetString(MSG_RESTART_SHORTCUT);
  820.  
  821.                                     Code = ToUpper(Code);
  822.  
  823.                                     if(Code == *W_Code)
  824.                                         Terminated = TRUE;
  825.                                     else
  826.                                     {
  827.                                         if(Code == *R_Code)
  828.                                             CloseDown(FALSE);
  829.                                     }
  830.                                 }
  831.  
  832.                                 if(InputClass == IDCMP_GADGETUP)
  833.                                 {
  834.                                     switch(Gadget -> GadgetID)
  835.                                     {
  836.                                         case GAD_RETURN:    Terminated = TRUE;
  837.                                                     break;
  838.  
  839.                                         case GAD_SHUTDOWN:    CloseDown(FALSE);
  840.  
  841.                                         default:        break;
  842.                                     }
  843.                                 }
  844.                             }
  845.                         }
  846.                     }
  847.  
  848.                     CloseAll();
  849.  
  850.                     ReleaseSemaphore(&GlobalBase -> ShutdownLock);
  851.  
  852.                     return(TRUE);
  853.                 }
  854.             }
  855.         }
  856.     }
  857.  
  858.     return(FALSE);
  859. }
  860.  
  861. APTR __saveds __asm
  862. AddShutdownInfoTagList(register __a0 struct Hook *Hook,register __a1 STRPTR Name,register __a2 struct TagItem *TagList)
  863. {
  864.     if(!GlobalBase -> Closing)
  865.     {
  866.         if(Hook && Name && TagList)
  867.         {
  868.             struct ShutdownInfo    *Info;
  869.             LONG             Len = strlen(Name);
  870.  
  871.             if(Info = (struct ShutdownInfo *)AllocVec(sizeof(struct ShutdownInfo) + Len + 1,MEMF_PUBLIC | MEMF_CLEAR))
  872.             {
  873.                 ObtainSemaphore(&GlobalBase -> AccessLock);
  874.  
  875.                 Info -> sdi_Hook    = Hook;
  876.                 Info -> sdi_Name    = (STRPTR)(Info + 1);
  877.  
  878.                 strcpy(Info -> sdi_Name,Name);
  879.  
  880.                 AddTail((struct List *)&GlobalBase -> ShutdownList,(struct Node *)Info);
  881.  
  882.                 ReleaseSemaphore(&GlobalBase -> AccessLock);
  883.  
  884.                 return(Info);
  885.             }
  886.         }
  887.     }
  888.  
  889.     return(NULL);
  890. }
  891.  
  892. LONG __saveds __asm
  893. RemShutdownInfo(register __a0 struct ShutdownInfo *Info)
  894. {
  895.     if(!GlobalBase -> Closing && Info)
  896.     {
  897.         struct ShutdownInfo    *Node,
  898.                     *Next;
  899.  
  900.         ObtainSemaphore(&GlobalBase -> AccessLock);
  901.  
  902.         Node = (struct ShutdownInfo *)GlobalBase -> ShutdownList . mlh_Head;
  903.  
  904.         while(Next = (struct ShutdownInfo *)Node -> sdi_Node . mln_Succ)
  905.         {
  906.             if(Info == (struct ShutdownInfo *)Node)
  907.             {
  908.                 Remove((struct Node *)Info);
  909.  
  910.                 FreeVec(Info);
  911.  
  912.                 ReleaseSemaphore(&GlobalBase -> AccessLock);
  913.  
  914.                 return(TRUE);
  915.             }
  916.  
  917.             Node = Next;
  918.         }
  919.  
  920.         ReleaseSemaphore(&GlobalBase -> AccessLock);
  921.     }
  922.  
  923.     return(FALSE);
  924. }
  925.