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