source: trunk/savebmp.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: 25.2 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#include <time.h>
21
22#include "gbm\gbm.h"
23#include "gbm\gbmmem.h"
24#include "model.h"
25
26#define __PMPRINTF__
27#include "PMPRINTF.H"
28
29/* ------------------------------ */
30static int StrideOf(const MOD *mod)
31{
32 DebugHereIAm();
33 return ( ( mod->gbm.w * mod->gbm.bpp + 31 ) / 32 ) * 4;
34 }
35/*...e*/
36
37/*...sAllocateData:0:*/
38static BOOL AllocateData(MOD *mod)
39 {
40 const unsigned long stride = StrideOf(mod);
41 if ( (mod->pbData = (UCHAR*) gbmmem_malloc(stride * mod->gbm.h)) == NULL )
42 return FALSE;
43 DebugHereIAm();
44 return TRUE;
45 }
46/*...e*/
47
48/*...sModCreate:0:*/
49MOD_ERR ModCreate(
50 int w, int h, int bpp, const GBMRGB gbmrgb[],
51 MOD *modNew
52 )
53 {
54 modNew->gbm.w = w;
55 modNew->gbm.h = h;
56 modNew->gbm.bpp = bpp;
57 if ( gbmrgb != NULL && bpp != 24 )
58 memcpy(&(modNew->gbmrgb), gbmrgb, sizeof(GBMRGB) << bpp);
59 if ( !AllocateData(modNew) )
60 return MOD_ERR_MEM;
61 DebugHereIAm();
62 return MOD_ERR_OK;
63 }
64/*...e*/
65
66/*MOD_ERR ModCreateFromHPS(
67 HPS hps, int w, int h, int bpp, //lBitCountScreen > 8 ) ? 24 : lBitCountScreen
68 MOD *modNew
69 )*/
70/*...sModCreateFromHPS:0:*/
71MOD_ERR ModCreateFromHPS(
72 HPS hps, int w, int h, int bpp,
73 MOD *modNew
74 )
75 {
76 MOD_ERR mrc;
77
78 #pragma pack(2)
79 struct
80 {
81 BITMAPINFOHEADER2 bmp2;
82 RGB2 argb2Color[0x100];
83 } bm;
84 #pragma pack()
85
86 if ( (mrc = ModCreate(w, h, bpp, NULL, modNew)) != MOD_ERR_OK )
87 return mrc;
88 DebugHereIAm();
89 memset(&(bm.bmp2), 0, sizeof(bm.bmp2));
90 bm.bmp2.cbFix = sizeof(BITMAPINFOHEADER2);
91 bm.bmp2.cx = w;
92 bm.bmp2.cy = h;
93 bm.bmp2.cBitCount = bpp;
94 bm.bmp2.cPlanes = 1;
95 GpiQueryBitmapBits(hps, 0L, h, modNew->pbData, (BITMAPINFO2 *) &bm);
96
97 if ( bpp != 24 )
98 {
99 int i;
100 for ( i = 0; i < (1<<bpp); i++ )
101 {
102 modNew->gbmrgb[i].r = bm.argb2Color[i].bRed ;
103 modNew->gbmrgb[i].g = bm.argb2Color[i].bGreen;
104 modNew->gbmrgb[i].b = bm.argb2Color[i].bBlue ;
105 }
106 }
107 DebugHereIAm();
108 return MOD_ERR_OK;
109 }
110/*...e*/
111
112/*MOD_ERR ModWriteToFile(
113 const MOD *mod,
114 const CHAR *szFn, const CHAR *szOpt // ""
115 )*/
116/*...sModWriteToFile:0:*/
117MOD_ERR ModWriteToFile(
118 const MOD *mod,
119 const CHAR *szFn, const CHAR *szOpt
120 )
121 {
122 GBM_ERR grc;
123 int fd, ft, flag = 0;
124 GBMFT gbmft;
125
126 if ( (grc = gbm_guess_filetype(szFn, &ft)) != GBM_ERR_OK ) {
127 return grc;
128 }
129 PmpfF(( "file type %i", ft ));
130 DebugHereIAm();
131 gbm_query_filetype(ft, &gbmft);
132 PmpfF(( "file type %i name %s flags %i bpp %i", ft, gbmft.short_name,
133 gbmft.flags, mod->gbm.bpp));
134 switch ( mod->gbm.bpp )
135 {
136 case 1: flag = GBM_FT_W1; break;
137 case 4: flag = GBM_FT_W4; break;
138 case 8: flag = GBM_FT_W8; break;
139 case 24: flag = GBM_FT_W24; break;
140 default: flag = 0; break;
141 }
142
143 if ( (gbmft.flags & flag) == 0 )
144 return MOD_ERR_SUPPORT;
145 DebugHereIAm();
146 if ( (fd = gbm_io_create(szFn, GBM_O_WRONLY)) == -1 )
147 return MOD_ERR_CREATE;
148 DebugHereIAm();
149 if ( (grc = gbm_write(szFn, fd, ft, &(mod->gbm), mod->gbmrgb, mod->pbData, szOpt)) != GBM_ERR_OK )
150 {
151 gbm_io_close(fd);
152 unlink(szFn);
153 return MOD_ERR_GBM(grc);
154 }
155 DebugHereIAm();
156 gbm_io_close(fd);
157 DebugHereIAm();
158 return MOD_ERR_OK;
159 }
160/*...e*/
161// ** SaveBitmap ********************************************************** /*FOLD00*/
162
163VOID SaveBitmap (HBITMAP hbm, HPS hps, int width, int height, int bitCount)
164{
165#ifdef _DOLOGMEM_
166 LogMem("SaveBitmap", TRUE);
167#endif
168 MOD newmod;
169
170 if( pset->QueryFileSaveStyle () == FSS_FORCEFILE )
171 {
172 PSZ psz = pset->QueryForceSaveFile();
173 psz = AddExtensionToFilename( psz );
174 //
175 /*if( ( pset->QueryFileFormat() == BMF_12 ) ||
176 ( pset->QueryFileFormat() == BMF_16 ) ||
177 ( pset->QueryFileFormat() == BMF_20 ) ) {
178 SaveBitmapToFile( hbm, psz, hps );
179 DebugHereIAm();
180 }
181 else { */
182 ModCreateFromHPS( hps, width, height,
183 (bitCount > 8 ) ? 24 : bitCount,
184 &newmod );
185 ModWriteToFile(&newmod, psz, "" );
186 //}
187#ifdef _DOLOGMEM_
188 LogMem( "SaveBitmap-1", FALSE );
189#endif
190 return;
191 }
192
193 if (pset->DoSound ())
194 {
195 DosBeep ( 500, 100);
196 DosBeep (1000, 100);
197 DosBeep (1500, 100);
198 }
199
200 switch (pset->QuerySaveStyle ())
201 {
202 case SAVESTYLE_CLIPBOARD:
203 SaveBitmapToClipboard (hbm);
204 break;
205
206 default:
207#ifdef _DOLOGDEBUG_
208 LogDebug( "SaveBitmap()" );
209#endif
210 if (SelectSaveFile ()) {
211#ifdef _DOLOGDEBUG_
212 LogDebug( "Before call to SaveBitmapToFile()" );
213#endif
214 //DebugHereIAm();
215 /*if( ( pset->QueryFileFormat() == BMF_12 ) ||
216 ( pset->QueryFileFormat() == BMF_16 ) ||
217 ( pset->QueryFileFormat() == BMF_20 ) ) {
218 DebugHereIAm();
219 SaveBitmapToFile( hbm, pset->QuerySaveFile (), hps );
220 DebugHereIAm();
221 }
222 else {*/
223 ModCreateFromHPS( hps, width, height,
224 (bitCount > 8 ) ? 24 : bitCount,
225 &newmod );
226 ModWriteToFile(&newmod, pset->QuerySaveFile (), "" );
227 //}
228#ifdef _DOLOGDEBUG_
229 LogDebug( "After call to SaveBitmapToFile()" );
230#endif
231 }
232 break;
233 }
234
235#ifdef _DOLOGMEM_
236 LogMem("SaveBitmap-2", FALSE);
237#endif
238}
239
240// ** SaveBitmapToClipboard *********************************************** /*FOLD00*/
241
242VOID SaveBitmapToClipboard (HBITMAP hbm)
243{
244#ifdef _DOLOGMEM_
245 LogMem("SaveBitmapToClipboard", TRUE);
246#endif
247 // copy the thing to the clipboard
248 WinOpenClipbrd (hab);
249 WinEmptyClipbrd (hab);
250 WinSetClipbrdData (hab, ULONG (hbm), CF_BITMAP, CFI_HANDLE);
251 WinCloseClipbrd (hab);
252#ifdef _DOLOGMEM_
253 LogMem("SaveBitmapToClipboard", FALSE);
254#endif
255}
256
257// ** SaveBitmapToFile **************************************************** /*FOLD00*/
258
259#define CB_12HEADER sizeof (BITMAPINFOHEADER) // == 12
260#define CB_16HEADER (sizeof (BITMAPINFOHEADER2)-24)
261#define CB_20HEADER sizeof (BITMAPINFOHEADER2) // == 64
262
263#if 0
264VOID SaveBitmapToFile (HBITMAP hbm, PSZ psz, HPS hps)
265{
266 ULONG rc;
267
268#ifdef _DOLOGMEM_
269 LogMem("SaveBitmapToFile", TRUE);
270#endif
271#ifdef _DOLOGDEBUG_
272 LogDebug( "Start of SaveBitmapToFile()" );
273#endif
274 // get the fullsized bitmap info header from the bitmap
275 BITMAPINFOHEADER2 bih2;
276
277 bih2.cbFix = sizeof (BITMAPINFOHEADER2);
278 if (! GpiQueryBitmapInfoHeader (hbm, &bih2))
279 {
280#ifdef _DOLOGDEBUG_
281 LogDebug( "SaveBitmapToFile(): Exit GpiQueryBitmapInfoHeader" );
282#endif
283 DisplayError (RSTR(IDS_HEADER_ERROR),
284 RSTR(IDS_ERROR_COULDNOTRETRIEVEHEADER),
285 WinGetLastError (hab));
286 return;
287 }
288#ifdef _DOLOGDEBUG_
289 LogDebug( "SaveBitmapToFile(): GpiQueryBitmapInfoHeader ok." );
290#endif
291
292 // get the size of the colortable
293 ULONG cbColtab = 0L, cColors = 0L;
294
295 if (bih2.cBitCount == 8)
296 cColors = 256L;
297 else if (bih2.cBitCount == 4)
298 cColors = 16L;
299 else if (bih2.cBitCount == 1)
300 cColors = 2L;
301
302 cbColtab = cColors * sizeof( RGB2 );
303
304 // get size of bits buffer and allocate it
305 ULONG cbBits =
306 (bih2.cBitCount * bih2.cx + 31L)/32L * bih2.cPlanes * 4L * bih2.cy;
307 PBYTE pb =
308 PBYTE (malloc (cbBits));
309
310 // allocate and init the file info header
311 PBITMAPFILEHEADER2 pbfh2 =
312 PBITMAPFILEHEADER2 (malloc (sizeof (BITMAPFILEHEADER2)+cbColtab));
313#ifdef _DOLOGDEBUG_
314 LogDebug( "SaveBitmapToFile(): Filling header." );
315#endif
316
317 // fill the bitmap header with the bitmap data
318 memcpy (&(pbfh2->bmp2), &bih2, sizeof (BITMAPINFOHEADER2));
319 pbfh2->bmp2.cbImage = cbBits;
320
321#ifdef _DOLOGDEBUG_
322 LogDebug( "SaveBitmapToFile(): Before GpiQueryBitmapBits." );
323#endif
324 // grab the bits!! ;-) - and the colortable
325 if (GpiQueryBitmapBits (hps, 0, bih2.cy, pb, PBITMAPINFO2 (&(pbfh2->bmp2)))
326 == GPI_ALTERROR)
327 {
328#ifdef _DOLOGDEBUG_
329 LogDebug( "SaveBitmapToFile(): Exit GpiQueryBitmapBits" );
330#endif
331 DisplayError (RSTR(IDS_HEADER_ERROR),
332 RSTR(IDS_ERROR_COULDNOTGETBITMAPBITS),
333 WinGetLastError (hab));
334 free (pb);
335 return;
336 }
337#ifdef _DOLOGDEBUG_
338 LogDebug( "SaveBitmapToFile(): GpiQueryBitmapBits ok." );
339#endif
340
341 pbfh2->usType = BFT_BMAP;
342 pbfh2->offBits = sizeof (BITMAPFILEHEADER2)-sizeof (BITMAPINFOHEADER2);
343
344 switch (pset->QueryFileFormat ())
345 {
346 case BMF_12:
347 pbfh2->offBits += CB_12HEADER + cColors*sizeof (RGB);
348 break;
349
350 case BMF_20:
351 pbfh2->offBits += CB_20HEADER + cColors*sizeof (RGB2);
352 break;
353
354 default:
355 pbfh2->offBits += CB_16HEADER + cColors*sizeof (RGB2);
356 break;
357 }
358
359 pbfh2->cbSize = pbfh2->offBits+cbBits;
360 pbfh2->xHotspot = pbfh2->yHotspot = 0;
361
362#ifdef _DOLOGDEBUG_
363 LogDebug( "SaveBitmapToFile(): Before if." );
364#endif
365 if( ( pset->QueryFileFormat() == BMF_12 ) ||
366 ( pset->QueryFileFormat() == BMF_16 ) ||
367 ( pset->QueryFileFormat() == BMF_20 ) )
368 {
369 // open out file
370 FILE *pf = fopen (psz, "wb");
371 if (! pf)
372 {
373 DisplayError (RSTR(IDS_HEADER_ERROR), RSTR(IDS_ERROR_COULDNOTOPENFILE),
374 psz);
375 free (pb);
376 return;
377 }
378
379 // write file info header
380 fwrite (pbfh2, sizeof (BITMAPFILEHEADER2)-sizeof (BITMAPINFOHEADER2),
381 1, pf);
382
383 // write bitmap info header
384 switch (pset->QueryFileFormat ())
385 {
386 case BMF_12:
387 {
388 BITMAPINFOHEADER bih;
389
390 bih.cbFix = CB_12HEADER;
391 bih.cx = USHORT (bih2.cx);
392 bih.cy = USHORT (bih2.cy);
393 bih.cPlanes = bih2.cPlanes;
394 bih.cBitCount = bih2.cBitCount;
395
396 fwrite (&bih, CB_12HEADER, 1, pf);
397 }
398 break;
399
400 case BMF_20:
401 pbfh2->bmp2.cbFix = CB_20HEADER;
402 fwrite (&(pbfh2->bmp2), CB_20HEADER, 1, pf);
403 break;
404
405 default:
406 pbfh2->bmp2.cbFix = CB_16HEADER;
407 fwrite (&(pbfh2->bmp2), CB_16HEADER, 1, pf);
408 break;
409 }
410
411 // write colortable if present
412 if (cbColtab)
413 {
414 switch (pset->QueryFileFormat ())
415 {
416 case BMF_12:
417 {
418 RGB rgb;
419 for (USHORT i = 0; i < cColors; i++)
420 {
421 rgb.bRed = PBITMAPINFO2 (&(pbfh2->bmp2))
422 ->argbColor[i].bRed;
423 rgb.bGreen = PBITMAPINFO2 (&(pbfh2->bmp2))
424 ->argbColor[i].bGreen;
425 rgb.bBlue = PBITMAPINFO2 (&(pbfh2->bmp2))
426 ->argbColor[i].bBlue;
427 fwrite (&rgb, sizeof (rgb), 1, pf);
428 }
429 }
430 break;
431
432 default:
433 fwrite (PBYTE (&(pbfh2->bmp2))+sizeof (BITMAPINFOHEADER2),
434 cbColtab, 1, pf);
435 break;
436 }
437 }
438
439 // write the actual bitmap data bits
440 fwrite (pb, cbBits, 1, pf);
441 fclose (pf);
442 }
443
444 /*else {
445#ifdef _DOLOGDEBUG_
446 LogDebug( "SaveBitmapToFile(): Starting 'else' path." );
447#endif
448 PFN xmmioClose = pset->GetMMIO()->pfmmioClose;
449// PFN xmmioOpen = pset->GetMMIO()->pfmmioOpen;
450 PFN xmmioWrite = pset->GetMMIO()->pfmmioWrite;
451 PFN xmmioQueryHeaderLength = pset->GetMMIO()->pfmmioQueryHeaderLength;
452 PFN xmmioSetHeader = pset->GetMMIO()->pfmmioSetHeader;
453
454#ifdef _DOLOGDEBUG_
455 LogDebug( "SaveBitmapToFile(): Before GetFOURCC." );
456#endif
457 // ********* WRITE TARGET
458 FOURCC fccTargetIOProc = pset->GetFOURCC();
459
460 // Initialize our info MMIOINFO structure.
461 MMIOINFO mmioinfoTarget;
462#ifdef _DOLOGDEBUG_
463 LogDebug( "SaveBitmapToFile(): Before memset." );
464#endif
465 memset( &mmioinfoTarget, 0L, sizeof( MMIOINFO ) );
466 mmioinfoTarget.fccIOProc = fccTargetIOProc;
467 mmioinfoTarget.ulTranslate = MMIO_TRANSLATEHEADER | MMIO_TRANSLATEDATA;
468
469#ifdef _DOLOGDEBUG_
470 LogDebug( "SaveBitmapToFile(): Trying to open file." );
471#endif
472 // Open target file.
473 HMMIO hmmioTarget;
474 if( ! ( hmmioTarget = mmioOpen( psz,
475 &mmioinfoTarget,
476 MMIO_CREATE | MMIO_WRITE |
477 MMIO_DENYWRITE | MMIO_NOIDENTIFY ))) {
478 DisplayError ("mmioOpen()-Error",
479 "mmioOpen()-Error %ld", mmioinfoTarget.ulErrorRet );
480 return;
481 }
482#ifdef _DOLOGDEBUG_
483 LogDebug( "SaveBitmapToFile(): Open file ok." );
484#endif
485
486 // Set the target header.
487 ULONG ulImageHeaderLength;
488
489 mmioQueryHeaderLength( hmmioTarget, (PLONG)&ulImageHeaderLength, 0L, 0L );
490 if( ulImageHeaderLength != sizeof( MMIMAGEHEADER ) )
491 {
492 // We have a problem.....possibly incompatible versions.
493 mmioClose( hmmioTarget, 0L );
494 DisplayError ("mmioQueryHeaderLength()-Error",
495 "mmioQueryHeaderLength()-Error",
496 WinGetLastError (hab));
497 return;
498 }
499#ifdef _DOLOGDEBUG_
500 LogDebug( "SaveBitmapToFile(): xmmioQueryHeaderLength ok." );
501#endif
502
503 MMIMAGEHEADER mmImgHdr;
504 mmImgHdr.ulHeaderLength = ulImageHeaderLength;
505 mmImgHdr.ulContentType = MMIO_IMAGE_UNKNOWN;
506 mmImgHdr.ulMediaType = MMIO_MEDIATYPE_IMAGE;
507
508#ifdef _DOLOGDEBUG_
509 LogDebug( "SaveBitmapToFile(): Before memcpy (colors)." );
510#endif
511 memcpy( mmImgHdr.bmiColors,
512 PBYTE( &( pbfh2->bmp2 ) ) + sizeof( BITMAPINFOHEADER2 ),
513 cbColtab );
514
515 mmImgHdr.mmXDIBHeader.XDIBHeaderPrefix.ulMemSize = cbBits; // FIXME;
516 mmImgHdr.mmXDIBHeader.XDIBHeaderPrefix.ulPelFormat = 0; // FIXME;
517 mmImgHdr.mmXDIBHeader.XDIBHeaderPrefix.usTransType = 0; // FIXME
518 mmImgHdr.mmXDIBHeader.XDIBHeaderPrefix.ulTransVal = 0; // FIXME
519 memcpy( &(mmImgHdr.mmXDIBHeader.BMPInfoHeader2), &bih2, sizeof (BITMAPINFOHEADER2));
520
521#ifdef _DOLOGDEBUG_
522 LogDebug( "SaveBitmapToFile(): Before xmmioSetHeader." );
523#endif
524 ULONG ulBytesRead;
525 if( ( rc = (LONG)mmioSetHeader( hmmioTarget, (MMIMAGEHEADER*)&mmImgHdr,
526 (LONG)sizeof( MMIMAGEHEADER ), (PLONG)&ulBytesRead,
527 0L, 0L ) ) != MMIO_SUCCESS )
528 {
529 // Header unavailable.
530 mmioClose( hmmioTarget, 0L );
531 DisplayError ("mmioSetHeader()-Error",
532 "mmioSetHeader()-Error %ld", rc );
533 return;
534 }
535#ifdef _DOLOGDEBUG_
536 LogDebug( "SaveBitmapToFile(): xmmioSetHeader ok." );
537#endif
538
539 // write the actual bitmap data bits
540 if( ( rc = mmioWrite( hmmioTarget, (CHAR *) pb, cbBits ) ) == MMIO_ERROR )
541 DisplayError ("mmioWrite()-Error",
542 "mmioWrite()-Error %ld", rc );
543#ifdef _DOLOGDEBUG_
544 LogDebug( "SaveBitmapToFile(): xmmioWrite ok." );
545#endif
546
547 if( ( rc = mmioClose( hmmioTarget, 0 ) ) != MMIO_SUCCESS )
548 DisplayError ("mmioClose()-Error",
549 "mmioClose()-Error %ld", rc );
550#ifdef _DOLOGDEBUG_
551 LogDebug( "SaveBitmapToFile(): xmmioClose ok." );
552#endif
553 } */
554
555#ifdef _DOLOGDEBUG_
556 LogDebug( "SaveBitmapToFile(): Everything done, closed file" );
557#endif
558
559 // set BITMAP file type ea
560 SetEAs( psz );
561
562 // cleanup and return
563 free (pbfh2);
564 free (pb);
565#ifdef _DOLOGMEM_
566 LogMem("SaveBitmapToFile", FALSE);
567#endif
568}
569#endif
570// ** SetEAs ************************************************************** /*FOLD00*/
571
572BOOL SetEAs (PSZ psz)
573{
574#ifdef _DOLOGMEM_
575 LogMem("SetEAs", TRUE);
576#endif
577 // alloc memory for EA data
578 CHAR achComment[ 100 ];
579 time_t tim = time_t( time( NULL ) );
580 sprintf( achComment, "Captured by %s on %s", PSZ_NAMEVERSION, ctime( &tim ) );
581 PSZ pszName = ".TYPE", pszName2 = ".COMMENT";
582 PSZ pszValue = pset->GetFileEAType();
583 USHORT cbName = strlen (pszName)+1, cbName2 = strlen( pszName2 )+1;
584 USHORT cbValue = strlen (pszValue)+1, cbValue2 = strlen( achComment )+1;
585 USHORT usMemNeeded = sizeof (FEA2LIST) + cbName + cbValue +cbName2 + cbValue2;
586 PBYTE pb = PBYTE (malloc (usMemNeeded));
587
588 EAOP2 eaop2;
589
590 eaop2.fpFEA2List = (FEA2LIST FAR *) pb;
591 eaop2.fpFEA2List->cbList = usMemNeeded;
592
593 eaop2.fpFEA2List->list[0].fEA = 0; // EA is no "must have"
594 eaop2.fpFEA2List->list[0].cbName = cbName-1;
595 eaop2.fpFEA2List->list[0].cbValue = cbValue;
596 eaop2.fpFEA2List->list[1].fEA = 0; // EA is no "must have"
597 eaop2.fpFEA2List->list[1].cbName = cbName2-1;
598 eaop2.fpFEA2List->list[1].cbValue = cbValue2;
599
600 strcpy (eaop2.fpFEA2List->list[0].szName, pszName);
601 memcpy (eaop2.fpFEA2List->list[0].szName+cbName, pszValue, cbValue);
602 strcpy (eaop2.fpFEA2List->list[1].szName, pszName2);
603 memcpy (eaop2.fpFEA2List->list[1].szName+cbName2, achComment, cbValue2);
604
605 if (DosSetPathInfo (psz, FIL_QUERYEASIZE, PVOID (&eaop2),
606 sizeof (EAOP2), DSPI_WRTTHRU))
607 {
608 DisplayError (RSTR(IDS_HEADER_ERROR),
609 RSTR(IDS_ERROR_COULDNOTWRITEFILETYPEEA));
610 free (pb);
611#ifdef _DOLOGMEM_
612 LogMem("SetEAs-1", FALSE);
613#endif
614 return FALSE;
615 }
616
617 free (pb);
618#ifdef _DOLOGMEM_
619 LogMem("SetEAs-2", FALSE);
620#endif
621 return TRUE;
622}
623
624// ** SelectSaveFile ****************************************************** /*FOLD00*/
625
626BOOL SelectSaveFile (VOID)
627{
628#ifdef _DOLOGMEM_
629 LogMem("SelectSaveFile", TRUE);
630#endif
631 // if FSS_NUMFILES, create and return a new name
632 if (pset->QueryFileSaveStyle () == FSS_NUMFILES)
633 {
634 CHAR ach[_MAX_PATH];
635 for (USHORT i = 0; i < 10000; i++)
636 {
637 sprintf( ach, "%s\\got%05d.%s", pset->QueryNumSaveDir(), i,
638 pset->GetFileExtension() );
639 if (access (ach, 0) != 0)
640 {
641 pset->SetSaveFile (ach);
642 return TRUE;
643 }
644 }
645 return FALSE;
646 }
647
648 // ... else do a file dlg
649 FILEDLG fdlg;
650
651 memset (&fdlg, 0, sizeof (fdlg));
652
653 fdlg.hMod = GETMODULE;
654 fdlg.usDlgId = ID_DLG_FILE;
655 fdlg.pfnDlgProc = FileDLGProcedure;
656 fdlg.cbSize = sizeof (fdlg);
657 fdlg.fl = FDS_SAVEAS_DIALOG | FDS_CENTER | FDS_CUSTOM;
658 fdlg.pszTitle = RSTR(IDS_SAVESCREENSHOTTO);
659 strcpy (fdlg.szFullFile, pset->QuerySaveFile ());
660
661 if (WinFileDlg (HWND_DESKTOP, HWND_DESKTOP, &fdlg))
662 {
663 if (fdlg.lReturn != DID_OK)
664 return FALSE;
665
666 PSZ pszOut = fdlg.szFullFile;
667
668 // Add bmp extension if not already present.
669 if( pset->AutoaddExtension() )
670 pszOut = AddExtensionToFilename( pszOut );
671
672 // if file exists and user wants it, confirm overwriting
673 if (pset->ConfirmOverwrite ())
674 if (access (pszOut, 0) == 0)
675 // let user confirm operation
676 if (WinMessageBox (HWND_DESKTOP, HWND_DESKTOP,
677 RSTR(IDS_FILEEXISTSOVERWRITE),
678 RSTR(IDS_HEADER_WARNING), 0L,
679 MB_OKCANCEL | MB_QUERY | MB_DEFBUTTON2 |
680 MB_MOVEABLE)
681 != MBID_OK)
682 return FALSE;
683
684 pset->SetSaveFile (pszOut);
685 return TRUE;
686 }
687 return FALSE;
688#ifdef _DOLOGMEM_
689 LogMem("SelectSaveFile", FALSE);
690#endif
691}
692
693// ** FileDLGProcedure **************************************************** /*fold00*/
694
695MRESULT EXPENTRY FileDLGProcedure (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
696{
697#ifdef _DOFNCOMPLETION_
698 static HDIR hdir = NULLHANDLE;
699 static BOOL fCompletion = FALSE;
700#endif
701
702 switch (msg)
703 {
704 case WM_INITDLG:
705 WinSendDlgItemMsg (hwnd, WID_CB_AUTOADDEXTENSION, BM_SETCHECK,
706 MPFROMLONG (pset->AutoaddExtension ()),
707 MPFROMLONG (0));
708 WinSendDlgItemMsg (hwnd, WID_CB_CONFIRMOVERWRITE, BM_SETCHECK,
709 MPFROMLONG (pset->ConfirmOverwrite ()),
710 MPFROMLONG (0));
711/* FIXME neither work ... WinSendDlgItemMsg (hwnd, DID_FILES_LB, WM_ENABLE,
712 MPFROMLONG (TRUE),
713 MPFROMLONG (0));
714 //WinEnableWindow( WinWindowFromID( hwnd, DID_FILES_LB ), TRUE ); */
715 break;
716
717#ifdef _DOFNCOMPLETION_
718 case WM_CHAR: {
719 HWND hwndFNE = WinWindowFromID (hwnd, DID_FILENAME_ED);
720 if (WinQueryFocus (HWND_DESKTOP) == hwndFNE)
721 {
722 // tab key, downpress
723 if ((CHARMSG (&msg)->chr == 9) && !
724 (CHARMSG (&msg)->fs & KC_KEYUP))
725 {
726 ULONG c = 1, fl;
727 FILEFINDBUF3 findbuf;
728 APIRET rc;
729 CHAR ach[_MAX_PATH];
730
731 if (! hdir)
732 {
733 WinQueryWindowText (hwndFNE, _MAX_PATH-1, ach);
734 strcat (ach, "*");
735 fl = FILE_NORMAL;
736 hdir = HDIR_CREATE;
737 rc = DosFindFirst (ach, &hdir, fl, &findbuf,
738 sizeof (findbuf), &c,
739 FIL_STANDARD);
740 }
741 else
742 {
743 rc = DosFindNext (hdir, &findbuf,
744 sizeof (findbuf), &c);
745 }
746
747 if (! rc)
748 {
749 fCompletion = TRUE;
750 WinSetWindowText (hwndFNE, findbuf.achName);
751 fCompletion = FALSE;
752 }
753 else
754 DosBeep (1000, 10);
755 return MRESULT (FALSE);
756 }
757 } } break;
758
759 case WM_CONTROL:
760 switch (SHORT1FROMMP (mp1))
761 {
762 case DID_FILENAME_ED:
763 if ((SHORT2FROMMP (mp1) == EN_CHANGE) ||
764 (SHORT2FROMMP (mp1) == EN_KILLFOCUS))
765 if (hdir && !fCompletion)
766 {
767 // FIXME maybe do this to when closing dialog?
768 DosFindClose (hdir);
769 hdir = NULLHANDLE;
770 }
771 break;
772 }
773 break;
774#endif
775
776 case WM_COMMAND:
777 case WM_CLOSE:
778 pset->AutoaddExtension
779 (BOOL (WinSendDlgItemMsg (hwnd, WID_CB_AUTOADDEXTENSION,
780 BM_QUERYCHECK, 0, 0)));
781 pset->ConfirmOverwrite
782 (BOOL (WinSendDlgItemMsg (hwnd, WID_CB_CONFIRMOVERWRITE,
783 BM_QUERYCHECK, 0, 0)));
784 break;
785 }
786
787 return WinDefFileDlgProc (hwnd, msg, mp1, mp2);
788}
789
790// ** AddExtensionToFilename ********************************************** /*FOLD00*/
791
792PSZ AddExtensionToFilename( PSZ psz )
793{
794 // Using a static buffer here is not really good, but good enough
795 // currently as we know there will be no concurrent access.
796 static CHAR ach[_MAX_PATH];
797 PSZ pszExtension;
798
799 PSZ apszValidExtensions[16] =
800 { "bmp", "tif", "tiff", "tga", "targa", "pcx", "pnm", "jpg", "jpeg",
801 "jpg2", "jbg", "jbig", "png", "ppm", "raw", "dib" };
802
803 if( ! ( pszExtension = strrchr( psz, '.' ) ) ) {
804 // No extension at all - add the appropriate one.
805 sprintf( ach, "%s.%s", psz, pset->GetFileExtension() );
806 } else if( stricmp ( pszExtension+1, pset->GetFileExtension() ) == 0 ) {
807 // Correct extension already - just return unchanged filename.
808 strcpy( ach, psz );
809 } else {
810 // Some extension, but not the correct one - change or append.
811 BOOL fValidExtension = FALSE;
812 for( int i = 0; i < 16; i++ ) {
813 if( stricmp( pszExtension+1, apszValidExtensions[i] ) == 0 ) {
814 fValidExtension = TRUE;
815 break;
816 }
817 }
818 if( fValidExtension ) {
819 // Valid extension, but not right for current format - replace.
820 *pszExtension = '\0';
821 sprintf( ach, "%s.%s", psz, pset->GetFileExtension() );
822 } else {
823 // Some extension but not a valid image file format extension - add.
824 sprintf( ach, "%s.%s", psz, pset->GetFileExtension() );
825 }
826 }
827 return ach;
828}
829
830// ************************************************************************
Note: See TracBrowser for help on using the repository browser.