home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Workbench / Misc / closew16.lha / CloseWB_1.6 / CloseWB.c next >
Encoding:
C/C++ Source or Header  |  1994-12-06  |  15.8 KB  |  551 lines

  1. ;/*
  2. sc DATA=FAR NMINC STRMERGE NOSTKCHK OPTSIZE NOSTDIO IGNORE=73 DEBUG=LINE CloseWB.c
  3. slink FROM LIB:c.o,CloseWB.o TO CloseWB LIBRARY LIB:sc.lib,LIB:Amiga.lib SC SD NOICONS STRIPDEBUG
  4. delete CloseWB.o
  5. quit
  6.  
  7.  CloseWB.c - Simple hot key commodity compiled with SASC 6.51
  8.  
  9.  This piece of code is Copyright © 1994 by Stefano Reksten of 3AM
  10.  - The Three Amigos!!!
  11.  
  12. */
  13.  
  14. #include <dos/dos.h>
  15. #include <exec/memory.h>
  16. #include <exec/libraries.h>
  17. #include <exec/execbase.h>
  18. #include <devices/input.h>
  19. #include <devices/inputevent.h>
  20. #include <graphics/gfxbase.h>
  21. #include <intuition/intuition.h>
  22. #include <intuition/intuitionbase.h>
  23. #include <intuition/screens.h>
  24. #include <libraries/commodities.h>
  25. #include <libraries/gadtools.h>
  26. #include <workbench/startup.h>
  27. #include <string.h>
  28.  
  29. #include <clib/exec_protos.h>
  30. #include <clib/intuition_protos.h>
  31. #include <clib/alib_protos.h>
  32. #include <clib/alib_stdio_protos.h>
  33. #include <clib/commodities_protos.h>
  34. #include <clib/intuition_protos.h>
  35. #include <clib/dos_protos.h>
  36. #include <clib/icon_protos.h>
  37. #include <clib/gadtools_protos.h>
  38. #include <clib/graphics_protos.h>
  39.  
  40. #define EVT_HOTKEY 1L
  41. #define EVT_POPKEY 2L
  42.  
  43. void ProcessMsg(void);
  44. struct Screen *FindWB(void);
  45. void CloseWindowsOrShells(void);
  46. void SendWindowcloseTo(struct Window *);
  47. void SendCtrlBackslashTo(struct Window *);
  48. BOOL ProcessCommodityMsg(void);
  49. BOOL ProcessWindowMsg(void);
  50. BOOL OpenWBWindow(void);
  51. void CloseWBWindow(void);
  52. void FlushAll(void);
  53.  
  54. struct EasyStruct warn_rq = { sizeof(struct EasyStruct),
  55.                               NULL,
  56.                               "CloseWB Request",
  57.                               "Please close all windows\nor shells before.",
  58.                               "OK|CANCEL" };
  59.  
  60. extern struct ExecBase *SysBase;
  61. struct IntuitionBase *IntuitionBase;
  62. struct GfxBase *GfxBase;
  63. struct Library *CxBase, *GadToolsBase, *IconBase;
  64. struct Window *wbwindow;
  65. struct MsgPort *broker_mp;
  66. CxObj *broker;
  67.  
  68. struct NewBroker newbroker = {
  69.     NB_VERSION,
  70.     "CloseWB",
  71.     "CloseWB 1.6 © 1994 by Stefano Reksten of 3AM",
  72.     "Closes or re-opens Workbench screen",
  73.     NBU_UNIQUE | NBU_NOTIFY,
  74.     COF_SHOW_HIDE, 0, 0, 0 };
  75.  
  76. ULONG cxsigflag;
  77. ULONG close_windows = TRUE, close_shells = TRUE, close_wb = TRUE, flush_all = TRUE;
  78.  
  79. #define CWND_ID 1
  80. #define CSHL_ID 2
  81. #define CWBS_ID 3
  82. #define FLSH_ID 4
  83. #define HIDE_ID 5
  84. #define QUIT_ID 6
  85.  
  86.  
  87. struct Gadget *glist = NULL;
  88.  
  89.  
  90. BOOL AttachFilter( STRPTR onkey, ULONG user_event )
  91. {
  92.     register CxObj *filter, *sender, *translator;
  93.  
  94.     if ( filter = CxFilter( onkey ) )
  95.     {
  96.         AttachCxObj( broker, filter );
  97.  
  98.        if ( sender = CxSender( broker_mp, user_event ) )
  99.        {
  100.            AttachCxObj( filter, sender );
  101.  
  102.            if ( translator = CxTranslate( NULL ) )
  103.            {
  104.                AttachCxObj( filter, translator );
  105.  
  106.                if ( !CxObjError( filter ) )
  107.                    return TRUE;
  108.            }
  109.        }
  110.     }
  111.     return FALSE;
  112. }
  113.  
  114.  
  115. void EmptyMsgPort( struct MsgPort *mp )
  116. {
  117. struct Message *msg;
  118.  
  119. while( msg = GetMsg( mp ) )
  120.     ReplyMsg( msg );
  121. }
  122.  
  123.  
  124. void __main( void )
  125. {
  126. UBYTE hotkey[30], popkey[30];
  127. BOOL popup;
  128.  
  129. if (IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 37L))
  130.     {
  131.         if (CxBase = OpenLibrary("commodities.library", 37L))
  132.         {
  133.             if (broker_mp = CreateMsgPort())
  134.             {
  135.                 newbroker.nb_Port = broker_mp;
  136.                 cxsigflag = 1L << broker_mp->mp_SigBit;
  137.  
  138.                 hotkey[0] = popkey[0] = NULL;
  139.  
  140.                 if (IconBase = OpenLibrary("icon.library",36L))
  141.                 {
  142.                     char **ttypes;
  143.                     struct DiskObject *ob;
  144.  
  145.                     if ( ob = GetDiskObject( "CloseWB" ) )
  146.                     {
  147.                         ttypes = ob->do_ToolTypes;
  148.  
  149.                         newbroker.nb_Pri = (BYTE)ArgInt(ttypes, "CX_PRIORITY", 0);
  150.  
  151.                         close_windows = MatchToolValue( FindToolType(ttypes, "CLOSEWINDOWS"), "TRUE" );
  152.                         close_shells = MatchToolValue( FindToolType(ttypes, "CLOSESHELLS"), "TRUE");
  153.                         close_wb = MatchToolValue( FindToolType(ttypes, "CLOSEWORKBENCH"), "TRUE");
  154.                         flush_all = MatchToolValue( FindToolType(ttypes, "FLUSH"), "TRUE");
  155.  
  156.                         popup = MatchToolValue(FindToolType(ttypes, "CX_POPUP"), "YES");
  157.  
  158.                         strcpy( hotkey, FindToolType(ttypes, "CX_HOTKEY") );
  159.                         strcpy( popkey, FindToolType(ttypes, "CX_POPKEY") );
  160.  
  161.                         FreeDiskObject( ob );
  162.                     }
  163.                     CloseLibrary(IconBase);
  164.                 }
  165.  
  166.                 if (!(hotkey[0]))
  167.                     strcpy( hotkey, "lalt w" );
  168.                 if (!(popkey[0]))
  169.                     strcpy( popkey, "ctrl lalt w" );
  170.  
  171.                 if (broker = CxBroker(&newbroker, NULL))
  172.                 {
  173.                     if ( AttachFilter( hotkey, EVT_HOTKEY ) &&
  174.                          AttachFilter( popkey, EVT_POPKEY ) )
  175.                     {
  176.                         ActivateCxObj(broker, 1L);
  177.                         if (popup)
  178.                             OpenWBWindow();
  179.                         ProcessMsg();
  180.                     }
  181.                     DeleteCxObjAll(broker);
  182.                 }
  183.                 EmptyMsgPort( broker_mp );
  184.                 DeletePort( broker_mp );
  185.             }
  186.             CloseLibrary( CxBase );
  187.         }
  188.         CloseWBWindow();
  189.         CloseLibrary( (struct Library *)IntuitionBase );
  190.     }
  191. }
  192.  
  193.  
  194. void ProcessMsg(void)
  195. {
  196.     BOOL stay = TRUE;
  197.     ULONG sigrcvd, waitmask;
  198.  
  199.     while(stay)
  200.     {
  201.         waitmask = cxsigflag | SIGBREAKF_CTRL_C;
  202.         if (wbwindow) waitmask |= 1L<<wbwindow->UserPort->mp_SigBit;
  203.         sigrcvd = Wait(waitmask);
  204.  
  205.         if (sigrcvd & SIGBREAKF_CTRL_C)
  206.             stay = FALSE;
  207.         else
  208.         if (sigrcvd & cxsigflag)
  209.             stay = ProcessCommodityMsg();
  210.         else
  211.             stay = ProcessWindowMsg();
  212.     }
  213. }
  214.  
  215.  
  216. struct Screen *FindWB(void)
  217. {
  218.     register struct Screen *scr = IntuitionBase->FirstScreen;
  219.  
  220.     while(scr && (!(scr->DefaultTitle) || strcmp(scr->DefaultTitle, "Workbench Screen")))
  221.         scr = scr->NextScreen;
  222.     return(scr);
  223. }
  224.  
  225.  
  226. void CloseWindowsOrShells()
  227. {
  228.     register struct Window *window, *next;
  229.  
  230.     if (close_windows && wbwindow)
  231.         CloseWBWindow();
  232.     
  233.     window = (FindWB())->FirstWindow;
  234.  
  235.     while(window)
  236.     {
  237.         next = window->NextWindow;
  238.         if (window->UserPort && close_windows)
  239.         {
  240.             if (window->Title && strcmp(window->Title, "Workbench"))
  241.                 SendWindowcloseTo(window);
  242.         }
  243.         else if (close_shells)
  244.         {
  245.             ActivateWindow(window);
  246.             SendCtrlBackslashTo(window);
  247.             Delay( 5 );
  248.         }
  249.         window = next;
  250.     }
  251. }
  252.  
  253.  
  254. void SendWindowcloseTo(struct Window *window)
  255. {
  256.     register struct IntuiMessage *imsg;
  257.     
  258.     if (imsg = (struct IntuiMessage *)AllocVec(sizeof(struct IntuiMessage), MEMF_ANY|MEMF_CLEAR))
  259.     {
  260.         imsg->ExecMessage.mn_ReplyPort = broker_mp;
  261.         imsg->ExecMessage.mn_Length = sizeof(struct IntuiMessage);
  262.         imsg->Class = IDCMP_CLOSEWINDOW;
  263.         imsg->ExecMessage.mn_Node.ln_Type = NT_MESSAGE;
  264.         imsg->IDCMPWindow = window;
  265.         PutMsg(window->UserPort, (struct Message *)imsg);
  266.         WaitPort(broker_mp);
  267.         GetMsg(broker_mp);
  268.         FreeVec(imsg);
  269.     }
  270. }
  271.  
  272.  
  273. void SendCtrlBackslashTo(struct Window *window)
  274. {
  275.     register struct InputEvent *fakeev;
  276.     register struct IOStdReq *ioreq;
  277.  
  278.     if (fakeev = AllocVec(sizeof(struct InputEvent),MEMF_PUBLIC|MEMF_CLEAR))
  279.     {
  280.         if (ioreq = CreateIORequest(broker_mp,sizeof(struct IOStdReq)))
  281.         {
  282.             if ( !OpenDevice("input.device",NULL,(struct IORequest *)ioreq,NULL))
  283.             {
  284.                 fakeev->ie_Class = IECLASS_RAWKEY;
  285.                 fakeev->ie_Code = 0x0D;
  286.                 fakeev->ie_Qualifier = IEQUALIFIER_CONTROL;
  287.  
  288.                 ioreq->io_Data = (APTR)fakeev;
  289.                 ioreq->io_Length = sizeof(struct InputEvent);
  290.                 ioreq->io_Command = IND_WRITEEVENT;
  291.  
  292.                 DoIO((struct IORequest *)ioreq);
  293.                 CloseDevice((struct IORequest *)ioreq);
  294.             }
  295.             DeleteIORequest(ioreq);
  296.         }
  297.         FreeVec(fakeev);
  298.     }
  299. }
  300.  
  301.  
  302. struct IntuiText it = { 0, 0, 0, 0, 0, NULL, NULL, NULL };
  303. struct NewGadget ng = { 0, 0, 50, 0, NULL, NULL, 0, 0, NULL, NULL };
  304. struct VisualInfo *vi;
  305. struct Gadget *gad;
  306. UWORD textw;
  307.  
  308. /* Some other routines to make it shorter */
  309.  
  310. UWORD MaxBetween( STRPTR text, UWORD prev )
  311. {
  312. register UWORD ilength, max;
  313.  
  314. it.IText = text;
  315. ilength = IntuiTextLength( &it );
  316. max = ( ilength > prev ? ilength : prev );
  317. return max;
  318. }
  319.  
  320. void AddCheckboxGadget( STRPTR name, ULONG ID, BOOL selected )
  321. {
  322. ng.ng_TopEdge += ng.ng_Height;
  323. ng.ng_GadgetText = name;
  324. ng.ng_GadgetID = ID;
  325. gad = CreateGadget(CHECKBOX_KIND,gad,&ng,GTCB_Checked,selected,TAG_END);
  326. textw = MaxBetween( name, textw );
  327. }
  328.  
  329.  
  330. BOOL OpenWBWindow(void)
  331. {
  332.     struct Screen *wbs = LockPubScreen(NULL);
  333.     register UWORD fonth, wheight, wwidth;
  334.  
  335.     if (!wbwindow)
  336.     {
  337.         fonth = wbs->Font->ta_YSize;
  338.         if ( fonth < 12 )
  339.             fonth = 12;
  340.         it.ITextFont = wbs->Font;
  341.         textw = 0;
  342.         wheight = wbs->WBorTop + fonth * 6 + 4 + wbs->WBorBottom;
  343.         ng.ng_Height = fonth;
  344.         if (GadToolsBase = OpenLibrary("gadtools.library",37L))
  345.         {
  346.             if (vi = GetVisualInfo(wbs,NULL))
  347.             {
  348.                 ng.ng_VisualInfo = vi;
  349.                 ng.ng_LeftEdge = wbs->WBorLeft + 4;
  350.                 ng.ng_TopEdge = wbs->WBorTop + fonth;
  351.  
  352.                 gad = CreateContext(&glist);
  353.                 if (gad)
  354.                 {
  355.                     ng.ng_TopEdge -= fonth;
  356.                     ng.ng_Flags = PLACETEXT_RIGHT;
  357.  
  358.                     AddCheckboxGadget( "Windows", CWND_ID, close_windows );
  359.                     AddCheckboxGadget( "Shells", CSHL_ID, close_shells );
  360.                     AddCheckboxGadget( "Workbench", CWBS_ID, close_wb );
  361.                     AddCheckboxGadget( "Flush", FLSH_ID, flush_all );
  362.  
  363.                     wwidth = textw + wbs->WBorLeft + wbs->WBorRight + 48;
  364.  
  365.                     ng.ng_TopEdge += fonth + 2;
  366.                     ng.ng_Width = (textw>>1) + 18;
  367.                     ng.ng_Flags = PLACETEXT_IN;
  368.                     ng.ng_GadgetText = "Hide";
  369.                     ng.ng_GadgetID = HIDE_ID;
  370.                     gad = CreateGadget(BUTTON_KIND,gad,&ng,TAG_END);
  371.  
  372.                     ng.ng_LeftEdge += ng.ng_Width + 4;
  373.                     ng.ng_GadgetText = "Quit";
  374.                     ng.ng_GadgetID = QUIT_ID;
  375.                     gad = CreateGadget(BUTTON_KIND,gad,&ng,TAG_END);
  376.  
  377.                     if (gad && (wbwindow = OpenWindowTags( NULL,
  378.                         WA_Left, (wbs->Width - wwidth)>>1,
  379.                         WA_Top, (wbs->Height - wheight)>>1,
  380.                         WA_Width, wwidth,
  381.                         WA_Height, wheight,
  382.                         WA_Title, "CloseWB",
  383.                         WA_ScreenTitle, "CloseWB 1.6 © 1994 by Stefano Reksten of 3AM",
  384.                         WA_Flags, WFLG_CLOSEGADGET|WFLG_DEPTHGADGET|WFLG_DRAGBAR|WFLG_ACTIVATE|WFLG_RMBTRAP,
  385.                         WA_Gadgets, glist,
  386.                         WA_IDCMP, IDCMP_CLOSEWINDOW|IDCMP_GADGETDOWN|IDCMP_REFRESHWINDOW|BUTTONIDCMP,
  387.                         TAG_END )))
  388.                     {
  389.                         WBenchToFront();
  390.                         UnlockPubScreen(NULL,wbs);
  391.                         return TRUE;
  392.                     }
  393.                 }
  394.                 FreeVisualInfo(vi);
  395.             }
  396.             CloseLibrary(GadToolsBase);
  397.         }
  398.     }
  399.     UnlockPubScreen(NULL,wbs);
  400.     return FALSE;
  401. }
  402.  
  403.  
  404. BOOL ProcessCommodityMsg(void)
  405. {
  406.     BOOL returnvalue = TRUE;
  407.     CxMsg *msg;
  408.     ULONG msgid, msgtype;
  409.     BOOL cont;
  410.  
  411.     while(msg = (CxMsg *)GetMsg(broker_mp))
  412.     {
  413.         msgid = CxMsgID(msg);
  414.         msgtype = CxMsgType(msg);
  415.         ReplyMsg((struct Message *)msg);
  416.  
  417.         switch(msgtype)
  418.         {
  419.             case CXM_IEVENT:
  420.                 switch(msgid)
  421.                 {
  422.                     case EVT_HOTKEY:
  423.                         if ((BOOL)FindWB())
  424.                         {
  425.                             if (close_wb && wbwindow)
  426.                                 CloseWBWindow();
  427.  
  428.                             if (close_windows || close_shells)
  429.                                 CloseWindowsOrShells();
  430.                             cont = TRUE;
  431.                             while (cont && close_wb)
  432.                                 {
  433.                                 cont = !CloseWorkBench();
  434.                                 if (cont)
  435.                                     {
  436.                                     DisplayBeep(NULL);
  437.                                     cont = EasyRequest(NULL, &warn_rq, NULL);
  438.                                     }
  439.                                 }
  440.                             if (flush_all)
  441.                                 FlushAll();
  442.                         }
  443.                         else
  444.                            OpenWorkBench();
  445.                         break;
  446.                     case EVT_POPKEY:
  447.                         OpenWBWindow();
  448.                     default:
  449.                         break;
  450.                 }
  451.                 break;
  452.             case CXM_COMMAND:
  453.                 switch(msgid)
  454.                 {
  455.                     case CXCMD_DISABLE:
  456.                         ActivateCxObj(broker, 0L);
  457.                         break;
  458.                     case CXCMD_ENABLE:
  459.                         ActivateCxObj(broker, 1L);
  460.                         break;
  461.                     case CXCMD_KILL:
  462.                         returnvalue = FALSE;
  463.                         break;
  464.                     case CXCMD_UNIQUE:
  465.                         OpenWBWindow();
  466.                         break;
  467.                     case CXCMD_APPEAR:
  468.                         OpenWBWindow();
  469.                         break;
  470.                     case CXCMD_DISAPPEAR:
  471.                         CloseWBWindow();
  472.                     default:
  473.                         break;
  474.                 }
  475.                 break;
  476.             default:
  477.                 break;
  478.         }
  479.     }
  480.     return returnvalue;
  481. }
  482.  
  483.  
  484. BOOL ProcessWindowMsg(void)
  485. {
  486.     register struct IntuiMessage *msg;
  487.     register BOOL returnvalue = TRUE;
  488.     register ULONG class;
  489.     register UWORD msgID;
  490.  
  491.     while(wbwindow && (msg = GT_GetIMsg(wbwindow->UserPort)))
  492.     {
  493.         class = msg->Class;
  494.         if (class & (BUTTONIDCMP|IDCMP_GADGETDOWN))
  495.             msgID = ((struct Gadget *)msg->IAddress)->GadgetID;
  496.         GT_ReplyIMsg(msg);
  497.  
  498.         switch(class)
  499.         {
  500.             case IDCMP_REFRESHWINDOW:
  501.                 GT_BeginRefresh(wbwindow);
  502.                 GT_EndRefresh(wbwindow,TRUE);
  503.                 break;
  504.             case IDCMP_CLOSEWINDOW:
  505.                 CloseWBWindow();
  506.                 break;
  507.             case BUTTONIDCMP:
  508.             case IDCMP_GADGETDOWN:
  509.                 if ( msgID == CWND_ID ) close_windows ^= TRUE;
  510.                 if ( msgID == CSHL_ID ) close_shells ^= TRUE;
  511.                 if ( msgID == CWBS_ID ) close_wb ^= TRUE;
  512.                 if ( msgID == FLSH_ID ) flush_all ^= TRUE;
  513.                 if ( msgID == HIDE_ID ) CloseWBWindow();
  514.                 if ( msgID == QUIT_ID ) returnvalue = FALSE;
  515.         }
  516.     }
  517.     return returnvalue;
  518. }
  519.  
  520.  
  521. void CloseWBWindow(void)
  522. {
  523.     if(wbwindow)
  524.     {
  525.         EmptyMsgPort( wbwindow->UserPort );
  526.         CloseWindow(wbwindow);
  527.         FreeGadgets(glist);
  528.         FreeVisualInfo(vi);
  529.         CloseLibrary(GadToolsBase);
  530.         wbwindow = NULL;
  531.     }
  532. }
  533.  
  534.  
  535. void FlushAll(void)
  536. {
  537.     register struct Node *node;
  538.  
  539.     Forbid();
  540.     for(node = SysBase->LibList.lh_Head; node->ln_Succ; node = node->ln_Succ)
  541.         RemLibrary((struct Library *)node);
  542.     for(node = SysBase->DeviceList.lh_Head; node->ln_Succ; node = node->ln_Succ)
  543.         RemDevice((struct Device *)node);
  544.     Permit();
  545.     if (GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0L))
  546.     {
  547.         for(node = GfxBase->TextFonts.lh_Head; node->ln_Succ; node = node->ln_Succ)
  548.             RemFont((struct TextFont *)node);
  549.     }
  550. }
  551.