home *** CD-ROM | disk | FTP | other *** search
- #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;
- }
- }
- }
-