home *** CD-ROM | disk | FTP | other *** search
- /* MacGAG.C - Copyright (c) 1987 John Hodgson
-
- Here's my attempt at spiffing up Intuition a little bit. Certain other
- graphic desktop environments perk up their screens by "blossoming" new windows
- just prior to display, and "withering" them just after closing. No reason why
- we can't do this as well; only "look and feel" issues are in question here!
-
- The idea is to intercept all calls to OpenWindow()/CloseWindow() and
- add some parasite code before or after the actual invocation of these routines.
- Keep in mind however, that this is a multitasking machine; since we're actually
- patching the ROM Kernel, parts of this code become a SHARED RESOURCE and better
- be reentrant. Also, any rubberband routines need to mutually exclude each other
- so we don't leave "snail trails" behind. The key to reentrancy is a local data
- area for each calling task; the stack pointer maintained by each task is ideal
- for this.
-
- Refer to the glue routines in SUPPORT.ASM to see how register
- preservation and parameter passing is accomplished between the zapped Exec
- library and C. This program MUST BE COMPILED under Aztec "C", 3.4 or later
- using the large code/data models, and run under KickStart 1.2 or later.
-
- P.S. This program will blossom/decay ALL windows, including potentially
- invisible BACKDROP and BORDERLESS ones. Feel free to modify this if you like.
- It also tips you off as to whether certain programs are using REQUESTERS
- (unaffected) or WINDOWS for their user input! -DJH
-
- */
-
- #define REV_1PT2 33
-
- #define OWOFFSET (-0x00cc) /* OpenWindow() vector; see RKM : Exec */
- #define CWOFFSET (-0x0048) /* CloseWindow() vector; see RKM : Exec */
-
- #define SPEED 4 /* blossoming speed, in pixels */
- #define BOXPATTERN 0xCCCC /* rubberband box pattern */
- #define TAGPORT "gag.port" /* how we identify ourselves */
-
- extern void NewOpenWindow(); /* 68K patch routines */
- extern void NewCloseWindow();
-
- /* the following globals are constants; reentrant by nature */
-
- void *GfxBase,*IntuitionBase,*LayersBase,*OldOpenWindow,*OldCloseWindow;
-
- void BoxUp(NewWindowArg)
- struct NewWindow *NewWindowArg;
- {
- struct Screen sc;
- struct RastPort rp;
- short x1,y1,x2,y2,minx,miny,maxx,maxy,poly[4*2];
-
- /* Make local copies of screens & rastports so we don't alter
- the programs actually using these resources! */
-
- if (NewWindowArg->Type==CUSTOMSCREEN) sc=*(NewWindowArg->Screen);
- else GetScreenData(&sc,sizeof(sc),WBENCHSCREEN,NULL);
-
- rp=sc.RastPort;
-
- minx=NewWindowArg->LeftEdge; maxx=minx+NewWindowArg->Width-1;
- miny=NewWindowArg->TopEdge; maxy=miny+NewWindowArg->Height-1;
-
- x1=x2=(minx+maxx)/2;
- y1=y2=(miny+maxy)/2;
-
- SetDrMd(&rp,COMPLEMENT); /* XOR, great for rubberbanding */
- SetDrPt(&rp,BOXPATTERN); /* dithered bands for Mac fans */
-
- /* Starting from the window-to-be's midpoint, expand a rubberbanded
- rectangle until it reaches the window's size. */
-
- while (x1>minx || y1>miny) {
-
- Move(&rp,x1,y1);
-
- poly[1]=y1;
- poly[0]=poly[2]=x2;
- poly[3]=poly[5]=y2;
- poly[4]=poly[6]=x1;
- poly[7]=y1+1;
-
- /* Make sure other graphics don't see our wickedness */
-
- LockLayers(&sc.LayerInfo);
-
- PolyDraw(&rp,4,&poly[0]); /* one dithered, XOR'd box, to go */
-
- WaitTOF(); /* give the user a chance to see */
-
- Move(&rp,x1,y1); PolyDraw(&rp,4,&poly[0]); /* erase box */
-
- UnlockLayers(&sc.LayerInfo);
-
- x1-=SPEED; x2+=SPEED;
- y1-=SPEED; y2+=SPEED;
-
- if (x1<minx) x1=minx;
- if (x2>maxx) x2=maxx;
- if (y1<miny) y1=miny;
- if (y2>maxy) y2=maxy;
- }
- }
-
- void BoxDown(window)
- struct Window *window;
- {
- struct RastPort rp;
- short x1,y1,x2,y2,midx,midy,poly[4*2];
-
- /* Duplicate rastport so we don't affect others using the real one */
-
- rp=window->WScreen->RastPort;
-
- x1=window->LeftEdge; x2=x1+window->Width-1;
- y1=window->TopEdge; y2=y1+window->Height-1;
-
- midx=(x1+x2)/2; midy=(y1+y2)/2;
-
- SetDrMd(&rp,COMPLEMENT); /* XOR, great for rubberbanding */
- SetDrPt(&rp,BOXPATTERN); /* dithered bands for Mac fans */
-
- /* shrink a box from window's edges to its midpoint */
-
- while (x1<midx || y1<midy) {
-
- Move(&rp,x1,y1);
-
- poly[1]=y1;
- poly[0]=poly[2]=x2;
- poly[3]=poly[5]=y2;
- poly[4]=poly[6]=x1;
- poly[7]=y1+1;
-
- /* Make sure other graphics don't see our wickedness */
-
- LockLayers(&window->WScreen->LayerInfo);
-
- PolyDraw(&rp,4,&poly[0]); /* one dithered, XOR'd box, to go */
-
- WaitTOF(); /* give the user a chance to see */
-
- Move(&rp,x1,y1); PolyDraw(&rp,4,&poly[0]); /* erase box */
-
- UnlockLayers(&window->WScreen->LayerInfo);
-
- x1+=SPEED; x2-=SPEED;
- y1+=SPEED; y2-=SPEED;
-
- if (x1>midx) x1=midx;
- if (x2<midx) x2=midx;
- if (y1>midy) y1=midy;
- if (y2<midy) y2=midy;
- }
- }
-
- main()
- {
- struct Window *window;
- struct NewWindow nw;
- struct MsgPort *tagport;
-
- if (FindPort(TAGPORT)) exit(0); /* prevent multiple invocations */
-
- if (!(tagport=CreatePort(TAGPORT,0))) exit(0);
-
- GfxBase=OpenLibrary("graphics.library",0);
- LayersBase=OpenLibrary("layers.library",0);
-
- /* quit if not running under 1.2 or later */
-
- if (!(IntuitionBase=OpenLibrary("intuition.library",REV_1PT2))) goto cleanup;
-
- /* Install new vectors, and save the originals for cleanup */
-
- OldOpenWindow=SetFunction(IntuitionBase,OWOFFSET,NewOpenWindow);
- OldCloseWindow=SetFunction(IntuitionBase,CWOFFSET,NewCloseWindow);
-
- setmem(&nw,sizeof(nw),0);
-
- nw.Width=308; nw.Height=10;
- nw.DetailPen=2; nw.BlockPen=3;
- nw.IDCMPFlags=CLOSEWINDOW;
- nw.Flags=WINDOWDEPTH|WINDOWCLOSE|WINDOWDRAG|SIMPLE_REFRESH;
- nw.Title=(UBYTE *)"MacGAG (c) 1987 John Hodgson";
- nw.Type=WBENCHSCREEN;
-
- if (window=OpenWindow(&nw)) {
- WaitPort(window->UserPort); /* MacGAG in effect until WINDOWCLOSE */
-
- CloseWindow(window);
- }
-
- SetFunction(IntuitionBase,OWOFFSET,OldOpenWindow); /* restore vectors */
- SetFunction(IntuitionBase,CWOFFSET,OldCloseWindow);
-
- cleanup:
- DeletePort(tagport);
-
- CloseLibrary(IntuitionBase);
- CloseLibrary(LayersBase);
- CloseLibrary(GfxBase);
- }
-