home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
038.lha
/
MacGag
/
macgag.c
< prev
next >
Wrap
C/C++ Source or Header
|
1987-05-16
|
6KB
|
203 lines
/* 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);
}