/*************************************************************************** * * MacWin.c - routines for making OpenWindow & CloseWindow * behave like a Macintosh 10-Jan-88 * * Version 1.3 18-Jun-88 Copyright (c) 1988 - Steven Sweeting * * Note: if the OpenWindow vector gets in before mwb * (ie run mwb first) then the opening of the window * is done on the real WBENCH screen. * ***************************************************************************/ #include #include "wicon.h" extern struct IntuitionBase *IntuitionBase; struct Box { LONG Left, Right; LONG Top, Bottom; }; #define REC_FIRST 1 #define REC_LAST 2 #define REC_HIRES 4 #define MIN(a,b) ((a)<(b) ? (a):(b)) #define MAX(a,b) ((a)>(b) ? (a):(b)) /************************************************************************* * SizeRec - resizes a rectangle on the given Screen * * 03-Jan-88 */ void SizeRec(Screen, From, To) struct Screen *Screen; struct BoxInfo *From, *To; { struct Box Box1, Box2, Box3; short inc; long Left, Right, Top, Bottom; int Flags; long factor, curr = 0, i; struct RastPort *RastPort = &(Screen->RastPort); static WORD ox1, oy1, ox2, oy2; /* Save them for redraw */ Box1.Left = MAX( From->LeftEdge, 0 ); Box1.Right = MIN( Box1.Left + From->Width, Screen->Width ); Box1.Top = MAX( From->TopEdge, 0 ); Box1.Bottom = MIN( Box1.Top + From->Height, Screen->Height ); Box2.Left = MAX( To->LeftEdge, 0 ); Box2.Right = MIN( Box2.Left + To->Width, Screen->Width ); Box2.Top = MAX( To->TopEdge, 0 ); Box2.Bottom = MIN( Box2.Top + To->Height, Screen->Height ); if (Screen->Flags | HIRES) Flags = REC_HIRES; else Flags = 0; SetDrMd(RastPort, (LONG)COMPLEMENT); if (Arg_Boxes) { SetDrMd(RastPort, (LONG)COMPLEMENT); LockLayers(&(Screen->LayerInfo)); inc = 256/Arg_Boxes; DrawRec(RastPort, ox1 = Box1.Left, oy1 = Box1.Top, ox2 = Box1.Right, oy2 = Box1.Bottom ); inc = 256/Arg_Boxes; for (i=0; i<256; i += inc ) { WaitTOF(); DrawRec(RastPort, ox1, oy1, ox2, oy2 ); DrawRec( RastPort, ox1 = (WORD)((Box1.Left *(255-i) + Box2.Left *i) >>8), oy1 = (WORD)((Box1.Top *(255-i) + Box2.Top *i) >>8), ox2 = (WORD)((Box1.Right *(255-i) + Box2.Right *i) >>8), oy2 = (WORD)((Box1.Bottom *(255-i) + Box2.Bottom *i) >>8) ); } DrawRec(RastPort, ox1, oy1, ox2, oy2); UnlockLayers(&(Screen->LayerInfo)); } } /************************************************************************* * DrawRec - draws an XOR rectangle on a given RastPort * * 03-Jan-88 */ int DrawRec(RastPort, x1, y1, x2, y2, status) struct RastPort *RastPort; WORD x1, y1, x2, y2; WORD status; { Move(RastPort, (LONG)x1, (LONG)y1); Draw(RastPort, (LONG)x2, (LONG)y1); Draw(RastPort, (LONG)x2, (LONG)y2); Draw(RastPort, (LONG)x1, (LONG)y2); Draw(RastPort, (LONG)x1, (LONG)y1); if (status & REC_HIRES) { Move(RastPort, (LONG)x1+1, (LONG)y1); Draw(RastPort, (LONG)x1+1, (LONG)y2); Move(RastPort, (LONG)x2-1, (LONG)y1); Draw(RastPort, (LONG)x2-1, (LONG)y2); } } /************************************************************************* * M_Open - opens a window - called from the OpenWindow vector * hence it is always run by the task that called it * */ struct BoxInfo SmallBox = { 0, 0, 0, 0 }; struct Window * M_Open( NewWindow ) struct NewWindow *NewWindow; { extern struct Window *OldOpenWindow(); struct Screen *Screen; if ((NewWindow->Type & SCREENTYPE) == WBENCHSCREEN) Screen = WorkBenchScreen; else Screen = NewWindow->Screen; SmallBox.LeftEdge = Screen->MouseX; SmallBox.TopEdge = Screen->MouseY; if (Arg_AllScreens || (Screen == WiconScreen)) SizeRec(Screen, &SmallBox, &(NewWindow->LeftEdge)); return (OldOpenWindow(NewWindow)); } /************************************************************************* * UnSetFunction - this routine handles properly * the opposite to SetFunction() which * replaces an AmigaDOS `OldVector' * with its own `NewVector'. This function * may never exit because the `NewVector' * may be lost by a newer function which * also does a SetFunction() * 10-Jan-87 */ void UnSetFunction(LibraryBase, FunctionOffset, LibVector, PresentVector) struct Library *LibraryBase; LONG FunctionOffset; VOID (*PresentVector)(),(*LibVector)(); { extern void (*SetFunction())(); /* AmigaDOS routine */ extern void (*GetFunction())(); /* Sweeting routine */ Forbid(); while (GetFunction( LibraryBase, FunctionOffset ) != PresentVector) { Permit(); Delay(50L); /* a second */ Forbid(); } /* It may be illegal to do this within a Forbid()/Permit() */ /* But it seems to work OK */ SetFunction( LibraryBase, FunctionOffset, LibVector ); Permit(); }