Turn a GDI object into a system object via an explicit Wine extension

rather then through magical pokes in memory.
This commit is contained in:
Dimi Paun 2005-05-25 09:55:55 +00:00 committed by Alexandre Julliard
parent 70bc9f39f1
commit 2a109307c3
3 changed files with 36 additions and 48 deletions

View File

@ -431,6 +431,15 @@
@ stdcall SetHookFlags16(long long)
@ stdcall WriteSpool16(long ptr long)
################################################################
# Wine internal extensions
#
# All functions must be prefixed with '__wine_' (for internal functions)
# or 'wine_' (for user-visible functions) to avoid namespace conflicts.
# GDI objects
@ cdecl __wine_make_gdi_object_system(long long)
################################################################
# Wine dll separation hacks, these will go away, don't use them
#

View File

@ -445,6 +445,26 @@ static const struct DefaultFontInfo default_fonts[] =
};
/*************************************************************************
* __wine_make_gdi_object_system (GDI32.@)
*
* USER has to tell GDI that its system brushes and pens are non-deletable.
* For a description of the GDI object magics and their flags,
* see "Undocumented Windows" (wrong about the OBJECT_NOSYSTEM flag, though).
*/
void __wine_make_gdi_object_system( HGDIOBJ handle, BOOL set)
{
GDIOBJHDR *ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE );
/* touch the "system" bit of the wMagic field of a GDIOBJHDR */
if (set)
ptr->wMagic &= ~OBJECT_NOSYSTEM;
else
ptr->wMagic |= OBJECT_NOSYSTEM;
GDI_ReleaseObj( handle );
}
/******************************************************************************
* get_default_fonts
*/
@ -604,7 +624,6 @@ BOOL GDI_Init(void)
{
HINSTANCE16 instance;
HKEY hkey;
GDIOBJHDR *ptr;
LOGFONTW default_gui_font;
const struct DefaultFontInfo* deffonts;
int i;
@ -659,9 +678,7 @@ BOOL GDI_Init(void)
ERR( "could not create stock object %d\n", i );
return FALSE;
}
ptr = GDI_GetObjPtr( stock_objects[i], MAGIC_DONTCARE );
ptr->wMagic &= ~OBJECT_NOSYSTEM;
GDI_ReleaseObj( stock_objects[i] );
__wine_make_gdi_object_system( stock_objects[i], TRUE );
}
if (hkey) RegCloseKey( hkey );

View File

@ -27,13 +27,9 @@
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "wine/winbase16.h"
#include "wine/winuser16.h"
#include "winuser.h"
#include "wownt32.h"
#include "winreg.h"
#include "winternl.h"
#include "gdi.h" /* sic */
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(syscolor);
@ -85,41 +81,7 @@ static const WORD wPattern55AA[] =
HBRUSH SYSCOLOR_55AABrush = 0;
/*************************************************************************
* SYSCOLOR_MakeObjectSystem
*
* OK, now for a very ugly hack.
* USER somehow has to tell GDI that its system brushes and pens are
* non-deletable.
* We don't want to export a function from GDI doing this for us,
* so we just do that ourselves by "wildly flipping some bits in memory".
* For a description of the GDI object magics and their flags,
* see "Undocumented Windows" (wrong about the OBJECT_NOSYSTEM flag, though).
*/
static void SYSCOLOR_MakeObjectSystem( HGDIOBJ16 handle, BOOL set)
{
static WORD heap_sel = 0;
LPWORD ptr;
if (!heap_sel) heap_sel = LoadLibrary16( "gdi" );
if (heap_sel >= 32)
{
STACK16FRAME* stack16 = MapSL((SEGPTR)NtCurrentTeb()->WOW32Reserved);
HANDLE16 oldDS = stack16->ds;
stack16->ds = heap_sel;
ptr = MapSL(LocalLock16(handle));
/* touch the "system" bit of the wMagic field of a GDIOBJHDR */
if (set)
*ptr &= ~OBJECT_NOSYSTEM;
else
*ptr |= OBJECT_NOSYSTEM;
LocalUnlock16( handle );
stack16->ds = oldDS;
}
}
extern void __wine_make_gdi_object_system( HGDIOBJ handle, BOOL set );
/*************************************************************************
* SYSCOLOR_SetColor
@ -130,19 +92,19 @@ static void SYSCOLOR_SetColor( int index, COLORREF color )
SysColors[index] = color;
if (SysColorBrushes[index])
{
SYSCOLOR_MakeObjectSystem( HBRUSH_16(SysColorBrushes[index]), FALSE);
__wine_make_gdi_object_system( SysColorBrushes[index], FALSE);
DeleteObject( SysColorBrushes[index] );
}
SysColorBrushes[index] = CreateSolidBrush( color );
SYSCOLOR_MakeObjectSystem( HBRUSH_16(SysColorBrushes[index]), TRUE);
__wine_make_gdi_object_system( SysColorBrushes[index], TRUE);
if (SysColorPens[index])
{
SYSCOLOR_MakeObjectSystem( HPEN_16(SysColorPens[index]), FALSE);
__wine_make_gdi_object_system( SysColorPens[index], FALSE);
DeleteObject( SysColorPens[index] );
}
SysColorPens[index] = CreatePen( PS_SOLID, 1, color );
SYSCOLOR_MakeObjectSystem( HPEN_16(SysColorPens[index]), TRUE);
__wine_make_gdi_object_system( SysColorPens[index], TRUE);
}
@ -192,7 +154,7 @@ void SYSCOLOR_Init(void)
h55AABitmap = CreateBitmap( 8, 8, 1, 1, wPattern55AA );
SYSCOLOR_55AABrush = CreatePatternBrush( h55AABitmap );
SYSCOLOR_MakeObjectSystem( HBRUSH_16(SYSCOLOR_55AABrush), TRUE );
__wine_make_gdi_object_system( SYSCOLOR_55AABrush, TRUE );
}