Commit 007fb240 authored by Andreas Mohr's avatar Andreas Mohr Committed by Alexandre Julliard

Added support for non-deletable system brushes and pens created by

USER.
parent 5180d563
......@@ -76,7 +76,7 @@ HGDIOBJ TTYDRV_DC_SelectObject(DC *dc, HGDIOBJ handle)
if(!ptr) return 0;
switch(ptr->wMagic)
switch(GDIMAGIC(ptr->wMagic))
{
case BITMAP_MAGIC:
result = TTYDRV_DC_BITMAP_SelectObject(dc, handle, (BITMAPOBJ *) ptr);
......@@ -95,7 +95,8 @@ HGDIOBJ TTYDRV_DC_SelectObject(DC *dc, HGDIOBJ handle)
result = (HGDIOBJ) SelectClipRgn(dc->hSelf, handle);
break;
default:
ERR("handle (0x%04x) has unknown magic (0x%04x)\n", handle, ptr->wMagic);
ERR("handle (0x%04x) has unknown magic (0x%04x)\n",
handle, GDIMAGIC(ptr->wMagic));
}
GDI_ReleaseObj(handle);
......@@ -113,7 +114,7 @@ BOOL TTYDRV_DC_DeleteObject(HGDIOBJ handle)
if(!ptr) return FALSE;
switch(ptr->wMagic)
switch(GDIMAGIC(ptr->wMagic))
{
case BITMAP_MAGIC:
result = TTYDRV_DC_BITMAP_DeleteObject(handle, (BITMAPOBJ *) ptr);
......@@ -125,7 +126,8 @@ BOOL TTYDRV_DC_DeleteObject(HGDIOBJ handle)
result = TRUE;
break;
default:
ERR("handle (0x%04x) has unknown magic (0x%04x)\n", handle, ptr->wMagic);
ERR("handle (0x%04x) has unknown magic (0x%04x)\n",
handle, GDIMAGIC(ptr->wMagic));
result = FALSE;
}
......
......@@ -36,7 +36,7 @@ HGDIOBJ PSDRV_SelectObject( DC *dc, HGDIOBJ handle )
if (!ptr) return 0;
TRACE("hdc=%04x %04x\n", dc->hSelf, handle );
switch(ptr->wMagic)
switch(GDIMAGIC(ptr->wMagic))
{
case PEN_MAGIC:
ret = PSDRV_PEN_SelectObject( dc, handle, (PENOBJ *)ptr );
......@@ -54,7 +54,7 @@ HGDIOBJ PSDRV_SelectObject( DC *dc, HGDIOBJ handle )
ret = (HGDIOBJ16)SelectClipRgn16( dc->hSelf, handle );
break;
default:
ERR("Unknown object magic %04x\n", ptr->wMagic);
ERR("Unknown object magic %04x\n", GDIMAGIC(ptr->wMagic));
break;
}
GDI_ReleaseObj( handle );
......
......@@ -288,7 +288,7 @@ HGDIOBJ EMFDRV_SelectObject( DC *dc, HGDIOBJ handle )
if (!ptr) return 0;
TRACE("hdc=%04x %04x\n", dc->hSelf, handle );
switch(ptr->wMagic)
switch(GDIMAGIC(ptr->wMagic))
{
case PEN_MAGIC:
ret = EMFDRV_PEN_SelectObject( dc, handle );
......
......@@ -243,7 +243,7 @@ HGDIOBJ MFDRV_SelectObject( DC *dc, HGDIOBJ handle )
if (!ptr) return 0;
TRACE_(gdi)("hdc=%04x %04x\n", dc->hSelf, handle );
switch(ptr->wMagic)
switch(GDIMAGIC(ptr->wMagic))
{
case PEN_MAGIC:
ret = MFDRV_PEN_SelectObject( dc, handle, (PENOBJ *)ptr );
......
......@@ -35,7 +35,7 @@ HGDIOBJ WIN16DRV_SelectObject( DC *dc, HGDIOBJ handle )
if (!ptr) return 0;
TRACE("hdc=%04x %04x\n", dc->hSelf, handle );
switch(ptr->wMagic)
switch(GDIMAGIC(ptr->wMagic))
{
case PEN_MAGIC:
ret = WIN16DRV_PEN_SelectObject( dc, handle, (PENOBJ *)ptr );
......
......@@ -40,7 +40,7 @@ HGDIOBJ X11DRV_SelectObject( DC *dc, HGDIOBJ handle )
if (!ptr) return 0;
TRACE("hdc=%04x %04x\n", dc->hSelf, handle );
switch(ptr->wMagic)
switch(GDIMAGIC(ptr->wMagic))
{
case PEN_MAGIC:
ret = X11DRV_PEN_SelectObject( dc, handle, (PENOBJ *)ptr );
......@@ -73,7 +73,7 @@ BOOL X11DRV_DeleteObject( HGDIOBJ handle )
if (!ptr) return FALSE;
switch(ptr->wMagic) {
switch(GDIMAGIC(ptr->wMagic)) {
case BITMAP_MAGIC:
ret = X11DRV_BITMAP_DeleteObject( handle, (BITMAPOBJ *)ptr );
break;
......
......@@ -18,6 +18,7 @@
#include <math.h>
/* GDI objects magic numbers */
#define FIRST_MAGIC 0x4f47
#define PEN_MAGIC 0x4f47
#define BRUSH_MAGIC 0x4f48
#define FONT_MAGIC 0x4f49
......@@ -31,9 +32,16 @@
#define METAFILE_DC_MAGIC 0x4f51
#define ENHMETAFILE_MAGIC 0x4f52
#define ENHMETAFILE_DC_MAGIC 0x4f53
#define LAST_MAGIC 0x4f53
#define MAGIC_DONTCARE 0xffff
/* GDI constants for making objects private/system (naming undoc. !) */
#define OBJECT_PRIVATE 0x2000
#define OBJECT_NOSYSTEM 0x8000
#define GDIMAGIC(magic) ((magic) & ~(OBJECT_PRIVATE|OBJECT_NOSYSTEM))
typedef struct tagGDIOBJHDR
{
HANDLE16 hNext;
......
......@@ -117,8 +117,9 @@ DC *DC_GetDCPtr( HDC hdc )
{
GDIOBJHDR *ptr = GDI_GetObjPtr( hdc, MAGIC_DONTCARE );
if (!ptr) return NULL;
if ((ptr->wMagic == DC_MAGIC) || (ptr->wMagic == METAFILE_DC_MAGIC) ||
(ptr->wMagic == ENHMETAFILE_DC_MAGIC))
if ((GDIMAGIC(ptr->wMagic) == DC_MAGIC) ||
(GDIMAGIC(ptr->wMagic) == METAFILE_DC_MAGIC) ||
(GDIMAGIC(ptr->wMagic) == ENHMETAFILE_DC_MAGIC))
return (DC *)ptr;
GDI_ReleaseObj( hdc );
SetLastError( ERROR_INVALID_HANDLE );
......
......@@ -383,7 +383,7 @@ void *GDI_AllocObject( WORD size, WORD magic, HGDIOBJ *handle )
}
obj = (GDIOBJHDR *)LOCAL_Lock( GDI_HeapSel, *handle );
obj->hNext = 0;
obj->wMagic = magic;
obj->wMagic = magic|OBJECT_NOSYSTEM;
obj->dwCount = ++count;
TRACE_SEC( *handle, "enter" );
......@@ -449,12 +449,14 @@ void *GDI_GetObjPtr( HGDIOBJ handle, WORD magic )
if (handle >= FIRST_STOCK_HANDLE)
{
if (handle <= LAST_STOCK_HANDLE) ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
if (ptr && (magic != MAGIC_DONTCARE) && (ptr->wMagic != magic)) ptr = NULL;
if (ptr && (magic != MAGIC_DONTCARE)
&& (GDIMAGIC(ptr->wMagic) != magic)) ptr = NULL;
}
else
{
ptr = (GDIOBJHDR *)LOCAL_Lock( GDI_HeapSel, handle );
if (ptr && (magic != MAGIC_DONTCARE) && (ptr->wMagic != magic))
if (ptr &&
(magic != MAGIC_DONTCARE) && (GDIMAGIC(ptr->wMagic) != magic))
{
LOCAL_Unlock( GDI_HeapSel, handle );
ptr = NULL;
......@@ -510,11 +512,19 @@ BOOL WINAPI DeleteObject( HGDIOBJ obj )
if (obj == hPseudoStockBitmap) return TRUE;
if (!(header = GDI_GetObjPtr( obj, MAGIC_DONTCARE ))) return FALSE;
if (!(header->wMagic & OBJECT_NOSYSTEM)
&& (header->wMagic >= FIRST_MAGIC) && (header->wMagic <= LAST_MAGIC))
{
TRACE("Preserving system object %04x\n", obj);
GDI_ReleaseObj( obj );
return TRUE;
}
TRACE("%04x\n", obj );
/* Delete object */
switch(header->wMagic)
switch(GDIMAGIC(header->wMagic))
{
case PEN_MAGIC: return GDI_FreeObject( obj, header );
case BRUSH_MAGIC: return BRUSH_DeleteObject( obj, (BRUSHOBJ*)header );
......@@ -529,7 +539,7 @@ BOOL WINAPI DeleteObject( HGDIOBJ obj )
WARN("Already deleted\n");
break;
default:
WARN("Unknown magic number (%d)\n",header->wMagic);
WARN("Unknown magic number (%d)\n",GDIMAGIC(header->wMagic));
}
GDI_ReleaseObj( obj );
return FALSE;
......@@ -570,7 +580,7 @@ INT16 WINAPI GetObject16( HANDLE16 handle, INT16 count, LPVOID buffer )
if (!(ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE ))) return 0;
switch(ptr->wMagic)
switch(GDIMAGIC(ptr->wMagic))
{
case PEN_MAGIC:
result = PEN_GetObject16( (PENOBJ *)ptr, count, buffer );
......@@ -612,7 +622,7 @@ INT WINAPI GetObjectA( HANDLE handle, INT count, LPVOID buffer )
if (!(ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE ))) return 0;
switch(ptr->wMagic)
switch(GDIMAGIC(ptr->wMagic))
{
case PEN_MAGIC:
result = PEN_GetObject( (PENOBJ *)ptr, count, buffer );
......@@ -645,12 +655,11 @@ INT WINAPI GetObjectA( HANDLE handle, INT count, LPVOID buffer )
case METAFILE_DC_MAGIC:
case ENHMETAFILE_MAGIC:
case ENHMETAFILE_DC_MAGIC:
FIXME("Magic %04x not implemented\n",
ptr->wMagic );
FIXME("Magic %04x not implemented\n", GDIMAGIC(ptr->wMagic) );
break;
default:
ERR("Invalid GDI Magic %04x\n", ptr->wMagic);
ERR("Invalid GDI Magic %04x\n", GDIMAGIC(ptr->wMagic));
break;
}
GDI_ReleaseObj( handle );
......@@ -669,7 +678,7 @@ INT WINAPI GetObjectW( HANDLE handle, INT count, LPVOID buffer )
if (!(ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE ))) return 0;
switch(ptr->wMagic)
switch(GDIMAGIC(ptr->wMagic))
{
case PEN_MAGIC:
result = PEN_GetObject( (PENOBJ *)ptr, count, buffer );
......@@ -694,8 +703,7 @@ INT WINAPI GetObjectW( HANDLE handle, INT count, LPVOID buffer )
result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer );
break;
default:
FIXME("Magic %04x not implemented\n",
ptr->wMagic );
FIXME("Magic %04x not implemented\n", GDIMAGIC(ptr->wMagic) );
break;
}
GDI_ReleaseObj( handle );
......@@ -713,7 +721,7 @@ DWORD WINAPI GetObjectType( HANDLE handle )
if (!(ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE ))) return 0;
switch(ptr->wMagic)
switch(GDIMAGIC(ptr->wMagic))
{
case PEN_MAGIC:
result = OBJ_PEN;
......@@ -752,8 +760,7 @@ DWORD WINAPI GetObjectType( HANDLE handle )
result = OBJ_ENHMETADC;
break;
default:
FIXME("Magic %04x not implemented\n",
ptr->wMagic );
FIXME("Magic %04x not implemented\n", GDIMAGIC(ptr->wMagic) );
break;
}
GDI_ReleaseObj( handle );
......@@ -778,7 +785,7 @@ HANDLE WINAPI GetCurrentObject(HDC hdc,UINT type)
case OBJ_BITMAP: ret = dc->w.hBitmap; break;
default:
/* the SDK only mentions those above */
WARN("(%08x,%d): unknown type.\n",hdc,type);
FIXME("(%08x,%d): unknown type.\n",hdc,type);
break;
}
GDI_ReleaseObj( hdc );
......@@ -836,7 +843,7 @@ BOOL WINAPI UnrealizeObject( HGDIOBJ obj )
/* Unrealize object */
switch(header->wMagic)
switch(GDIMAGIC(header->wMagic))
{
case PALETTE_MAGIC:
result = PALETTE_UnrealizeObject( obj, (PALETTEOBJ *)header );
......@@ -1018,7 +1025,7 @@ BOOL16 WINAPI IsGDIObject16( HGDIOBJ16 handle )
GDIOBJHDR *object = GDI_GetObjPtr( handle, MAGIC_DONTCARE );
if (object)
{
magic = object->wMagic - PEN_MAGIC + 1;
magic = GDIMAGIC(object->wMagic) - PEN_MAGIC + 1;
GDI_ReleaseObj( handle );
}
return magic;
......@@ -1042,12 +1049,27 @@ void WINAPI SetObjectOwner( HGDIOBJ handle, HANDLE owner )
/* Nothing to do */
}
/***********************************************************************
* MakeObjectPrivate (GDI.463)
*
* What does that mean ?
* Some little docu can be found in "Undocumented Windows",
* but this is basically useless.
* At least we know that this flags the GDI object's wMagic
* with 0x2000 (OBJECT_PRIVATE), so we just do it.
* But Wine doesn't react on that yet.
*/
void WINAPI MakeObjectPrivate16( HGDIOBJ16 handle, BOOL16 private )
{
/* FIXME */
GDIOBJHDR *ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE );
if (!ptr)
{
ERR("invalid GDI object %04x !\n", handle);
return;
}
ptr->wMagic |= OBJECT_PRIVATE;
GDI_ReleaseObj( handle );
}
......
......@@ -20,6 +20,8 @@
#include "debugtools.h"
#include "tweak.h"
#include "winreg.h"
#include "local.h"
#include "gdi.h" /* sic */
DEFAULT_DEBUG_CHANNEL(syscolor)
......@@ -99,6 +101,39 @@ static HPEN SysColorPens[NUM_SYS_COLORS];
#define MAKE_SOLID(color) \
(PALETTEINDEX(GetNearestPaletteIndex(STOCK_DEFAULT_PALETTE,(color))))
/*************************************************************************
* 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( HGDIOBJ handle, BOOL set)
{
static WORD GDI_heap_sel = 0;
LPWORD ptr;
if (!GDI_heap_sel)
{
GDI_heap_sel = LoadLibrary16("gdi");
FreeLibrary16(GDI_heap_sel);
}
ptr = (LPWORD)LOCAL_Lock(GDI_heap_sel, handle);
/* touch the "system" bit of the wMagic field of a GDIOBJHDR */
if (set)
*(ptr+1) &= ~OBJECT_NOSYSTEM;
else
*(ptr+1) |= OBJECT_NOSYSTEM;
LOCAL_Unlock( GDI_heap_sel, handle );
}
/*************************************************************************
* SYSCOLOR_SetColor
*/
......@@ -106,10 +141,21 @@ static void SYSCOLOR_SetColor( int index, COLORREF color )
{
if (index < 0 || index >= NUM_SYS_COLORS) return;
SysColors[index] = color;
if (SysColorBrushes[index]) DeleteObject( SysColorBrushes[index] );
if (SysColorBrushes[index])
{
SYSCOLOR_MakeObjectSystem(SysColorBrushes[index], FALSE);
DeleteObject( SysColorBrushes[index] );
}
SysColorBrushes[index] = CreateSolidBrush( color );
if (SysColorPens[index]) DeleteObject( SysColorPens[index] );
SYSCOLOR_MakeObjectSystem(SysColorBrushes[index], TRUE);
if (SysColorPens[index])
{
SYSCOLOR_MakeObjectSystem(SysColorBrushes[index], FALSE);
DeleteObject( SysColorPens[index] );
}
SysColorPens[index] = CreatePen( PS_SOLID, 1, color );
SYSCOLOR_MakeObjectSystem(SysColorBrushes[index], TRUE);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment