gdi32: Reimplement SelectObject on top of ntgdi interface.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2021-07-02 12:41:01 +02:00 committed by Alexandre Julliard
parent aeb8c22f76
commit 341be5f3f2
12 changed files with 103 additions and 106 deletions

View File

@ -41,6 +41,7 @@ C_SRCS = \
mfdrv/init.c \
mfdrv/objects.c \
mfdrv/text.c \
objects.c \
opengl.c \
opentype.c \
painting.c \

View File

@ -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

View File

@ -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
*/

View File

@ -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 */

View File

@ -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
*/

View File

@ -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
*/

View File

@ -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 );

View File

@ -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.@)
*/

102
dlls/gdi32/objects.c Normal file
View File

@ -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 <stdarg.h>
#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;
}

View File

@ -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 */

View File

@ -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

View File

@ -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