home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d5xx / d588 / fracblank.lha / FracBlank / FracBlank.c < prev    next >
C/C++ Source or Header  |  1992-01-04  |  32KB  |  1,548 lines

  1. /* $Revision Header * Header built automatically - do not edit! *************
  2.  *
  3.  *    (C) Copyright 1991 by Olaf Barthel & MXM
  4.  *
  5.  *    Name .....: FracBlank.c
  6.  *    Created ..: Friday 18-Jun-91 15:28
  7.  *    Revision .: 8
  8.  *
  9.  *    Date            Author          Comment
  10.  *    =========       ========        ====================
  11.  *    09-Sep-91    Olsen        Numerous bug fixes.
  12.  *    17-Aug-91    Olsen        Rewrote sprite blanker code.
  13.  *    17-Aug-91    Olsen        Added cycle gadget.
  14.  *    12-Aug-91    Olsen        Added multicolour/monochrome mode.
  15.  *    30-Jun-91    Olsen        VBlank code revised.
  16.  *    29-Jun-91    Olsen        Added VBlank interrupt server.
  17.  *    21-Jun-91    Olsen        Optimizations, cleanups.
  18.  *    18-Jun-91    Olsen        Created this file!
  19.  *
  20.  * $Revision Header ********************************************************/
  21.  
  22.     /* Include the specific math pragmas/header files here (is there
  23.      * any way to figure this out by taking a look at predefined
  24.      * compiler symbols?).
  25.      */
  26.  
  27. #ifdef MATH_FFP
  28. #include <clib/mathtrans_protos.h>
  29. #include <proto/mathtrans.h>
  30. #include <mffp.h>
  31. #else
  32. #include <m68881.h>
  33. #endif    /* MATH_FFP */
  34.  
  35. #include <math.h>
  36.  
  37.     /* sin -45° = cos -45° (saves precious calculation time). */
  38.  
  39. #define deg45    (-0.707106781)
  40.  
  41.     /* Hotkey IDs. */
  42.  
  43. enum    {    POP_WINDOW,BLANK_SCREEN };
  44.  
  45.     /* Gadget IDs. */
  46.  
  47. enum    {    GAD_SCREENTIMEOUT,GAD_PATTERNCHANGE,GAD_HOTKEY,
  48.         GAD_BLANKSCREEN,GAD_MONO,GAD_CYCLE,GAD_HIDE,GAD_QUIT };
  49.  
  50.     /* Dimensions of the control panel. */
  51.  
  52. #define WIDTH    284
  53. #define HEIGHT    113
  54.  
  55.     /* Program revision tag. */
  56.  
  57. STATIC const UBYTE * const VersTag = "\0$VER: FracBlank 1.8 (9.9.91)";
  58.  
  59.     /* Shared library identifiers. */
  60.  
  61. extern struct ExecBase    *SysBase;
  62. struct IntuitionBase    *IntuitionBase;
  63. struct GfxBase        *GfxBase;
  64. struct Library        *CxBase,
  65.             *IconBase,
  66.             *GadToolsBase;
  67.  
  68.     /* Blanker data. */
  69.  
  70. struct Task        *BlankTask;
  71. struct Screen        *BlankScreen;
  72.  
  73.     /* Commodities interface data. */
  74.  
  75. struct MsgPort        *CxPort;
  76. CxObj            *Broker;
  77.  
  78.     /* Gfx and gadtools data. */
  79.  
  80. struct Screen        *DefaultScreen;
  81. APTR             VisualInfo;
  82. struct TextFont        *Topaz;
  83. struct Gadget        *GadgetList;
  84. struct Gadget        *GadgetArray[8];
  85. struct Window        *Window;
  86.  
  87.     /* Window zoom data. */
  88.  
  89. WORD             ZoomData[4] = { -1,-1,-1,-1 };
  90.  
  91.     /* Rainbow colour table. */
  92.  
  93. UWORD             Table[75];
  94.  
  95.     /* Key sequence buffers. */
  96.  
  97. UBYTE             HotkeyBuffer[256],BlankScreenBuffer[256];
  98.  
  99.     /* Screen and pattern change timeout. */
  100.  
  101. ULONG             ScreenCount = 0,PatternCount = 0,ScreenTimeout = 60,PatternTimeout = 60;
  102.  
  103.     /* Display mode: monochrome / multicolor. */
  104.  
  105. BYTE             Mono = FALSE,Cycle = TRUE;
  106.  
  107.     /* The default font to be used by the control panel. */
  108.  
  109. struct TextAttr DefaultFont =
  110. {
  111.     (UBYTE *)"topaz.font",
  112.     8,
  113.     FS_NORMAL,
  114.     FPF_ROMFONT
  115. };
  116.  
  117.     /* A new broker definition, Commodities needs this. */
  118.  
  119. struct NewBroker NewBroker =
  120. {
  121.     NB_VERSION,
  122.     "FracBlanker",
  123.     "Fractal Blanker v1.8",
  124.     "Screen Blanker",
  125.     NBU_NOTIFY | NBU_UNIQUE,
  126.     COF_SHOW_HIDE,
  127.     0,NULL,0
  128. };
  129.  
  130.     /* Function prototypes. */
  131.  
  132. extern VOID __asm    MonoPlot(register __a0 PLANEPTR Plane,register __d0 WORD x,register __d1 WORD y,register __d2 UWORD Modulo,register __d3 WORD MaxX,register __d4 WORD MaxY);
  133. extern VOID __asm    MultiPlot(register __a0 struct Screen *,register __d0 WORD X,register __d1 WORD Y,register __d2 WORD Colour);
  134.  
  135. VOID            StartBlanker(VOID);
  136. ULONG __regargs        Random(ULONG MaxValue);
  137. VOID __saveds        Blanker(VOID);
  138. VOID __saveds __stdargs    BlankerAction(CxMsg *CxMessage,CxObj *CxObject);
  139. VOID            ShutdownCx(VOID);
  140. BYTE __regargs        SetupCx(UBYTE **ToolTypes);
  141. VOID __regargs        HandleCxMsg(CxMsg *Message);
  142. LONG __saveds __stdargs    ShowTime(struct Gadget *SomeGadget,WORD Level);
  143. struct Gadget *        CreateAllGadgets(struct Gadget **GadgetArray,struct Gadget **GadgetList,APTR VisualInfo,UWORD TopEdge);
  144. VOID            ShutdownWindow(VOID);
  145. VOID __regargs        CentreWindow(struct Screen *Screen,WORD *LeftEdge,WORD *TopEdge);
  146. BYTE            SetupWindow(VOID);
  147. VOID __regargs        CloseAll(LONG ReturnCode);
  148. VOID __regargs        OpenAll(int argc,char **argv);
  149. VOID __stdargs        main(int argc,char **argv);
  150.  
  151.     /* StartBlanker():
  152.      *
  153.      *    Open the display screen and create the blanker task.
  154.      */
  155.  
  156. VOID
  157. StartBlanker()
  158. {
  159.     if(!BlankScreen)
  160.     {
  161.         struct Screen *Screen;
  162.  
  163.         if(Screen = OpenScreenTags(NULL,
  164.             SA_Behind,    TRUE,
  165.             SA_Quiet,    TRUE,
  166.             SA_DisplayID,    Mono ? HIRESLACE_KEY : LORES_KEY,
  167.             SA_Overscan,    OSCAN_MAX,
  168.             SA_Depth,    Mono ? 1 : 5,
  169.         TAG_DONE))
  170.         {
  171.             struct UCopList    *UserCopperList;
  172.  
  173.                 /* I had a lot of problems trying to shut down
  174.                  * the sprite display hardware completely.
  175.                  * The mouse pointer would pop up again after
  176.                  * a certain time interval, no matter what I
  177.                  * did.
  178.                  *
  179.                  * Now, Amy, you had your chance, hadn't you?
  180.                  * 
  181.                  * This is the big one: a user copper list will
  182.                  * shut down the sprite hardware. Full stop.
  183.                  */
  184.  
  185.             if(UserCopperList = (struct UCopList *)AllocMem(sizeof(struct UCopList),MEMF_PUBLIC|MEMF_CLEAR))
  186.             {
  187.                     /* Set up for 3 instruction. */
  188.  
  189.                 CINIT(UserCopperList,3);
  190.  
  191.                     /* Wait for first line. */
  192.  
  193.                 CWAIT(UserCopperList,0,0);
  194.  
  195.                     /* Disable sprite DMA. */
  196.  
  197.                 CMOVE(UserCopperList,custom . dmacon,BITCLR|DMAF_SPRITE);
  198.  
  199.                     /* Terminate copper instruction list. */
  200.  
  201.                 CEND(UserCopperList);
  202.  
  203.                     /* Install the copper list. */
  204.  
  205.                 Screen -> ViewPort . UCopIns = UserCopperList;
  206.  
  207.                     /* Link it into the screen copper list. */
  208.  
  209.                 RethinkDisplay();
  210.  
  211.                     /* Set the background colour to black. */
  212.  
  213.                 SetRGB4(&Screen -> ViewPort,0,0x0,0x0,0x0);
  214.  
  215.                     /* Display the screen. */
  216.  
  217.                 ScreenToFront(Screen);
  218.  
  219.                 BlankScreen = Screen;
  220.             }
  221.             else
  222.                 CloseScreen(Screen);
  223.         }
  224.     }
  225.  
  226.     if(BlankScreen)
  227.     {
  228.         PatternCount = 0;
  229.  
  230.         BlankTask = (struct Task *)CreateTask("FracBlank.task",-20,Blanker,4000);
  231.     }
  232. }
  233.  
  234.     /* Random(ULONG MaxValue):
  235.      *
  236.      *    Simple random number generation routine.
  237.      */
  238.  
  239. ULONG __regargs
  240. Random(ULONG MaxValue)
  241. {
  242.     STATIC ULONG RandomSeed = 0xDEAD0123;
  243.  
  244.     RandomSeed = RandomSeed * custom . vhposr + 0xE153766F;
  245.  
  246.     return(RandomSeed % MaxValue);
  247. }
  248.  
  249.     /* Blanker():
  250.      *
  251.      *    The screen blanker itself.
  252.      */
  253.  
  254. VOID __saveds
  255. Blanker()
  256. {
  257.     STATIC BYTE Wheel = 0;
  258.  
  259.     UWORD    Colours[32],OffsetX = BlankScreen -> Width >> 1,OffsetY = BlankScreen -> Height >> 1;
  260.     float    x = 0,y = 0,yy,a,b,c,sx,sy,mag,save;
  261.  
  262.     SetSignal(0,SIGBREAKF_CTRL_D|SIGBREAKF_CTRL_E);
  263.  
  264.         /* Are we running in monochrome mode? */
  265.  
  266.     if(Mono)
  267.     {
  268.         UWORD        Modulo = BlankScreen -> RastPort . BitMap -> BytesPerRow;
  269.         PLANEPTR    Plane = BlankScreen -> RastPort . BitMap -> Planes[0];
  270.  
  271.             /* Provide starting numbers for the fractal
  272.              * parameters.
  273.              */
  274.  
  275.         a = (float)Random(300) / 100;
  276.         b = (float)Random(100) / 100;
  277.         c = (float)Random( 50) / 100;
  278.  
  279.         mag = (float)(1 << (Random(4) + 5)) * deg45;
  280.  
  281.             /* Set up the screen colour table. */
  282.  
  283.         Colours[0] = 0;
  284.         Colours[1] = Table[Wheel];
  285.  
  286.         LoadRGB4(&BlankScreen -> ViewPort,Colours,2);
  287.  
  288.             /* Go into fractal generation loop. */
  289.  
  290.         FOREVER
  291.         {
  292.                 /* The original formula looks like
  293.                  * this:
  294.                  *                                     ½
  295.                  *    x <- y - SIGN(x) * ABS(b * x - c)
  296.                  *    y <- a - x
  297.                  *
  298.                  * I have split the calculation into
  299.                  * several steps to save time and
  300.                  * variables.
  301.                  */
  302.  
  303.             yy = a - x;
  304.  
  305.             if((save = b * x - c) < 0)
  306.                 save = -save;
  307.  
  308.             if(x < 0)
  309.                 x = y + sqrt(save);
  310.             else
  311.                 x = y - sqrt(save);
  312.  
  313.             y = yy;
  314.  
  315.                 /* The resulting image appears to have
  316.                  * been rotated by 45°, so we'll
  317.                  * rotate the pixel coordinates by -45°
  318.                  *
  319.                  *    x <-  x * cos alpha + y * sin alpha
  320.                  *    y <- -x * sin alpha + y * cos alpha
  321.                  *
  322.                  * We also magnify the image (i.e. the
  323.                  * distribution of pixels) in the following
  324.                  * lines.
  325.                  */
  326.  
  327.             sx = mag * ( x + y);
  328.             sy = mag * (-x + y);
  329.  
  330.                 /* If the pixel happens to reside within
  331.                  * the boundaries of the screen, draw it.
  332.                  */
  333.  
  334.             MonoPlot(Plane,(WORD)(sx) + OffsetX,(WORD)(sy) + OffsetY,Modulo,BlankScreen -> Width,BlankScreen -> Height);
  335.  
  336.                 /* ^D tells the blanker to change the pattern. */
  337.  
  338.             if(SetSignal(0,0) & SIGBREAKF_CTRL_D)
  339.             {
  340.                 SetSignal(0,SIGBREAKF_CTRL_D);
  341.  
  342.                 SetRast(&BlankScreen -> RastPort,0);
  343.  
  344.                 x = y = 0;
  345.  
  346.                 a = (float)Random(300) / 100;
  347.                 b = (float)Random(100) / 100;
  348.                 c = (float)Random( 50) / 100;
  349.  
  350.                 mag = (float)(1 << (Random(4) + 5)) * deg45;
  351.             }
  352.  
  353.                 /* ^E tells the blanker to rotate the
  354.                  * colours.
  355.                  */
  356.  
  357.             if(SetSignal(0,0) & SIGBREAKF_CTRL_E)
  358.             {
  359.                 SetSignal(0,SIGBREAKF_CTRL_E);
  360.  
  361.                 Colours[1] = Table[Wheel];
  362.  
  363.                 LoadRGB4(&BlankScreen -> ViewPort,Colours,2);
  364.  
  365.                 Wheel = (Wheel + 1) % 75;
  366.             }
  367.         }
  368.     }
  369.     else
  370.     {
  371.         STATIC UWORD Rainbow[32] =
  372.         {
  373.             0x0000,0x0F00,0x0F30,0x0F50,
  374.             0x0F70,0x0F90,0x0FB0,0x0FD0,
  375.             0x0FF0,0x0DF0,0x0BF0,0x09F0,
  376.             0x07F0,0x05F0,0x03F0,0x00F0,
  377.             0x00D1,0x00B3,0x0095,0x0077,
  378.             0x0059,0x003B,0x001D,0x000F,
  379.             0x010F,0x030F,0x050F,0x070F,
  380.             0x090F,0x0B0F,0x0D0F,0x0F0F
  381.         };
  382.  
  383.         UWORD         Count = 0;
  384.         WORD         i;
  385.         BYTE         Colour = 1,Plus = 1;
  386.         struct RastPort    *RPort;
  387.  
  388.         a = (float)Random(300) / 100;
  389.         b = (float)Random(100) / 100;
  390.         c = (float)Random( 50) / 100;
  391.  
  392.         mag = (float)(1 << (Random(4) + 2)) * deg45;
  393.  
  394.         Colours[0] = 0x000;
  395.  
  396.         for(i = 1 ; i < 32 ; i++)
  397.             Colours[i] = Table[(Wheel + i) % 75];
  398.  
  399.         if(Cycle)
  400.             LoadRGB4(&BlankScreen -> ViewPort,Colours,32);
  401.         else
  402.             LoadRGB4(&BlankScreen -> ViewPort,Rainbow,32);
  403.  
  404.         Wheel = (Wheel + 1) % 75;
  405.  
  406.         RPort = &BlankScreen -> RastPort;
  407.  
  408.         FOREVER
  409.         {
  410.             yy = a - x;
  411.  
  412.             if((save = b * x - c) < 0)
  413.                 save = -save;
  414.  
  415.             if(x < 0)
  416.                 x = y + sqrt(save);
  417.             else
  418.                 x = y - sqrt(save);
  419.  
  420.             y = yy;
  421.  
  422.             sx = mag * ( x + y);
  423.             sy = mag * (-x + y);
  424.  
  425.             MultiPlot(BlankScreen,(WORD)(sx) + OffsetX,(WORD)(sy) + OffsetY,Colour);
  426.  
  427.                 /* Oh well, it's not that easy to
  428.                  * produce decent colour values for
  429.                  * the pixels to be rendered.
  430.                  *
  431.                  * The following statement will change
  432.                  * the current drawing pen after exactly
  433.                  * 900 pixels have been rendered and will
  434.                  * pick a new colour between 1 and 31.
  435.                  */
  436.  
  437.             if(Count++ >= 900)
  438.             {
  439.                 Count = 0;
  440.  
  441.                 Colour += Plus;
  442.  
  443.                 if(!Colour)
  444.                 {
  445.                     Plus    = 1;
  446.                     Colour    = 2;
  447.                 }
  448.                 else
  449.                 {
  450.                     if(Colour == 32)
  451.                     {
  452.                         Plus    = -1;
  453.                         Colour    = 30;
  454.                     }
  455.                 }
  456.             }
  457.  
  458.             if(SetSignal(0,0) & SIGBREAKF_CTRL_D)
  459.             {
  460.                 SetSignal(0,SIGBREAKF_CTRL_D);
  461.  
  462.                 SetRast(RPort,0);
  463.  
  464.                 x = y = 0;
  465.  
  466.                 a = (float)Random(300) / 100;
  467.                 b = (float)Random(100) / 100;
  468.                 c = (float)Random( 50) / 100;
  469.  
  470.                 mag = (float)(1 << (Random(4) + 2)) * deg45;
  471.             }
  472.  
  473.             if(SetSignal(0,0) & SIGBREAKF_CTRL_E)
  474.             {
  475.                 SetSignal(0,SIGBREAKF_CTRL_E);
  476.  
  477.                 for(i = 1 ; i < 32 ; i++)
  478.                     Colours[i] = Table[(Wheel + i) % 75];
  479.  
  480.                 if(Cycle)
  481.                     LoadRGB4(&BlankScreen -> ViewPort,Colours,32);
  482.  
  483.                 Wheel = (Wheel + 1) % 75;
  484.             }
  485.         }
  486.     }
  487.  
  488.         /* Quietly remove ourselves. */
  489.  
  490.     Forbid();
  491.  
  492.     BlankTask = NULL;
  493.  
  494.     RemTask(SysBase -> ThisTask);
  495. }
  496.  
  497.     /* BlankerAction(CxMsg *CxMessage,CxObj *CxObject):
  498.      *
  499.      *    Commodities support routine, handles the Commodities
  500.      *    custom actions (in this case: filter the InputEvents
  501.      *    coming in and enable/disable the screen blanker).
  502.      */
  503.  
  504. VOID __saveds __stdargs
  505. BlankerAction(CxMsg *CxMessage,CxObj *CxObject)
  506. {
  507.     STATIC BYTE Count = 1;
  508.  
  509.     struct InputEvent *Event = (struct InputEvent *)CxMsgData(CxMessage);
  510.  
  511.         /* Push the blanker screen to the front if necessary. */
  512.  
  513.     if(BlankScreen)
  514.     {
  515.         if(BlankScreen -> TopEdge)
  516.             MoveScreen(BlankScreen,0,-BlankScreen -> TopEdge);
  517.  
  518.         if(IntuitionBase -> FirstScreen != BlankScreen)
  519.             ScreenToFront(BlankScreen);
  520.     }
  521.  
  522.         /* This looks like a timer event. */
  523.  
  524.     if(Event -> ie_Class == IECLASS_TIMER && !Window)
  525.     {
  526.             /* Screen blanker still inactive? */
  527.  
  528.         if(!BlankTask)
  529.         {
  530.                 /* Is there a timeout to take care of? */
  531.  
  532.             if(ScreenTimeout)
  533.             {
  534.                     /* Are we ready to create the
  535.                      * screenblanker?
  536.                      */
  537.  
  538.                 if(ScreenCount++ >= ScreenTimeout * 10)
  539.                 {
  540.                     if(!BlankTask)
  541.                         StartBlanker();
  542.                 }
  543.             }
  544.         }
  545.         else
  546.         {
  547.             if(Count < 0)
  548.                 Count = 0;
  549.  
  550.                 /* Every 5/60 second we signal the blanker
  551.                  * task to rotate the palette.
  552.                  */
  553.  
  554.             if(Count++ >= 2)
  555.             {
  556.                 Signal(BlankTask,SIGBREAKF_CTRL_E);
  557.  
  558.                 Count = 0;
  559.             }
  560.  
  561.                 /* Is it time to change the pattern? */
  562.  
  563.             if(PatternTimeout)
  564.             {
  565.                 if(PatternCount++ >= PatternTimeout * 10)
  566.                 {
  567.                     Signal(BlankTask,SIGBREAKF_CTRL_D);
  568.  
  569.                     PatternCount = 0;
  570.                 }
  571.             }
  572.         }
  573.     }
  574.     else
  575.     {
  576.             /* The following line determines whether
  577.              * the blanker is to be removed or to
  578.              * be left running.
  579.              */
  580.  
  581.         if((Event -> ie_Class == IECLASS_RAWKEY && !(Event -> ie_Code & IECODE_UP_PREFIX) && !(Event -> ie_Qualifier & IEQUALIFIER_REPEAT)) || Event -> ie_Class == IECLASS_RAWMOUSE)
  582.         {
  583.                 /* Remove the blanker task. */
  584.  
  585.             if(BlankTask)
  586.             {
  587.                 struct Task *Task = BlankTask;
  588.  
  589.                 BlankTask = NULL;
  590.  
  591.                 RemTask(Task);
  592.             }
  593.  
  594.                 /* Close the blanker screen. */
  595.  
  596.             if(BlankScreen)
  597.             {
  598.                 struct Screen *Screen = BlankScreen;
  599.  
  600.                 BlankScreen = NULL;
  601.  
  602.                 ScreenToBack(Screen);
  603.  
  604.                 FreeVPortCopLists(&Screen -> ViewPort);
  605.  
  606.                 RemakeDisplay();
  607.  
  608.                 CloseScreen(Screen);
  609.             }
  610.         }
  611.  
  612.         ScreenCount = 0;
  613.     }
  614. }
  615.  
  616.     /* ShutdownCx():
  617.      *
  618.      *    Close the Commodities interface.
  619.      */
  620.  
  621. VOID
  622. ShutdownCx()
  623. {
  624.     if(CxPort)
  625.     {
  626.         struct Message *Message;
  627.  
  628.             /* Remove the broker. */
  629.  
  630.         if(Broker)
  631.             DeleteCxObjAll(Broker);
  632.  
  633.             /* Remove the MsgPort from the public list. */
  634.  
  635.         RemPort(CxPort);
  636.  
  637.             /* Remove all pending messages. */
  638.  
  639.         while(Message = GetMsg(CxPort))
  640.             ReplyMsg(Message);
  641.  
  642.             /* Delete the MsgPort. */
  643.  
  644.         DeleteMsgPort(CxPort);
  645.  
  646.         CxPort = NULL;
  647.         Broker = NULL;
  648.     }
  649. }
  650.  
  651.     /* GetSeconds(UBYTE *String):
  652.      *
  653.      *    Calculates the number of seconds corresponding to
  654.      *    expressions such as `11:25' or `10'.
  655.      */
  656.  
  657. WORD
  658. GetSeconds(UBYTE *String)
  659. {
  660.     WORD i,Seconds;
  661.  
  662.     for(i = strlen(String) - 1 ; i >= 0 ; i--)
  663.     {
  664.         if(String[i] == ':')
  665.         {
  666.             Seconds = atol(&String[i + 1]);
  667.  
  668.             String[i] = 0;
  669.  
  670.             Seconds += 60 * atol(String);
  671.  
  672.             if(Seconds > 30 * 60)
  673.                 Seconds = 30 * 60;
  674.  
  675.             return(Seconds);
  676.         }
  677.     }
  678.  
  679.     if((Seconds = atol(String)) > 30 * 60)
  680.         Seconds = 30 * 60;
  681.  
  682.     return(Seconds);
  683. }
  684.  
  685.     /* SetupCx(UBYTE **ToolTypes):
  686.      *
  687.      *    Set up the Commodities interface.
  688.      */
  689.  
  690. BYTE __regargs
  691. SetupCx(UBYTE **ToolTypes)
  692. {
  693.         /* Cancel any previously made assignments. */
  694.  
  695.     ShutdownCx();
  696.  
  697.         /* Create a reply port. */
  698.  
  699.     if(CxPort = CreateMsgPort())
  700.     {
  701.             /* Fill in a unique name. */
  702.  
  703.         CxPort -> mp_Node . ln_Name = NewBroker . nb_Name;
  704.  
  705.             /* Add the reply port to the public list. */
  706.  
  707.         AddPort(CxPort);
  708.  
  709.             /* Install the replyport. */
  710.  
  711.         NewBroker . nb_Port = CxPort;
  712.  
  713.             /* Set the Commodity priority if possible. */
  714.  
  715.         if(ToolTypes)
  716.             NewBroker . nb_Pri  = ArgInt(ToolTypes,"CX_PRIORITY",0);
  717.  
  718.             /* Create the broker. */
  719.  
  720.         if(Broker = CxBroker(&NewBroker,NULL))
  721.         {
  722.             CxObj    *ObjectList;
  723.             UBYTE    *String,Buffer[256];
  724.  
  725.             if(ToolTypes)
  726.             {
  727.                     /* Set the Commodity popup hotkey if possible. */
  728.  
  729.                 String = ArgString(ToolTypes,"CX_POPKEY","shift f1");
  730.  
  731.                 strcpy(HotkeyBuffer,String);
  732.  
  733.                     /* Determine the screen blanker hotkey. */
  734.  
  735.                 String = ArgString(ToolTypes,"BLANKSCREEN","shift f2");
  736.  
  737.                 strcpy(BlankScreenBuffer,String);
  738.  
  739.                     /* Cycle the multicolour palette? */
  740.  
  741.                 String = ArgString(ToolTypes,"CYCLE","yes");
  742.  
  743.                 if(!strcmpi(String,"yes"))
  744.                     Cycle = TRUE;
  745.                 else
  746.                     Cycle = FALSE;
  747.  
  748.                     /* Run in monochrome mode? */
  749.  
  750.                 String = ArgString(ToolTypes,"MONO","no");
  751.  
  752.                 if(!strcmpi(String,"yes"))
  753.                     Mono = TRUE;
  754.                 else
  755.                     Mono = FALSE;
  756.  
  757.                     /* Adjust the screen timeout if possible. */
  758.  
  759.                 strcpy(Buffer,ArgString(ToolTypes,"SCREENTIMEOUT","1:00"));
  760.  
  761.                 ScreenTimeout = GetSeconds(Buffer);
  762.  
  763.                     /* Adjust the pattern change timeout if possible. */
  764.  
  765.                 strcpy(Buffer,ArgString(ToolTypes,"PATTERNTIMEOUT","1:00"));
  766.  
  767.                 PatternTimeout = GetSeconds(Buffer);
  768.             }
  769.  
  770.                 /* Link the hotkey. */
  771.  
  772.             AttachCxObj(Broker,HotKey(HotkeyBuffer,CxPort,POP_WINDOW));
  773.  
  774.                 /* Link another hotkey. */
  775.  
  776.             AttachCxObj(Broker,HotKey(BlankScreenBuffer,CxPort,BLANK_SCREEN));
  777.  
  778.                 /* Install the plain InputEvent handler. */
  779.  
  780.             ObjectList = CxCustom(BlankerAction,NULL);
  781.  
  782.                 /* Any accumulated errors? */
  783.  
  784.             if(!CxObjError(ObjectList))
  785.             {
  786.                     /* Add the custom object. */
  787.  
  788.                 AttachCxObj(Broker,ObjectList);
  789.  
  790.                     /* Any errors? */
  791.  
  792.                 if(!CxObjError(Broker))
  793.                 {
  794.                         /* Activate the broker. */
  795.  
  796.                     ActivateCxObj(Broker,TRUE);
  797.  
  798.                     return(TRUE);
  799.                 }
  800.             }
  801.         }
  802.     }
  803.  
  804.     ShutdownCx();
  805.  
  806.     return(FALSE);
  807. }
  808.  
  809.     /* HandleCxMsg(CxMsg *Message):
  810.      *
  811.      *    Handle incoming Commodities messages.
  812.      */
  813.  
  814. VOID __regargs
  815. HandleCxMsg(CxMsg *Message)
  816. {
  817.     ULONG MessageID = CxMsgID(Message),MessageType = CxMsgType(Message);
  818.  
  819.     ReplyMsg((struct Message *)Message);
  820.  
  821.         /* Take a look at the message type. */
  822.  
  823.     switch(MessageType)
  824.     {
  825.             /* It's a hotkey. */
  826.  
  827.         case CXM_IEVENT:    switch(MessageID)
  828.                     {
  829.                             /* Create the control panel. */
  830.  
  831.                         case POP_WINDOW:    SetupWindow();
  832.                                     break;
  833.  
  834.                             /* Blank the screen. */
  835.  
  836.                         case BLANK_SCREEN:    if(!BlankTask)
  837.                                         StartBlanker();
  838.                                     else
  839.                                     {
  840.                                             /* Tell the blanker task to change the pattern. */
  841.  
  842.                                         Signal(BlankTask,SIGBREAKF_CTRL_D);
  843.  
  844.                                         PatternCount = 0;
  845.                                     }
  846.  
  847.                                     break;
  848.                     }
  849.  
  850.                     break;
  851.  
  852.             /* It's an internal Commodities command. */
  853.  
  854.         case CXM_COMMAND:    switch(MessageID)
  855.                     {
  856.                             /* Disable the Commodity. */
  857.  
  858.                         case CXCMD_DISABLE:    ActivateCxObj(Broker,FALSE);
  859.                                     break;
  860.  
  861.                             /* Enable the Commodity. */
  862.  
  863.                         case CXCMD_ENABLE:    ActivateCxObj(Broker,TRUE);
  864.                                     break;
  865.  
  866.                             /* Create the control panel. */
  867.  
  868.                         case CXCMD_APPEAR:
  869.                         case CXCMD_UNIQUE:    SetupWindow();
  870.                                     break;
  871.  
  872.                             /* Close the control panel. */
  873.  
  874.                         case CXCMD_DISAPPEAR:    ShutdownWindow();
  875.                                     break;
  876.  
  877.                             /* Remove this Commodity. */
  878.  
  879.                         case CXCMD_KILL:    CloseAll(RETURN_OK);
  880.                                     break;
  881.                     }
  882.  
  883.                     break;
  884.     }
  885. }
  886.  
  887.     /* ShowTime(struct Gadget *SomeGadget,WORD Level):
  888.      *
  889.      *    Gadtools support routine, displays the timeouts.
  890.      */
  891.  
  892. LONG __saveds __stdargs
  893. ShowTime(struct Gadget *SomeGadget,WORD Level)
  894. {
  895.     STATIC UBYTE Buffer[30];
  896.  
  897.     if(Level)
  898.         SPrintf(Buffer,"%2ld.%02ld",Level / 60,Level % 60);
  899.     else
  900.         SPrintf(Buffer,"-Off-");
  901.  
  902.     return((LONG)Buffer);
  903. }
  904.  
  905.     /* CreateAllGadgets():
  906.      *
  907.      *    Gadtools support routine, creates all the gadgets
  908.      *    required by the control panel.
  909.      */
  910.  
  911. struct Gadget *
  912. CreateAllGadgets(struct Gadget **GadgetArray,struct Gadget **GadgetList,APTR VisualInfo,UWORD TopEdge)
  913. {
  914.     struct Gadget        *Gadget;
  915.     struct NewGadget     NewGadget;
  916.     UWORD             Counter = 0;
  917.  
  918.     if(Gadget = CreateContext(GadgetList))
  919.     {
  920.         NewGadget . ng_Width        = 104;
  921.         NewGadget . ng_Height        = 12;
  922.         NewGadget . ng_GadgetText    = "_Screen Timeout      ";
  923.         NewGadget . ng_TextAttr        = &DefaultFont;
  924.         NewGadget . ng_VisualInfo    = VisualInfo;
  925.         NewGadget . ng_GadgetID        = Counter;
  926.         NewGadget . ng_Flags        = 0;
  927.         NewGadget . ng_LeftEdge        = (strlen(NewGadget . ng_GadgetText) + 2 - 1) * 8 - 2;
  928.         NewGadget . ng_TopEdge        = 1 + TopEdge;
  929.  
  930.         GadgetArray[Counter++] = Gadget = CreateGadget(SLIDER_KIND,Gadget,&NewGadget,
  931.             GT_Underscore,        '_',
  932.             GTSL_Min,        0,
  933.             GTSL_Max,        30 * 60,
  934.             GTSL_Level,        ScreenTimeout,
  935.             GTSL_DispFunc,        ShowTime,
  936.             GTSL_LevelFormat,    "%s",
  937.             GTSL_MaxLevelLen,    5,
  938.         TAG_DONE);
  939.  
  940.         NewGadget . ng_GadgetText     = "_Pattern Change      ";
  941.         NewGadget . ng_GadgetID         = Counter;
  942.         NewGadget . ng_TopEdge        += NewGadget . ng_Height + 1;
  943.  
  944.         GadgetArray[Counter++] = Gadget = CreateGadget(SLIDER_KIND,Gadget,&NewGadget,
  945.             GT_Underscore,        '_',
  946.             GTSL_Min,        0,
  947.             GTSL_Max,        30 * 60,
  948.             GTSL_Level,        PatternTimeout,
  949.             GTSL_DispFunc,        ShowTime,
  950.             GTSL_LevelFormat,    "%s",
  951.             GTSL_MaxLevelLen,    5,
  952.         TAG_DONE);
  953.  
  954.         NewGadget . ng_GadgetText     = "Hot _Key";
  955.         NewGadget . ng_GadgetID         = Counter;
  956.         NewGadget . ng_TopEdge        += NewGadget . ng_Height + 2;
  957.         NewGadget . ng_Height         = 14;
  958.  
  959.         GadgetArray[Counter++] = Gadget = CreateGadget(STRING_KIND,Gadget,&NewGadget,
  960.             GT_Underscore,    '_',
  961.             GTST_MaxChars,    256,
  962.             GTST_String,    HotkeyBuffer,
  963.         TAG_DONE);
  964.  
  965.         NewGadget . ng_GadgetText     = "_Blank Screen";
  966.         NewGadget . ng_GadgetID         = Counter;
  967.         NewGadget . ng_TopEdge        += NewGadget . ng_Height + 1;
  968.         NewGadget . ng_Height         = 14;
  969.  
  970.         GadgetArray[Counter++] = Gadget = CreateGadget(STRING_KIND,Gadget,&NewGadget,
  971.             GT_Underscore,    '_',
  972.             GTST_MaxChars,    256,
  973.             GTST_String,    BlankScreenBuffer,
  974.         TAG_DONE);
  975.  
  976.         NewGadget . ng_GadgetText     = "_Monochrome";
  977.         NewGadget . ng_GadgetID         = Counter;
  978.         NewGadget . ng_TopEdge        += NewGadget . ng_Height + 2;
  979.         NewGadget . ng_Height         = 12;
  980.  
  981.         GadgetArray[Counter++] = Gadget = CreateGadget(CHECKBOX_KIND,Gadget,&NewGadget,
  982.             GT_Underscore,    '_',
  983.             GTCB_Checked,    Mono,
  984.         TAG_DONE);
  985.  
  986.         NewGadget . ng_GadgetText     = "_Cycle";
  987.         NewGadget . ng_GadgetID         = Counter;
  988.         NewGadget . ng_TopEdge        += NewGadget . ng_Height + 1;
  989.  
  990.         GadgetArray[Counter++] = Gadget = CreateGadget(CHECKBOX_KIND,Gadget,&NewGadget,
  991.             GT_Underscore,    '_',
  992.             GTCB_Checked,    Cycle,
  993.         TAG_DONE);
  994.  
  995.         NewGadget . ng_GadgetText    = "_Hide";
  996.         NewGadget . ng_GadgetID        = Counter;
  997.         NewGadget . ng_Flags        = 0;
  998.         NewGadget . ng_LeftEdge        = 6;
  999.         NewGadget . ng_TopEdge        = HEIGHT - 3 - NewGadget . ng_Height;
  1000.  
  1001.         GadgetArray[Counter++] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
  1002.             GT_Underscore,    '_',
  1003.         TAG_DONE);
  1004.  
  1005.         NewGadget . ng_GadgetText    = "_Quit";
  1006.         NewGadget . ng_GadgetID        = Counter;
  1007.         NewGadget . ng_LeftEdge        = WIDTH - 6 - NewGadget . ng_Width;
  1008.  
  1009.         GadgetArray[Counter++] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
  1010.             GT_Underscore,    '_',
  1011.         TAG_DONE);
  1012.     }
  1013.  
  1014.     return(Gadget);
  1015. }
  1016.  
  1017.     /* ShutdownWindow():
  1018.      *
  1019.      *    Closes the control panel.
  1020.      */
  1021.  
  1022. VOID
  1023. ShutdownWindow()
  1024. {
  1025.     if(Window)
  1026.     {
  1027.         CloseWindow(Window);
  1028.  
  1029.         Window = NULL;
  1030.     }
  1031.  
  1032.     if(GadgetList)
  1033.     {
  1034.         FreeGadgets(GadgetList);
  1035.  
  1036.         GadgetList = NULL;
  1037.     }
  1038.  
  1039.     if(VisualInfo)
  1040.     {
  1041.         FreeVisualInfo(VisualInfo);
  1042.  
  1043.         VisualInfo = NULL;
  1044.     }
  1045.  
  1046.     if(DefaultScreen)
  1047.     {
  1048.         UnlockPubScreen(NULL,DefaultScreen);
  1049.  
  1050.         DefaultScreen = NULL;
  1051.     }
  1052.  
  1053.     if(Topaz)
  1054.     {
  1055.         CloseFont(Topaz);
  1056.  
  1057.         Topaz = NULL;
  1058.     }
  1059. }
  1060.  
  1061.     /* CentreWindow():
  1062.      *
  1063.      *    Adjust left/top coordinates of window to be opened to
  1064.      *    become visible right below the mouse pointer.
  1065.      */
  1066.  
  1067. VOID __regargs
  1068. CentreWindow(struct Screen *Screen,WORD *LeftEdge,WORD *TopEdge)
  1069. {
  1070.     (*LeftEdge)    = Screen -> MouseX - (WIDTH >> 1);
  1071.     (*TopEdge)    = Screen -> MouseY - (HEIGHT >> 1);
  1072.  
  1073.     while((*LeftEdge) + WIDTH > Screen -> Width)
  1074.         (*LeftEdge)--;
  1075.  
  1076.     while((*LeftEdge) < 0)
  1077.         (*LeftEdge)++;
  1078.  
  1079.     while((*TopEdge) + HEIGHT > Screen -> Height)
  1080.         (*TopEdge)--;
  1081.  
  1082.     while((*TopEdge) < 0)
  1083.         (*TopEdge)++;
  1084. }
  1085.  
  1086.     /* SetupWindow():
  1087.      *
  1088.      *    Creates the control panel and disables the screen
  1089.      *    blanker.
  1090.      */
  1091.  
  1092. BYTE
  1093. SetupWindow()
  1094. {
  1095.     if(BlankTask)
  1096.     {
  1097.         struct Task *Task = BlankTask;
  1098.  
  1099.         BlankTask = NULL;
  1100.  
  1101.         RemTask(Task);
  1102.     }
  1103.  
  1104.     if(BlankScreen)
  1105.     {
  1106.         struct Screen *Screen = BlankScreen;
  1107.  
  1108.         BlankScreen = NULL;
  1109.  
  1110.         ScreenToBack(Screen);
  1111.  
  1112.         FreeVPortCopLists(&Screen -> ViewPort);
  1113.  
  1114.         RemakeDisplay();
  1115.  
  1116.         CloseScreen(Screen);
  1117.     }
  1118.  
  1119.     if(Window)
  1120.         return(TRUE);
  1121.  
  1122.     if(Topaz = (struct TextFont *)OpenFont(&DefaultFont))
  1123.     {
  1124.         if(DefaultScreen = (struct Screen *)LockPubScreen(NULL))
  1125.         {
  1126.             if(VisualInfo = GetVisualInfo(DefaultScreen,TAG_DONE))
  1127.             {
  1128.                 if(CreateAllGadgets(&GadgetArray[0],&GadgetList,VisualInfo,DefaultScreen -> WBorTop + DefaultScreen -> Font -> ta_YSize + 1))
  1129.                 {
  1130.                     WORD Left,Top;
  1131.  
  1132.                     CentreWindow(DefaultScreen,&Left,&Top);
  1133.  
  1134.                     if(ZoomData[0] == -1)
  1135.                     {
  1136.                         ZoomData[0] = 0;
  1137.                         ZoomData[1] = 0;
  1138.                         ZoomData[2] = WIDTH;
  1139.                         ZoomData[3] = DefaultScreen -> WBorTop + DefaultScreen -> Font -> ta_YSize + 1;
  1140.                     }
  1141.  
  1142.                     if(Window = OpenWindowTags(NULL,
  1143.                         WA_Left,    Left,
  1144.                         WA_Top,        Top,
  1145.  
  1146.                         WA_Width,    WIDTH,
  1147.                         WA_Height,    HEIGHT + DefaultScreen -> Font -> ta_YSize - 8,
  1148.  
  1149.                         WA_Activate,    TRUE,
  1150.                         WA_DragBar,    TRUE,
  1151.                         WA_DepthGadget,    TRUE,
  1152.                         WA_CloseGadget,    TRUE,
  1153.                         WA_RMBTrap,    TRUE,
  1154.                         WA_Zoom,    ZoomData,
  1155.  
  1156.                         WA_IDCMP,    IDCMP_CLOSEWINDOW | IDCMP_VANILLAKEY | IDCMP_NEWSIZE | SLIDERIDCMP | BUTTONIDCMP,
  1157.  
  1158.                         WA_Title,    "Fractal Blanker v1.8",
  1159.                     TAG_DONE))
  1160.                     {
  1161.                         SetFont(Window -> RPort,Topaz);
  1162.  
  1163.                         AddGList(Window,GadgetList,(UWORD)-1,(UWORD)-1,NULL);
  1164.                         RefreshGList(GadgetList,Window,NULL,(UWORD)-1);
  1165.                         GT_RefreshWindow(Window,NULL);
  1166.  
  1167.                         MoveScreen(Window -> WScreen,0,-Window -> WScreen -> TopEdge);
  1168.                         ScreenToFront(Window -> WScreen);
  1169.  
  1170.                         UnlockPubScreen(NULL,DefaultScreen);
  1171.  
  1172.                         DefaultScreen = NULL;
  1173.  
  1174.                         return(TRUE);
  1175.                     }
  1176.                 }
  1177.             }
  1178.         }
  1179.     }
  1180.  
  1181.     ShutdownWindow();
  1182.  
  1183.     return(FALSE);
  1184. }
  1185.  
  1186.     /* CloseAll(LONG ReturnCode):
  1187.      *
  1188.      *    Free all resources and exit the program.
  1189.      */
  1190.  
  1191. VOID __regargs
  1192. CloseAll(LONG ReturnCode)
  1193. {
  1194.     if(CxBase && IconBase)
  1195.     {
  1196.         ShutdownCx();
  1197.  
  1198.         ArgArrayDone();
  1199.     }
  1200.  
  1201.     if(BlankTask)
  1202.         RemTask(BlankTask);
  1203.  
  1204.     if(BlankScreen)
  1205.     {
  1206.         ScreenToBack(BlankScreen);
  1207.  
  1208.         FreeVPortCopLists(&BlankScreen -> ViewPort);
  1209.  
  1210.         RemakeDisplay();
  1211.  
  1212.         CloseScreen(BlankScreen);
  1213.  
  1214.         BlankScreen = NULL;
  1215.     }
  1216.  
  1217.     ShutdownWindow();
  1218.  
  1219.     if(IconBase)
  1220.         CloseLibrary(IconBase);
  1221.  
  1222.     if(CxBase)
  1223.         CloseLibrary(CxBase);
  1224.  
  1225.     if(GadToolsBase)
  1226.         CloseLibrary(GadToolsBase);
  1227.  
  1228.     if(GfxBase)
  1229.         CloseLibrary(GfxBase);
  1230.  
  1231.     if(IntuitionBase)
  1232.         CloseLibrary(IntuitionBase);
  1233.  
  1234.     exit(ReturnCode);
  1235. }
  1236.  
  1237.     /* OpenAll(int argc,char **argv):
  1238.      *
  1239.      *    Open all resources, initialize the colour table and
  1240.      *    create the Commodities interface.
  1241.      */
  1242.  
  1243. VOID __regargs
  1244. OpenAll(int argc,char **argv)
  1245. {
  1246.     UBYTE    **ToolTypes,*String;
  1247.     WORD    i,c = 0,r = 15,g = 0,b = 0;
  1248.  
  1249.         /* Create a table of rainbow colours. */
  1250.  
  1251.     for(i = 0 ; i < 16 ; i++)
  1252.         Table[c++] = (r << 8) | ((g++) << 4) | b;
  1253.  
  1254.     g = 15;
  1255.     r--;
  1256.  
  1257.     for(i = 0 ; i < 15 ; i++)
  1258.         Table[c++] = ((r--) << 8) | (g << 4) | b;
  1259.  
  1260.     r = 0;
  1261.     g--;
  1262.     b++;
  1263.  
  1264.     for(i = 0 ; i < 15 ; i++)
  1265.         Table[c++] = (r << 8) | ((g--) << 4) | (b++);
  1266.  
  1267.     g = 0;
  1268.     b = 15;
  1269.     r++;
  1270.  
  1271.     for(i = 0 ; i < 15 ; i++)
  1272.         Table[c++] = ((r++) << 8) | (g << 4) | b;
  1273.  
  1274.     r = 15;
  1275.     b--;
  1276.  
  1277.     for(i = 0 ; i < 14 ; i++)
  1278.         Table[c++] = (r << 8) | (g << 4) | (b--);
  1279.  
  1280.         /* Open the libraries we need. */
  1281.  
  1282.     if(!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",37)))
  1283.         CloseAll(RETURN_FAIL + 0);
  1284.  
  1285.     if(!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",37)))
  1286.         CloseAll(RETURN_FAIL + 1);
  1287.  
  1288.     if(!(GadToolsBase = OpenLibrary("gadtools.library",37)))
  1289.         CloseAll(RETURN_FAIL + 2);
  1290.  
  1291.     if(!(CxBase = OpenLibrary("commodities.library",37)))
  1292.         CloseAll(RETURN_FAIL + 3);
  1293.  
  1294.     if(!(IconBase = OpenLibrary("icon.library",37)))
  1295.         CloseAll(RETURN_FAIL + 4);
  1296.  
  1297.         /* Parse the startup arguments. */
  1298.  
  1299.     ToolTypes = ArgArrayInit(argc,argv);
  1300.  
  1301.         /* Provide default values. */
  1302.  
  1303.     strcpy(HotkeyBuffer,        "shift f1");
  1304.     strcpy(BlankScreenBuffer,    "shift f2");
  1305.  
  1306.         /* Create the commodities interface. */
  1307.  
  1308.     if(!SetupCx(ToolTypes))
  1309.         CloseAll(RETURN_FAIL + 5);
  1310.  
  1311.         /* Pop up the control panel if necessary. */
  1312.  
  1313.     if(ToolTypes)
  1314.     {
  1315.         String = ArgString(ToolTypes,"CX_POPUP","no");
  1316.  
  1317.         if(!strcmpi(String,"yes"))
  1318.             SetupWindow();
  1319.     }
  1320. }
  1321.  
  1322.     /* main(int argc,char **argv):
  1323.      *
  1324.      *    That's where all the trouble starts.
  1325.      */
  1326.  
  1327. VOID __stdargs
  1328. main(int argc,char **argv)
  1329. {
  1330.     ULONG SignalSet;
  1331.  
  1332.         /* Open everything we need. */
  1333.  
  1334.     OpenAll(argc,argv);
  1335.  
  1336.         /* Go into loop waiting for messages. */
  1337.  
  1338.     FOREVER
  1339.     {
  1340.         SignalSet = (1 << CxPort -> mp_SigBit) | SIGBREAKF_CTRL_C;
  1341.  
  1342.             /* If the window is still open, wait for
  1343.              * some news.
  1344.              */
  1345.  
  1346.         if(Window)
  1347.             SignalSet |= (1 << Window -> UserPort -> mp_SigBit);
  1348.  
  1349.         SignalSet = Wait(SignalSet);
  1350.  
  1351.             /* There are messages pending at the
  1352.              * Commodities reply port.
  1353.              */
  1354.  
  1355.         if(SignalSet & (1 << CxPort -> mp_SigBit))
  1356.         {
  1357.             CxMsg *Message;
  1358.  
  1359.             while(Message = (CxMsg *)GetMsg(CxPort))
  1360.                 HandleCxMsg(Message);
  1361.         }
  1362.  
  1363.             /* ^E tells the program to quit. */
  1364.  
  1365.         if(SignalSet & SIGBREAKF_CTRL_C)
  1366.             CloseAll(RETURN_OK);
  1367.  
  1368.             /* If the control panel is still open,
  1369.              * check for new messages.
  1370.              */
  1371.  
  1372.         if(Window)
  1373.         {
  1374.             if(SignalSet & (1 << Window -> UserPort -> mp_SigBit))
  1375.             {
  1376.                 struct IntuiMessage    *Massage;
  1377.                 struct Gadget        *Gadget;
  1378.                 ULONG             Class,Code;
  1379.  
  1380.                 while(Massage = (struct IntuiMessage *)GT_GetIMsg(Window -> UserPort))
  1381.                 {
  1382.                     Class    = Massage -> Class;
  1383.                     Code    = Massage -> Code;
  1384.                     Gadget    = (struct Gadget *)Massage -> IAddress;
  1385.  
  1386.                     GT_ReplyIMsg(Massage);
  1387.  
  1388.                     switch(Class)
  1389.                     {
  1390.                             /* Close the window. */
  1391.  
  1392.                         case IDCMP_CLOSEWINDOW:    ShutdownWindow();
  1393.                                     break;
  1394.  
  1395.                         case IDCMP_NEWSIZE:    GT_RefreshWindow(Window,NULL);
  1396.                                     break;
  1397.  
  1398.                             /* Set the slider values. */
  1399.  
  1400.                         case IDCMP_MOUSEMOVE:    switch(Gadget -> GadgetID)
  1401.                                     {
  1402.                                         case GAD_SCREENTIMEOUT:    ScreenCount = 0;
  1403.                                                     ScreenTimeout = Code;
  1404.                                                     break;
  1405.  
  1406.                                         case GAD_PATTERNCHANGE:    PatternCount = 0;
  1407.                                                     PatternTimeout = Code;
  1408.                                                     break;
  1409.                                     }
  1410.  
  1411.                                     break;
  1412.  
  1413.                             /* Handle the keyboard shortcuts. */
  1414.  
  1415.                         case IDCMP_VANILLAKEY:    switch(toupper(Code))
  1416.                                     {
  1417.                                         case 'S':    ScreenCount = 0;
  1418.  
  1419.                                                 if(Code == 's')
  1420.                                                 {
  1421.                                                     if(ScreenTimeout + 1 <= 30 * 60)
  1422.                                                         ScreenTimeout++;
  1423.                                                     else
  1424.                                                         ScreenTimeout = ScreenTimeout + 1 - 30 * 60;
  1425.                                                 }
  1426.                                                 else
  1427.                                                 {
  1428.                                                     if(ScreenTimeout > 0)
  1429.                                                         ScreenTimeout--;
  1430.                                                     else
  1431.                                                         ScreenTimeout = 30 * 60;
  1432.                                                 }
  1433.  
  1434.                                                 GT_SetGadgetAttrs(GadgetArray[GAD_SCREENTIMEOUT],Window,NULL,
  1435.                                                     GTSL_Level,ScreenTimeout,
  1436.                                                 TAG_DONE);
  1437.  
  1438.                                                 break;
  1439.  
  1440.                                         case 'P':    PatternCount = 0;
  1441.  
  1442.                                                 if(Code == 'p')
  1443.                                                 {
  1444.                                                     if(PatternTimeout + 1 <= 30 * 60)
  1445.                                                         PatternTimeout++;
  1446.                                                     else
  1447.                                                         PatternTimeout = PatternTimeout + 1 - 30 * 60;
  1448.                                                 }
  1449.                                                 else
  1450.                                                 {
  1451.                                                     if(PatternTimeout > 0)
  1452.                                                         PatternTimeout--;
  1453.                                                     else
  1454.                                                         PatternTimeout = 30 * 60;
  1455.                                                 }
  1456.  
  1457.                                                 GT_SetGadgetAttrs(GadgetArray[GAD_PATTERNCHANGE],Window,NULL,
  1458.                                                     GTSL_Level,PatternTimeout,
  1459.                                                 TAG_DONE);
  1460.  
  1461.                                                 break;
  1462.  
  1463.                                         case 'K':    ActivateGadget(GadgetArray[GAD_HOTKEY],Window,NULL);
  1464.                                                 break;
  1465.  
  1466.                                         case 'B':    ActivateGadget(GadgetArray[GAD_BLANKSCREEN],Window,NULL);
  1467.                                                 break;
  1468.  
  1469.                                         case 'M':    Mono ^= TRUE;
  1470.  
  1471.                                                 GT_SetGadgetAttrs(GadgetArray[GAD_MONO],Window,NULL,
  1472.                                                     GTCB_Checked,Mono,
  1473.                                                 TAG_DONE);
  1474.  
  1475.                                                 break;
  1476.  
  1477.                                         case 'C':    Cycle ^= TRUE;
  1478.  
  1479.                                                 GT_SetGadgetAttrs(GadgetArray[GAD_CYCLE],Window,NULL,
  1480.                                                     GTCB_Checked,Cycle,
  1481.                                                 TAG_DONE);
  1482.  
  1483.                                                 break;
  1484.  
  1485.                                         case 'H':    ShutdownWindow();
  1486.                                                 break;
  1487.  
  1488.                                         case 'Q':    CloseAll(RETURN_OK);
  1489.  
  1490.                                         default:    break;
  1491.                                     }
  1492.  
  1493.                                     break;
  1494.  
  1495.                             /* Handle the gadgets themselves. */
  1496.  
  1497.                         case IDCMP_GADGETUP:    switch(Gadget -> GadgetID)
  1498.                                     {
  1499.                                         case GAD_HOTKEY:    strcpy(HotkeyBuffer,((struct StringInfo *)Gadget -> SpecialInfo) -> Buffer);
  1500.  
  1501.                                                     if(!SetupCx(NULL))
  1502.                                                         CloseAll(RETURN_FAIL + 5);
  1503.  
  1504.                                                     break;
  1505.  
  1506.                                         case GAD_BLANKSCREEN:    strcpy(BlankScreenBuffer,((struct StringInfo *)Gadget -> SpecialInfo) -> Buffer);
  1507.  
  1508.                                                     if(!SetupCx(NULL))
  1509.                                                         CloseAll(RETURN_FAIL + 5);
  1510.  
  1511.                                                     break;
  1512.  
  1513.                                         case GAD_MONO:        if(Gadget -> Flags & GFLG_SELECTED)
  1514.                                                         Mono = TRUE;
  1515.                                                     else
  1516.                                                         Mono = FALSE;
  1517.  
  1518.                                                     break;
  1519.  
  1520.                                         case GAD_CYCLE:        if(Gadget -> Flags & GFLG_SELECTED)
  1521.                                                         Cycle = TRUE;
  1522.                                                     else
  1523.                                                         Cycle = FALSE;
  1524.  
  1525.                                                     break;
  1526.  
  1527.                                         case GAD_HIDE:        ShutdownWindow();
  1528.                                                     break;
  1529.  
  1530.                                         case GAD_QUIT:        CloseAll(RETURN_OK);
  1531.                                     }
  1532.  
  1533.                                     break;
  1534.                     }
  1535.  
  1536.                         /* Window has been closed, do not
  1537.                          * continue requesting messages
  1538.                          * from the UserPort.
  1539.                          */
  1540.  
  1541.                     if(!Window)
  1542.                         break;
  1543.                 }
  1544.             }
  1545.         }
  1546.     }
  1547. }
  1548.