diff --git a/dlls/gdi/mfdrv/init.c b/dlls/gdi/mfdrv/init.c index 6097127e22e..e20a16db2a3 100644 --- a/dlls/gdi/mfdrv/init.c +++ b/dlls/gdi/mfdrv/init.c @@ -97,7 +97,7 @@ static const DC_FUNCTIONS MFDRV_Funcs = MFDRV_Polyline, /* pPolyline */ NULL, /* pPolylineTo */ NULL, /* pRealizeDefaultPalette */ - NULL, /* pRealizePalette */ + MFDRV_RealizePalette, /* pRealizePalette */ MFDRV_Rectangle, /* pRectangle */ NULL, /* pResetDC */ MFDRV_RestoreDC, /* pRestoreDC */ @@ -109,7 +109,7 @@ static const DC_FUNCTIONS MFDRV_Funcs = MFDRV_SelectBrush, /* pSelectBrush */ MFDRV_SelectClipPath, /* pSelectClipPath */ MFDRV_SelectFont, /* pSelectFont */ - NULL, /* pSelectPalette */ + MFDRV_SelectPalette, /* pSelectPalette */ MFDRV_SelectPen, /* pSelectPen */ NULL, /* pSetBitmapBits */ MFDRV_SetBkColor, /* pSetBkColor */ diff --git a/dlls/gdi/mfdrv/metafiledrv.h b/dlls/gdi/mfdrv/metafiledrv.h index 696604fc482..53960891111 100644 --- a/dlls/gdi/mfdrv/metafiledrv.h +++ b/dlls/gdi/mfdrv/metafiledrv.h @@ -118,6 +118,8 @@ extern HBRUSH MFDRV_SelectBrush( PHYSDEV dev, HBRUSH handle ); extern BOOL MFDRV_SelectClipPath( PHYSDEV dev, INT iMode ); extern HFONT MFDRV_SelectFont( PHYSDEV dev, HFONT handle ); extern HPEN MFDRV_SelectPen( PHYSDEV dev, HPEN handle ); +extern HPALETTE MFDRV_SelectPalette( PHYSDEV dev, HPALETTE hPalette, BOOL bForceBackground); +extern UINT MFDRV_RealizePalette(PHYSDEV dev, HPALETTE hPalette, BOOL primary); extern COLORREF MFDRV_SetBkColor( PHYSDEV dev, COLORREF color ); extern INT MFDRV_SetBkMode( PHYSDEV dev, INT mode ); extern INT MFDRV_SetMapMode( PHYSDEV dev, INT mode ); diff --git a/dlls/gdi/mfdrv/objects.c b/dlls/gdi/mfdrv/objects.c index 8dc04332a36..89ce51cacb1 100644 --- a/dlls/gdi/mfdrv/objects.c +++ b/dlls/gdi/mfdrv/objects.c @@ -234,3 +234,94 @@ HPEN MFDRV_SelectPen( PHYSDEV dev, HPEN hpen ) if (MFDRV_CreatePenIndirect( dev, hpen, &logpen )) return hpen; return 0; } + + +/****************************************************************** + * MFDRV_CreatePalette + */ +static BOOL MFDRV_CreatePalette(PHYSDEV dev, HPALETTE hPalette, LOGPALETTE* logPalette, int sizeofPalette) +{ + int index; + BOOL ret; + METARECORD *mr; + + mr = HeapAlloc( GetProcessHeap(), 0, sizeof(METARECORD) + sizeofPalette - sizeof(WORD) ); + mr->rdSize = (sizeof(METARECORD) + sizeofPalette - sizeof(WORD)) / sizeof(WORD); + mr->rdFunction = META_CREATEPALETTE; + memcpy(&(mr->rdParm), logPalette, sizeofPalette); + if (!(MFDRV_WriteRecord( dev, mr, mr->rdSize * sizeof(WORD)))) + { + HeapFree(GetProcessHeap(), 0, mr); + return FALSE; + } + + mr->rdSize = sizeof(METARECORD) / sizeof(WORD); + mr->rdFunction = META_SELECTPALETTE; + + if ((index = MFDRV_AddHandleDC( dev )) == -1) ret = FALSE; + else + { + *(mr->rdParm) = index; + ret = MFDRV_WriteRecord( dev, mr, mr->rdSize * sizeof(WORD)); + } + HeapFree(GetProcessHeap(), 0, mr); + return ret; +} + + +/*********************************************************************** + * MFDRV_SelectPalette + */ +HPALETTE MFDRV_SelectPalette( PHYSDEV dev, HPALETTE hPalette, BOOL bForceBackground ) +{ +#define PALVERSION 0x0300 + + PLOGPALETTE logPalette; + WORD wNumEntries = 0; + BOOL creationSucceed; + int sizeofPalette; + + GetObjectA(hPalette, sizeof(WORD), (LPSTR) &wNumEntries); + + if (wNumEntries == 0) return 0; + + sizeofPalette = sizeof(LOGPALETTE) + ((wNumEntries-1) * sizeof(PALETTEENTRY)); + logPalette = HeapAlloc( GetProcessHeap(), 0, sizeofPalette ); + + if (logPalette == NULL) return 0; + + logPalette->palVersion = PALVERSION; + logPalette->palNumEntries = wNumEntries; + + GetPaletteEntries(hPalette, 0, wNumEntries, logPalette->palPalEntry); + + creationSucceed = MFDRV_CreatePalette( dev, hPalette, logPalette, sizeofPalette ); + + HeapFree( GetProcessHeap(), 0, logPalette ); + + if (creationSucceed) + return hPalette; + + return 0; +} + +/*********************************************************************** + * MFDRV_RealizePalette + */ +UINT MFDRV_RealizePalette(PHYSDEV dev, HPALETTE hPalette, BOOL dummy) +{ + char buffer[sizeof(METARECORD) - sizeof(WORD)]; + METARECORD *mr = (METARECORD *)&buffer; + + mr->rdSize = (sizeof(METARECORD) - sizeof(WORD)) / sizeof(WORD); + mr->rdFunction = META_REALIZEPALETTE; + + if (!(MFDRV_WriteRecord( dev, mr, mr->rdSize * sizeof(WORD)))) return 0; + + /* The return value is suppose to be the number of entries + in the logical palette mapped to the system palette or 0 + if the function failed. Since it's not trivial here to + get that kind of information and since it's of little + use in the case of metafiles, we'll always return 1. */ + return 1; +} diff --git a/objects/palette.c b/objects/palette.c index 54423af413f..66615b60dc4 100644 --- a/objects/palette.c +++ b/objects/palette.c @@ -677,7 +677,7 @@ static BOOL PALETTE_DeleteObject( HGDIOBJ handle, void *obj ) */ HPALETTE WINAPI GDISelectPalette( HDC hdc, HPALETTE hpal, WORD wBkg) { - HPALETTE prev; + HPALETTE ret; DC *dc; TRACE("%p %p\n", hdc, hpal ); @@ -688,11 +688,16 @@ HPALETTE WINAPI GDISelectPalette( HDC hdc, HPALETTE hpal, WORD wBkg) return 0; } if (!(dc = DC_GetDCPtr( hdc ))) return 0; - prev = dc->hPalette; - dc->hPalette = hpal; + ret = dc->hPalette; + if (dc->funcs->pSelectPalette) hpal = dc->funcs->pSelectPalette( dc->physDev, hpal, FALSE ); + if (hpal) + { + dc->hPalette = hpal; + if (!wBkg) hPrimaryPalette = hpal; + } + else ret = 0; GDI_ReleaseObj( hdc ); - if (!wBkg) hPrimaryPalette = hpal; - return prev; + return ret; }