home *** CD-ROM | disk | FTP | other *** search
/ The CDPD Public Domain Collection for CDTV 3 / CDPDIII.bin / pd / commodities / yak / source / main.c < prev    next >
C/C++ Source or Header  |  1993-04-22  |  16KB  |  714 lines

  1. /*
  2.  * Yak version 1.3f
  3.  * ----------------
  4.  * [Yak == Yet Another K(?)ommodity
  5.  *
  6.  * There seems to be a profusion of commodities doing this or that.
  7.  * Heres mine, to do what I want it to:
  8.  *
  9.  *    AutoActivate windows (SunMouse)
  10.  *    ClickToFront, ClickToBack, ScreenCycle
  11.  *    Close/Zip/Shrink/Zoom/Turn a window via keyboard.
  12.  *    Bring up a palette on front screen.
  13.  *    Insert date into read-stream.
  14.  *    Produce key-click (like my keyclick program).
  15.  *    Some other things...
  16.  *
  17.  * Martin W. Scott, 9/92.
  18.  */
  19. #include <exec/types.h>
  20. #include <exec/libraries.h>
  21. #include <exec/memory.h>
  22. #include <devices/inputevent.h>
  23. #include <dos/dos.h>
  24. #include <dos/dostags.h>
  25. #include <graphics/displayinfo.h>
  26. #include <libraries/commodities.h>
  27. #include <libraries/reqtools.h>
  28. #include <libraries/locale.h>
  29. #include <intuition/intuitionbase.h>
  30. #include <proto/exec.h>
  31. #include <proto/dos.h>
  32. #include <proto/graphics.h>
  33. #include <proto/commodities.h>
  34. #include <proto/intuition.h>
  35. #include <proto/reqtools.h>
  36. #include <proto/locale.h>
  37. #include <string.h>
  38.  
  39. #include "yak.h"
  40. #include "beep.h"
  41. #include "icon.h"
  42. #include "version.h"
  43.  
  44. #include "WB2CLI.h"    /* we'll be a shell process */
  45. #define DEF_CURRENTDIR    "SYS:"
  46.  
  47. /* local prototypes for main.c */
  48. static void CloseResources(void);
  49. static BOOL OpenResources(void);
  50. static void __regargs EasyEasyRequest(char *str);
  51. static void FreePatterns(void);
  52. static void DoCloseWindow(void);
  53. static void __regargs HandleWindowKey(LONG what);
  54. static void InsertDate(void);
  55. static void DoCycleWindows(void);
  56. static void DoCycleScreens(void);
  57. static void DoCenterScreen(void);
  58. static struct Window *FindWBWindow(void);
  59. static LONG ProcessMsg(void);
  60. static void __saveds DoPalette(void);
  61.  
  62. void __saveds __asm putcharfunc(register __a0 struct Hook * h,
  63.                 register __a2 void * object,
  64.                 register __a1 char c);
  65. void __main(void);
  66.  
  67.  
  68.  
  69. #ifdef __SASC_60    /* save some bytes */
  70. void _MemCleanup(void){}
  71. #else
  72. void MemCleanup(void){}
  73. #endif
  74.  
  75. /* global data - library bases and the like */
  76. extern struct WBStartup *_WBenchMsg;
  77. struct Library    *CxBase, *IconBase,
  78.         *GadToolsBase, *LayersBase,
  79.         *WorkbenchBase, *LocaleBase;
  80. struct IntuitionBase *IntuitionBase;
  81. struct GfxBase *GfxBase;
  82. struct Locale *locale;
  83. struct MsgPort *broker_mp;
  84. CxObj *broker;
  85.  
  86. char *versionstr="\0$VER: "VERSION_NAME;
  87.  
  88. struct NewBroker newbroker = {
  89.     NB_VERSION,
  90.     "Yak",           /* string to identify this broker */
  91.     VERSION_STR,
  92.     "Multi-purpose commodity",
  93.     NBU_UNIQUE | NBU_NOTIFY,      /* Don't want any new commodities
  94.                                    * starting with this name.  If someone
  95.                                    * tries it, let me know */
  96.     COF_SHOW_HIDE
  97. };
  98.  
  99. ULONG        wndsigflag;        /* here for overlay purposes */
  100. ULONG        cxsigflag;
  101. ULONG        invariantsigflag;
  102. BYTE        palette_count;        /* how many palettes are open */
  103.  
  104. /* from handler.c */
  105. extern ULONG    clicksigflag, intuiopsigflag;
  106. extern void (*intui_routine)(APTR);    /* for intui_op's */
  107. extern APTR intui_parameter;
  108.  
  109. /* from icon.c */
  110. extern ULONG    appsigflag;
  111.  
  112. /* close what we opened */
  113. static void
  114. CloseResources()
  115. {
  116.     if (IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
  117.     if (GfxBase) CloseLibrary((struct Library *)GfxBase);
  118.     if (CxBase) CloseLibrary(CxBase);
  119.     if (LayersBase) CloseLibrary(LayersBase);
  120.     if (IconBase) CloseLibrary(IconBase);
  121.     if (GadToolsBase) CloseLibrary(GadToolsBase);
  122.     if (WorkbenchBase) CloseLibrary(WorkbenchBase);
  123.     if (LocaleBase)
  124.     {
  125.         CloseLocale(locale);
  126.         CloseLibrary(LocaleBase);
  127.     }
  128. }
  129.  
  130. /* open libraries, devices that we need */
  131. static BOOL
  132. OpenResources()
  133. {
  134.     if ((IntuitionBase = (void *)OpenLibrary("intuition.library", 37L)) &&
  135.         (GfxBase = (void *)OpenLibrary("graphics.library", 37L)) &&
  136.         (CxBase = OpenLibrary("commodities.library", 37L)) &&
  137.         (LayersBase = OpenLibrary("layers.library", 37L)) &&
  138.         (IconBase = OpenLibrary("icon.library", 37L)) &&
  139.         (GadToolsBase = OpenLibrary("gadtools.library", 37L)) &&
  140.         (WorkbenchBase = OpenLibrary("workbench.library", 37L)))
  141.         {
  142.         if (LocaleBase = OpenLibrary("locale.library", 38L))
  143.             if (!(locale = OpenLocale(NULL)))
  144.             {
  145.                 PostError("No locale set!\n");
  146.                 CloseLibrary(LocaleBase);
  147.                 LocaleBase = NULL;
  148.             }
  149.  
  150.         return TRUE;
  151.     }
  152.     CloseResources();
  153.     return FALSE;
  154. }
  155.  
  156. /* pop up a requester */
  157. static void __regargs
  158. EasyEasyRequest(char *str)
  159. {
  160.     struct EasyStruct es;
  161.  
  162.     es.es_StructSize = sizeof(struct EasyStruct);
  163.     es.es_Flags = 0L;
  164.     es.es_Title = "Yak Message";
  165.     es.es_TextFormat = str;
  166.     es.es_GadgetFormat = "OK";
  167.     EasyRequestArgs(NULL, &es, NULL, NULL);
  168. }
  169.  
  170. /* display an error appropriately */
  171. void __regargs
  172. PostError(char *str)
  173. {
  174.     if (IntuitionBase)
  175.         EasyEasyRequest(str);
  176.     else
  177.     {
  178.         PutStr("Yak: ");
  179.         PutStr(str);
  180.         PutStr("\n");
  181.     }
  182. }
  183.  
  184. /* modify hk array with new hotkey */    
  185. BOOL __regargs
  186. AddHotKey(char *newstr, UWORD n)
  187. {
  188.     CxObj *newfilter;
  189.     char *hotkey = newstr ? newstr : hk[n].key;
  190.  
  191.     if (!hotkey[0])        /* hotkey being cancelled */
  192.     {
  193.         if (hk[n].filter) DeleteCxObjAll(hk[n].filter);
  194.         hk[n].filter = NULL;
  195.         hk[n].key[0] = '\0';
  196.         return TRUE;
  197.     }
  198.     else if (newfilter = HotKey(hotkey, broker_mp, hk[n].msgid))
  199.     {
  200.         if (hk[n].filter) DeleteCxObjAll(hk[n].filter);
  201.         hk[n].filter = newfilter;
  202.         if (newstr) strncpy(hk[n].key, newstr, MAXKEYLEN);
  203.         AttachCxObj(broker, hk[n].filter);
  204.         return TRUE;
  205.     }
  206.     PostError("Invalid hotkey definition");
  207.     return FALSE;
  208. }
  209.  
  210. /* parse pattern, report errors */
  211. BOOL __regargs
  212. InitPattern(char *newpatstr, UWORD n)
  213. {
  214.     char *patstr = newpatstr ? newpatstr : patterns[n].patstr;
  215.     char *pat;
  216.     LONG len;
  217.  
  218.     if (pat = AllocVec(len = strlen(patstr)*3+10, MEMF_CLEAR))
  219.     {
  220.         if (ParsePattern(patstr, pat, len) != -1)
  221.         {
  222.             if (newpatstr) strncpy(patterns[n].patstr, newpatstr, PATLEN);
  223.             if (patterns[n].pat) FreeVec(patterns[n].pat);
  224.             patterns[n].pat = pat;
  225.             return TRUE;
  226.         }
  227.         PostError("Pattern parse error");
  228.         FreeVec(pat);
  229.     }
  230.     else PostError("Allocation error");
  231.     return FALSE;
  232. }
  233.  
  234. static void
  235. FreePatterns()
  236. {
  237.     UWORD i;
  238.  
  239.     for (i = 0; i < NUM_PATTERNS; i++)
  240.         if (patterns[i].pat) FreeVec(patterns[i].pat);
  241. }
  242.  
  243. void
  244. __main()        /* Yak: multi-function commodity */
  245. {
  246.     BPTR    newdir = NULL, olddir;
  247.  
  248.     if (OpenResources())
  249.     {
  250.         if (broker_mp = CreateMsgPort())
  251.             {
  252.                 newbroker.nb_Port = broker_mp;
  253.                 cxsigflag = 1L << broker_mp->mp_SigBit;
  254.  
  255.         /* process tool-types */
  256.         GetOurIcon(_WBenchMsg);
  257.                 newbroker.nb_Pri = (BYTE)TTInt("CX_PRIORITY", 0);
  258.  
  259.         if (_WBenchMsg)
  260.         {
  261.             if (newdir = Lock(DEF_CURRENTDIR, ACCESS_READ))
  262.                 olddir = CurrentDir(newdir);
  263.             WB2CLI(_WBenchMsg,4000,DOSBase);        /* get it over with... */
  264.         }
  265.  
  266.         if (broker = CxBroker(&newbroker, NULL))
  267.                 {
  268.             /* HANDLER FIRST, SO IT SEES EVERYTHING!!! */
  269.             if (InitHandler())
  270.             {
  271.                 LoadSettings(CONFIG_FILE);
  272.                 /* tooltype overrides config file */
  273.                 AddHotKey(TTString("CX_POPKEY", NULL), HK_POPKEY);
  274.  
  275.                 MyPri(ACTIVE);
  276.                 ActivateCxObj(broker, 1L);
  277.  
  278.                 if (TTBool("CX_POPUP", FALSE))
  279.                     ShowWindow();
  280.  
  281.                 if (!TTBool("NOICON", FALSE))
  282.                 {
  283.                     if (!MakeOurAppIcon(TTString("ICONNAME", "Yak!")))
  284.                         if (_WBenchMsg)
  285.                             PostError("Couldn't create icon");
  286.                 }
  287.                 /* WB makes a copy of icon, so can free it */
  288.                 FreeOurIcon();
  289.  
  290.                 /* these are the signals waited for, + window sig */
  291.                 invariantsigflag = SIGBREAKF_CTRL_C | cxsigflag
  292.                            | clicksigflag | intuiopsigflag
  293.                            | appsigflag;
  294.  
  295.                 while (ProcessMsg())
  296.                     ;
  297.                 HideWindow();
  298.                 RemoveOurAppIcon();
  299.  
  300.                 MyPri(ORIGINAL);
  301.  
  302.                 EndHandler();
  303.                 FreePatterns();
  304.             }
  305.             else PostError("Allocation error");
  306.  
  307.                     DeleteCxObjAll(broker);
  308.                 }
  309.  
  310.         if (newdir) {
  311.             CurrentDir(olddir);
  312.             UnLock(newdir);
  313.         }
  314.  
  315.                 DeleteMsgPort(broker_mp);
  316.         FreeOurIcon();    /* may already be gone, but so what? */
  317.             }
  318.         else PostError("Allocation error");
  319.  
  320.         CloseResources();
  321.     }
  322.     else PostError("Resource error");
  323. }
  324.  
  325. /* simulate user clicking close-gadget */
  326. static void
  327. DoCloseWindow()
  328. {
  329.     struct InputEvent ev;
  330.     struct Window *window;
  331.     ULONG lock;
  332.  
  333.     lock = LockIBase(0);
  334.     window = IntuitionBase->ActiveWindow;
  335.     UnlockIBase(lock);
  336.  
  337.     if (window && (window->IDCMPFlags & CLOSEWINDOW))
  338.     {
  339.         ev.ie_NextEvent = NULL;
  340.         ev.ie_Class = IECLASS_CLOSEWINDOW;
  341.         ev.ie_SubClass = 0;
  342.         ev.ie_Code = 0;
  343.         ev.ie_Qualifier = 0;
  344.         ev.ie_EventAddress = 0;
  345.         AddIEvents(&ev);
  346.     }
  347. }
  348.  
  349. #define AdjustedLeftEdge(w, width)    (w->LeftEdge + width > w->WScreen->Width ? \
  350.                         w->WScreen->Width - width : w->LeftEdge)
  351. #define AdjustedTopEdge(w, height)    (w->TopEdge + height > w->WScreen->Height ? \
  352.                         w->WScreen->Height - height : w->TopEdge)
  353.  
  354. /* zip/enlarge or whatever the currently active window */
  355. static void __regargs
  356. HandleWindowKey(LONG what)
  357. {
  358.     struct Window *window;
  359.     ULONG lock;
  360.  
  361.     lock = LockIBase(0);
  362.     if (window = IntuitionBase->ActiveWindow)
  363.     {
  364.         switch (what)
  365.         {
  366.         case HK_ZIPKEY:
  367.             if (window->Flags & WFLG_HASZOOM)
  368.                 ZipWindow(window);
  369.             break;
  370.  
  371.         case HK_SHRINKKEY:
  372.             if (window->Flags & WFLG_SIZEGADGET)
  373.                 ChangeWindowBox(window,
  374.                         window->LeftEdge,
  375.                         window->TopEdge,
  376.                         window->MinWidth,
  377.                         window->MinHeight);
  378.             break;
  379.  
  380.         case HK_ZOOMKEY:
  381.             {    /* sometimes Max vars are -1 == NO LIMIT */
  382.             USHORT width, height;
  383.  
  384.             width = window->MaxWidth;
  385.             if (width == -1) width = window->WScreen->Width-width;
  386.             height = window->MaxHeight;
  387.             if (height == -1) height = window->WScreen->Height-height;
  388.             
  389.             if (window->Flags & WFLG_SIZEGADGET)
  390.                 ChangeWindowBox(window,
  391.                         AdjustedLeftEdge(window, width),
  392.                         AdjustedTopEdge(window, height),
  393.                         width,
  394.                         height);
  395.             }
  396.             break;
  397.  
  398.         } /* switch */
  399.     }
  400.     UnlockIBase(lock);
  401. }
  402.  
  403. /* bring a palette up on frontmost screen */
  404. /* CreateNewProc it... */
  405. static void __saveds
  406. DoPalette()
  407. {
  408.     struct ReqToolsBase *ReqToolsBase;
  409.     LONG tags[3];
  410.  
  411.     palette_count++;
  412.     if (ReqToolsBase = (void *)OpenLibrary("reqtools.library", 0L))
  413.     {
  414.         tags[0] = RT_Screen;
  415.         tags[1] = (LONG)ReqToolsBase->IntuitionBase->FirstScreen;
  416.         tags[2] = TAG_DONE;
  417.         (void) rtPaletteRequestA("Palette", NULL, (struct TagItem *)tags);
  418.         CloseLibrary(ReqToolsBase);
  419.     }
  420.     palette_count--;
  421. }
  422.  
  423. /* hook-function for inserting chars into input-stream */
  424. void __saveds __asm
  425. putcharfunc(    register __a0 struct Hook *h,
  426.         register __a2 void *object,
  427.         register __a1 char c)
  428. {
  429.     struct InputEvent ev;
  430.  
  431.     if (c)    /* stop at null-terminator */
  432.     {
  433.         ev.ie_NextEvent = NULL;
  434.         InvertKeyMap(c, &ev, NULL);
  435.         AddIEvents(&ev);
  436.         ev.ie_Code |= IECODE_UP_PREFIX;
  437.         AddIEvents(&ev);
  438.     }
  439. }
  440. /* and its associated structure */
  441. struct Hook putcharhook = {
  442.     {NULL, NULL},
  443.     (APTR)putcharfunc,
  444.     NULL,
  445.     NULL
  446. };
  447.  
  448. /* if locale present, insert date as string into read-stream */
  449. static void
  450. InsertDate()
  451. {
  452.     struct DateStamp datestamp;
  453.     DateStamp(&datestamp);
  454.     if (LocaleBase)
  455.         FormatDate(locale, DateFormat, &datestamp, &putcharhook);
  456.     else
  457.         DisplayBeep(NULL);
  458. }
  459.  
  460. /* cyle windows, like IHelp */
  461. /*#define NOCYCLEFLAGS (WFLG_WBENCHWINDOW|WFLG_BACKDROP)*/
  462. #define NOCYCLEFLAGS (WFLG_BACKDROP)
  463. static void
  464. DoCycleWindows()
  465. {
  466.     struct Screen *s;
  467.     struct Window *w, *backmost;
  468.     struct Layer *l;
  469.     ULONG lock;
  470.  
  471.     lock = LockIBase(0);
  472.     if (s = IntuitionBase->FirstScreen)
  473.     {
  474.         Forbid();
  475.         backmost = NULL;
  476.         for (l = s->LayerInfo.top_layer; l; l = l->back)
  477.         {
  478.             w = (struct Window *)l->Window;
  479.             if (w && !(w->Flags & NOCYCLEFLAGS))
  480.                 backmost = w;
  481.         }
  482.  
  483.         if (backmost)
  484.         {
  485.             ScreenToFront(s);
  486.             WindowToFront(backmost);
  487.             ActivateWindow(backmost);
  488.         }
  489.         Permit();
  490.     }
  491.     UnlockIBase(lock);
  492. }
  493.  
  494. /* cyle screens, like IHelp */
  495. static void
  496. DoCycleScreens()
  497. {
  498.     struct Screen *s;
  499.     ULONG lock;
  500.  
  501.     lock = LockIBase(0);
  502.     for (s = IntuitionBase->FirstScreen; s; s = s->NextScreen)
  503.         if (!s->NextScreen)
  504.         {
  505.             ScreenToFront(s);
  506.             if (scractivate)
  507.                 ActivateMouseWindow(SCREEN);
  508.             break;
  509.         }
  510.     UnlockIBase(lock);
  511. }
  512.  
  513. /* center horizontally the frontmost screen */
  514. static void
  515. DoCenterScreen()
  516. {
  517.     struct Rectangle rect;
  518.     struct Screen *s;
  519.     ULONG    lock;
  520.     ULONG    modeid;
  521.     WORD    newle;
  522.  
  523.     lock = LockIBase(0);
  524.     if ((s = IntuitionBase->FirstScreen) &&
  525.         (modeid = GetVPModeID(&s->ViewPort)) != INVALID_ID &&
  526.         QueryOverscan(modeid, &rect, OSCAN_TEXT))
  527.     {
  528.         newle = (rect.MinX + rect.MaxX + 1 - s->Width) >> 1;
  529.         MoveScreen(s, newle - s->LeftEdge, 0);
  530.     }
  531.     UnlockIBase(lock);
  532. }
  533.  
  534. /* find (a) Workbench window; used below, AND in handler.c */
  535. static struct Window *
  536. FindWBWindow()
  537. {
  538.     struct Screen *s = LockPubScreen("Workbench");
  539.     if (s)
  540.     {
  541.     struct Window *w = s->FirstWindow;
  542.     WBenchToFront();
  543.     Forbid();
  544.     for (; w; w = w->NextWindow)
  545.         if (w->Flags & WFLG_WBENCHWINDOW)
  546.             break;
  547.     Permit();
  548.     UnlockPubScreen(NULL, s);
  549.     return w;
  550.     }
  551.     return NULL;
  552. }
  553.  
  554. /* taglist for CreateNewProc */
  555. LONG palette_taglist[] = {
  556.     NP_Entry, (LONG)DoPalette,
  557.     NP_Name, (LONG)"Yak Palette",
  558.     TAG_DONE
  559. };
  560.  
  561. /* monitor cx port, act on messages */
  562. static LONG
  563. ProcessMsg(void)
  564. {
  565.     CxMsg *msg;
  566.     ULONG sigrcvd, msgid, msgtype;
  567.     LONG returnvalue = 1L;
  568.  
  569.     sigrcvd = Wait(invariantsigflag | wndsigflag);
  570.  
  571.     if ((sigrcvd & clicksigflag) && click_volume)    /* keyclick please */
  572.     {
  573.     beep(click_volume);
  574.         Delay(1);   /* avoid ugly sound when key repeating */
  575.     }
  576.  
  577.     if (sigrcvd & intuiopsigflag)    /* intuiop requested */
  578.     intui_routine(intui_parameter);
  579.  
  580.     if (sigrcvd & appsigflag)        /* settings change */
  581.     {
  582.     RespondToAppIcon();
  583.     ShowWindow();
  584.     }
  585.  
  586.     if (sigrcvd & wndsigflag)        /* settings change */
  587.         if (HandleIDCMP() != HELP_OKAY)
  588.         returnvalue = 0;
  589.     else if (!wndsigflag)        /* window gone */
  590.         DummyOverlay();        /* remove code */
  591.  
  592.     while(msg = (CxMsg *)GetMsg(broker_mp))
  593.     {
  594.         msgid = CxMsgID(msg);
  595.         msgtype = CxMsgType(msg);
  596.         ReplyMsg((struct Message *)msg);
  597.  
  598.         switch(msgtype)
  599.         {
  600.             case CXM_IEVENT:
  601.  
  602.                 switch(msgid)
  603.                 {
  604.             case HK_POPKEY:
  605.             ShowWindow();    /* check error return? */
  606.             break;
  607.  
  608.             case HK_CLOSEKEY:
  609.             DoCloseWindow();
  610.             break;
  611.  
  612.             case HK_ZIPKEY:
  613.             case HK_SHRINKKEY:
  614.             case HK_ZOOMKEY:
  615.             HandleWindowKey(msgid);
  616.                         break;
  617.  
  618.             case HK_WORKBENCH:
  619.             {
  620.                 struct Window *w;
  621.  
  622.                 if (w = FindWBWindow())
  623.                 {
  624.                 WBenchToFront();
  625.                 ActivateWindow(w);
  626.                 }
  627.             }
  628.             break;
  629.                 
  630.             case HK_POPPALKEY:
  631.             CreateNewProc((struct TagItem *)palette_taglist);
  632.             break;
  633.  
  634.             case HK_POPCLI:
  635.             {
  636.                 struct Screen *s;
  637.                 if (s = LockPubScreen(NULL))
  638.                 {
  639.                 ScreenToFront(s);
  640.                 UnlockPubScreen(NULL, s);
  641.                 }
  642.                 MyPri(ORIGINAL);
  643.                 SystemTagList(PopCommand, NULL);
  644.                 MyPri(ACTIVE);
  645.             }
  646.             break;
  647.  
  648.             case HK_INSDATE:
  649.             InsertDate();
  650.             break;
  651.  
  652.             case HK_CYCLEWIN:
  653.             DoCycleWindows();
  654.             break;
  655.  
  656.             case HK_CYCLESCR:
  657.             DoCycleScreens();
  658.             break;
  659.  
  660.             case HK_CENTERSCR:
  661.             DoCenterScreen();
  662.             break;
  663.  
  664.             case HK_SCRTOBACK:    /* replacement for lcommand m */
  665.             MyScreenToBack(IntuitionBase->FirstScreen);
  666.             break;
  667.  
  668.             case HK_BLANK:
  669.             BlankScreen();
  670.             break;
  671.                 }
  672.                 break;
  673.  
  674.             case CXM_COMMAND:
  675.                 switch(msgid)
  676.                 {
  677.                     case CXCMD_UNIQUE:
  678.             case CXCMD_APPEAR:
  679.             ShowWindow();    /* check error return? */
  680.             break;
  681.  
  682.             case CXCMD_DISAPPEAR:
  683.             HideWindow();
  684.             DummyOverlay();
  685.             break;
  686.  
  687.                     case CXCMD_DISABLE:
  688.                         ActivateCxObj(broker, 0L);
  689.                         break;
  690.  
  691.                     case CXCMD_ENABLE:
  692.                         ActivateCxObj(broker, 1L);
  693.                         break;
  694.  
  695.                     case CXCMD_KILL:
  696.                         returnvalue = 0L;
  697.                         break;
  698.                 }
  699.                 break;
  700.         }
  701.     }
  702.  
  703.     if (sigrcvd & SIGBREAKF_CTRL_C)
  704.         returnvalue = 0L;
  705.  
  706.     if (!returnvalue && palette_count)
  707.     {
  708.     PostError("Cannot exit yet:\npalette(s) remain open");
  709.     returnvalue = 1;
  710.     }
  711.     
  712.     return(returnvalue);
  713. }
  714.