source: trunk/bitmap.cpp@ 170

Last change on this file since 170 was 170, checked in by Gregg Young, 4 weeks ago

Rework Gotcha's dialogs to work better with the new font sizing in WPS. Replace some global variables with more C++ alternatives

  • Property svn:eol-style set to native
File size: 8.9 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#include <ctype.h>
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] = {0};
36
37 // wait for the selected window to rise to the surface
38 if (f)
39 {
40 INT rc = WinSetFocus(HWND_DESKTOP, hwndParent);
41
42 // FIXME uh, yukki! polling! but seems to be the easiest way for now.
43 for (USHORT i = 0; i < MAX_WAIT; i++)
44 {
45 DosSleep (100);
46 if (hwndParent == WinQueryFocus(HWND_DESKTOP)) {
47 break;
48 }
49 else
50 {
51 // check if topmost window is a menu
52 WinQueryClassName (WinQueryFocus(HWND_DESKTOP),
53 sizeof (ach), ach);
54 if (stricmp (ach, "#4") == 0)
55 break;
56 }
57 WinQueryWindowPos (hwndParent, &swp);
58 if ((swp.hwndInsertBehind == HWND_TOP) ||
59 (swp.hwndInsertBehind == hwndSnapshot)) {
60 break;
61 }
62 else
63 {
64 // check if topmost window is a menu
65 WinQueryClassName (swp.hwndInsertBehind, sizeof (ach), ach);
66 if (stricmp (ach, "#4") == 0)
67 break;
68 }
69 }
70 }
71
72 // if no capture rectangle given, we'll take the whole window
73 if (! prcl)
74 {
75 INT rc = WinQueryWindowPos (hwnd, &swp);
76 sWidth = swp.cx;
77 sHeight = swp.cy;
78 }
79 else
80 {
81 sWidth = prcl->xRight-prcl->xLeft+1;
82 sHeight = prcl->yTop-prcl->yBottom+1;
83 }
84
85 /* create the memory device context and presentation space so they
86 are compatible with the screen device context and presentation space */
87 HDC hdcMem =
88 DevOpenDC (hab, OD_MEMORY, "*", 4, PDEVOPENDATA (pszData), 0);
89 HPS hpsMem =
90 GpiCreatePS (hab, hdcMem, &sizlPage, PU_PELS| GPIA_ASSOC| GPIT_MICRO);
91
92 // determine the device's plane/bit-count format
93 GpiQueryDeviceBitmapFormats (hpsMem, 2, alData);
94
95 // FIXME even if it seems to work ...
96 if (alData[1] == 16)
97 alData[1] = 24;
98
99 BITMAPINFOHEADER2 bmp;
100
101 /* load the BITMAPINFOHEADER2 and BITMAPINFO2 structures. The sWidth and
102 sHeight fields specify the width and height of the destination rect. */
103 bmp.cbFix = ULONG (sizeof(BITMAPINFOHEADER2));
104 bmp.cx = sWidth;
105 bmp.cy = sHeight;
106 bmp.cPlanes = alData[0];
107 bmp.cBitCount = alData[1];
108
109 bmp.ulCompression = BCA_UNCOMP;
110 /*SOME STUFF MISSING IN THIS STATEMENT: 1 << bmp.cPlanes) *
111 (1 << bmp.cBitCount)) + 31) / 32) * sHeight;*/
112 bmp.cxResolution = 0;
113 bmp.cyResolution = 0;
114 bmp.cclrUsed = 0;
115 bmp.cclrImportant = 0;
116
117 bmp.usUnits = BRU_METRIC;
118 bmp.usReserved = 0;
119 bmp.usRecording = BRA_BOTTOMUP;
120 bmp.usRendering = BRH_NOTHALFTONED;
121 bmp.cSize1 = 0;
122 bmp.cSize2 = 0;
123 bmp.ulColorEncoding = BCE_RGB;
124 bmp.ulIdentifier = 0;
125
126 // create a bit map that is compatible with the display
127 HBITMAP hbm = GpiCreateBitmap (hpsMem, &bmp, 0L, NULL, NULL/*pbmi*/);
128
129 // associate the bit map and the memory presentation space
130 HBITMAP hbmOld = GpiSetBitmap (hpsMem, hbm);
131
132 /* Copy the screen to the bit map. */
133 aptl[0].x = 0; /* Lower-left corner of destination rectangle */
134 aptl[0].y = 0; /* Lower-left corner of destination rectangle */
135 aptl[1].x = sWidth; /* Upper-right corner of destination rectangle */
136 aptl[1].y = sHeight; /* Upper-right corner of destination rectangle */
137
138 if (! prcl)
139 {
140 aptl[2].x = 0; /* Lower-left corner of source rectangle */
141 aptl[2].y = 0; /* Lower-left corner of source rectangle */
142 }
143 else
144 {
145 aptl[2].x = prcl->xLeft; /* Lower-left corner of source rectangle */
146 aptl[2].y = prcl->yBottom; /* Lower-left corner of source rectangle */
147 }
148
149 HPS hps;
150
151 // esp. important if serial capture enabled: window may have been closed!
152 if (WinIsWindow (GETHAB, hwnd) || (hwnd == HWND_DESKTOP))
153 hps = WinGetPS (hwnd);
154 else
155 {
156 GpiDeleteBitmap (hbm);
157 DevCloseDC (hdcMem);
158 return NULL;
159 }
160
161 GpiBitBlt (hpsMem, hps,
162 sizeof (aptl) / sizeof (POINTL), /* Number of points in aptl */
163 aptl, ROP_SRCCOPY, BBO_IGNORE);
164
165 SWCNTRL swctl;
166 PID pid;
167 TID tid;
168 BOOL screen = FALSE, region = FALSE;
169 CHAR title[11];
170
171 if (!f) {
172 //hwndParent = WinQueryFocus(HWND_DESKTOP);
173 if (hwndParent == hwndFrame) {
174 hwndParent = WinQueryWindow(hwndFrame, QW_NEXTTOP );
175 }
176 screen = TRUE;
177 if (prcl)
178 region = TRUE;
179 }
180
181 int rc = WinQueryWindowProcess(hwndParent, &pid, &tid);
182 if (WinQuerySwitchEntry(WinQuerySwitchHandle(hwndParent, pid),
183 &swctl))
184 WinQuerySwitchEntry(WinQuerySwitchHandle(NULLHANDLE, pid),
185 &swctl);
186
187 char buffer[MAXNAMEL+4];
188 int length = strlen( swctl.szSwtitle );
189 strcpy(buffer, swctl.szSwtitle);
190 char *p;
191 p = buffer;
192 for (int i = 0; i < (length < 11 ? length : 11); i++) {
193 if ( ispunct( *p ) || *p == '\\' || isblank( *p )) {
194 *p = '_';
195 }
196 p++;
197 }
198
199 if (region)
200 snprintf( title, length < 8 ? length + 3 : 11, "SR%s", buffer);
201 else if (screen)
202 snprintf( title, length < 8 ? length + 3 : 11, "SC%s", buffer);
203 else
204 snprintf( title, length < 8 ? length + 3 : 11, "WD%s", buffer);
205
206 SaveBitmap (hbm, hpsMem, sWidth, sHeight, bmp.cBitCount, title);
207
208 // re-associate the previous bit map and the memory presentation space
209 GpiSetBitmap (hpsMem, hbmOld);
210
211 GpiDeleteBitmap (hbm);
212 WinReleasePS (hps);
213 GpiDestroyPS (hps);
214 DevCloseDC (hdcMem);
215
216#ifdef _DOLOGMEM_
217 LogMem("CaptureWindow", FALSE);
218#endif
219
220 return hbm;
221}
222
223// ** DoTracking ********************************************************** /*FOLD00*/
224
225BOOL DoTracking (RECTL *prclTrack)
226{
227 LONG cxScreen, cyScreen, cxPointer, cyPointer;
228 TRACKINFO ti;
229
230 cxScreen = WinQuerySysValue (HWND_DESKTOP, SV_CXSCREEN);
231 cyScreen = WinQuerySysValue (HWND_DESKTOP, SV_CYSCREEN);
232 cxPointer = WinQuerySysValue (HWND_DESKTOP, SV_CXPOINTER);
233 cyPointer = WinQuerySysValue (HWND_DESKTOP, SV_CYPOINTER);
234
235 ti.cxBorder = 1;
236 ti.cyBorder = 1;
237
238 ti.cxGrid = 0;
239 ti.cyGrid = 0;
240
241 ti.cxKeyboard = 4;
242 ti.cyKeyboard = 4;
243
244 ti.rclBoundary.xLeft = 0;
245 ti.rclBoundary.yBottom = 0;
246 ti.rclBoundary.xRight = cxScreen;
247 ti.rclBoundary.yTop = cyScreen;
248
249 ti.ptlMinTrackSize.x = 1;
250 ti.ptlMinTrackSize.y = 1;
251 ti.ptlMaxTrackSize.x = cxScreen;
252 ti.ptlMaxTrackSize.y = cyScreen;
253
254 ti.rclTrack.xLeft = (cxScreen-cxPointer)/2;
255 ti.rclTrack.yBottom = (cyScreen-cyPointer)/2;
256 ti.rclTrack.xRight = (cxScreen+cxPointer)/2;
257 ti.rclTrack.yTop = (cyScreen+cyPointer)/2;
258
259 ti.fs = TF_MOVE | TF_STANDARD | TF_SETPOINTERPOS;
260
261 if (! WinTrackRect (HWND_DESKTOP, NULL, &ti))
262 return FALSE;
263
264 WinSetPointer (HWND_DESKTOP,
265 WinQuerySysPointer (HWND_DESKTOP, SPTR_SIZENESW, FALSE));
266
267 ti.fs = TF_RIGHT | TF_TOP | TF_STANDARD | TF_SETPOINTERPOS;
268
269 if (! WinTrackRect (HWND_DESKTOP, NULL, &ti))
270 return FALSE;
271
272 *prclTrack = ti.rclTrack;
273
274 return TRUE;
275}
276
277// ** StartSelection ****************************************************** /*FOLD00*/
278
279VOID StartSelection (HWND hwnd)
280{
281 WinSetPointer (HWND_DESKTOP, WinLoadPointer (HWND_DESKTOP, GETMODULE, 2));
282 WinSetCapture (HWND_DESKTOP, hwnd);
283}
284
285// ************************************************************************
Note: See TracBrowser for help on using the repository browser.