home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
365.lha
/
VSnap
/
snapgfx.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-04-10
|
7KB
|
220 lines
#include "snap.h"
#define MINWIDTH 75
#define MINHEIGHT 15
/* Window structure for snapped gfx */
struct NewWindow Nw = {
0, 1, /* LeftEdge, TopEdge */
0, 0, /* Width, Height */
-1, -1, /* DetailPen, BlockPen */
NULL, /* IDCMPFlags */
WINDOWDRAG|WINDOWDEPTH|WINDOWCLOSE|SMART_REFRESH,
NULL, NULL, /* FirstGadget, CheckMark */
(UBYTE *)"Snap © 1989 Mikael Karlsson & Sirius Software",
NULL, NULL, /* Screen, BitMap */
32, 32, /* MinWidth, MinHeight */
-1, -1, /* MaxWidth, MaxHeight */
WBENCHSCREEN /* Type */
};
LONG xl; /* leftmost x position */
LONG xr; /* rightmost x position */
LONG yt; /* topmost y position */
LONG yb; /* bottommost y position */
LONG mx, my; /* Mouse position in pixels */
#define GfxFrame 4L
IMPORT Point OldFrame[];
IMPORT Point NewFrame[];
IMPORT LONG OFType; /* Old frame type: ShortFrame/LongFrame */
IMPORT UWORD Ptrn;
STATIC LONG TitleBarHeight;
STATIC LONG width, height;
IMPORT struct RastPort MyRP;
IMPORT struct BitMap MyBM;
IMPORT struct Screen *theScreen;
IMPORT struct Layer_Info *LockedLayerInfo;
IMPORT struct RastPort rp;
IMPORT UWORD CrawlPtrn;
IMPORT LONGBITS cancelsignal, donesignal, movesignal, clicksignal, timersignal;
IMPORT WORD action;
VOID FixTitleHeight()
{
struct Screen WBScreen;
if (GetScreenData(&WBScreen, (LONG)sizeof(struct Screen), WBENCHSCREEN, NULL)) {
/* Now this is a good practice */
TitleBarHeight = WBScreen.RastPort.TxHeight+2;
} else {
/* Sorry, but I don't realise how this could fail.
Well, if we're snapping on another screen and
WB is closed and it can't be opened by GetScreenData()...
Anyway, IF this should happen -- Use Topaz 8 */
TitleBarHeight = 10;
}
}
/* SnapGfx is the actual graphics snapper.
** It steals the bitmap data from the given rastport
** and puts it in a separate bitmap.
** It also prepares the NewWindow structure according
** to the snapped bitmap.
** The coordinates are assumed to be valid.
*/
WORD SnapGfx(rp)
struct RastPort *rp;
{
REGISTER UBYTE i;
width = xr - xl;
height = yb - yt;
/* Set up a nice bitmap */
InitBitMap(&MyBM, (long)rp->BitMap->Depth, width, height);
/* Get a handle on the bitmap */
InitRastPort(&MyRP);
MyRP.BitMap = &MyBM;
if (!AllocPlanes(&MyBM, width, height)) {
FreePlanes(&MyBM, width, height);
return 0;
}
/* Copy the selected part of the screen */
SetRast(&MyRP, 0L); /** clear our rastport, added by SOV **/
ClipBlit(rp, xl, yt, &MyRP, 0L, 0L, width, height, 0xC0L);
Nw.LeftEdge = xl;
Nw.TopEdge = yt;
Nw.Width = width+4; /* Two pixels on each side */
Nw.Height = height+TitleBarHeight+1; /* Bar above, one below */
Nw.MinWidth = 0;
Nw.MaxWidth = 0;
Nw.MinHeight = 0;
Nw.MaxHeight = 0;
return 1;
}
VOID ExtendGfx()
{
/* Fix which row we're talking about */
if (my-yt < yb-my) { /* Find closest row */
yt = my; /* change top row */
} else {
yb = my; /* change bottom row */
}
if (mx-xl < xr-mx) {
xl = mx;
} else {
xr = mx;
}
}
VOID gfx_frame()
{
NewFrame[0].x = xl; NewFrame[0].y = yt;
NewFrame[1].x = xr; NewFrame[1].y = yt;
NewFrame[2].x = xr; NewFrame[2].y = yb;
NewFrame[3].x = xl; NewFrame[3].y = yb;
NewFrame[4].x = xl; NewFrame[4].y = yt;
draw_frame(GfxFrame);
}
WORD HandleGfx()
{
theScreen = WhichScreen(); /* Find out where we are */
if (!theScreen) { /* Don't know? Forget it. */
action = noaction;
return 0;
}
/* Lock everything - find out what happens */
LockedLayerInfo = &theScreen->LayerInfo;
LockLayers(LockedLayerInfo);
/* Get a copy. Don't mess with somebody else's RP. */
CopyMem(&theScreen->RastPort, &rp, (long)sizeof(struct RastPort));
SetDrMd(&rp, COMPLEMENT);
Ptrn = CrawlPtrn;
SetDrPt(&rp, Ptrn);
xl = theScreen->MouseX-9;
if (xl<0) {
xl = 0;
}
yt = theScreen->MouseY-9;
if (yt<0) {
yt = 0;
}
xr = xl + 9;
if (xr>=theScreen->Width) { /* Check those corners. Check those corners. */
xr = theScreen->Width-1;
}
yb = yt + 9;
if (yb>=theScreen->Height) {
yb = theScreen->Height-1;
}
OFType = 0L;
gfx_frame();
FOREVER {
REGISTER LONGBITS sig =
Wait(movesignal|clicksignal|cancelsignal|donesignal|timersignal);
if ((sig & timersignal) && (CrawlPtrn != 0xffff)) {
crawl_frame(1L);
}
if (sig & movesignal || sig & clicksignal) {
mx = theScreen->MouseX;
if (mx>=theScreen->Width) {
mx = theScreen->Width-1;
}
my = theScreen->MouseY;
if (my>=theScreen->Height) {
my = theScreen->Height-1;
}
ExtendGfx();
gfx_frame();
}
if (sig & cancelsignal) { /* Cancelled? */
erase_frame();
UnlockLayers(LockedLayerInfo);
action = noaction;
return 0;
}
if (sig & donesignal) { /* Finished. Copy gfx. */
SHORT goodsnap = 0;
erase_frame();
if (xr<xl+MINWIDTH) { /* Can't have too small windows */
xr = xl+MINWIDTH;
}
if (xr>=theScreen->Width) {
xl -= xr-theScreen->Width-1;
xr = theScreen->Width-1;
}
if (yb<yt+MINHEIGHT) {
yb = yt+MINHEIGHT;
}
if (yb>=theScreen->Height) {
yt -= yb-theScreen->Height-1;
yb = theScreen->Height-1;
}
FixTitleHeight();
goodsnap = SnapGfx(&rp); /* Snap! */
if (goodsnap) save_bm(&MyBM, theScreen); /* write it to clipboard */
UnlockLayers(LockedLayerInfo);
if (goodsnap) {
REGISTER struct Window *MyWin;
if (MyWin = opensharedwindow(&Nw))
/* Put gfx in our new window */
ClipBlit(&MyRP, 0L, 0L,
MyWin->RPort, 2L, TitleBarHeight, width, height, 0xC0L);
FreePlanes(&MyBM, width, height); /* Give some mem back */
} else { /* Good question */
}
action = noaction;
return 0;
}
}
}