palette.c 27.8 KB
Newer Older
Alexandre Julliard's avatar
Alexandre Julliard committed
1 2 3
/*
 * GDI palette objects
 *
Alexandre Julliard's avatar
Alexandre Julliard committed
4
 * Copyright 1993,1994 Alexandre Julliard
Alexandre Julliard's avatar
Alexandre Julliard committed
5
 * Copyright 1996 Alex Korobka
Alexandre Julliard's avatar
Alexandre Julliard committed
6
 *
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * NOTES:
Alexandre Julliard's avatar
Alexandre Julliard committed
22 23
 * PALETTEOBJ is documented in the Dr. Dobbs Journal May 1993.
 * Information in the "Undocumented Windows" is incorrect.
Alexandre Julliard's avatar
Alexandre Julliard committed
24
 */
Alexandre Julliard's avatar
Alexandre Julliard committed
25

Alexandre Julliard's avatar
Alexandre Julliard committed
26
#include <stdlib.h>
Alexandre Julliard's avatar
Alexandre Julliard committed
27
#include <string.h>
28

29
#include "winbase.h"
30 31
#include "windef.h"
#include "wingdi.h"
32
#include "wine/winuser16.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
33
#include "gdi.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
34
#include "color.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
35
#include "palette.h"
36
#include "wine/debug.h"
37
#include "winerror.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
38

39
WINE_DEFAULT_DEBUG_CHANNEL(palette);
40

41 42
PALETTE_DRIVER *PALETTE_Driver = NULL;

43 44
/* Pointers to USER implementation of SelectPalette/RealizePalette */
/* they will be patched by USER on startup */
45 46
FARPROC pfnSelectPalette = NULL;
FARPROC pfnRealizePalette = NULL;
Alexandre Julliard's avatar
Alexandre Julliard committed
47

48
static UINT SystemPaletteUse = SYSPAL_STATIC;  /* currently not considered */
Alexandre Julliard's avatar
Alexandre Julliard committed
49

Alexandre Julliard's avatar
Alexandre Julliard committed
50 51 52
static HPALETTE16 hPrimaryPalette = 0; /* used for WM_PALETTECHANGED */
static HPALETTE16 hLastRealizedPalette = 0; /* UnrealizeObject() needs it */

Alexandre Julliard's avatar
Alexandre Julliard committed
53

Alexandre Julliard's avatar
Alexandre Julliard committed
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
/***********************************************************************
 *           PALETTE_Init
 *
 * Create the system palette.
 */
HPALETTE16 PALETTE_Init(void)
{
    int                 i;
    HPALETTE16          hpalette;
    LOGPALETTE *        palPtr;
    PALETTEOBJ*         palObj;
    const PALETTEENTRY* __sysPalTemplate = COLOR_GetSystemPaletteTemplate();

    /* create default palette (20 system colors) */

Alexandre Julliard's avatar
Alexandre Julliard committed
69 70
    palPtr = HeapAlloc( GetProcessHeap(), 0,
             sizeof(LOGPALETTE) + (NB_RESERVED_COLORS-1)*sizeof(PALETTEENTRY));
Alexandre Julliard's avatar
Alexandre Julliard committed
71 72 73 74 75 76 77 78 79 80 81 82
    if (!palPtr) return FALSE;

    palPtr->palVersion = 0x300;
    palPtr->palNumEntries = NB_RESERVED_COLORS;
    for( i = 0; i < NB_RESERVED_COLORS; i ++ )
    {
        palPtr->palPalEntry[i].peRed = __sysPalTemplate[i].peRed;
        palPtr->palPalEntry[i].peGreen = __sysPalTemplate[i].peGreen;
        palPtr->palPalEntry[i].peBlue = __sysPalTemplate[i].peBlue;
        palPtr->palPalEntry[i].peFlags = 0;
    }
    hpalette = CreatePalette16( palPtr );
83
    HeapFree( GetProcessHeap(), 0, palPtr );
Alexandre Julliard's avatar
Alexandre Julliard committed
84 85

    palObj = (PALETTEOBJ*) GDI_GetObjPtr( hpalette, PALETTE_MAGIC );
86 87
    if (palObj)
    {
88
        if (!(palObj->mapping = HeapAlloc( GetProcessHeap(), 0, sizeof(int) * 20 )))
89
            ERR("Can not create palette mapping -- out of memory!\n");
90
        GDI_ReleaseObj( hpalette );
91
    }
Alexandre Julliard's avatar
Alexandre Julliard committed
92 93 94
    return hpalette;
}

Alexandre Julliard's avatar
Alexandre Julliard committed
95 96 97 98 99 100 101 102 103 104 105
/***********************************************************************
 *           PALETTE_ValidateFlags
 */
void PALETTE_ValidateFlags(PALETTEENTRY* lpPalE, int size)
{
    int i = 0;
    for( ; i<size ; i++ )
        lpPalE[i].peFlags = PC_SYS_USED | (lpPalE[i].peFlags & 0x07);
}


Alexandre Julliard's avatar
Alexandre Julliard committed
106
/***********************************************************************
107
 *           CreatePalette    (GDI.360)
Alexandre Julliard's avatar
Alexandre Julliard committed
108
 */
Alexandre Julliard's avatar
Alexandre Julliard committed
109
HPALETTE16 WINAPI CreatePalette16( const LOGPALETTE* palette )
Alexandre Julliard's avatar
Alexandre Julliard committed
110
{
111
    return CreatePalette( palette );
Alexandre Julliard's avatar
Alexandre Julliard committed
112 113 114 115
}


/***********************************************************************
116
 * CreatePalette [GDI32.@]  Creates a logical color palette
Alexandre Julliard's avatar
Alexandre Julliard committed
117 118 119 120
 *
 * RETURNS
 *    Success: Handle to logical palette
 *    Failure: NULL
Alexandre Julliard's avatar
Alexandre Julliard committed
121
 */
122
HPALETTE WINAPI CreatePalette(
Alexandre Julliard's avatar
Alexandre Julliard committed
123
    const LOGPALETTE* palette) /* [in] Pointer to logical color palette */
Alexandre Julliard's avatar
Alexandre Julliard committed
124 125
{
    PALETTEOBJ * palettePtr;
126
    HPALETTE hpalette;
127 128 129
    int size;
    
    if (!palette) return 0;
130
    TRACE("entries=%i\n", palette->palNumEntries);
Alexandre Julliard's avatar
Alexandre Julliard committed
131

132 133
    size = sizeof(LOGPALETTE) + (palette->palNumEntries - 1) * sizeof(PALETTEENTRY);

134 135
    if (!(palettePtr = GDI_AllocObject( size + sizeof(int*) +sizeof(GDIOBJHDR),
                                        PALETTE_MAGIC, &hpalette ))) return 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
136
    memcpy( &palettePtr->logpalette, palette, size );
Alexandre Julliard's avatar
Alexandre Julliard committed
137 138 139
    PALETTE_ValidateFlags(palettePtr->logpalette.palPalEntry, 
			  palettePtr->logpalette.palNumEntries);
    palettePtr->mapping = NULL;
140
    GDI_ReleaseObj( hpalette );
Alexandre Julliard's avatar
Alexandre Julliard committed
141

142
    TRACE("   returning %04x\n", hpalette);
Alexandre Julliard's avatar
Alexandre Julliard committed
143 144 145
    return hpalette;
}

Alexandre Julliard's avatar
Alexandre Julliard committed
146

Alexandre Julliard's avatar
Alexandre Julliard committed
147
/***********************************************************************
148
 * CreateHalftonePalette [GDI.529]  Creates a halftone palette
Alexandre Julliard's avatar
Alexandre Julliard committed
149 150 151 152
 *
 * RETURNS
 *    Success: Handle to logical halftone palette
 *    Failure: 0
Alexandre Julliard's avatar
Alexandre Julliard committed
153
 */
Brad Pepers's avatar
Brad Pepers committed
154 155 156
HPALETTE16 WINAPI CreateHalftonePalette16(
    HDC16 hdc) /* [in] Handle to device context */
{
157
    return CreateHalftonePalette(hdc);
158
}
Brad Pepers's avatar
Brad Pepers committed
159

160
	
Brad Pepers's avatar
Brad Pepers committed
161
/***********************************************************************
162
 * CreateHalftonePalette [GDI32.@]  Creates a halftone palette
Brad Pepers's avatar
Brad Pepers committed
163 164 165 166 167
 *
 * RETURNS
 *    Success: Handle to logical halftone palette
 *    Failure: 0
 *
168 169 170 171
 * FIXME: This simply creates the halftone palette dirived from runing
 *        tests on an windows NT machine. this is assuming a color depth
 *        of greater that 256 color. On a 256 color device the halftone
 *        palette will be differnt and this funtion will be incorrect
Brad Pepers's avatar
Brad Pepers committed
172
 */
173 174
HPALETTE WINAPI CreateHalftonePalette(
    HDC hdc) /* [in] Handle to device context */
Brad Pepers's avatar
Brad Pepers committed
175
{
176
    int i;
Brad Pepers's avatar
Brad Pepers committed
177 178 179 180
    struct {
	WORD Version;
	WORD NumberOfEntries;
	PALETTEENTRY aEntries[256];
181
    } Palette;
Brad Pepers's avatar
Brad Pepers committed
182

183 184
    Palette.Version = 0x300;
    Palette.NumberOfEntries = 256;
185
    GetSystemPaletteEntries(hdc, 0, 256, Palette.aEntries);
Brad Pepers's avatar
Brad Pepers committed
186

187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251
    Palette.NumberOfEntries = 20;

    for (i = 0; i < Palette.NumberOfEntries; i++)
    {
        Palette.aEntries[i].peRed=0xff;
        Palette.aEntries[i].peGreen=0xff;
        Palette.aEntries[i].peBlue=0xff;
        Palette.aEntries[i].peFlags=0x00;
    }

    Palette.aEntries[0].peRed=0x00;
    Palette.aEntries[0].peBlue=0x00;
    Palette.aEntries[0].peGreen=0x00;

    /* the first 6 */
    for (i=1; i <= 6; i++)
    {
        Palette.aEntries[i].peRed=(i%2)?0x80:0;
        Palette.aEntries[i].peGreen=(i==2)?0x80:(i==3)?0x80:(i==6)?0x80:0;
        Palette.aEntries[i].peBlue=(i>3)?0x80:0;
    }
    
    for (i=7;  i <= 12; i++)
    {
        switch(i)
        {
            case 7:
                Palette.aEntries[i].peRed=0xc0;
                Palette.aEntries[i].peBlue=0xc0;
                Palette.aEntries[i].peGreen=0xc0;
                break;
            case 8:
                Palette.aEntries[i].peRed=0xc0;
                Palette.aEntries[i].peGreen=0xdc;
                Palette.aEntries[i].peBlue=0xc0;
                break;
            case 9:
                Palette.aEntries[i].peRed=0xa6;
                Palette.aEntries[i].peGreen=0xca;
                Palette.aEntries[i].peBlue=0xf0;
                break;
            case 10:    
                Palette.aEntries[i].peRed=0xff;
                Palette.aEntries[i].peGreen=0xfb;
                Palette.aEntries[i].peBlue=0xf0;
                break;
            case 11:
                Palette.aEntries[i].peRed=0xa0;
                Palette.aEntries[i].peGreen=0xa0;
                Palette.aEntries[i].peBlue=0xa4;
                break;
            case 12:
                Palette.aEntries[i].peRed=0x80;
                Palette.aEntries[i].peGreen=0x80;
                Palette.aEntries[i].peBlue=0x80;
        }
    }

   for (i=13; i <= 18; i++)
    {
        Palette.aEntries[i].peRed=(i%2)?0xff:0;
        Palette.aEntries[i].peGreen=(i==14)?0xff:(i==15)?0xff:(i==18)?0xff:0;
        Palette.aEntries[i].peBlue=(i>15)?0xff:0x00;
    }

252
    return CreatePalette((LOGPALETTE *)&Palette);
Alexandre Julliard's avatar
Alexandre Julliard committed
253
}
Alexandre Julliard's avatar
Alexandre Julliard committed
254

Alexandre Julliard's avatar
Alexandre Julliard committed
255

Alexandre Julliard's avatar
Alexandre Julliard committed
256
/***********************************************************************
257
 *           GetPaletteEntries    (GDI.363)
Alexandre Julliard's avatar
Alexandre Julliard committed
258
 */
Alexandre Julliard's avatar
Alexandre Julliard committed
259 260
UINT16 WINAPI GetPaletteEntries16( HPALETTE16 hpalette, UINT16 start,
                                   UINT16 count, LPPALETTEENTRY entries )
Alexandre Julliard's avatar
Alexandre Julliard committed
261
{
262
    return GetPaletteEntries( hpalette, start, count, entries );
Alexandre Julliard's avatar
Alexandre Julliard committed
263 264 265 266
}


/***********************************************************************
267
 * GetPaletteEntries [GDI32.@]  Retrieves palette entries
Alexandre Julliard's avatar
Alexandre Julliard committed
268 269 270 271
 *
 * RETURNS
 *    Success: Number of entries from logical palette
 *    Failure: 0
Alexandre Julliard's avatar
Alexandre Julliard committed
272
 */
273 274 275 276
UINT WINAPI GetPaletteEntries(
    HPALETTE hpalette,    /* [in]  Handle of logical palette */
    UINT start,           /* [in]  First entry to receive */
    UINT count,           /* [in]  Number of entries to receive */
Alexandre Julliard's avatar
Alexandre Julliard committed
277
    LPPALETTEENTRY entries) /* [out] Address of array receiving entries */
Alexandre Julliard's avatar
Alexandre Julliard committed
278 279
{
    PALETTEOBJ * palPtr;
280
    UINT numEntries;
Alexandre Julliard's avatar
Alexandre Julliard committed
281

282
    TRACE("hpal = %04x, count=%i\n", hpalette, count );
Alexandre Julliard's avatar
Alexandre Julliard committed
283 284 285
        
    palPtr = (PALETTEOBJ *) GDI_GetObjPtr( hpalette, PALETTE_MAGIC );
    if (!palPtr) return 0;
286 287 288 289 290 291 292 293
    
    /* NOTE: not documented but test show this to be the case */
    if (count == 0)
    {   
        int rc = palPtr->logpalette.palNumEntries;
	    GDI_ReleaseObj( hpalette );
        return rc;
    }
Alexandre Julliard's avatar
Alexandre Julliard committed
294

Alexandre Julliard's avatar
Alexandre Julliard committed
295
    numEntries = palPtr->logpalette.palNumEntries;
Alexandre Julliard's avatar
Alexandre Julliard committed
296 297 298 299 300
    if (start+count > numEntries) count = numEntries - start;
    if (entries)
    { 
      if (start >= numEntries) 
      {
301
	GDI_ReleaseObj( hpalette );
Alexandre Julliard's avatar
Alexandre Julliard committed
302 303 304 305 306 307 308
	return 0;
      }
      memcpy( entries, &palPtr->logpalette.palPalEntry[start],
	      count * sizeof(PALETTEENTRY) );
      for( numEntries = 0; numEntries < count ; numEntries++ )
	   if (entries[numEntries].peFlags & 0xF0)
	       entries[numEntries].peFlags = 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
309
    }
Alexandre Julliard's avatar
Alexandre Julliard committed
310

311
    GDI_ReleaseObj( hpalette );
Alexandre Julliard's avatar
Alexandre Julliard committed
312 313 314 315 316
    return count;
}


/***********************************************************************
317
 *           SetPaletteEntries    (GDI.364)
Alexandre Julliard's avatar
Alexandre Julliard committed
318
 */
Alexandre Julliard's avatar
Alexandre Julliard committed
319 320
UINT16 WINAPI SetPaletteEntries16( HPALETTE16 hpalette, UINT16 start,
                                   UINT16 count, LPPALETTEENTRY entries )
Alexandre Julliard's avatar
Alexandre Julliard committed
321
{
322
    return SetPaletteEntries( hpalette, start, count, entries );
Alexandre Julliard's avatar
Alexandre Julliard committed
323 324 325 326
}


/***********************************************************************
327
 * SetPaletteEntries [GDI32.@]  Sets color values for range in palette
Alexandre Julliard's avatar
Alexandre Julliard committed
328 329 330 331
 *
 * RETURNS
 *    Success: Number of entries that were set
 *    Failure: 0
Alexandre Julliard's avatar
Alexandre Julliard committed
332
 */
333 334 335 336
UINT WINAPI SetPaletteEntries(
    HPALETTE hpalette,    /* [in] Handle of logical palette */
    UINT start,           /* [in] Index of first entry to set */
    UINT count,           /* [in] Number of entries to set */
Alexandre Julliard's avatar
Alexandre Julliard committed
337
    LPPALETTEENTRY entries) /* [in] Address of array of structures */
Alexandre Julliard's avatar
Alexandre Julliard committed
338 339
{
    PALETTEOBJ * palPtr;
340
    UINT numEntries;
Alexandre Julliard's avatar
Alexandre Julliard committed
341

342
    TRACE("hpal=%04x,start=%i,count=%i\n",hpalette,start,count );
Alexandre Julliard's avatar
Alexandre Julliard committed
343

Alexandre Julliard's avatar
Alexandre Julliard committed
344 345
    palPtr = (PALETTEOBJ *) GDI_GetObjPtr( hpalette, PALETTE_MAGIC );
    if (!palPtr) return 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
346

Alexandre Julliard's avatar
Alexandre Julliard committed
347
    numEntries = palPtr->logpalette.palNumEntries;
Alexandre Julliard's avatar
Alexandre Julliard committed
348 349
    if (start >= numEntries) 
    {
350
      GDI_ReleaseObj( hpalette );
Alexandre Julliard's avatar
Alexandre Julliard committed
351 352
      return 0;
    }
Alexandre Julliard's avatar
Alexandre Julliard committed
353 354 355
    if (start+count > numEntries) count = numEntries - start;
    memcpy( &palPtr->logpalette.palPalEntry[start], entries,
	    count * sizeof(PALETTEENTRY) );
Alexandre Julliard's avatar
Alexandre Julliard committed
356 357
    PALETTE_ValidateFlags(palPtr->logpalette.palPalEntry, 
			  palPtr->logpalette.palNumEntries);
358
    HeapFree( GetProcessHeap(), 0, palPtr->mapping );
Alexandre Julliard's avatar
Alexandre Julliard committed
359
    palPtr->mapping = NULL;
360
    GDI_ReleaseObj( hpalette );
Alexandre Julliard's avatar
Alexandre Julliard committed
361 362 363
    return count;
}

Alexandre Julliard's avatar
Alexandre Julliard committed
364 365

/***********************************************************************
366
 *           ResizePalette   (GDI.368)
Alexandre Julliard's avatar
Alexandre Julliard committed
367
 */
Alexandre Julliard's avatar
Alexandre Julliard committed
368
BOOL16 WINAPI ResizePalette16( HPALETTE16 hPal, UINT16 cEntries )
Alexandre Julliard's avatar
Alexandre Julliard committed
369
{
370
    return ResizePalette( hPal, cEntries );
Alexandre Julliard's avatar
Alexandre Julliard committed
371 372 373
}


Alexandre Julliard's avatar
Alexandre Julliard committed
374
/***********************************************************************
375
 * ResizePalette [GDI32.@]  Resizes logical palette
Alexandre Julliard's avatar
Alexandre Julliard committed
376 377 378 379
 *
 * RETURNS
 *    Success: TRUE
 *    Failure: FALSE
Alexandre Julliard's avatar
Alexandre Julliard committed
380
 */
381 382 383
BOOL WINAPI ResizePalette(
    HPALETTE hPal, /* [in] Handle of logical palette */
    UINT cEntries) /* [in] Number of entries in logical palette */
Alexandre Julliard's avatar
Alexandre Julliard committed
384
{
Alexandre Julliard's avatar
Alexandre Julliard committed
385
    PALETTEOBJ * palPtr = (PALETTEOBJ *) GDI_GetObjPtr( hPal, PALETTE_MAGIC );
386
    UINT	 cPrevEnt, prevVer;
Alexandre Julliard's avatar
Alexandre Julliard committed
387 388 389
    int		 prevsize, size = sizeof(LOGPALETTE) + (cEntries - 1) * sizeof(PALETTEENTRY);
    int*	 mapping = NULL;

390
    TRACE("hpal = %04x, prev = %i, new = %i\n",
Alexandre Julliard's avatar
Alexandre Julliard committed
391 392
		    hPal, palPtr ? palPtr->logpalette.palNumEntries : -1,
                    cEntries );
Alexandre Julliard's avatar
Alexandre Julliard committed
393 394 395 396 397 398 399
    if( !palPtr ) return FALSE;
    cPrevEnt = palPtr->logpalette.palNumEntries;
    prevVer = palPtr->logpalette.palVersion;
    prevsize = sizeof(LOGPALETTE) + (cPrevEnt - 1) * sizeof(PALETTEENTRY) +
	      				sizeof(int*) + sizeof(GDIOBJHDR);
    size += sizeof(int*) + sizeof(GDIOBJHDR);
    mapping = palPtr->mapping;
Alexandre Julliard's avatar
Alexandre Julliard committed
400
    
401
    if (!(palPtr = GDI_ReallocObject( size, hPal, palPtr ))) return FALSE;
Alexandre Julliard's avatar
Alexandre Julliard committed
402

403 404 405 406 407 408
    if( mapping ) 
    {
        int *newMap = (int*) HeapReAlloc(GetProcessHeap(), 0, 
                                    mapping, cEntries * sizeof(int) );
	if(newMap == NULL) 
        {
409
            ERR("Can not resize mapping -- out of memory!\n");
410
            GDI_ReleaseObj( hPal );
411 412 413 414 415
            return FALSE;
        }
        palPtr->mapping = newMap;
    }

Alexandre Julliard's avatar
Alexandre Julliard committed
416 417 418 419 420 421 422 423 424 425
    if( cEntries > cPrevEnt ) 
    {
	if( mapping )
	    memset(palPtr->mapping + cPrevEnt, 0, (cEntries - cPrevEnt)*sizeof(int));
	memset( (BYTE*)palPtr + prevsize, 0, size - prevsize );
        PALETTE_ValidateFlags((PALETTEENTRY*)((BYTE*)palPtr + prevsize), 
						     cEntries - cPrevEnt );
    }
    palPtr->logpalette.palNumEntries = cEntries;
    palPtr->logpalette.palVersion = prevVer;
426
    GDI_ReleaseObj( hPal );
Alexandre Julliard's avatar
Alexandre Julliard committed
427
    return TRUE;
Alexandre Julliard's avatar
Alexandre Julliard committed
428 429
}

Alexandre Julliard's avatar
Alexandre Julliard committed
430 431

/***********************************************************************
432
 *           AnimatePalette   (GDI.367)
Alexandre Julliard's avatar
Alexandre Julliard committed
433
 */
Alexandre Julliard's avatar
Alexandre Julliard committed
434
void WINAPI AnimatePalette16( HPALETTE16 hPal, UINT16 StartIndex,
435
                              UINT16 NumEntries, const PALETTEENTRY* PaletteColors)
Alexandre Julliard's avatar
Alexandre Julliard committed
436
{
437
    AnimatePalette( hPal, StartIndex, NumEntries, PaletteColors );
Alexandre Julliard's avatar
Alexandre Julliard committed
438 439 440
}


Alexandre Julliard's avatar
Alexandre Julliard committed
441
/***********************************************************************
442
 * AnimatePalette [GDI32.@]  Replaces entries in logical palette
Alexandre Julliard's avatar
Alexandre Julliard committed
443 444 445 446
 *
 * RETURNS
 *    Success: TRUE
 *    Failure: FALSE
Alexandre Julliard's avatar
Alexandre Julliard committed
447
 *
Alexandre Julliard's avatar
Alexandre Julliard committed
448 449
 * FIXME
 *    Should use existing mapping when animating a primary palette
Alexandre Julliard's avatar
Alexandre Julliard committed
450
 */
451 452 453 454
BOOL WINAPI AnimatePalette(
    HPALETTE hPal,              /* [in] Handle to logical palette */
    UINT StartIndex,            /* [in] First entry in palette */
    UINT NumEntries,            /* [in] Count of entries in palette */
455
    const PALETTEENTRY* PaletteColors) /* [in] Pointer to first replacement */
Alexandre Julliard's avatar
Alexandre Julliard committed
456
{
457
    TRACE("%04x (%i - %i)\n", hPal, StartIndex,StartIndex+NumEntries);
Alexandre Julliard's avatar
Alexandre Julliard committed
458

459
    if( hPal != GetStockObject(DEFAULT_PALETTE) )
Alexandre Julliard's avatar
Alexandre Julliard committed
460 461
    {
        PALETTEOBJ* palPtr = (PALETTEOBJ *)GDI_GetObjPtr(hPal, PALETTE_MAGIC);
462
        if (!palPtr) return FALSE;
Alexandre Julliard's avatar
Alexandre Julliard committed
463

Alexandre Julliard's avatar
Alexandre Julliard committed
464
	if( (StartIndex + NumEntries) <= palPtr->logpalette.palNumEntries )
Alexandre Julliard's avatar
Alexandre Julliard committed
465
	{
466
	    UINT u;
Alexandre Julliard's avatar
Alexandre Julliard committed
467 468
	    for( u = 0; u < NumEntries; u++ )
		palPtr->logpalette.palPalEntry[u + StartIndex] = PaletteColors[u];
469 470
            if (PALETTE_Driver) PALETTE_Driver->pSetMapping(palPtr, StartIndex, NumEntries,
                                                            hPal != hPrimaryPalette );
471
            GDI_ReleaseObj( hPal );
Alexandre Julliard's avatar
Alexandre Julliard committed
472 473
	    return TRUE;
	}
474
	GDI_ReleaseObj( hPal );
Alexandre Julliard's avatar
Alexandre Julliard committed
475 476
    }
    return FALSE;
Alexandre Julliard's avatar
Alexandre Julliard committed
477
}
Alexandre Julliard's avatar
Alexandre Julliard committed
478

Alexandre Julliard's avatar
Alexandre Julliard committed
479 480

/***********************************************************************
481
 *           SetSystemPaletteUse   (GDI.373)
Alexandre Julliard's avatar
Alexandre Julliard committed
482
 */
Alexandre Julliard's avatar
Alexandre Julliard committed
483
UINT16 WINAPI SetSystemPaletteUse16( HDC16 hdc, UINT16 use )
Alexandre Julliard's avatar
Alexandre Julliard committed
484
{
485
    return SetSystemPaletteUse( hdc, use );
Alexandre Julliard's avatar
Alexandre Julliard committed
486 487 488 489
}


/***********************************************************************
490
 * SetSystemPaletteUse [GDI32.@]
Alexandre Julliard's avatar
Alexandre Julliard committed
491 492 493 494
 *
 * RETURNS
 *    Success: Previous system palette
 *    Failure: SYSPAL_ERROR
Alexandre Julliard's avatar
Alexandre Julliard committed
495
 */
496 497 498
UINT WINAPI SetSystemPaletteUse(
    HDC hdc,  /* [in] Handle of device context */
    UINT use) /* [in] Palette-usage flag */
Alexandre Julliard's avatar
Alexandre Julliard committed
499
{
500
    UINT old = SystemPaletteUse;
501
    FIXME("(%04x,%04x): stub\n", hdc, use );
Alexandre Julliard's avatar
Alexandre Julliard committed
502 503 504 505 506 507
    SystemPaletteUse = use;
    return old;
}


/***********************************************************************
508
 *           GetSystemPaletteUse   (GDI.374)
Alexandre Julliard's avatar
Alexandre Julliard committed
509
 */
Alexandre Julliard's avatar
Alexandre Julliard committed
510
UINT16 WINAPI GetSystemPaletteUse16( HDC16 hdc )
Alexandre Julliard's avatar
Alexandre Julliard committed
511 512 513 514 515
{
    return SystemPaletteUse;
}


Alexandre Julliard's avatar
Alexandre Julliard committed
516
/***********************************************************************
517
 * GetSystemPaletteUse [GDI32.@]  Gets state of system palette
Alexandre Julliard's avatar
Alexandre Julliard committed
518 519 520
 *
 * RETURNS
 *    Current state of system palette
Alexandre Julliard's avatar
Alexandre Julliard committed
521
 */
522 523
UINT WINAPI GetSystemPaletteUse(
    HDC hdc) /* [in] Handle of device context */
Alexandre Julliard's avatar
Alexandre Julliard committed
524
{
Alexandre Julliard's avatar
Alexandre Julliard committed
525
    return SystemPaletteUse;
Alexandre Julliard's avatar
Alexandre Julliard committed
526 527
}

Alexandre Julliard's avatar
Alexandre Julliard committed
528

Alexandre Julliard's avatar
Alexandre Julliard committed
529
/***********************************************************************
530
 *           GetSystemPaletteEntries   (GDI.375)
Alexandre Julliard's avatar
Alexandre Julliard committed
531
 */
Alexandre Julliard's avatar
Alexandre Julliard committed
532 533
UINT16 WINAPI GetSystemPaletteEntries16( HDC16 hdc, UINT16 start, UINT16 count,
                                         LPPALETTEENTRY entries )
Alexandre Julliard's avatar
Alexandre Julliard committed
534
{
535
    return GetSystemPaletteEntries( hdc, start, count, entries );
Alexandre Julliard's avatar
Alexandre Julliard committed
536 537 538
}


Alexandre Julliard's avatar
Alexandre Julliard committed
539
/***********************************************************************
540
 * GetSystemPaletteEntries [GDI32.@]  Gets range of palette entries
Alexandre Julliard's avatar
Alexandre Julliard committed
541 542 543 544
 *
 * RETURNS
 *    Success: Number of entries retrieved from palette
 *    Failure: 0
Alexandre Julliard's avatar
Alexandre Julliard committed
545
 */
546 547 548 549
UINT WINAPI GetSystemPaletteEntries(
    HDC hdc,              /* [in]  Handle of device context */
    UINT start,           /* [in]  Index of first entry to be retrieved */
    UINT count,           /* [in]  Number of entries to be retrieved */
Alexandre Julliard's avatar
Alexandre Julliard committed
550
    LPPALETTEENTRY entries) /* [out] Array receiving system-palette entries */
Alexandre Julliard's avatar
Alexandre Julliard committed
551
{
552
    UINT i;
553
    INT sizePalette = GetDeviceCaps( hdc, SIZEPALETTE );
Alexandre Julliard's avatar
Alexandre Julliard committed
554

555
    TRACE("hdc=%04x,start=%i,count=%i\n", hdc,start,count);
Alexandre Julliard's avatar
Alexandre Julliard committed
556

557 558 559
    if (!entries) return sizePalette;
    if (start >= sizePalette) return 0;
    if (start+count >= sizePalette) count = sizePalette - start;
560

Alexandre Julliard's avatar
Alexandre Julliard committed
561 562
    for (i = 0; i < count; i++)
    {
Alexandre Julliard's avatar
Alexandre Julliard committed
563
	*(COLORREF*)(entries + i) = COLOR_GetSystemPaletteEntry( start + i );
Alexandre Julliard's avatar
Alexandre Julliard committed
564

565
        TRACE("\tidx(%02x) -> RGB(%08lx)\n",
Alexandre Julliard's avatar
Alexandre Julliard committed
566
                         start + i, *(COLORREF*)(entries + i) );
Alexandre Julliard's avatar
Alexandre Julliard committed
567 568 569 570 571
    }
    return count;
}


Alexandre Julliard's avatar
Alexandre Julliard committed
572
/***********************************************************************
573
 *           GetNearestPaletteIndex   (GDI.370)
Alexandre Julliard's avatar
Alexandre Julliard committed
574
 */
Alexandre Julliard's avatar
Alexandre Julliard committed
575
UINT16 WINAPI GetNearestPaletteIndex16( HPALETTE16 hpalette, COLORREF color )
Alexandre Julliard's avatar
Alexandre Julliard committed
576
{
577
    return GetNearestPaletteIndex( hpalette, color );
Alexandre Julliard's avatar
Alexandre Julliard committed
578 579 580 581
}


/***********************************************************************
582
 * GetNearestPaletteIndex [GDI32.@]  Gets palette index for color
Alexandre Julliard's avatar
Alexandre Julliard committed
583 584 585 586 587 588 589
 *
 * NOTES
 *    Should index be initialized to CLR_INVALID instead of 0?
 *
 * RETURNS
 *    Success: Index of entry in logical palette
 *    Failure: CLR_INVALID
Alexandre Julliard's avatar
Alexandre Julliard committed
590
 */
591 592
UINT WINAPI GetNearestPaletteIndex(
    HPALETTE hpalette, /* [in] Handle of logical color palette */
Alexandre Julliard's avatar
Alexandre Julliard committed
593
    COLORREF color)      /* [in] Color to be matched */
Alexandre Julliard's avatar
Alexandre Julliard committed
594
{
Alexandre Julliard's avatar
Alexandre Julliard committed
595
    PALETTEOBJ*	palObj = (PALETTEOBJ*)GDI_GetObjPtr( hpalette, PALETTE_MAGIC );
596
    UINT index  = 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
597 598

    if( palObj )
599
    {
600 601 602
      index = COLOR_PaletteLookupPixel(palObj->logpalette.palPalEntry, 
				       palObj->logpalette.palNumEntries,
				       NULL, color, FALSE );
Alexandre Julliard's avatar
Alexandre Julliard committed
603

604 605
      GDI_ReleaseObj( hpalette );
    }
606
    TRACE("(%04x,%06lx): returning %d\n", hpalette, color, index );
Alexandre Julliard's avatar
Alexandre Julliard committed
607 608 609 610
    return index;
}


Alexandre Julliard's avatar
Alexandre Julliard committed
611
/***********************************************************************
612
 *           GetNearestColor   (GDI.154)
Alexandre Julliard's avatar
Alexandre Julliard committed
613
 */
Alexandre Julliard's avatar
Alexandre Julliard committed
614
COLORREF WINAPI GetNearestColor16( HDC16 hdc, COLORREF color )
Alexandre Julliard's avatar
Alexandre Julliard committed
615
{
616
    return GetNearestColor( hdc, color );
Alexandre Julliard's avatar
Alexandre Julliard committed
617 618 619 620
}


/***********************************************************************
621
 * GetNearestColor [GDI32.@]  Gets a system color to match
Alexandre Julliard's avatar
Alexandre Julliard committed
622 623 624 625
 *
 * RETURNS
 *    Success: Color from system palette that corresponds to given color
 *    Failure: CLR_INVALID
Alexandre Julliard's avatar
Alexandre Julliard committed
626
 */
627 628
COLORREF WINAPI GetNearestColor(
    HDC hdc,      /* [in] Handle of device context */
Alexandre Julliard's avatar
Alexandre Julliard committed
629
    COLORREF color) /* [in] Color to be matched */
Alexandre Julliard's avatar
Alexandre Julliard committed
630
{
631
    COLORREF 	 nearest = CLR_INVALID;
Alexandre Julliard's avatar
Alexandre Julliard committed
632 633 634
    DC 		*dc;
    PALETTEOBJ  *palObj;

635 636 637
    if(!(GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE)) {
        return color;
    }
638
    if ( (dc = DC_GetDCPtr( hdc )) )
Alexandre Julliard's avatar
Alexandre Julliard committed
639
    {
640
        HPALETTE hpal = (dc->hPalette)? dc->hPalette : GetStockObject( DEFAULT_PALETTE );
641 642 643 644 645 646 647 648 649 650
        palObj = GDI_GetObjPtr( hpal, PALETTE_MAGIC );
        if (!palObj) {
            GDI_ReleaseObj( hdc );
            return nearest;
        }

        nearest = COLOR_LookupNearestColor( palObj->logpalette.palPalEntry,
                                            palObj->logpalette.palNumEntries, color );
        GDI_ReleaseObj( hpal );
        GDI_ReleaseObj( hdc );
Alexandre Julliard's avatar
Alexandre Julliard committed
651
    }
Alexandre Julliard's avatar
Alexandre Julliard committed
652

653
    TRACE("(%06lx): returning %06lx\n", color, nearest );
Alexandre Julliard's avatar
Alexandre Julliard committed
654 655 656 657
    return nearest;
}


Alexandre Julliard's avatar
Alexandre Julliard committed
658 659 660 661 662 663 664 665 666
/***********************************************************************
 *           PALETTE_GetObject
 */
int PALETTE_GetObject( PALETTEOBJ * palette, int count, LPSTR buffer )
{
    if (count > sizeof(WORD)) count = sizeof(WORD);
    memcpy( buffer, &palette->logpalette.palNumEntries, count );
    return count;
}
Alexandre Julliard's avatar
Alexandre Julliard committed
667 668


Alexandre Julliard's avatar
Alexandre Julliard committed
669 670 671
/***********************************************************************
 *           PALETTE_UnrealizeObject
 */
672
BOOL PALETTE_UnrealizeObject( HPALETTE16 hpalette, PALETTEOBJ *palette )
Alexandre Julliard's avatar
Alexandre Julliard committed
673 674 675
{
    if (palette->mapping)
    {
676
        HeapFree( GetProcessHeap(), 0, palette->mapping );
Alexandre Julliard's avatar
Alexandre Julliard committed
677 678 679 680 681 682 683 684 685 686
        palette->mapping = NULL;
    }
    if (hLastRealizedPalette == hpalette) hLastRealizedPalette = 0;
    return TRUE;
}


/***********************************************************************
 *           PALETTE_DeleteObject
 */
687
BOOL PALETTE_DeleteObject( HPALETTE16 hpalette, PALETTEOBJ *palette )
Alexandre Julliard's avatar
Alexandre Julliard committed
688
{
689
    HeapFree( GetProcessHeap(), 0, palette->mapping );
Alexandre Julliard's avatar
Alexandre Julliard committed
690
    if (hLastRealizedPalette == hpalette) hLastRealizedPalette = 0;
691
    return GDI_FreeObject( hpalette, palette );
Alexandre Julliard's avatar
Alexandre Julliard committed
692 693 694
}


Alexandre Julliard's avatar
Alexandre Julliard committed
695 696 697
/***********************************************************************
 *           GDISelectPalette    (GDI.361)
 */
698
HPALETTE16 WINAPI GDISelectPalette16( HDC16 hdc, HPALETTE16 hpal, WORD wBkg)
Alexandre Julliard's avatar
Alexandre Julliard committed
699
{
Alexandre Julliard's avatar
Alexandre Julliard committed
700
    HPALETTE16 prev;
Alexandre Julliard's avatar
Alexandre Julliard committed
701 702
    DC *dc;

703
    TRACE("%04x %04x\n", hdc, hpal );
704

705
    if (GetObjectType(hpal) != OBJ_PAL)
706 707 708 709
    {
      WARN("invalid selected palette %04x\n",hpal);
      return 0;
    }
710
    if (!(dc = DC_GetDCPtr( hdc ))) return 0;
711 712
    prev = dc->hPalette;
    dc->hPalette = hpal;
713
    GDI_ReleaseObj( hdc );
Alexandre Julliard's avatar
Alexandre Julliard committed
714
    if (!wBkg) hPrimaryPalette = hpal; 
Alexandre Julliard's avatar
Alexandre Julliard committed
715 716 717 718 719 720 721
    return prev;
}


/***********************************************************************
 *           GDIRealizePalette    (GDI.362)
 */
722
UINT16 WINAPI GDIRealizePalette16( HDC16 hdc )
Alexandre Julliard's avatar
Alexandre Julliard committed
723
{
Alexandre Julliard's avatar
Alexandre Julliard committed
724
    PALETTEOBJ* palPtr;
Alexandre Julliard's avatar
Alexandre Julliard committed
725
    int realized = 0;
726 727 728
    DC* dc = DC_GetDCPtr( hdc );

    if (!dc) return 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
729

730
    TRACE("%04x...\n", hdc );
Alexandre Julliard's avatar
Alexandre Julliard committed
731
    
732
    if(dc->hPalette != hLastRealizedPalette )
Alexandre Julliard's avatar
Alexandre Julliard committed
733
    {
734
	if( dc->hPalette == GetStockObject( DEFAULT_PALETTE )) {
735 736 737 738 739
            realized = RealizeDefaultPalette16( hdc );
	    GDI_ReleaseObj( hdc );
	    return (UINT16)realized;
	}

Alexandre Julliard's avatar
Alexandre Julliard committed
740

741
        palPtr = (PALETTEOBJ *) GDI_GetObjPtr( dc->hPalette, PALETTE_MAGIC );
Alexandre Julliard's avatar
Alexandre Julliard committed
742 743

	if (!palPtr) {
744
	    GDI_ReleaseObj( hdc );
745
            FIXME("invalid selected palette %04x\n",dc->hPalette);
746
            return 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
747
	}
748 749 750 751
        if (PALETTE_Driver)
            realized = PALETTE_Driver->pSetMapping(palPtr,0,palPtr->logpalette.palNumEntries,
                                        (dc->hPalette != hPrimaryPalette) ||
                                        (dc->hPalette == GetStockObject( DEFAULT_PALETTE )));
752 753
	hLastRealizedPalette = dc->hPalette;
	GDI_ReleaseObj( dc->hPalette );
Alexandre Julliard's avatar
Alexandre Julliard committed
754
    }
755
    else TRACE("  skipping (hLastRealizedPalette = %04x)\n",
Alexandre Julliard's avatar
Alexandre Julliard committed
756
			 hLastRealizedPalette);
757
    GDI_ReleaseObj( hdc );
Alexandre Julliard's avatar
Alexandre Julliard committed
758

759
    TRACE("   realized %i colors.\n", realized );
Alexandre Julliard's avatar
Alexandre Julliard committed
760
    return (UINT16)realized;
Alexandre Julliard's avatar
Alexandre Julliard committed
761 762 763
}


Alexandre Julliard's avatar
Alexandre Julliard committed
764
/***********************************************************************
Alexandre Julliard's avatar
Alexandre Julliard committed
765
 *           RealizeDefaultPalette    (GDI.365)
Alexandre Julliard's avatar
Alexandre Julliard committed
766
 */
767
UINT16 WINAPI RealizeDefaultPalette16( HDC16 hdc )
Alexandre Julliard's avatar
Alexandre Julliard committed
768
{
769
    UINT16 ret = 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
770 771
    DC          *dc;
    PALETTEOBJ*  palPtr;
Alexandre Julliard's avatar
Alexandre Julliard committed
772

773
    TRACE("%04x\n", hdc );
Alexandre Julliard's avatar
Alexandre Julliard committed
774

775 776
    if (!(dc = DC_GetDCPtr( hdc ))) return 0;

777
    if (!(dc->flags & DC_MEMORY))
Alexandre Julliard's avatar
Alexandre Julliard committed
778
    {
779
        palPtr = (PALETTEOBJ*)GDI_GetObjPtr( GetStockObject(DEFAULT_PALETTE), PALETTE_MAGIC );
780 781 782
        if (palPtr)
        {
            /* lookup is needed to account for SetSystemPaletteUse() stuff */
783
            if (PALETTE_Driver) ret = PALETTE_Driver->pUpdateMapping(palPtr);
784
            GDI_ReleaseObj( GetStockObject(DEFAULT_PALETTE) );
785
        }
Alexandre Julliard's avatar
Alexandre Julliard committed
786
    }
787 788
    GDI_ReleaseObj( hdc );
    return ret;
Alexandre Julliard's avatar
Alexandre Julliard committed
789
}
Alexandre Julliard's avatar
Alexandre Julliard committed
790

Alexandre Julliard's avatar
Alexandre Julliard committed
791
/***********************************************************************
Alexandre Julliard's avatar
Alexandre Julliard committed
792
 *           IsDCCurrentPalette   (GDI.412)
Alexandre Julliard's avatar
Alexandre Julliard committed
793
 */
794
BOOL16 WINAPI IsDCCurrentPalette16(HDC16 hDC)
Alexandre Julliard's avatar
Alexandre Julliard committed
795
{
796
    DC *dc = DC_GetDCPtr( hDC );
Alexandre Julliard's avatar
Alexandre Julliard committed
797 798
    if (dc) 
    {
799
      BOOL bRet = dc->hPalette == hPrimaryPalette;
800 801
      GDI_ReleaseObj( hDC );
      return bRet;
Alexandre Julliard's avatar
Alexandre Julliard committed
802 803
    }
    return FALSE;
Alexandre Julliard's avatar
Alexandre Julliard committed
804 805
}

Alexandre Julliard's avatar
Alexandre Julliard committed
806

Alexandre Julliard's avatar
Alexandre Julliard committed
807
/***********************************************************************
808
 * SelectPalette [GDI32.@]  Selects logical palette into DC
Alexandre Julliard's avatar
Alexandre Julliard committed
809 810 811 812
 *
 * RETURNS
 *    Success: Previous logical palette
 *    Failure: NULL
Alexandre Julliard's avatar
Alexandre Julliard committed
813
 */
814 815 816 817
HPALETTE WINAPI SelectPalette(
    HDC hDC,               /* [in] Handle of device context */
    HPALETTE hPal,         /* [in] Handle of logical color palette */
    BOOL bForceBackground) /* [in] Foreground/background mode */
Alexandre Julliard's avatar
Alexandre Julliard committed
818
{
819
    return pfnSelectPalette( hDC, hPal, bForceBackground );
Alexandre Julliard's avatar
Alexandre Julliard committed
820 821
}

Alexandre Julliard's avatar
Alexandre Julliard committed
822

Alexandre Julliard's avatar
Alexandre Julliard committed
823
/***********************************************************************
824
 * RealizePalette [GDI32.@]  Maps palette entries to system palette
Alexandre Julliard's avatar
Alexandre Julliard committed
825 826 827 828
 *
 * RETURNS
 *    Success: Number of entries in logical palette
 *    Failure: GDI_ERROR
Alexandre Julliard's avatar
Alexandre Julliard committed
829
 */
830 831
UINT WINAPI RealizePalette(
    HDC hDC) /* [in] Handle of device context */
Alexandre Julliard's avatar
Alexandre Julliard committed
832
{
833
    return pfnRealizePalette( hDC );
Alexandre Julliard's avatar
Alexandre Julliard committed
834 835
}

Alexandre Julliard's avatar
Alexandre Julliard committed
836

837 838
typedef HWND (WINAPI *WindowFromDC_funcptr)( HDC );
typedef BOOL (WINAPI *RedrawWindow_funcptr)( HWND, const RECT *, HRGN, UINT );
839

Alexandre Julliard's avatar
Alexandre Julliard committed
840
/**********************************************************************
841 842 843 844 845
 * UpdateColors [GDI32.@]  Remaps current colors to logical palette
 *
 * RETURNS
 *    Success: TRUE
 *    Failure: FALSE
Alexandre Julliard's avatar
Alexandre Julliard committed
846
 */
847 848
BOOL WINAPI UpdateColors(
    HDC hDC) /* [in] Handle of device context */
Alexandre Julliard's avatar
Alexandre Julliard committed
849
{
850
    HMODULE mod;
851
    int size = GetDeviceCaps( hDC, SIZEPALETTE );
852

853
    if (!size) return 0;
854

855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871
    mod = GetModuleHandleA("user32.dll");
    if (mod)
    {
        WindowFromDC_funcptr pWindowFromDC = (WindowFromDC_funcptr)GetProcAddress(mod,"WindowFromDC");
        if (pWindowFromDC)
        {
            HWND hWnd = pWindowFromDC( hDC );

            /* Docs say that we have to remap current drawable pixel by pixel
             * but it would take forever given the speed of XGet/PutPixel.
             */
            if (hWnd && size)
            {
                RedrawWindow_funcptr pRedrawWindow = GetProcAddress( mod, "RedrawWindow" );
                if (pRedrawWindow) pRedrawWindow( hWnd, NULL, 0, RDW_INVALIDATE );
            }
        }
872
    }
Alexandre Julliard's avatar
Alexandre Julliard committed
873 874
    return 0x666;
}
Alexandre Julliard's avatar
Alexandre Julliard committed
875

Alexandre Julliard's avatar
Alexandre Julliard committed
876 877

/**********************************************************************
Patrik Stridvall's avatar
Patrik Stridvall committed
878
 *            UpdateColors   (GDI.366)
Alexandre Julliard's avatar
Alexandre Julliard committed
879
 */
880
INT16 WINAPI UpdateColors16( HDC16 hDC )
Alexandre Julliard's avatar
Alexandre Julliard committed
881
{
882
    UpdateColors( hDC );
Alexandre Julliard's avatar
Alexandre Julliard committed
883 884
    return TRUE;
}
Alexandre Julliard's avatar
Alexandre Julliard committed
885

886 887

/*********************************************************************
888
 *           SetMagicColors   (GDI.606)
889 890 891
 */
VOID WINAPI SetMagicColors16(HDC16 hDC, COLORREF color, UINT16 index)
{
892
    FIXME("(hDC %04x, color %04x, index %04x): stub\n", hDC, (int)color, index);
893 894

}
895 896

/**********************************************************************
897
 * GetICMProfileA [GDI32.@]
898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917
 *
 * Returns the filename of the specified device context's color
 * management profile, even if color management is not enabled
 * for that DC.
 *
 * RETURNS
 *    TRUE if name copied succesfully OR lpszFilename is NULL
 *    FALSE if the buffer length pointed to by lpcbName is too small
 *
 * NOTE
 *    The buffer length pointed to by lpcbName is ALWAYS updated to
 *    the length required regardless of other actions this function
 *    may take.
 *
 * FIXME
 *    How does Windows assign these?  Some registry key?
 */

#define WINEICM "winefake.icm"  /* easy-to-identify fake filename */

918 919
/*********************************************************************/

920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942
BOOL WINAPI GetICMProfileA(HDC hDC, LPDWORD lpcbName, LPSTR lpszFilename)
{
    DWORD callerLen;

    FIXME("(%04x, %p, %p): partial stub\n", hDC, lpcbName, lpszFilename);

    callerLen = *lpcbName;

    /* all 3 behaviors require the required buffer size to be set */
    *lpcbName = strlen(WINEICM);

    /* behavior 1: if lpszFilename is NULL, return size of string and no error */
    if ((DWORD)lpszFilename == (DWORD)0x00000000)
 	return TRUE;
    
    /* behavior 2: if buffer size too small, return size of string and error */
    if (callerLen < strlen(WINEICM)) 
    {
	SetLastError(ERROR_INSUFFICIENT_BUFFER);
	return FALSE;
    }

    /* behavior 3: if buffer size OK and pointer not NULL, copy and return size */
943
    strcpy(lpszFilename, WINEICM);
944 945
    return TRUE;
}