home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: Graphics / Graphics.zip / gotch175.zip / src / bitmap.cpp < prev    next >
Text File  |  2002-03-29  |  8KB  |  231 lines

  1. /***
  2.  This file belongs to the Gotcha! distribution.
  3.  Copyright (C) 1998-2002 Thorsten Thielen <thth@gmx.net>
  4.  
  5.  This program is free software; you can redistribute it and/or modify
  6.  it under the terms of the GNU General Public License as published by
  7.  the Free Software Foundation; either version 2 of the License, or
  8.  (at your option) any later version.
  9.  
  10.  This program is distributed in the hope that it will be useful,
  11.  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  GNU General Public License for more details.
  14.  
  15.  You should have received a copy of the GNU General Public License
  16.  along with this program; if not, write to the Free Software
  17.  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18.  ***/
  19.  
  20. // ** CaptureWindow ******************************************************* /*fold00*/
  21.  
  22. #define MAX_WAIT   15
  23.  
  24. HBITMAP CaptureWindow (HWND hwnd, HWND hwndParent, PRECTL prcl, BOOL f)
  25. {
  26. #ifdef _DOLOGMEM_
  27.     LogMem("CaptureWindow", TRUE);
  28. #endif
  29.     static PSZ pszData[4] = { "Display", NULL, NULL, NULL };
  30.     SIZEL   sizlPage = {0, 0};
  31.     POINTL  aptl[3];
  32.     LONG    alData[2];
  33.     SWP     swp;
  34.     SHORT   sWidth, sHeight;
  35.     CHAR    ach[32];
  36.  
  37.     // wait for the selected window to rise to the surface
  38.     if ((hwndParent != HWND_DESKTOP) &&  f)
  39.     {
  40.         WinSetWindowPos (hwndParent, HWND_TOP, 0,0, 0,0, SWP_ZORDER);
  41.         // FIXME uh, yukki! polling! but seems to be the easiest way for now.
  42.         for (USHORT i = 0; i < MAX_WAIT; i++)
  43.         {
  44.             _sleep2 (100);
  45.             WinQueryWindowPos (hwndParent, &swp);
  46.             if ((swp.hwndInsertBehind == HWND_TOP) ||
  47.                 (swp.hwndInsertBehind == hwndSnapshot))
  48.                 break;
  49.             else
  50.             {
  51.                 // check if topmost window is a menu
  52.                 WinQueryClassName (swp.hwndInsertBehind, sizeof (ach), ach);
  53.                 if (stricmp (ach, "#4") == 0)
  54.                     break;
  55.             }
  56.         }
  57.     }
  58.  
  59.     // if no capture rectangle given, we'll take the whole window
  60.     if (! prcl)
  61.     {
  62.         WinQueryWindowPos (hwnd, &swp);
  63.         sWidth  = swp.cx;
  64.         sHeight = swp.cy;
  65.     }
  66.     else
  67.     {
  68.         sWidth  = prcl->xRight-prcl->xLeft+1;
  69.         sHeight = prcl->yTop-prcl->yBottom+1;
  70.     }
  71.  
  72.     /* create the memory device context and presentation space so they
  73.      are compatible with the screen device context and presentation space */
  74.     HDC hdcMem =
  75.         DevOpenDC (hab, OD_MEMORY, "*", 4, PDEVOPENDATA (pszData), 0);
  76.     HPS hpsMem =
  77.         GpiCreatePS (hab, hdcMem, &sizlPage, PU_PELS| GPIA_ASSOC| GPIT_MICRO);
  78.  
  79.     // determine the device's plane/bit-count format
  80.     GpiQueryDeviceBitmapFormats (hpsMem, 2, alData);
  81.  
  82.     // FIXME even if it seems to work ...
  83.     if (alData[1] == 16)
  84.         alData[1] = 24;
  85.  
  86.     BITMAPINFOHEADER2 bmp;
  87.  
  88.     /* load the BITMAPINFOHEADER2 and BITMAPINFO2 structures. The sWidth and
  89.      sHeight fields specify the width and height of the destination rect. */
  90.     bmp.cbFix           = ULONG (sizeof(BITMAPINFOHEADER2));
  91.     bmp.cx              = sWidth;
  92.     bmp.cy              = sHeight;
  93.     bmp.cPlanes         = alData[0];
  94.     bmp.cBitCount       = alData[1];
  95.  
  96.     bmp.ulCompression   = BCA_UNCOMP;
  97.     /*SOME STUFF MISSING IN THIS STATEMENT: 1 << bmp.cPlanes) *
  98.                              (1 << bmp.cBitCount)) + 31) / 32) * sHeight;*/
  99.     bmp.cxResolution    = 0;
  100.     bmp.cyResolution    = 0;
  101.     bmp.cclrUsed        = 0;
  102.     bmp.cclrImportant   = 0;
  103.  
  104.     bmp.usUnits         = BRU_METRIC;
  105.     bmp.usReserved      = 0;
  106.     bmp.usRecording     = BRA_BOTTOMUP;
  107.     bmp.usRendering     = BRH_NOTHALFTONED;
  108.     bmp.cSize1          = 0;
  109.     bmp.cSize2          = 0;
  110.     bmp.ulColorEncoding = BCE_RGB;
  111.     bmp.ulIdentifier    = 0;
  112.  
  113.     // create a bit map that is compatible with the display
  114.     HBITMAP hbm = GpiCreateBitmap (hpsMem, &bmp, 0L, NULL, NULL/*pbmi*/);
  115.  
  116.     // associate the bit map and the memory presentation space
  117.     HBITMAP hbmOld = GpiSetBitmap (hpsMem, hbm);
  118.  
  119.     /* Copy the screen to the bit map.                                  */
  120.     aptl[0].x = 0;       /* Lower-left corner of destination rectangle  */
  121.     aptl[0].y = 0;       /* Lower-left corner of destination rectangle  */
  122.     aptl[1].x = sWidth;  /* Upper-right corner of destination rectangle */
  123.     aptl[1].y = sHeight; /* Upper-right corner of destination rectangle */
  124.  
  125.     if (! prcl)
  126.     {
  127.         aptl[2].x = 0;       /* Lower-left corner of source rectangle       */
  128.         aptl[2].y = 0;       /* Lower-left corner of source rectangle       */
  129.     }
  130.     else
  131.     {
  132.         aptl[2].x = prcl->xLeft;       /* Lower-left corner of source rectangle       */
  133.         aptl[2].y = prcl->yBottom;       /* Lower-left corner of source rectangle       */
  134.     }
  135.  
  136.     HPS hps;
  137.  
  138.     // esp. important if serial capture enabled: window may have been closed!
  139.     if (WinIsWindow (GETHAB, hwnd) || (hwnd == HWND_DESKTOP))
  140.         hps = WinGetPS (hwnd);
  141.     else
  142.     {
  143.         GpiDeleteBitmap (hbm);
  144.         DevCloseDC (hdcMem);
  145.         return NULL;
  146.     }
  147.  
  148.     GpiBitBlt (hpsMem, hps,
  149.                sizeof (aptl) / sizeof (POINTL), /* Number of points in aptl */
  150.                aptl, ROP_SRCCOPY, BBO_IGNORE);
  151.     SaveBitmap (hbm, hpsMem);
  152.  
  153.     // re-associate the previous bit map and the memory presentation space
  154.     GpiSetBitmap (hpsMem, hbmOld);
  155.  
  156.     GpiDeleteBitmap (hbm);
  157.     WinReleasePS (hps);
  158.     GpiDestroyPS (hps);
  159.     DevCloseDC (hdcMem);
  160.  
  161. #ifdef _DOLOGMEM_
  162.     LogMem("CaptureWindow", FALSE);
  163. #endif
  164.  
  165.     return hbm;
  166. }
  167.  
  168. // ** DoTracking ********************************************************** /*FOLD00*/
  169.  
  170. BOOL DoTracking (RECTL *prclTrack)
  171. {
  172.     LONG       cxScreen, cyScreen, cxPointer, cyPointer;
  173.     TRACKINFO  ti;
  174.  
  175.     cxScreen  = WinQuerySysValue (HWND_DESKTOP, SV_CXSCREEN);
  176.     cyScreen  = WinQuerySysValue (HWND_DESKTOP, SV_CYSCREEN);
  177.     cxPointer = WinQuerySysValue (HWND_DESKTOP, SV_CXPOINTER);
  178.     cyPointer = WinQuerySysValue (HWND_DESKTOP, SV_CYPOINTER);
  179.  
  180.     ti.cxBorder = 1;
  181.     ti.cyBorder = 1;
  182.  
  183.     ti.cxGrid = 0;
  184.     ti.cyGrid = 0;
  185.  
  186.     ti.cxKeyboard = 4;
  187.     ti.cyKeyboard = 4;
  188.  
  189.     ti.rclBoundary.xLeft   = 0;
  190.     ti.rclBoundary.yBottom = 0;
  191.     ti.rclBoundary.xRight  = cxScreen;
  192.     ti.rclBoundary.yTop    = cyScreen;
  193.  
  194.     ti.ptlMinTrackSize.x = 1;
  195.     ti.ptlMinTrackSize.y = 1;
  196.     ti.ptlMaxTrackSize.x = cxScreen;
  197.     ti.ptlMaxTrackSize.y = cyScreen;
  198.  
  199.     ti.rclTrack.xLeft   = (cxScreen-cxPointer)/2;
  200.     ti.rclTrack.yBottom = (cyScreen-cyPointer)/2;
  201.     ti.rclTrack.xRight  = (cxScreen+cxPointer)/2;
  202.     ti.rclTrack.yTop    = (cyScreen+cyPointer)/2;
  203.  
  204.     ti.fs = TF_MOVE | TF_STANDARD | TF_SETPOINTERPOS;
  205.  
  206.     if (! WinTrackRect (HWND_DESKTOP, NULL, &ti))
  207.         return FALSE;
  208.  
  209.     WinSetPointer (HWND_DESKTOP,
  210.                    WinQuerySysPointer (HWND_DESKTOP, SPTR_SIZENESW, FALSE));
  211.  
  212.     ti.fs = TF_RIGHT | TF_TOP | TF_STANDARD | TF_SETPOINTERPOS;
  213.  
  214.     if (! WinTrackRect (HWND_DESKTOP, NULL, &ti))
  215.         return FALSE;
  216.  
  217.     *prclTrack = ti.rclTrack;
  218.  
  219.     return TRUE;
  220. }
  221.  
  222. // ** StartSelection ****************************************************** /*FOLD00*/
  223.  
  224. VOID StartSelection (HWND hwnd)
  225. {
  226.     WinSetPointer (HWND_DESKTOP, WinLoadPointer (HWND_DESKTOP, GETMODULE, 2));
  227.     WinSetCapture (HWND_DESKTOP, hwnd);
  228. }
  229.  
  230. // ************************************************************************
  231.