From 341be5f3f22029de527697a04f782a0f238bafe0 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Fri, 2 Jul 2021 12:41:01 +0200 Subject: [PATCH] gdi32: Reimplement SelectObject on top of ntgdi interface. Signed-off-by: Jacek Caban Signed-off-by: Huw Davies Signed-off-by: Alexandre Julliard --- dlls/gdi32/Makefile.in | 1 + dlls/gdi32/bitmap.c | 10 ---- dlls/gdi32/brush.c | 13 ----- dlls/gdi32/dc.c | 1 - dlls/gdi32/dib.c | 11 ----- dlls/gdi32/font.c | 11 ----- dlls/gdi32/gdi_private.h | 1 - dlls/gdi32/gdiobj.c | 36 -------------- dlls/gdi32/objects.c | 102 +++++++++++++++++++++++++++++++++++++++ dlls/gdi32/palette.c | 1 - dlls/gdi32/pen.c | 12 ----- dlls/gdi32/region.c | 10 ---- 12 files changed, 103 insertions(+), 106 deletions(-) create mode 100644 dlls/gdi32/objects.c diff --git a/dlls/gdi32/Makefile.in b/dlls/gdi32/Makefile.in index 910450b9f64..1bf6a4fa711 100644 --- a/dlls/gdi32/Makefile.in +++ b/dlls/gdi32/Makefile.in @@ -41,6 +41,7 @@ C_SRCS = \ mfdrv/init.c \ mfdrv/objects.c \ mfdrv/text.c \ + objects.c \ opengl.c \ opentype.c \ painting.c \ diff --git a/dlls/gdi32/bitmap.c b/dlls/gdi32/bitmap.c index 3d2c2e365e1..d1805beb99c 100644 --- a/dlls/gdi32/bitmap.c +++ b/dlls/gdi32/bitmap.c @@ -32,13 +32,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(bitmap); -static HGDIOBJ BITMAP_SelectObject( HGDIOBJ handle, HDC hdc ); static INT BITMAP_GetObject( HGDIOBJ handle, INT count, LPVOID buffer ); static BOOL BITMAP_DeleteObject( HGDIOBJ handle ); static const struct gdi_obj_funcs bitmap_funcs = { - BITMAP_SelectObject, /* pSelectObject */ BITMAP_GetObject, /* pGetObjectA */ BITMAP_GetObject, /* pGetObjectW */ NULL, /* pUnrealizeObject */ @@ -492,14 +490,6 @@ HGDIOBJ WINAPI NtGdiSelectBitmap( HDC hdc, HGDIOBJ handle ) return ret; } -/*********************************************************************** - * BITMAP_SelectObject - */ -static HGDIOBJ BITMAP_SelectObject( HGDIOBJ handle, HDC hdc ) -{ - return NtGdiSelectBitmap( hdc, handle ); -} - /*********************************************************************** * BITMAP_DeleteObject diff --git a/dlls/gdi32/brush.c b/dlls/gdi32/brush.c index acb0e67199a..c7b80479594 100644 --- a/dlls/gdi32/brush.c +++ b/dlls/gdi32/brush.c @@ -39,13 +39,11 @@ typedef struct #define NB_HATCH_STYLES 6 -static HGDIOBJ BRUSH_SelectObject( HGDIOBJ handle, HDC hdc ); static INT BRUSH_GetObject( HGDIOBJ handle, INT count, LPVOID buffer ); static BOOL BRUSH_DeleteObject( HGDIOBJ handle ); static const struct gdi_obj_funcs brush_funcs = { - BRUSH_SelectObject, /* pSelectObject */ BRUSH_GetObject, /* pGetObjectA */ BRUSH_GetObject, /* pGetObjectW */ NULL, /* pUnrealizeObject */ @@ -453,17 +451,6 @@ HGDIOBJ WINAPI NtGdiSelectBrush( HDC hdc, HGDIOBJ handle ) } -/*********************************************************************** - * BRUSH_SelectObject - */ -static HGDIOBJ BRUSH_SelectObject( HGDIOBJ handle, HDC hdc ) -{ - HGDIOBJ ret = NtGdiSelectBrush( hdc, handle ); - if (!ret) SetLastError( ERROR_INVALID_HANDLE ); - return ret; -} - - /*********************************************************************** * BRUSH_DeleteObject */ diff --git a/dlls/gdi32/dc.c b/dlls/gdi32/dc.c index 5fda958e906..be3b0f589f4 100644 --- a/dlls/gdi32/dc.c +++ b/dlls/gdi32/dc.c @@ -38,7 +38,6 @@ static BOOL DC_DeleteObject( HGDIOBJ handle ); static const struct gdi_obj_funcs dc_funcs = { - NULL, /* pSelectObject */ NULL, /* pGetObjectA */ NULL, /* pGetObjectW */ NULL, /* pUnrealizeObject */ diff --git a/dlls/gdi32/dib.c b/dlls/gdi32/dib.c index fdd7c9bcfbc..0e44f552f48 100644 --- a/dlls/gdi32/dib.c +++ b/dlls/gdi32/dib.c @@ -78,13 +78,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(bitmap); -static HGDIOBJ DIB_SelectObject( HGDIOBJ handle, HDC hdc ); static INT DIB_GetObject( HGDIOBJ handle, INT count, LPVOID buffer ); static BOOL DIB_DeleteObject( HGDIOBJ handle ); static const struct gdi_obj_funcs dib_funcs = { - DIB_SelectObject, /* pSelectObject */ DIB_GetObject, /* pGetObjectA */ DIB_GetObject, /* pGetObjectW */ NULL, /* pUnrealizeObject */ @@ -1717,15 +1715,6 @@ NTSTATUS WINAPI D3DKMTDestroyDCFromMemory( const D3DKMT_DESTROYDCFROMMEMORY *des } -/*********************************************************************** - * DIB_SelectObject - */ -static HGDIOBJ DIB_SelectObject( HGDIOBJ handle, HDC hdc ) -{ - return NtGdiSelectBitmap( hdc, handle ); -} - - /*********************************************************************** * DIB_GetObject */ diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c index 9a3695293fc..0a6c8b267a1 100644 --- a/dlls/gdi32/font.c +++ b/dlls/gdi32/font.c @@ -180,14 +180,12 @@ static inline WCHAR *strdupW( const WCHAR *p ) return ret; } -static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, HDC hdc ); static INT FONT_GetObjectA( HGDIOBJ handle, INT count, LPVOID buffer ); static INT FONT_GetObjectW( HGDIOBJ handle, INT count, LPVOID buffer ); static BOOL FONT_DeleteObject( HGDIOBJ handle ); static const struct gdi_obj_funcs fontobj_funcs = { - FONT_SelectObject, /* pSelectObject */ FONT_GetObjectA, /* pGetObjectA */ FONT_GetObjectW, /* pGetObjectW */ NULL, /* pUnrealizeObject */ @@ -4569,15 +4567,6 @@ HGDIOBJ WINAPI NtGdiSelectFont( HDC hdc, HGDIOBJ handle ) } -/*********************************************************************** - * FONT_SelectObject - */ -static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, HDC hdc ) -{ - return NtGdiSelectFont( hdc, handle ); -} - - /*********************************************************************** * FONT_GetObjectA */ diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h index 11fc144e07d..a4bc141811f 100644 --- a/dlls/gdi32/gdi_private.h +++ b/dlls/gdi32/gdi_private.h @@ -50,7 +50,6 @@ typedef struct { struct gdi_obj_funcs { - HGDIOBJ (*pSelectObject)( HGDIOBJ handle, HDC hdc ); INT (*pGetObjectA)( HGDIOBJ handle, INT count, LPVOID buffer ); INT (*pGetObjectW)( HGDIOBJ handle, INT count, LPVOID buffer ); BOOL (*pUnrealizeObject)( HGDIOBJ handle ); diff --git a/dlls/gdi32/gdiobj.c b/dlls/gdi32/gdiobj.c index b0fad2660ee..c6eb15ce2ab 100644 --- a/dlls/gdi32/gdiobj.c +++ b/dlls/gdi32/gdiobj.c @@ -1155,42 +1155,6 @@ HGDIOBJ WINAPI GetCurrentObject(HDC hdc,UINT type) } -/*********************************************************************** - * SelectObject (GDI32.@) - * - * Select a Gdi object into a device context. - * - * PARAMS - * hdc [I] Device context to associate the object with - * hObj [I] Gdi object to associate with hdc - * - * RETURNS - * Success: A non-NULL handle representing the previously selected object of - * the same type as hObj. - * Failure: A NULL object. If hdc is invalid, GetLastError() returns ERROR_INVALID_HANDLE. - * if hObj is not a valid object handle, no last error is set. In either - * case, hdc is unaffected by the call. - */ -HGDIOBJ WINAPI SelectObject( HDC hdc, HGDIOBJ hObj ) -{ - GDI_HANDLE_ENTRY *entry; - const struct gdi_obj_funcs *funcs = NULL; - - TRACE( "(%p,%p)\n", hdc, hObj ); - - EnterCriticalSection( &gdi_section ); - if ((entry = handle_entry( hObj ))) - { - funcs = entry_obj( entry )->funcs; - hObj = entry_to_handle( entry ); /* make it a full handle */ - } - LeaveCriticalSection( &gdi_section ); - - if (funcs && funcs->pSelectObject) return funcs->pSelectObject( hObj, hdc ); - return 0; -} - - /*********************************************************************** * UnrealizeObject (GDI32.@) */ diff --git a/dlls/gdi32/objects.c b/dlls/gdi32/objects.c new file mode 100644 index 00000000000..53335fd48df --- /dev/null +++ b/dlls/gdi32/objects.c @@ -0,0 +1,102 @@ +/* + * GDI functions + * + * Copyright 1993 Alexandre Julliard + * Copyright 2021 Jacek Caban for CodeWeavers + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#include "windef.h" +#include "winbase.h" +#include "ntgdi.h" +#include "winternl.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(gdi); + + +static GDI_SHARED_MEMORY *get_gdi_shared(void) +{ +#ifndef _WIN64 + if (NtCurrentTeb()->GdiBatchCount) + { + TEB64 *teb64 = (TEB64 *)(UINT_PTR)NtCurrentTeb()->GdiBatchCount; + PEB64 *peb64 = (PEB64 *)(UINT_PTR)teb64->Peb; + return (GDI_SHARED_MEMORY *)(UINT_PTR)peb64->GdiSharedHandleTable; + } +#endif + return (GDI_SHARED_MEMORY *)NtCurrentTeb()->Peb->GdiSharedHandleTable; +} + +static inline GDI_HANDLE_ENTRY *handle_entry( HGDIOBJ handle ) +{ + GDI_SHARED_MEMORY *gdi_shared = get_gdi_shared(); + unsigned int idx = LOWORD(handle); + + if (idx < GDI_MAX_HANDLE_COUNT && gdi_shared->Handles[idx].Type) + { + if (!HIWORD( handle ) || HIWORD( handle ) == gdi_shared->Handles[idx].Unique) + return &gdi_shared->Handles[idx]; + } + if (handle) WARN( "invalid handle %p\n", handle ); + return NULL; +} + +static WORD get_object_type( HGDIOBJ obj ) +{ + GDI_HANDLE_ENTRY *entry = handle_entry( obj ); + return entry ? entry->Type : 0; +} + +/*********************************************************************** + * SelectObject (GDI32.@) + * + * Select a Gdi object into a device context. + */ +HGDIOBJ WINAPI SelectObject( HDC hdc, HGDIOBJ obj ) +{ + HGDIOBJ ret; + + TRACE( "(%p,%p)\n", hdc, obj ); + + switch (get_object_type( obj )) + { + case OBJ_PEN: + case OBJ_EXTPEN: + ret = NtGdiSelectPen( hdc, obj ); + break; + case OBJ_BRUSH: + ret = NtGdiSelectBrush( hdc, obj ); + break; + case OBJ_FONT: + ret = NtGdiSelectFont( hdc, obj ); + break; + case OBJ_BITMAP: + ret = NtGdiSelectBitmap( hdc, obj ); + break; + case OBJ_REGION: + ret = ULongToHandle(SelectClipRgn( hdc, obj )); + break; + default: + return 0; + } + + if (!ret) SetLastError( ERROR_INVALID_HANDLE ); + return ret; +} diff --git a/dlls/gdi32/palette.c b/dlls/gdi32/palette.c index 378598fdd06..f9d5851d20e 100644 --- a/dlls/gdi32/palette.c +++ b/dlls/gdi32/palette.c @@ -55,7 +55,6 @@ static BOOL PALETTE_DeleteObject( HGDIOBJ handle ); static const struct gdi_obj_funcs palette_funcs = { - NULL, /* pSelectObject */ PALETTE_GetObject, /* pGetObjectA */ PALETTE_GetObject, /* pGetObjectW */ PALETTE_UnrealizeObject, /* pUnrealizeObject */ diff --git a/dlls/gdi32/pen.c b/dlls/gdi32/pen.c index 6ef3d45c4cb..0cc242ead5a 100644 --- a/dlls/gdi32/pen.c +++ b/dlls/gdi32/pen.c @@ -40,13 +40,11 @@ typedef struct } PENOBJ; -static HGDIOBJ PEN_SelectObject( HGDIOBJ handle, HDC hdc ); static INT PEN_GetObject( HGDIOBJ handle, INT count, LPVOID buffer ); static BOOL PEN_DeleteObject( HGDIOBJ handle ); static const struct gdi_obj_funcs pen_funcs = { - PEN_SelectObject, /* pSelectObject */ PEN_GetObject, /* pGetObjectA */ PEN_GetObject, /* pGetObjectW */ NULL, /* pUnrealizeObject */ @@ -264,16 +262,6 @@ HGDIOBJ WINAPI NtGdiSelectPen( HDC hdc, HGDIOBJ handle ) return ret; } -/*********************************************************************** - * PEN_SelectObject - */ -static HGDIOBJ PEN_SelectObject( HGDIOBJ handle, HDC hdc ) -{ - HGDIOBJ ret = NtGdiSelectPen( hdc, handle ); - if (!ret) SetLastError( ERROR_INVALID_HANDLE ); - return ret; -} - /*********************************************************************** * PEN_DeleteObject diff --git a/dlls/gdi32/region.c b/dlls/gdi32/region.c index bdaca476e44..3d0f9cfc211 100644 --- a/dlls/gdi32/region.c +++ b/dlls/gdi32/region.c @@ -107,12 +107,10 @@ SOFTWARE. WINE_DEFAULT_DEBUG_CHANNEL(region); -static HGDIOBJ REGION_SelectObject( HGDIOBJ handle, HDC hdc ); static BOOL REGION_DeleteObject( HGDIOBJ handle ); static const struct gdi_obj_funcs region_funcs = { - REGION_SelectObject, /* pSelectObject */ NULL, /* pGetObjectA */ NULL, /* pGetObjectW */ NULL, /* pUnrealizeObject */ @@ -488,14 +486,6 @@ static BOOL REGION_DeleteObject( HGDIOBJ handle ) return TRUE; } -/*********************************************************************** - * REGION_SelectObject - */ -static HGDIOBJ REGION_SelectObject( HGDIOBJ handle, HDC hdc ) -{ - return ULongToHandle(SelectClipRgn( hdc, handle )); -} - /*********************************************************************** * REGION_OffsetRegion