home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 365.lha / VSnap / snapgfx.c < prev    next >
C/C++ Source or Header  |  1990-04-10  |  7KB  |  220 lines

  1. #include "snap.h"
  2.  
  3. #define MINWIDTH 75
  4. #define MINHEIGHT 15
  5.  
  6. /* Window structure for snapped gfx */
  7. struct NewWindow Nw = {
  8.   0, 1,             /* LeftEdge, TopEdge  */
  9.   0, 0,             /* Width, Height */
  10.   -1, -1,           /* DetailPen, BlockPen */
  11.   NULL,             /* IDCMPFlags */
  12.   WINDOWDRAG|WINDOWDEPTH|WINDOWCLOSE|SMART_REFRESH,
  13.   NULL, NULL,       /* FirstGadget, CheckMark */
  14.   (UBYTE *)"Snap © 1989 Mikael Karlsson & Sirius Software",
  15.   NULL, NULL,       /* Screen, BitMap */
  16.   32, 32,           /* MinWidth, MinHeight */
  17.   -1, -1,           /* MaxWidth, MaxHeight */
  18.   WBENCHSCREEN      /* Type */
  19. };
  20.  
  21. LONG xl; /* leftmost x position */
  22. LONG xr; /* rightmost x position */
  23. LONG yt; /* topmost y position */
  24. LONG yb; /* bottommost y position */
  25. LONG mx, my; /* Mouse position in pixels */
  26.  
  27. #define GfxFrame 4L
  28. IMPORT Point OldFrame[];
  29. IMPORT Point NewFrame[];
  30. IMPORT LONG OFType;        /* Old frame type: ShortFrame/LongFrame */
  31. IMPORT UWORD Ptrn;
  32.  
  33. STATIC LONG TitleBarHeight;
  34. STATIC LONG width, height;
  35. IMPORT struct RastPort MyRP;
  36. IMPORT struct BitMap MyBM;
  37. IMPORT struct Screen *theScreen;
  38. IMPORT struct Layer_Info *LockedLayerInfo;
  39. IMPORT struct RastPort rp;
  40. IMPORT UWORD CrawlPtrn;
  41.  
  42. IMPORT LONGBITS cancelsignal, donesignal, movesignal, clicksignal, timersignal;
  43. IMPORT WORD action;
  44.  
  45. VOID FixTitleHeight()
  46. {
  47.     struct Screen WBScreen;
  48.     if (GetScreenData(&WBScreen, (LONG)sizeof(struct Screen), WBENCHSCREEN, NULL)) {
  49.           /* Now this is a good practice */
  50.         TitleBarHeight = WBScreen.RastPort.TxHeight+2;
  51.     } else {
  52.           /* Sorry, but I don't realise how this could fail.
  53.              Well, if we're snapping on another screen and
  54.              WB is closed and it can't be opened by GetScreenData()...
  55.              Anyway, IF this should happen -- Use Topaz 8 */
  56.         TitleBarHeight = 10;
  57.     }
  58. }
  59.  
  60. /* SnapGfx is the actual graphics snapper.
  61. ** It steals the bitmap data from the given rastport
  62. ** and puts it in a separate bitmap.
  63. ** It also prepares the NewWindow structure according
  64. ** to the snapped bitmap.
  65. ** The coordinates are assumed to be valid.
  66. */
  67.  
  68. WORD SnapGfx(rp)
  69. struct RastPort *rp;
  70. {
  71.     REGISTER UBYTE i;
  72.     width = xr - xl;
  73.     height = yb - yt;
  74.       /* Set up a nice bitmap */
  75.     InitBitMap(&MyBM, (long)rp->BitMap->Depth, width, height);
  76.       /* Get a handle on the bitmap */
  77.     InitRastPort(&MyRP);
  78.     MyRP.BitMap = &MyBM;
  79.     if (!AllocPlanes(&MyBM, width, height)) {
  80.         FreePlanes(&MyBM, width, height);
  81.         return 0;
  82.     }
  83.       /* Copy the selected part of the screen */
  84.     SetRast(&MyRP, 0L);  /** clear our rastport, added by SOV **/
  85.     ClipBlit(rp, xl, yt, &MyRP, 0L, 0L, width, height, 0xC0L);
  86.     Nw.LeftEdge = xl;
  87.     Nw.TopEdge = yt;
  88.     Nw.Width = width+4;                  /* Two pixels on each side */
  89.     Nw.Height = height+TitleBarHeight+1; /* Bar above, one below */
  90.     Nw.MinWidth = 0;
  91.     Nw.MaxWidth = 0;
  92.     Nw.MinHeight = 0;
  93.     Nw.MaxHeight = 0;
  94.     return 1;
  95. }
  96.  
  97. VOID ExtendGfx()
  98. {
  99.     /* Fix which row we're talking about */
  100.     if (my-yt < yb-my) {       /* Find closest row */
  101.         yt = my;               /* change top row */
  102.     } else {
  103.         yb = my;               /* change bottom row */
  104.     }
  105.     if (mx-xl < xr-mx) {
  106.         xl = mx;
  107.     } else {
  108.         xr = mx;
  109.     }
  110. }
  111.  
  112. VOID gfx_frame()
  113. {
  114.     NewFrame[0].x = xl;  NewFrame[0].y = yt;
  115.     NewFrame[1].x = xr;  NewFrame[1].y = yt;
  116.     NewFrame[2].x = xr;  NewFrame[2].y = yb;
  117.     NewFrame[3].x = xl;  NewFrame[3].y = yb;
  118.     NewFrame[4].x = xl;  NewFrame[4].y = yt;
  119.     draw_frame(GfxFrame);
  120. }
  121.  
  122.  
  123. WORD HandleGfx()
  124. {
  125.     theScreen = WhichScreen();   /* Find out where we are */
  126.     if (!theScreen) {            /* Don't know? Forget it. */
  127.         action = noaction;
  128.         return 0;
  129.     }
  130.       /* Lock everything - find out what happens */
  131.     LockedLayerInfo = &theScreen->LayerInfo;
  132.     LockLayers(LockedLayerInfo);
  133.  
  134.       /* Get a copy. Don't mess with somebody else's RP. */
  135.     CopyMem(&theScreen->RastPort, &rp, (long)sizeof(struct RastPort));
  136.     SetDrMd(&rp, COMPLEMENT);
  137.     Ptrn = CrawlPtrn;
  138.     SetDrPt(&rp, Ptrn);
  139.  
  140.     xl = theScreen->MouseX-9;
  141.     if (xl<0) {
  142.         xl = 0;
  143.     }
  144.     yt = theScreen->MouseY-9;
  145.     if (yt<0) {
  146.         yt = 0;
  147.     }
  148.     xr = xl + 9;
  149.     if (xr>=theScreen->Width) {  /* Check those corners. Check those corners. */
  150.         xr = theScreen->Width-1;
  151.     }
  152.     yb = yt + 9;
  153.     if (yb>=theScreen->Height) {
  154.         yb = theScreen->Height-1;
  155.     }
  156.     OFType = 0L;
  157.     gfx_frame();
  158.  
  159.     FOREVER {
  160.         REGISTER LONGBITS sig =
  161.           Wait(movesignal|clicksignal|cancelsignal|donesignal|timersignal);
  162.  
  163.         if ((sig & timersignal) && (CrawlPtrn != 0xffff)) {
  164.             crawl_frame(1L);
  165.         }
  166.  
  167.         if (sig & movesignal || sig & clicksignal) {
  168.             mx = theScreen->MouseX;
  169.             if (mx>=theScreen->Width) {
  170.                 mx = theScreen->Width-1;
  171.             }
  172.             my = theScreen->MouseY;
  173.             if (my>=theScreen->Height) {
  174.                 my = theScreen->Height-1;
  175.             }
  176.             ExtendGfx();
  177.             gfx_frame();
  178.         }
  179.         if (sig & cancelsignal) {          /* Cancelled? */
  180.             erase_frame();
  181.             UnlockLayers(LockedLayerInfo);
  182.             action = noaction;
  183.             return 0;
  184.         }
  185.         if (sig & donesignal) {            /* Finished. Copy gfx. */
  186.             SHORT goodsnap = 0;
  187.             erase_frame();
  188.             if (xr<xl+MINWIDTH) {          /* Can't have too small windows */
  189.                 xr = xl+MINWIDTH;
  190.             }
  191.             if (xr>=theScreen->Width) {
  192.                 xl -= xr-theScreen->Width-1;
  193.                 xr = theScreen->Width-1;
  194.             }
  195.             if (yb<yt+MINHEIGHT) {
  196.                 yb = yt+MINHEIGHT;
  197.             }
  198.             if (yb>=theScreen->Height) {
  199.                 yt -= yb-theScreen->Height-1;
  200.                 yb = theScreen->Height-1;
  201.             }
  202.             FixTitleHeight();
  203.             goodsnap = SnapGfx(&rp); /* Snap! */
  204.             if (goodsnap) save_bm(&MyBM, theScreen);  /* write it to clipboard */
  205.             UnlockLayers(LockedLayerInfo);
  206.             if (goodsnap) {
  207.                 REGISTER struct Window *MyWin;
  208.                 if (MyWin = opensharedwindow(&Nw))
  209.                       /* Put gfx in our new window */
  210.                     ClipBlit(&MyRP, 0L, 0L,
  211.                       MyWin->RPort, 2L, TitleBarHeight, width, height, 0xC0L);
  212.                 FreePlanes(&MyBM, width, height);  /* Give some mem back */
  213.             } else { /* Good question */
  214.             }
  215.             action = noaction;
  216.             return 0;
  217.         }
  218.     }
  219. }
  220.