ewhac@well.UUCP (03/11/87)
[ I've been released from the NSA mental health ward. ] Hello again, I had hoped that I might be able to give you all an actual utility. As it turns out, I can't. Once upon a time, I saw a program for the Macintrash computer that loaded a picture into the Desktop's background, so that you would have a pretty picture to look at behind all your windows instead of just a boring pattern. I thought I'd try writing this for the Amiga. It shouldn't be too hard, I thought. Just change the WorkBench's backdrop window from SIMPLE_REFRESH to SMART_REFRESH, without mashing anything. Well, I got that far. But after modifying the backdrop window, I discovered a "feature" of the WorkBench. The disk icons are attached to the WorkBench backdrop window (obviously), and are therefore rendered in its RastPort. I had anticipated problems with this (disk icons might permanently mark a loaded image), but didn't know exactly how WorkBench dealt with it. I found out. Whenever you move a disk icon, or remove a volume from a drive, the WorkBench program *clears the screen* and redraws all the disk icons. Thus, if you render anything into the WorkBench window, it will get erased the moment you fiddle with the disk icons. This pretty much blew my idea out of the water. I can see no way around this, apart from replacing the SetRast() call in the graphics library (to check for to see if they're trying to clear the WorkBench and prevent it), or by rewriting the WorkBench (no, thanks). I also tried setting the RastPort's Mask value to 0. I thought this would prevent any subsequent rendering into the window. It was here I encountered what appears to be at first sight a bug in the graphics library. After rendering into the window, I set the Mask to 0. Everything appeared to be fixed on the screen. Then I moved my CLI window around. Everything underneath it was erased. "Hmmm," I thought. "Could it be that, when returning backup bitmaps to the visible screen, it's wrongly observing the Mask value?" As an experiment, I changed the mask value to 1 and tried moving the CLI window around again. After uncovering something, anything that was in the masked bitplane disappeared. I can only assume that the graphics library is trying to restore the visible bitmap while observing the Mask value, which strikes me as wrong. Dale Luck, you out there? Can you comment on this? (KS 1.2R, 512K CHIP, 2M FAST, 2 drives, MANX, written while listening to 1812 Overture (Guru alerts take on a whole new meaning :-) )) In any event, I did end up with some code that does, in fact, change the WorkBench window from SIMPLE_ to SMART_REFRESH. I thought you people might find it instuctive. And who knows; someone else may actually get my original idea working. The following program changes the identity of the WorkBench backdrop window, then draws a couple of lines in it to "prove" that it's really SMART now. You can move windows around, and the background will be preserved. However, the moment you fiddle with the disk icons, the window will be cleared, and the only thing you'll have to show for all this is a major loss of chip RAM. By the way, this is a MANX program. cc fixwb.c ln fixwb.o -lc -o fixwb Maybe you people can do something constructive with this. Thanks for your time and disk space. _-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_ ________ ___ Leo L. Schwab \ /___--__ The Guy in The Cape ___ ___ /\ ---##\ ihnp4!ptsfa!well!ewhac / X \_____ | __ _---)) ..or.. / /_\-- -----+==____\ // \ _ well ---\ ___ ( o---+------------------O/ \/ \ dual ----> !unicom!ewhac \ / ___ \_ (`o ) hplabs -/ ("AE-wack") ____ \___/ \_/ Recumbent Bikes: "Work FOR? I don't work FOR The _O_n_l_y Way To Fly! anybody! I'm just having fun." _-_-_-_-_-_-_-_-_-_-_ Apply Andy Finkel here. _-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_ /* :ts=8 bk=0 * * fixwb.c: A program to fix the WorkBench backdrop window into place, * by turning it into a SMART_REFRESH window. Also will load * an IFF image into the window, assuming I can figure out the * IFF spec. * * Sigh. As it turns out, the WorkBench program makes this effort * impossible since it clears the backdrop window everytime something new * happens with the disk icons. * * Leo L. Schwab 8703.10 (415)-456-6565 */ #include <exec/types.h> #include <intuition/intuition.h> /* Only the full-screen WorkBench window has these two flags set. */ #define WBACK (WBENCHWINDOW | BACKDROP) extern void *OpenLibrary(), *OpenWindow(), *CreateBehindLayer(); struct NewWindow windef = { 0, 30, 200, 10, -1, -1, NULL, WINDOWDRAG | WINDOWDEPTH | SMART_REFRESH | ACTIVATE, NULL, NULL, (UBYTE *) "Computing...", NULL, NULL, 0, 0, 0, 0, WBENCHSCREEN }; struct Window *win; void *IntuitionBase, *GfxBase, *LayersBase; main () { struct Screen *wbs; struct Layer_Info *li; struct Layer *wbl; struct Window *chk, *wbw = 0; long top, left, wide, high; long flags; openstuff (); wbs = win -> WScreen; /* Get pointer to WorkBench screen */ li = &wbs -> LayerInfo; for (chk = wbs -> FirstWindow; chk; chk = chk -> NextWindow) { flags = chk -> Flags; if ((flags & WBACK) == WBACK) { wbw = chk; break; } } if (!wbw) die ("WorkBench not loaded."); if ((flags & REFRESHBITS) == SMART_REFRESH) die ("WorkBench already fixed."); top = wbw -> TopEdge; left = wbw -> LeftEdge; wide = wbw -> Width; high = wbw -> Height; wbl = wbw -> RPort -> Layer; /* Get the layer pointer */ /* * At this point, we are about to perform what is probably * tantamount to rape to the system. Therefore, I'm Forbid()ing * anything else from running so as to prevent a major collapse. * * First, we stop everyone else. Then, we un-backdrop the layer * so we can depth-arrange it. We then bring it to the front, * forcing the layers library to save the state of everything else. * Then we change the identity of the layer from SIMPLE to SMART. * Then we depth-arrange it to the back again. This will make all * previous layers visible, and cause the library to create all the * necssary ClipRects and backup bitmaps for us. Then we re-set * the backdrop bit, anchoring the window into place. */ Forbid (); wbl -> Flags &= ~LAYERBACKDROP; UpfrontLayer (li, wbl); wbl -> Flags = wbl -> Flags & ~LAYERSIMPLE | LAYERSMART; BehindLayer (li, wbl); wbl -> Flags |= LAYERBACKDROP; /* Correct Intuition's ideas about the window. */ wbw -> Flags = flags & ~SIMPLE_REFRESH | SMART_REFRESH; Permit (); /* That should do it */ /* Do things in the newly fixed WorkBench */ SetAPen (wbw -> RPort, 1L); Move (wbw -> RPort, 0L, 0L); Draw (wbw -> RPort, wide-1, high-1); Move (wbw -> RPort, 0L, high-1); Draw (wbw -> RPort, wide-1, 0L); /* * If you want to watch the Mask "bug" at work, uncomment this next * line of code. Move window on and off disk icons and watch the * results. * * wbw -> RPort -> Mask = 1; */ closestuff (); } openstuff () { if (!(IntuitionBase = OpenLibrary ("intuition.library", 0L))) die ("Intuition unavailable, use logic."); if (!(GfxBase = OpenLibrary ("graphics.library", 0L))) die ("Art shop closed."); if (!(LayersBase = OpenLibrary ("layers.library", 0L))) die ("Nothing laying around."); if (!(win = OpenWindow (&windef))) die ("Window painted shut."); } closestuff () { if (win) CloseWindow (win); if (LayersBase) CloseLibrary (LayersBase); if (GfxBase) CloseLibrary (GfxBase); if (IntuitionBase) CloseLibrary (IntuitionBase); } die (str) char *str; { puts (str); closestuff (); exit (10); }