diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h index 2bf8132d043..8cc5201d4c1 100644 --- a/dlls/ddraw/ddraw_private.h +++ b/dlls/ddraw/ddraw_private.h @@ -575,6 +575,13 @@ void DDSD2_to_DDSD(const DDSURFACEDESC2 *in, DDSURFACEDESC *out) DECLSPEC_HIDDEN void multiply_matrix(D3DMATRIX *dst, const D3DMATRIX *src1, const D3DMATRIX *src2) DECLSPEC_HIDDEN; +static inline BOOL format_is_paletteindexed(const DDPIXELFORMAT *fmt) +{ + DWORD flags = DDPF_PALETTEINDEXED1 | DDPF_PALETTEINDEXED2 | DDPF_PALETTEINDEXED4 + | DDPF_PALETTEINDEXED8 | DDPF_PALETTEINDEXEDTO8; + return !!(fmt->dwFlags & flags); +} + /* Used for generic dumping */ struct flag_info { diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c index e184cfd2469..4f270fd44ca 100644 --- a/dlls/ddraw/device.c +++ b/dlls/ddraw/device.c @@ -1798,10 +1798,7 @@ static HRESULT WINAPI d3d_device2_GetCurrentViewport(IDirect3DDevice2 *iface, ID static BOOL validate_surface_palette(struct ddraw_surface *surface) { - return !(surface->surface_desc.u4.ddpfPixelFormat.dwFlags - & (DDPF_PALETTEINDEXED1 | DDPF_PALETTEINDEXED2 - | DDPF_PALETTEINDEXED4 | DDPF_PALETTEINDEXED8 - | DDPF_PALETTEINDEXEDTO8)) + return !format_is_paletteindexed(&surface->surface_desc.u4.ddpfPixelFormat) || surface->palette; } diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index 2efc98c9694..3f230a2cbe0 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -461,8 +461,7 @@ static HRESULT ddraw_surface_set_palette(struct ddraw_surface *surface, IDirectD return DDERR_INVALIDSURFACETYPE; } - if (!(surface->surface_desc.u4.ddpfPixelFormat.dwFlags & (DDPF_PALETTEINDEXED1 | DDPF_PALETTEINDEXED2 - | DDPF_PALETTEINDEXED4 | DDPF_PALETTEINDEXED8 | DDPF_PALETTEINDEXEDTO8))) + if (!format_is_paletteindexed(&surface->surface_desc.u4.ddpfPixelFormat)) return DDERR_INVALIDPIXELFORMAT; wined3d_mutex_lock(); @@ -2017,6 +2016,22 @@ static HRESULT WINAPI ddraw_surface7_GetDC(IDirectDrawSurface7 *iface, HDC *hdc) hr = ddraw_surface_update_frontbuffer(surface, NULL, TRUE); if (SUCCEEDED(hr)) hr = wined3d_surface_getdc(surface->wined3d_surface, hdc); + + if (SUCCEEDED(hr) && format_is_paletteindexed(&surface->surface_desc.u4.ddpfPixelFormat)) + { + const struct ddraw_palette *palette; + + if (surface->palette) + palette = surface->palette; + else if (surface->ddraw->primary) + palette = surface->ddraw->primary->palette; + else + palette = NULL; + + if (palette) + wined3d_palette_apply_to_dc(palette->wineD3DPalette, *hdc); + } + wined3d_mutex_unlock(); switch(hr) { diff --git a/dlls/wined3d/palette.c b/dlls/wined3d/palette.c index e103b5bda4a..24b344cf543 100644 --- a/dlls/wined3d/palette.c +++ b/dlls/wined3d/palette.c @@ -83,6 +83,12 @@ HRESULT CDECL wined3d_palette_get_entries(const struct wined3d_palette *palette, return WINED3D_OK; } +void CDECL wined3d_palette_apply_to_dc(const struct wined3d_palette *palette, HDC dc) +{ + if (SetDIBColorTable(dc, 0, 256, palette->colors) != 256) + ERR("Failed to set DIB color table.\n"); +} + HRESULT CDECL wined3d_palette_set_entries(struct wined3d_palette *palette, DWORD flags, DWORD start, DWORD count, const PALETTEENTRY *entries) { diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index dea27ab70f6..023439d99f5 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -1378,7 +1378,7 @@ static void gdi_surface_realize_palette(struct wined3d_surface *surface) /* Tell the swapchain to update the screen. */ if (surface->swapchain && surface == surface->swapchain->front_buffer) { - SetDIBColorTable(surface->hDC, 0, 256, palette->colors); + wined3d_palette_apply_to_dc(palette, surface->hDC); x11_copy_to_screen(surface->swapchain, NULL); } } @@ -3122,31 +3122,6 @@ HRESULT CDECL wined3d_surface_getdc(struct wined3d_surface *surface, HDC *dc) surface_load_location(surface, WINED3D_LOCATION_DIB); surface_invalidate_location(surface, ~WINED3D_LOCATION_DIB); - if (surface->resource.format->id == WINED3DFMT_P8_UINT - || surface->resource.format->id == WINED3DFMT_P8_UINT_A8_UNORM) - { - /* GetDC on palettized formats is unsupported in D3D9, and the method - * is missing in D3D8, so this should only be used for DX <=7 - * surfaces (with non-device palettes). */ - const RGBQUAD *colors = NULL; - - if (surface->palette) - { - colors = surface->palette->colors; - } - else - { - struct wined3d_swapchain *swapchain = surface->resource.device->swapchains[0]; - struct wined3d_surface *dds_primary = swapchain->front_buffer; - - if (dds_primary && dds_primary->palette) - colors = dds_primary->palette->colors; - } - - if (colors) - SetDIBColorTable(surface->hDC, 0, 256, colors); - } - surface->flags |= SFLAG_DCINUSE; surface->resource.map_count++; diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 41b31582bab..f1a45ddf43a 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -160,6 +160,7 @@ @ cdecl wined3d_palette_create(ptr long long ptr ptr) @ cdecl wined3d_palette_decref(ptr) @ cdecl wined3d_palette_get_entries(ptr long long long ptr) +@ cdecl wined3d_palette_apply_to_dc(ptr ptr) @ cdecl wined3d_palette_incref(ptr) @ cdecl wined3d_palette_set_entries(ptr long long long ptr) diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index db36fbf8c3f..328b5950414 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2261,6 +2261,7 @@ HRESULT __cdecl wined3d_palette_create(struct wined3d_device *device, DWORD flag ULONG __cdecl wined3d_palette_decref(struct wined3d_palette *palette); HRESULT __cdecl wined3d_palette_get_entries(const struct wined3d_palette *palette, DWORD flags, DWORD start, DWORD count, PALETTEENTRY *entries); +void __cdecl wined3d_palette_apply_to_dc(const struct wined3d_palette *palette, HDC dc); ULONG __cdecl wined3d_palette_incref(struct wined3d_palette *palette); HRESULT __cdecl wined3d_palette_set_entries(struct wined3d_palette *palette, DWORD flags, DWORD start, DWORD count, const PALETTEENTRY *entries);