#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=theScreen->Width) { xl -= xr-theScreen->Width-1; xr = theScreen->Width-1; } 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; } } }