source: trunk/bitmap.cpp@ 11

Last change on this file since 11 was 11, checked in by Gregg Young, 7 years ago

This changes the bitmap save from an internal bitmap or the use of MMOS2 to using GBM. The save code was adapted from GBMv2 by Heiko Nitzsche and Andy Keys. Also fixed the failure of the file dialog to update the file extension name on the first save after a format changes. Non English resources haven't been updated yet. Several more build error warning fixes.

  • Property svn:eol-style set to native
File size: 7.3 KB
Line 
1/***
2 This file belongs to the Gotcha! distribution.
3 Copyright (C) 1998-2002 Thorsten Thielen <thth@c2226.de>
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
24HBITMAP 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 DosSleep (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, sWidth, sHeight, bmp.cBitCount);
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
170BOOL 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
224VOID StartSelection (HWND hwnd)
225{
226 WinSetPointer (HWND_DESKTOP, WinLoadPointer (HWND_DESKTOP, GETMODULE, 2));
227 WinSetCapture (HWND_DESKTOP, hwnd);
228}
229
230// ************************************************************************
Note: See TracBrowser for help on using the repository browser.