home *** CD-ROM | disk | FTP | other *** search
- /*
- * Backdrop (C) Copyright Eddy Carroll 1989, may be Freely Redistributed
- *
- * Backdrop allows you to define a pattern which will then be displayed
- * in the empty screen area behind all the windows (who said Macintosh? :-)
- *
- * Usage: Backdrop { -a# | -b# | -f | -p# | -q | -s | B1B2B3B4B5B6B7B8}
- *
- * If no parameters are given, the default is a half tone grey pattern.
- *
- * -a or -b followed by a number sets the foreground or background colour
- * to the corresponding pen number (0 - 3)
- *
- * -f and -s select either a SMART_REFRESH or SIMPLE_REFRESH window to
- * display the backdrop pattern in. The former gives fast screen updates,
- * but uses up quite a bit of memory, whereas the latter uses up very
- * little memory but is slower at updating the screen.
- *
- * -p followed by a number selects the built in pattern corresponding to that
- * number. If you try and select a pattern number not available, you get
- * the default.
- *
- * -q kills the background copy of Backdrop currently installed, if any.
- *
- * A list of 16 hex digits will be interpreted as a user defined pattern,
- * which should be viewed as an 8x8 grid.
- *
- * The first time you run Backdrop, it installs itself in memory. Future
- * invocations of Backdrop will merely tell this first copy about any
- * changes in parameters, until the -q option is used to remove it. Note
- * that all the parameters, including window type, can be changed even
- * while Backdrop is currently running.
- *
- * Compiles under Lattice C V4.0
- *
- */
-
- #include <exec/types.h>
- #include <graphics/gfxbase.h>
- #include <graphics/gfxmacros.h>
- #include <intuition/intuition.h>
- #include <intuition/intuitionbase.h>
- #include <libraries/dos.h>
- #include <proto/exec.h>
- #include <proto/graphics.h>
- #include <proto/dos.h>
- #include <proto/intuition.h>
- #include <string.h>
-
- #define tolower(c) ((c) >= 'A' && (c) <= 'Z' ? (c) + 'a' - 'A' : (c))
- #define YES 1
- #define NO 0
- #define NUMPATS 19 /* Number of predefined patterns available */
- #define REPEAT 9999 /* Special return value indicates reopen window */
- #define UNSET -1 /* Indicates a parameter is currently unset */
-
- #define htoi(c) (((c) - '0' - 7 * ((c) >= 'A')) & 0x0F) /* Hex to int */
-
- struct IntuitionBase *IntuitionBase;
- struct GfxBase *GfxBase;
- ULONG BackGroundIO = 0;
-
- char usage1[] = "\
- Backdrop (C) Copyright Eddy Carroll 1989, adds backdrop to Workbench screen\n",
- usage2[] = "\
- Usage: Backdrop {-f | -p# | -q | -s | B1B2B3B4B5B6B7B8}\n\
- \n\
- -a# - Set foreground colour to specified pen #\n\
- -b# - Set background colour to specified pen #\n",
- usage3[] = "\
- -f - Enable fast update (uses more memory)\n\
- -p# - Use specified pattern # (1-5)\n\
- -q - Remove backdrop from memory\n\
- -s - Enable slow update\n\
- B1B2B3B4B5B6B7B8 - 16 hex digits defining an 8x8 pattern\n\
- \n> ";
-
- char Portname[] = "Backdrop";
-
- struct Pattern {
- UWORD value[8];
- } Patterns[] = {
- { 0x5555,0xAAAA,0x5555,0xAAAA,0x5555,0xAAAA,0x5555,0xAAAA }, /* Check */
- { 0xFFFF,0x4040,0x4040,0x4040,0xFFFF,0x0404,0x0404,0x0404 }, /* Brick */
- { 0x8888,0x0000,0x0000,0x0000,0x8888,0x0000,0x0000,0x0000 },
- { 0x8888,0x0000,0x2222,0x0000,0x8888,0x0000,0x2222,0x0000 },
- { 0xAAAA,0x0000,0xAAAA,0x0000,0xAAAA,0x0000,0xAAAA,0x0000 },
- { 0xAAAA,0x0000,0x5555,0x0000,0xAAAA,0x0000,0x5555,0x0000 },
- { 0x8888,0x2222,0x8888,0x2222,0x8888,0x2222,0x8888,0x2222 },
- { 0xAAAA,0xAAAA,0x5555,0x5555,0xAAAA,0xAAAA,0x5555,0x5555 },
- { 0xCCCC,0x3333,0xCCCC,0x3333,0xCCCC,0x3333,0xCCCC,0x3333 },
- { 0xFFFF,0x8181,0xBDBD,0xA5A5,0xA5A5,0xBDBD,0x8181,0xFFFF },
- { 0xFEFE,0x8282,0xBABA,0xAAAA,0xBABA,0x8282,0xFEFE,0x0000 },
- { 0x9999,0xCCCC,0x6666,0x3333,0x9999,0xCCCC,0x6666,0x3333 },
- { 0x9999,0x3333,0x6666,0xCCCC,0x9999,0x3333,0x6666,0xCCCC },
- { 0x0000,0x4444,0x2828,0x1010,0x2828,0x4444,0x0000,0x0000 },
- { 0x0000,0x5454,0x0202,0x5858,0x1A1A,0x4040,0x2A2A,0x0000 },
- { 0xAAAA,0x4444,0xAAAA,0x0000,0xAAAA,0x4444,0xAAAA,0x0000 },
- { 0xC3C3,0x6666,0x3C3C,0x1818,0x3C3C,0x6666,0xC3C3,0x8181 },
- { 0xDBDB,0x6666,0x3C3C,0x9999,0x9999,0x3C3C,0x6666,0xDBDB },
- { 0x6666,0xF0F0,0x9999,0x0F0F,0x6666,0xF0F0,0x9999,0x0F0F },
- { 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF }
- };
-
- struct MyMsgPort {
- struct MsgPort mp; /* A genuine message port */
- struct Pattern pat; /* Current pattern */
- ULONG windowflags; /* Flags for our window */
- UBYTE foreground,background; /* Colours for window */
- } port;
-
- typedef struct MessagePort MP;
- typedef struct MyMsgPort MyMP;
- typedef struct IntuiMessage IM;
-
- #define WINDOWFLAGS (BORDERLESS | BACKDROP)
-
- struct NewWindow nw = {
- 0,0,
- 320,200, /* Max dimensions will be filled in at run time */
- 0,1, /* These colours are also filled in at run time */
- REFRESHWINDOW,
- NULL, /* Window flags will be filled in at run time */
- NULL, NULL,
- NULL,
- NULL, NULL,
- 0,0,0,0,
- WBENCHSCREEN
- };
-
- /*
- * The start of the program. All main does is interpret the command line
- * parameters, and then determine whether there is already a copy of Backdrop
- * running or not. If there isn't, a public message port is set up for
- * future reference, else the other copy of Backdrop is informed of the
- * changes to the parameters.
- *
- */
-
- void main(argc,argv)
- int argc;
- char *argv[];
- {
- int quit = NO, error = NO;
- UWORD n,i,j;
- MyMP *myport;
- struct Task *FindTask(), *othertask;
- char *p;
- int doback();
- void resloop();
- BPTR stdout;
-
- stdout = Output();
- Write(stdout,usage1,sizeof(usage1));
-
- /* Check to see if we are already running. If we are, initialise
- * contents of our local port structure with the current contents,
- * else initialise them to default values.
- */
-
- if ((myport = (MyMP *)FindPort(Portname)) == NULL) {
- /* --- First time being run --- */
- port.foreground = 1; /* Default pen colour */
- port.background = 0; /* Default background col */
- port.windowflags = SMART_REFRESH | WINDOWFLAGS; /* Window type */
- port.pat = Patterns[0]; /* Default pattern */
- port.mp.mp_Node.ln_Name = Portname; /* Set the port name */
- port.mp.mp_SigBit = AllocSignal(-1L); /* Get signal # for port */
- } else {
- /* --- Already running a copy --- */
- port = *myport; /* Get copy of current contents */
- }
-
- /* Now parse command line, updating parameters as necessary */
-
- while (argc > 1) {
- if (argv[1][0] == '-') {
- n = atoi(&argv[1][2]); /* Get possible second parameter */
- switch (tolower(argv[1][1])) {
- case 'a':
- port.foreground = n;
- break;
- case 'b':
- port.background = n;
- break;
- case 'p':
- if (n < 0 || n > NUMPATS-1)
- n = 0;
- port.pat = Patterns[n];
- break;
- case 'q':
- quit = YES;
- break;
- case 'f':
- port.windowflags = WINDOWFLAGS | SMART_REFRESH;
- break;
- case 's':
- port.windowflags = WINDOWFLAGS | SIMPLE_REFRESH;
- break;
- default:
- error = YES;
- break;
- }
- } else if ((strlen(p = argv[1])) == 16) {
- /* Convert 16 digit hex value into pattern */
- for (i = 0; i < 8; i++) {
- for (n = 0, j = 0; j < 2; j++,p++) {
- n = n<<4 | htoi(*p);
- }
- port.pat.value[i] = n<<8 | n;
- }
- } else
- error = YES;
-
- if (error) {
- Write(stdout,usage2,sizeof(usage2));
- Write(stdout,usage3,sizeof(usage3));
- exit(10);
- }
- argv++;
- argc--;
- }
-
- /* Now local copy of port contains an up-to-date copy of the
- * current settings
- */
-
- if (myport == NULL) {
- /* --- First time being run --- */
- if (quit)
- exit(10); /* No work to do if backdrop not active already */
- AddPort(&port); /* Make our port public */
- /* Detach this process from CLI, and setup process ID in port */
- if (!res("Backdrop",4,resloop,4000))
- RemPort(&port);
- exit(0);
- } else {
- othertask = myport->mp.mp_SigTask;
-
- /* If quit, tell the other copy to quit */
- if (quit) {
- Signal(othertask, SIGBREAKF_CTRL_C);
- exit(0);
- }
-
- /* Else we have a new pattern to install */
- Forbid(); /* Stop other copy trying to access the array */
- *myport = port; /* Copy updated parameters back to global store */
- Permit();
- Signal(othertask, SIGBREAKF_CTRL_F); /* Force screen update */
- exit(0);
- }
- }
-
- /*
- * This is the main loop. It just keeps looping around, until it is told
- * to exit (via a special return value from doback()). When it returns,
- * it actually is returning to AmigaDOS() which will then remove it from
- * the system.
- *
- */
- void resloop()
- {
- port.mp.mp_SigTask = FindTask(0L); /* Set pointer to our task */
- while (doback() == REPEAT) /* Do intuition stuff */
- ;
- /* We got some kind of exit code, so clean up */
- RemPort(&port); /* Kill our public port */
- }
-
- /*
- * This routine is where all the actual work gets done. A backdrop window
- * is opened on the workbench screen, and filled with the current pattern.
- * Then it waits for messages from Intuition saying the window needs to be
- * refreshed, and for signals from other invocations of Backdrop. A CTRL-C
- * signal causes Backdrop to remove itself, and CTRL-F forces the screen
- * to be updated. The return value is an error code, in case some resources
- * couldn't be allocated (0 or 10).
- *
- */
-
- #define OLIB(a,b) ((a = (struct a *)OpenLibrary(b,33L)) == NULL)
-
- int doback()
- {
- struct Window *win;
- struct RastPort *rp;
- struct Screen *scr;
- IM *msg;
- int err = 10, xmax, ymax,;
- ULONG signal,lock;
-
- if (OLIB(IntuitionBase,"intuition.library"))
- goto err1;
-
- if (OLIB(GfxBase,"graphics.library"))
- goto err2;
-
- /* Now find the maximum size for our window by peeking at the dimensions
- * of the Workbench screen. If no workbench screen is open, we exit.
- */
- lock = LockIBase(0L);
- for (scr = IntuitionBase->FirstScreen; scr; scr = scr->NextScreen) {
- if ((scr->Flags & SCREENTYPE) == WBENCHSCREEN) {
- xmax = scr->Width;
- ymax = scr->Height;
- break;
- }
- }
- UnlockIBase(lock);
-
- if (scr == NULL)
- goto err2; /* If couldn't find workbench screen, we fail */
-
- nw.Width = xmax;
- nw.Height = ymax;
- nw.Flags = port.windowflags;
-
- if ((win = OpenWindow(&nw)) == NULL)
- goto err3;
-
- err = 0; /* Everything opened ok, so indicate no error */
- rp = win->RPort;
- SetDrMd(rp,JAM2);
- SetAfPt(rp,&port.pat.value[0],3); /* Set area pattern */
-
-
- #define IDCMPMASK (1<<win->UserPort->mp_SigBit)
- #define CTRL_C (SIGBREAKF_CTRL_C)
- #define CTRL_F (SIGBREAKF_CTRL_F)
-
- while (1) {
- SetAPen(rp,port.foreground);
- SetBPen(rp,port.background);
- RectFill(rp,0,0,xmax,ymax);
- signal = Wait(CTRL_C | CTRL_F | IDCMPMASK);
-
- /* If we got a CTRL_C, break out of this loop */
- if (signal & CTRL_C)
- break;
-
- /* Else was CTRL_F or a refresh event from Intuition */
-
- if (signal & IDCMPMASK) {
- /* Flush Intuition messages */
- while ((msg = (IM *)GetMsg(win->UserPort)) != NULL)
- ReplyMsg((APTR)msg);
- }
-
- /* Now check if user wants a different sort of window type */
-
- if (nw.Flags != port.windowflags) {
- err = REPEAT; /* Indicate we want to reopen window */
- break;
- }
- /* Else loop back to start, and force redraw of window */
- }
-
- /* We get down to here if a CTRL_C is received */
-
- err4:
- CloseWindow(win);
-
- err3:
- CloseLibrary(GfxBase);
-
- err2:
- CloseLibrary(IntuitionBase);
-
- err1:
- return(err);
- }
-
- /*
- * These definitions just stop the corresponding library routines getting
- * pulled in, which helps keep the code size down.
- */
-
- int brk(){return(0);}
- void MemCleanup(){}
- void chkabort(){}
-