home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 2: PC / frozenfish_august_1995.bin / bbs / d02xx / d0216.lha / BackDrop / src / backdrop.c < prev    next >
C/C++ Source or Header  |  1989-06-02  |  11KB  |  388 lines

  1. /*
  2.  * Backdrop (C) Copyright Eddy Carroll 1989, may be Freely Redistributed
  3.  *
  4.  * Backdrop allows you to define a pattern which will then be displayed
  5.  * in the empty screen area behind all the windows (who said Macintosh? :-)
  6.  *
  7.  * Usage: Backdrop { -a# | -b# | -f | -p# | -q | -s | B1B2B3B4B5B6B7B8}
  8.  *
  9.  * If no parameters are given, the default is a half tone grey pattern.
  10.  *
  11.  * -a or -b followed by a number sets the foreground or background colour
  12.  * to the corresponding pen number (0 - 3)
  13.  *
  14.  * -f and -s select either a SMART_REFRESH or SIMPLE_REFRESH window to
  15.  * display the backdrop pattern in. The former gives fast screen updates,
  16.  * but uses up quite a bit of memory, whereas the latter uses up very
  17.  * little memory but is slower at updating the screen.
  18.  *
  19.  * -p followed by a number selects the built in pattern corresponding to that
  20.  * number. If you try and select a pattern number not available, you get
  21.  * the default.
  22.  *
  23.  * -q kills the background copy of Backdrop currently installed, if any.
  24.  *
  25.  * A list of 16 hex digits will be interpreted as a user defined pattern,
  26.  * which should be viewed as an 8x8 grid.
  27.  *
  28.  * The first time you run Backdrop, it installs itself in memory. Future
  29.  * invocations of Backdrop will merely tell this first copy about any
  30.  * changes in parameters, until the -q option is used to remove it. Note
  31.  * that all the parameters, including window type, can be changed even
  32.  * while Backdrop is currently running.
  33.  *
  34.  * Compiles under Lattice C V4.0
  35.  *
  36.  */
  37.  
  38. #include <exec/types.h>
  39. #include <graphics/gfxbase.h>
  40. #include <graphics/gfxmacros.h>
  41. #include <intuition/intuition.h>
  42. #include <intuition/intuitionbase.h>
  43. #include <libraries/dos.h>
  44. #include <proto/exec.h>
  45. #include <proto/graphics.h>
  46. #include <proto/dos.h>
  47. #include <proto/intuition.h>
  48. #include <string.h>
  49.  
  50. #define tolower(c) ((c) >= 'A' && (c) <= 'Z' ? (c) + 'a' - 'A' : (c))
  51. #define YES        1
  52. #define NO        0
  53. #define NUMPATS    19        /* Number of predefined patterns available        */
  54. #define REPEAT  9999    /* Special return value indicates reopen window */
  55. #define UNSET    -1        /* Indicates a parameter is currently unset        */
  56.  
  57. #define htoi(c) (((c) >= 'A' ? (c) - 7 : (c)) & 0x0F)    /* Hex to int */
  58.  
  59. struct IntuitionBase *IntuitionBase;
  60. struct GfxBase *GfxBase;
  61. ULONG BackGroundIO = 0;
  62.  
  63. char usage1[] = "\
  64. Backdrop (C) Copyright Eddy Carroll 1989, adds backdrop to Workbench screen\n",
  65. usage2[] = "\
  66. Usage: Backdrop {-f | -p# | -q | -s | B1B2B3B4B5B6B7B8}\n\
  67. \n\
  68.         -a# - Set foreground colour to specified pen #\n\
  69.         -b# - Set background colour to specified pen #\n",
  70. usage3[] = "\
  71.         -f  - Enable fast update (uses more memory)\n\
  72.         -p# - Use specified pattern # (1-5)\n\
  73.         -q  - Remove backdrop from memory\n\
  74.         -s  - Enable slow update\n\
  75.    B1B2B3B4B5B6B7B8 - 16 hex digits defining an 8x8 pattern\n\
  76. \n> ";
  77. char quit1[] = "Backdrop removed.\n";
  78. char quit2[] = "Backdrop not installed.\n";
  79.  
  80. char Portname[] = "Backdrop";
  81.  
  82. struct Pattern {
  83.     UWORD value[8];
  84. } Patterns[] = {
  85.     { 0x5555,0xAAAA,0x5555,0xAAAA,0x5555,0xAAAA,0x5555,0xAAAA }, /* Check */
  86.     { 0xFFFF,0x4040,0x4040,0x4040,0xFFFF,0x0404,0x0404,0x0404 }, /* Brick */
  87.     { 0x8888,0x0000,0x0000,0x0000,0x8888,0x0000,0x0000,0x0000 },
  88.     { 0x8888,0x0000,0x2222,0x0000,0x8888,0x0000,0x2222,0x0000 },
  89.     { 0xAAAA,0x0000,0xAAAA,0x0000,0xAAAA,0x0000,0xAAAA,0x0000 },
  90.     { 0xAAAA,0x0000,0x5555,0x0000,0xAAAA,0x0000,0x5555,0x0000 },
  91.     { 0x8888,0x2222,0x8888,0x2222,0x8888,0x2222,0x8888,0x2222 },
  92.     { 0xAAAA,0xAAAA,0x5555,0x5555,0xAAAA,0xAAAA,0x5555,0x5555 },
  93.     { 0xCCCC,0x3333,0xCCCC,0x3333,0xCCCC,0x3333,0xCCCC,0x3333 },
  94.     { 0xFFFF,0x8181,0xBDBD,0xA5A5,0xA5A5,0xBDBD,0x8181,0xFFFF },
  95.     { 0xFEFE,0x8282,0xBABA,0xAAAA,0xBABA,0x8282,0xFEFE,0x0000 },
  96.     { 0x9999,0xCCCC,0x6666,0x3333,0x9999,0xCCCC,0x6666,0x3333 },
  97.     { 0x9999,0x3333,0x6666,0xCCCC,0x9999,0x3333,0x6666,0xCCCC },
  98.     { 0x0000,0x4444,0x2828,0x1010,0x2828,0x4444,0x0000,0x0000 },
  99.     { 0x0000,0x5454,0x0202,0x5858,0x1A1A,0x4040,0x2A2A,0x0000 },
  100.     { 0xAAAA,0x4444,0xAAAA,0x0000,0xAAAA,0x4444,0xAAAA,0x0000 },
  101.     { 0xC3C3,0x6666,0x3C3C,0x1818,0x3C3C,0x6666,0xC3C3,0x8181 },
  102.     { 0xDBDB,0x6666,0x3C3C,0x9999,0x9999,0x3C3C,0x6666,0xDBDB },
  103.     { 0x6666,0xF0F0,0x9999,0x0F0F,0x6666,0xF0F0,0x9999,0x0F0F },
  104.     { 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF }
  105. };
  106.  
  107. struct MyMsgPort {
  108.     struct MsgPort mp;                /* A genuine message port    */
  109.     struct Pattern pat;                /* Current pattern            */
  110.     ULONG  windowflags;                /* Flags for our window        */
  111.     UBYTE  foreground,background;    /* Colours for window        */
  112. } port;
  113.  
  114. typedef struct MessagePort    MP;
  115. typedef struct MyMsgPort    MyMP;
  116. typedef struct IntuiMessage    IM;
  117.  
  118. #define WINDOWFLAGS    (BORDERLESS | BACKDROP)
  119.  
  120. struct NewWindow nw = {
  121.     0,0,
  122.     320,200,    /* Max dimensions will be filled in at run time */
  123.     0,1,        /* These colours are also filled in at run time */
  124.     REFRESHWINDOW,
  125.     NULL,    /* Window flags will be filled in at run time */
  126.     NULL, NULL,
  127.     NULL,
  128.     NULL, NULL,
  129.     0,0,0,0,
  130.     WBENCHSCREEN
  131. };
  132.  
  133. /*
  134.  * The start of the program. All main does is interpret the command line
  135.  * parameters, and then determine whether there is already a copy of Backdrop
  136.  * running or not. If there isn't, a public message port is set up for
  137.  * future reference, else the other copy of Backdrop is informed of the
  138.  * changes to the parameters.
  139.  *
  140.  */
  141.  
  142. void main(argc,argv)
  143. int argc;
  144. char *argv[];
  145. {
  146.     int quit = NO, error = NO;
  147.     UWORD n,i,j;
  148.     MyMP *myport;
  149.     struct Task *FindTask(), *othertask;
  150.     char *p;
  151.     int doback();
  152.     void resloop();
  153.     BPTR stdout;
  154.  
  155.     stdout = Output();
  156.  
  157.     /*   Check to see if we are already running. If we are, initialise
  158.      *   contents of our local port structure with the current contents,
  159.      *   else initialise them to default values.
  160.      */
  161.  
  162.     if ((myport = (MyMP *)FindPort(Portname)) == NULL) {
  163.         /* --- First time being run --- */
  164.         port.foreground = 1;                     /* Default pen colour     */
  165.         port.background = 0;                     /* Default background col */
  166.         port.windowflags = SMART_REFRESH | WINDOWFLAGS;     /* Window type    */
  167.         port.pat = Patterns[0];                     /* Default pattern        */
  168.         port.mp.mp_Node.ln_Name = Portname;      /* Set the port name      */
  169.         port.mp.mp_SigBit = AllocSignal(-1L);     /* Get signal # for port  */
  170.     } else {
  171.         /* --- Already running a copy --- */
  172.         port = *myport;    /* Get copy of current contents */
  173.     }
  174.  
  175.     /* Now parse command line, updating parameters as necessary */
  176.  
  177.     while (argc > 1) {
  178.         if (argv[1][0] == '-') {
  179.             n = atoi(&argv[1][2]);    /* Get possible second parameter */
  180.             switch (tolower(argv[1][1])) {
  181.                 case 'a':
  182.                     port.foreground = n;
  183.                     break;
  184.                 case 'b':
  185.                     port.background = n;
  186.                     break;
  187.                 case 'p':
  188.                     if (n < 0 || n > NUMPATS-1)
  189.                         n = 0;
  190.                     port.pat = Patterns[n];
  191.                     break;
  192.                 case 'q':
  193.                     quit = YES;
  194.                     break;
  195.                 case 'f':
  196.                     port.windowflags = WINDOWFLAGS | SMART_REFRESH;
  197.                     break;
  198.                 case 's':
  199.                     port.windowflags = WINDOWFLAGS | SIMPLE_REFRESH;
  200.                     break;
  201.                 default:
  202.                     error = YES;
  203.                     break;
  204.             }
  205.         } else if ((strlen(p = argv[1])) == 16) {
  206.             /* Convert 16 digit hex value into pattern */
  207.             for (i = 0; i < 8; i++) {
  208.                 for (n = 0, j = 0; j < 2; j++,p++) {
  209.                     n = n<<4 | htoi(*p);
  210.                 }
  211.                 port.pat.value[i] = n<<8 | n;
  212.             }
  213.         } else
  214.             error = YES;
  215.  
  216.         if (error) {
  217.             Write(stdout,usage1,sizeof(usage1));
  218.             Write(stdout,usage2,sizeof(usage2));
  219.             Write(stdout,usage3,sizeof(usage3));
  220.             exit(10);
  221.         }
  222.         argv++;
  223.         argc--;
  224.     }
  225.  
  226.     /*   Now local copy of port contains an up-to-date copy of the
  227.      *   current settings
  228.      */
  229.  
  230.     if (myport == NULL) {
  231.         /* --- First time being run --- */
  232.         if (quit) {
  233.             Write(stdout,quit2,sizeof(quit2));
  234.             exit(10);    /* No work to do if backdrop not active already */
  235.         }
  236.         Write(stdout,usage1,sizeof(usage1));
  237.         AddPort(&port);                             /* Make our port public  */
  238.         /* Detach this process from CLI, and setup process ID in port    */
  239.         if (!res("Backdrop",4,resloop,4000))
  240.             RemPort(&port);
  241.         exit(0);
  242.     } else {
  243.         othertask = myport->mp.mp_SigTask;
  244.  
  245.         /* If quit, tell the other copy to quit */
  246.         if (quit) {
  247.             Write(stdout,quit1,sizeof(quit1));
  248.             Signal(othertask, SIGBREAKF_CTRL_C);
  249.             exit(0);
  250.         }
  251.  
  252.         /* Else we have a new pattern to install */
  253.         Forbid();    /* Stop other copy trying to access the array */
  254.         *myport = port; /* Copy updated parameters back to global store */
  255.         Permit();
  256.         Signal(othertask, SIGBREAKF_CTRL_F); /* Force screen update */
  257.         exit(0);
  258.     }
  259. }
  260.  
  261. /*
  262.  * This is the main loop. It just keeps looping around, until it is told
  263.  * to exit (via a special return value from doback()). When it returns,
  264.  * it actually is returning to AmigaDOS() which will then remove it from
  265.  * the system.
  266.  *
  267.  */
  268. void resloop()
  269. {
  270.     port.mp.mp_SigTask = FindTask(0L);    /* Set pointer to our task */
  271.     while (doback() == REPEAT)         /* Do intuition stuff      */
  272.         ;
  273.     /* We got some kind of exit code, so clean up */
  274.     RemPort(&port);    /* Kill our public port  */
  275. }
  276.  
  277. /*
  278.  * This routine is where all the actual work gets done. A backdrop window
  279.  * is opened on the workbench screen, and filled with the current pattern.
  280.  * Then it waits for messages from Intuition saying the window needs to be
  281.  * refreshed, and for signals from other invocations of Backdrop. A CTRL-C
  282.  * signal causes Backdrop to remove itself, and CTRL-F forces the screen
  283.  * to be updated. The return value is an error code, in case some resources
  284.  * couldn't be allocated (0 or 10).
  285.  *
  286.  */
  287.  
  288. #define OLIB(a,b) ((a = (struct a *)OpenLibrary(b,33L)) == NULL)
  289.  
  290. int doback()
  291. {
  292.     struct Window *win;
  293.     struct RastPort *rp;
  294.     struct Screen *scr;
  295.     IM *msg;
  296.     int err = 10, xmax, ymax,;
  297.     ULONG signal,lock;
  298.  
  299.     if (OLIB(IntuitionBase,"intuition.library"))
  300.         goto err1;
  301.  
  302.     if (OLIB(GfxBase,"graphics.library"))
  303.         goto err2;
  304.  
  305.     /* Now find the maximum size for our window by peeking at the dimensions
  306.      * of the Workbench screen. If no workbench screen is open, we exit.
  307.      */
  308.     lock = LockIBase(0L);
  309.     for (scr = IntuitionBase->FirstScreen; scr; scr = scr->NextScreen) {
  310.         if ((scr->Flags & SCREENTYPE) == WBENCHSCREEN) {
  311.             xmax = scr->Width;
  312.             ymax = scr->Height;
  313.             break;
  314.         }
  315.     }
  316.     UnlockIBase(lock);
  317.  
  318.     if (scr == NULL)
  319.         goto err2;    /* If couldn't find workbench screen, we fail */
  320.  
  321.     nw.Width  = xmax;
  322.     nw.Height = ymax;
  323.     nw.Flags  = port.windowflags;
  324.  
  325.     if ((win = OpenWindow(&nw)) == NULL)
  326.         goto err3;
  327.  
  328.     err = 0;    /* Everything opened ok, so indicate no error */
  329.     rp = win->RPort;
  330.     SetDrMd(rp,JAM2);
  331.     SetAfPt(rp,&port.pat.value[0],3);    /* Set area pattern */
  332.  
  333.  
  334. #define IDCMPMASK (1<<win->UserPort->mp_SigBit)
  335. #define CTRL_C (SIGBREAKF_CTRL_C)
  336. #define CTRL_F (SIGBREAKF_CTRL_F)
  337.  
  338.     while (1) {
  339.         SetAPen(rp,port.foreground);
  340.         SetBPen(rp,port.background);
  341.         RectFill(rp,0,0,xmax,ymax);
  342.         signal = Wait(CTRL_C | CTRL_F | IDCMPMASK);
  343.  
  344.         /* If we got a CTRL_C, break out of this loop */
  345.         if (signal & CTRL_C)
  346.             break;
  347.  
  348.         /* Else was CTRL_F or a refresh event from Intuition */
  349.  
  350.         if (signal & IDCMPMASK) {
  351.             /* Flush Intuition messages */
  352.             while ((msg = (IM *)GetMsg(win->UserPort)) != NULL)
  353.                 ReplyMsg(msg);
  354.         }
  355.  
  356.         /* Now check if user wants a different sort of window type */
  357.  
  358.         if (nw.Flags != port.windowflags) {
  359.             err = REPEAT;    /* Indicate we want to reopen window */
  360.             break;
  361.         }
  362.         /* Else loop back to start, and force redraw of window */
  363.     }
  364.  
  365.     /* We get down to here if a CTRL_C is received */
  366.  
  367.     err4:
  368.         CloseWindow(win);
  369.  
  370.     err3:
  371.         CloseLibrary(GfxBase);
  372.  
  373.     err2:
  374.         CloseLibrary(IntuitionBase);
  375.  
  376.     err1:
  377.         return(err);
  378. }
  379.  
  380. /*
  381.  *   These definitions just stop the corresponding library routines getting
  382.  *   pulled in, which helps keep the code size down.
  383.  */
  384.  
  385. int brk(){return(0);}
  386. void MemCleanup(){}
  387. void chkabort(){}
  388.