source: trunk/gotcha.cpp@ 94

Last change on this file since 94 was 94, checked in by Gregg Young, 4 years ago

Add unicode support; Add -i switch for AOS install to GQ; Remove language selection from GQ; Remove help file lang selection from Gotcha; Clean up and rework dialogs/strings

  • Property svn:eol-style set to native
File size: 13.6 KB
Line 
1/***
2 Main source of the Gotcha! screencapture program.
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#define INCL_WINHOOKS
21
22#include "gotcha.h"
23#include "dll/gotchdll.h"
24#include "settings.h"
25#include "string.h"
26
27#include "io.h"
28#define INCL_EXCEPTQ_CLASS
29#define INCL_LOADEXCEPTQ
30#include "exceptq.h"
31
32HAB hab;
33HWND hwndFrame, hwndSnapshot;
34PFNWP OldFrameWP, wpOldButton;
35PSETTINGS pset;
36BOOL g_fIdle = FALSE, g_fSetPathName = FALSE;
37HWND g_hwndMenuSSW;
38HMODULE g_hmod = NULLHANDLE;
39Helper *g_phelp = NULL;
40BOOL g_usePMps = FALSE;
41
42#include "bitmap.cpp"
43#include "mainwin.cpp"
44#include "snapshot.cpp"
45#include "savebmp.cpp"
46
47// ** CheckCmdlineArgs **************************************************** /*FOLD00*/
48
49BOOL CheckCmdlineArgs (int argc, char *argv[])
50{
51 BOOL fAuto = FALSE;
52
53 for (USHORT i = 1; i < argc; i++)
54 {
55#ifndef _QUIET_
56 // batch mode
57 if ((stricmp (argv[i], "-a") == 0))
58 {
59 if (pset->QuerySaveStyle () != FSS_FORCEFILE)
60 pset->SetFileSaveStyle (FSS_NUMFILES);
61 fAuto = TRUE;
62
63 if (i < argc-1)
64 if (argv[i+1][0] != '-')
65 {
66 i++;
67 pset->SetFileSaveStyle (FSS_NUMFILES);
68 pset->SetNumSaveDir (argv[i]);
69 }
70 }
71 // force saving to the given file name
72 else if ((stricmp (argv[i], "-f") == 0) && (i < argc-1))
73 {
74 if (argv[i+1][0] != '-')
75 {
76 i++;
77 pset->SetFileSaveStyle (FSS_FORCEFILE);
78 pset->SetForceSaveFile (argv[i]);
79 g_fSetPathName = TRUE;
80 }
81 }
82 // set to idle priority
83 else if (stricmp (argv[i], "-i") == 0)
84 {
85 g_fIdle = TRUE;
86 pset->SetFlag (SEI_IDLEPRIORITY, TRUE);
87 }
88#else
89 // use default PM print screen
90 if (stricmp (argv[i], "-p") == 0)
91 {
92 g_usePMps = TRUE;
93 }
94 if (stricmp (argv[i], "-i") == 0)
95 {
96 g_installer = TRUE;
97 pset->SetFileSaveStyle (FSS_NUMFILES);
98 pset->SetNumSaveDir ("Z:\\");
99 }
100#endif
101 }
102
103 return fAuto;
104}
105
106// ** main **************************************************************** /*FOLD00*/
107
108int main (int argc, PSZ argv[])
109{
110 ScopedExceptqLoader sel;
111#ifdef _DOLOGDEBUG_
112 LogDebug( "Gotcha! start" );
113#endif
114#ifdef _DOLOGMEM_
115 LogMem("main", TRUE);
116#endif
117
118 // init system and msg queue
119 hab = WinInitialize (0);
120 HMQ hmq = WinCreateMsgQueue (hab, 0);
121 int rc;
122
123 // Load settings moved up here so the string table is available for the already running error
124 pset = new SETTINGS;
125
126 pset->idleSetInIni = pset->QueryFlag(SEI_IDLEPRIORITY);
127 pset->saveStyle = pset->QuerySaveStyle ();
128 pset->pNumSaveDir = pset->QueryNumSaveDir ();
129 pset->pForceSaveFile = pset->QueryForceSaveFile();
130 pset->bSerialCapture = pset->SerialCapture ();
131 //DisplayError("DEBUG", "%d", Version());
132#if 0
133#ifdef _QUIET_
134 HINI hini = PrfOpenProfile (hab, "gotchaq.ini");
135#else
136 HINI hini = PrfOpenProfile (hab, "gotcha.ini");
137#endif
138 BOOL fLChange = FALSE;
139 ULONG ulDataSize;
140 PrfQueryProfileSize(hini, "Language", "LangChangeRequested", &ulDataSize );
141 PrfQueryProfileData(hini, "Language", "LangChangeRequested", &fLChange, &ulDataSize);
142 if (!fLChange) {
143 CHAR *lang = getenv("LANG");
144#ifdef _QUIET_
145 PSZ psz = "goqresen";
146#else
147 PSZ psz = "gotresen";
148#endif
149 PSZ pszh = "gotcha_en";
150 if (lang) {
151 if (!strnicmp(lang, "es", 2)) {
152 psz = "gotreses";
153 pszh = "gotcha_es";
154 }
155 else if (!strnicmp(lang, "cs", 2)) {
156 psz = "gotrescz";
157 }
158 else if (!strnicmp(lang, "de", 2)) {
159 psz = "gotresde";
160 }
161 else if (!strnicmp(lang, "it", 2)) {
162 psz = "gotresit";
163 pszh = "gotcha_it";
164 }
165 else if (!strnicmp(lang, "br", 2)) {
166 psz = "gotresbr";
167 pszh = "gotcha_br";
168 }
169 }
170 pset->SetString(SEI_LANGUAGE, psz);
171 pset->SetString (SEI_LANGUAGEHELP, pszh);
172
173 pset->Save ();
174 pset->ReloadResources (pset->QueryString(SEI_LANGUAGE));
175 //fLChange = FALSE;
176 //PrfWriteProfileData(hini, "Language", "LangChangeRequested", &fLChange, sizeof(BOOL));
177 }
178 if (hini)
179 PrfCloseProfile (hini);
180#endif
181#ifdef _QUIET_
182 CheckCmdlineArgs (argc, argv);
183 if ((Version() < 2))
184 {
185 if (! g_installer)
186 DisplayError(RSTR (IDS_ERROR_DLLOUTDATED),
187 RSTR (IDS_ERROR_DLLOUTDATEDMSG));
188 exit (0);
189 }
190 HMTX hmtx = NULLHANDLE;
191 // running multiple instances orphans all but the first hook unloaded
192 rc = DosOpenMutexSem("\\SEM32\\GOTCHA", &hmtx);
193 if (!rc) {
194 if (! g_installer)
195 DisplayError(RSTR (IDS_ERROR_ALREADYRUNNING),
196 RSTR (IDS_ERROR_ALREADYRUNNINGMSG));
197 exit (0);
198 }
199 rc = DosCreateMutexSem("\\SEM32\\GOTCHA", &hmtx, 0, FALSE);
200 if (rc) {
201 if (! g_installer)
202 DisplayError(RSTR (IDS_ERROR_SEMAPHOREFAILED),
203 RSTR (IDS_ERROR_SEMAPHOREFAILEDMSG));
204 exit (0);
205 }
206#endif
207
208 // register our window classes
209 WinRegisterClass (hab, "thth.wc.gotcha.main", WindowProcedure, 0L,
210 sizeof (ULONG)*2L);
211#ifndef _QUIET_
212 WinRegisterClass (hab, "thth.wc.gotcha.snapshot", wpSnapshot,
213 CS_SIZEREDRAW, sizeof (ULONG)*2L);
214
215 // check cmd line args and if "-a" found take screenshot and exit
216 if (CheckCmdlineArgs (argc, argv))
217 {
218 CaptureWindow (HWND_DESKTOP, HWND_DESKTOP, NULL, TRUE);
219 pset->SetFileSaveStyle(pset->saveStyle);
220 pset->SetNumSaveDir (pset->pNumSaveDir);
221 delete pset;
222 WinDestroyMsgQueue (hmq);
223 WinTerminate (hab);
224 exit (0);
225 }
226#endif
227 SetIdlePriority(pset->QueryFlag(SEI_IDLEPRIORITY));
228
229 // create the windows
230 hwndFrame = CreateMainWindow ();
231#ifndef _QUIET_
232 hwndSnapshot = CreateSnapshotWindow ();
233 SWP swp;
234 USHORT us[7];
235
236 // position main window
237 pset->QueryWindowData (&swp, us, FALSE);
238 WinSetWindowPos (hwndFrame, HWND_DESKTOP, swp.x,swp.y, 0,0,
239 SWP_SHOW | SWP_MOVE);
240#endif
241
242#ifdef _QUIET_
243 bool fPrtScr = FALSE;
244 if (!g_usePMps) {
245 // always turn it off while running
246 // WinSet does not effect the ini setting
247 WinSetSysValue(HWND_DESKTOP, SV_PRINTSCREEN , fPrtScr);
248 }
249 InitDLL (hab, hwndFrame, g_usePMps);
250 StartInputHook ();
251#endif
252#ifndef _QUIET_
253 // position snapshot window
254 pset->QueryWindowData (&swp, us);
255
256 // size, activate & show window
257 WinSetWindowPos (hwndSnapshot, HWND_DESKTOP, swp.x,swp.y, swp.cx,swp.cy,
258 SWP_SHOW | SWP_SIZE | SWP_MOVE);
259 if (! pset->SnapshotWindow ())
260 WinShowWindow (hwndSnapshot, FALSE);
261 else
262 WinShowWindow (hwndSnapshot, TRUE);
263
264 WinSetWindowPos (hwndFrame, NULLHANDLE, 0,0, 0,0, SWP_SHOW);
265 WinSetWindowPos (WinWindowFromID (hwndFrame, FID_CLIENT), NULLHANDLE,
266 0,0, 0,0, SWP_SHOW);
267#endif
268 g_phelp = new Helper(hwndFrame);
269
270
271 // do the main msg loop
272 QMSG qmsg;
273 while (WinGetMsg (hab, &qmsg, 0L, 0, 0))
274 WinDispatchMsg (hab, &qmsg);
275
276
277 // Set priorty to unless user set regular since running -q sets it to idle in the ini
278 if (g_fIdle) {
279 pset->SetFlag (SEI_IDLEPRIORITY, pset->idleSetInIni);
280 }
281 // Don't change the ini stored paths if the paths were set from the command line
282 if (g_fSetPathName) {
283 pset->SetFileSaveStyle(pset->saveStyle);
284 pset->SetForceSaveFile (pset->pForceSaveFile);
285 pset->SetNumSaveDir (pset->pNumSaveDir);
286 }
287#ifndef _QUIET_
288 // save size, etc. of snapshot window
289 WinQueryWindowPos (hwndSnapshot, &swp);
290 pset->SetWindowData (&swp);
291
292 // save size, etc. of main window
293 WinQueryWindowPos (hwndFrame, &swp);
294 pset->SetWindowData (&swp, FALSE);
295#endif
296 // goodbye windows!
297#ifndef _QUIET_
298 WinDestroyWindow (hwndSnapshot);
299#endif
300 WinDestroyWindow (hwndFrame);
301
302#ifdef _QUIET_
303 // Reset to user PM print screen choice
304 if (!g_usePMps) {
305 ULONG ulDataSize = 0;
306 rc = PrfQueryProfileSize(HINI_USERPROFILE, "PM_ControlPanel",
307 "PrintScreen", &ulDataSize );
308 rc = PrfQueryProfileData(HINI_USERPROFILE, "PM_ControlPanel",
309 "PrintScreen", &fPrtScr, &ulDataSize);
310 if (!rc) // Print screen is on by default (no ini entry)
311 fPrtScr = TRUE;
312 WinSetSysValue(HWND_DESKTOP, SV_PRINTSCREEN , fPrtScr);
313 }
314 StopInputHook ();
315 DosCloseMutexSem(hmtx);
316#endif
317
318 delete g_phelp;
319 delete pset;
320
321 WinDestroyMsgQueue (hmq);
322 WinTerminate (hab);
323
324#ifdef _DOLOGMEM_
325 LogMem("main", FALSE);
326#endif
327#ifdef _DOLOGDEBUG_
328 LogDebug( "Gotcha! end" );
329#endif
330}
331
332// ** DisplayError ******************************************************** /*FOLD00*/
333
334VOID DisplayError (PSZ pszTitle, PSZ psz, ...)
335{
336 CHAR dstring[401];
337 va_list valst;
338
339 va_start (valst, psz);
340 vsnprintf (dstring, 401, psz, valst);
341 va_end (valst);
342
343 WinMessageBox (HWND_DESKTOP, WinQueryActiveWindow (HWND_DESKTOP), dstring,
344 pszTitle, 0, MB_OK | MB_ERROR | MB_APPLMODAL | MB_MOVEABLE);
345}
346
347// saymsg2 was adapted from code in FM/2
348APIRET saymsg2(int DefaultButton, HWND hwnd, PCSZ pszTitle, PCSZ pszFmt, ...)
349{
350 ULONG i;
351 APIRET rc;
352 CHAR szMsg[4096];
353 va_list va;
354 MB2INFO *pmbInfo;
355 MB2D mb2dBut[3];
356 ULONG ulInfoSize = (sizeof(MB2INFO) + (sizeof(MB2D) * 2));
357
358 va_start(va, pszFmt);
359 szMsg[sizeof(szMsg) - 1] = 0;
360 vsprintf(szMsg, pszFmt, va);
361 va_end(va);
362
363 if (szMsg[sizeof(szMsg) - 1]) {
364 fprintf(stderr, "Buffer overflow in saymsg2 - need %u bytes\n", strlen(szMsg) + 1);
365 fflush(stderr);
366 }
367
368 memset(mb2dBut, 0, sizeof(MB2D) * 2);
369 strcpy(mb2dBut[0].achText,RSTR(IDS_OK));
370 strcpy(mb2dBut[1].achText,RSTR(IDS_CANCEL));
371 //strcpy(mb2dBut[2].achText,RSTR(IDS_SETTINGS));
372 mb2dBut[0].idButton = 1;
373 mb2dBut[1].idButton = 2;
374 //mb2dBut[2].idButton = 3;
375 if (DefaultButton)
376 mb2dBut[DefaultButton - 1].flStyle = BS_DEFAULT;
377 pmbInfo = (MB2INFO *) malloc(ulInfoSize);
378 memset(pmbInfo, 0, ulInfoSize);
379 if (pmbInfo) {
380 pmbInfo->cb = ulInfoSize;
381 pmbInfo->hIcon = 0;
382 pmbInfo->cButtons = 2;
383 pmbInfo->flStyle = MB_MOVEABLE | MB_ICONQUESTION ;
384 pmbInfo->hwndNotify = NULLHANDLE;
385 for (i = 0; i < 2; i++) {
386 memcpy( pmbInfo->mb2d+i , mb2dBut+i , sizeof(MB2D));
387 }
388 rc = WinMessageBox2(HWND_DESKTOP, hwnd,
389 szMsg, pszTitle, SM2_DIALOG,
390 pmbInfo);
391 WinSetFocus(HWND_DESKTOP, SM2_DIALOG);
392 free(pmbInfo);
393 return rc;
394 }
395 return MBID_ERROR;
396}
397// ** AddSysMenuItem ****************************************************** /*FOLD00*/
398
399VOID AddSysMenuItem (HWND hwndFrame, MENUITEM *Item, PSZ Text)
400{
401 HWND hwndSysMenu = WinWindowFromID (hwndFrame, FID_SYSMENU);
402 USHORT idSysMenu = SHORT1FROMMR (WinSendMsg (hwndSysMenu,
403 MM_ITEMIDFROMPOSITION, NULL,
404 NULL ));
405 MENUITEM miSysMenu;
406 WinSendMsg (hwndSysMenu, MM_QUERYITEM,
407 MPFROM2SHORT (idSysMenu,FALSE), MPFROMP(&miSysMenu));
408
409 HWND hwndSysSubMenu = miSysMenu.hwndSubMenu;
410
411 WinSendMsg (hwndSysSubMenu, MM_INSERTITEM, MPFROMP(Item), MPFROMP(Text));
412}
413
414// ** DoCountdown ********************************************************* /*fold00*/
415
416VOID DoCountdown (ULONG ul)
417{
418 if (ul > 10)
419 DosBeep (4000L-3000L, 20);
420 else
421 DosBeep (4000L-ul*300L, 20);
422}
423
424// ** SetIdlePriority **************************************************** /*FOLD00*/
425
426VOID SetIdlePriority (BOOL f)
427{
428#ifndef _QUEIT_
429 if (f)
430 DosSetPriority(PRTYS_PROCESS, PRTYC_IDLETIME, 0, 0);
431 else
432 DosSetPriority(PRTYS_PROCESS, PRTYC_REGULAR, 0, 0);
433#else
434 DosSetPriority(PRTYS_PROCESS, PRTYC_FOREGROUNDSERVER, 0, 0);
435#endif
436}
437
438// ***********************************************************************
439
440#ifdef _DOLOGMEM_
441VOID LogMem (PSZ psz, BOOL f)
442{
443 FILE *pf = fopen("gotcha.mem","ab");
444 static ULONG TotalPhysicalMemory, ul = 0;
445 ULONG i;
446 if (!f)
447 ul--;
448 DosQuerySysInfo(QSV_TOTAVAILMEM, QSV_TOTAVAILMEM, &TotalPhysicalMemory,
449 sizeof(TotalPhysicalMemory));
450 for (i = 0; i < ul; i++)
451 fputs(" ", pf);
452 fprintf(pf,"%10ld (%s)\n", TotalPhysicalMemory, psz);
453 if (f)
454 ul++;
455 fclose(pf);
456}
457#endif
458
459#ifdef _DOLOGDEBUG_
460VOID LogDebug( PSZ psz, ... )
461{
462 CHAR dstring[401];
463 va_list valst;
464
465 va_start (valst, psz);
466 vsnprintf (dstring, 401, psz, valst);
467 va_end (valst);
468
469 FILE *pf = fopen( "gotcha.log", "ab" );
470 fprintf( pf, "%s\n", dstring );
471 fclose( pf );
472}
473#endif
474
475// ***********************************************************************
Note: See TracBrowser for help on using the repository browser.