Create GDI stock objects as normal objects instead of using magic
handle values.

diff --git a/objects/gdiobj.c b/objects/gdiobj.c
index ff69b03..1a2b621 100644
--- a/objects/gdiobj.c
+++ b/objects/gdiobj.c
@@ -34,247 +34,116 @@
  *          GDI stock objects 
  */
 
-static BRUSHOBJ WhiteBrush =
-{
-    { 0, BRUSH_MAGIC, 1 },             /* header */
-    { BS_SOLID, RGB(255,255,255), 0 }  /* logbrush */
-};
+static const LOGBRUSH WhiteBrush = { BS_SOLID, RGB(255,255,255), 0 };
+static const LOGBRUSH BlackBrush = { BS_SOLID, RGB(0,0,0), 0 };
+static const LOGBRUSH NullBrush  = { BS_NULL, 0, 0 };
 
-static BRUSHOBJ LtGrayBrush =
-{
-    { 0, BRUSH_MAGIC, 1 },             /* header */
-/* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
-    { BS_SOLID, RGB(192,192,192), 0 }  /* logbrush */
-};
+/* FIXME: these should perhaps be BS_HATCHED, at least for 1 bitperpixel */
+static const LOGBRUSH LtGrayBrush = { BS_SOLID, RGB(192,192,192), 0 };
+static const LOGBRUSH GrayBrush   = { BS_SOLID, RGB(128,128,128), 0 };
 
-static BRUSHOBJ GrayBrush =
-{
-    { 0, BRUSH_MAGIC, 1 },             /* header */
-/* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
-    { BS_SOLID, RGB(128,128,128), 0 }  /* logbrush */
-};
-
-static BRUSHOBJ DkGrayBrush =
-{
-    { 0, BRUSH_MAGIC, 1 },          /* header */
 /* This is BS_HATCHED, for 1 bitperpixel. This makes the spray work in pbrush */
 /* NB_HATCH_STYLES is an index into HatchBrushes */
-    { BS_HATCHED, RGB(0,0,0), NB_HATCH_STYLES }  /* logbrush */
-};
+static const LOGBRUSH DkGrayBrush = { BS_HATCHED, RGB(0,0,0), NB_HATCH_STYLES };
 
-static BRUSHOBJ BlackBrush =
-{
-    { 0, BRUSH_MAGIC, 1 },       /* header */
-    { BS_SOLID, RGB(0,0,0), 0 }  /* logbrush */
-};
+static const LOGPEN WhitePen = { PS_SOLID, { 0, 0 }, RGB(255,255,255) };
+static const LOGPEN BlackPen = { PS_SOLID, { 0, 0 }, RGB(0,0,0) };
+static const LOGPEN NullPen  = { PS_NULL,  { 0, 0 }, 0 };
 
-static BRUSHOBJ NullBrush =
-{
-    { 0, BRUSH_MAGIC, 1 },  /* header */
-    { BS_NULL, 0, 0 }       /* logbrush */
-};
+static const LOGFONTW OEMFixedFont =
+{ 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, OEM_CHARSET,
+  0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, {'\0'} };
 
-static PENOBJ WhitePen =
-{
-    { 0, PEN_MAGIC, 1 },                     /* header */
-    { PS_SOLID, { 0, 0 }, RGB(255,255,255) } /* logpen */
-};
+static const LOGFONTW AnsiFixedFont =
+{ 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
+  0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, {'\0'} };
 
-static PENOBJ BlackPen =
-{
-    { 0, PEN_MAGIC, 1 },               /* header */
-    { PS_SOLID, { 0, 0 }, RGB(0,0,0) } /* logpen */
-};
+static const LOGFONTW AnsiVarFont =
+{ 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
+  0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
+  {'M','S',' ','S','a','n','s',' ','S','e','r','i','f','\0'} };
 
-static PENOBJ NullPen =
-{
-    { 0, PEN_MAGIC, 1 },      /* header */
-    { PS_NULL, { 0, 0 }, 0 }  /* logpen */
-};
+static const LOGFONTW SystemFont =
+{ 16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
+  0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
+  {'S','y','s','t','e','m','\0'} };
 
-static FONTOBJ OEMFixedFont =
-{
-    { 0, FONT_MAGIC, 1 },   /* header */
-    { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, OEM_CHARSET,
-      0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, {'\0'} }
-};
+static const LOGFONTW DeviceDefaultFont =
+{ 16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
+  0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, {'\0'} };
 
-static FONTOBJ AnsiFixedFont =
-{
-    { 0, FONT_MAGIC, 1 },   /* header */
-    { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
-      0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, {'\0'} }
-};
-
-static FONTOBJ AnsiVarFont =
-{
-    { 0, FONT_MAGIC, 1 },   /* header */
-    { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
-      0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
-      {'M','S',' ','S','a','n','s',' ','S','e','r','i','f','\0'} }
-};
-
-static FONTOBJ SystemFont =
-{
-    { 0, FONT_MAGIC, 1 },
-    { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
-      0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
-      {'S','y','s','t','e','m','\0'} }
-};
-
-static FONTOBJ DeviceDefaultFont =
-{
-    { 0, FONT_MAGIC, 1 },   /* header */
-    { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
-      0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, {'\0'} }
-};
-
-static FONTOBJ SystemFixedFont =
-{
-    { 0, FONT_MAGIC, 1 },   /* header */
-    { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
-      0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, {'\0'} }
-};
+static const LOGFONTW SystemFixedFont =
+{ 16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
+  0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, {'\0'} };
 
 /* FIXME: Is this correct? */
-static FONTOBJ DefaultGuiFont =
-{
-    { 0, FONT_MAGIC, 1 },   /* header */
-    { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
-      0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
-      {'M','S',' ','S','a','n','s',' ','S','e','r','i','f','\0'} }
-};
+static const LOGFONTW DefaultGuiFont =
+{ -11, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
+  0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
+  {'M','S',' ','S','a','n','s',' ','S','e','r','i','f','\0'} };
 
+/* reserve one extra entry for the stock default bitmap */
+/* this is what Windows does too */
+#define NB_STOCK_OBJECTS (STOCK_LAST+2)
 
-static GDIOBJHDR * StockObjects[NB_STOCK_OBJECTS] =
-{
-    (GDIOBJHDR *) &WhiteBrush,
-    (GDIOBJHDR *) &LtGrayBrush,
-    (GDIOBJHDR *) &GrayBrush,
-    (GDIOBJHDR *) &DkGrayBrush,
-    (GDIOBJHDR *) &BlackBrush,
-    (GDIOBJHDR *) &NullBrush,
-    (GDIOBJHDR *) &WhitePen,
-    (GDIOBJHDR *) &BlackPen,
-    (GDIOBJHDR *) &NullPen,
-    NULL,
-    (GDIOBJHDR *) &OEMFixedFont,
-    (GDIOBJHDR *) &AnsiFixedFont,
-    (GDIOBJHDR *) &AnsiVarFont,
-    (GDIOBJHDR *) &SystemFont,
-    (GDIOBJHDR *) &DeviceDefaultFont,
-    NULL,            /* DEFAULT_PALETTE created by PALETTE_Init */
-    (GDIOBJHDR *) &SystemFixedFont,
-    (GDIOBJHDR *) &DefaultGuiFont
-};
-
-HBITMAP hPseudoStockBitmap; /* 1x1 bitmap for memory DCs */
+static HGDIOBJ stock_objects[NB_STOCK_OBJECTS];
 
 static SYSLEVEL GDI_level = { CRITICAL_SECTION_INIT("GDI_level"), 3 };
 static WORD GDI_HeapSel;
 
-static BOOL get_bool(char *buffer, BOOL def_value)
+inline static BOOL get_bool(char *buffer)
 {
-    switch(buffer[0])
-    {
-	case 'n':
-	case 'N':
-	case 'f':
-	case 'F':
-	case '0':
-	    return FALSE;
-
-	case 'y':
-	case 'Y':
-	case 't':
-	case 'T':
-	case '1':
-	    return TRUE;
-
-	default:
-	    return def_value;
-    }
+    return (buffer[0] == 'y' || buffer[0] == 'Y' ||
+            buffer[0] == 't' || buffer[0] == 'T' ||
+            buffer[0] == '1');
 }
 
-/******************************************************************************
- *
- *   void  ReadFontInformation(
- *      char const  *fontName,
- *      FONTOBJ  *font,
- *      int  defHeight,
- *      int  defBold,
- *      int  defItalic,
- *      int  defUnderline,
- *      int  defStrikeOut )
- *
- *   ReadFontInformation() checks the Wine configuration file's Tweak.Fonts
- *   section for entries containing fontName.Height, fontName.Bold, etc.,
- *   where fontName is the name specified in the call (e.g., "System").  It
- *   attempts to be user friendly by accepting 'n', 'N', 'f', 'F', or '0' as
- *   the first character in the boolean attributes (bold, italic, and
- *   underline).
- *****************************************************************************/
 
-static void  ReadFontInformation(
-    char const *fontName,
-    FONTOBJ *font,
-    int  defHeight,
-    int  defBold,
-    int  defItalic,
-    int  defUnderline,
-    int  defStrikeOut )
+/******************************************************************************
+ *           create_stock_font
+ */
+static HFONT create_stock_font( char const *fontName, const LOGFONTW *font, HKEY hkey )
 {
+    LOGFONTW lf;
     char  key[256];
     char buffer[MAX_PATH];
-    HKEY hkey;
     DWORD type, count;
 
-    /* In order for the stock fonts to be independent of 
-     * mapping mode, the height (& width) must be 0
-     */
+    if (!hkey) return CreateFontIndirectW( font );
 
-    /* assign defaults */
-    font->logfont.lfHeight = defHeight;
-    font->logfont.lfWeight = defBold;
-    font->logfont.lfItalic = defItalic;
-    font->logfont.lfUnderline = defUnderline;
-    font->logfont.lfStrikeOut = defStrikeOut;
-
-    if(RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\Tweak.Fonts", &hkey))
-	return;
-
+    lf = *font;
     sprintf(key, "%s.Height", fontName);
     count = sizeof(buffer);
     if(!RegQueryValueExA(hkey, key, 0, &type, buffer, &count))
-	font->logfont.lfHeight = atoi(buffer);
+        lf.lfHeight = atoi(buffer);
 
     sprintf(key, "%s.Bold", fontName);
     count = sizeof(buffer);
     if(!RegQueryValueExA(hkey, key, 0, &type, buffer, &count))
-	font->logfont.lfWeight = get_bool(buffer, defBold) ? FW_BOLD : FW_NORMAL;
+        lf.lfWeight = get_bool(buffer) ? FW_BOLD : FW_NORMAL;
 
     sprintf(key, "%s.Italic", fontName);
     count = sizeof(buffer);
     if(!RegQueryValueExA(hkey, key, 0, &type, buffer, &count))
-	font->logfont.lfItalic = get_bool(buffer, defItalic);
+        lf.lfItalic = get_bool(buffer);
 
     sprintf(key, "%s.Underline", fontName);
     count = sizeof(buffer);
     if(!RegQueryValueExA(hkey, key, 0, &type, buffer, &count))
-	font->logfont.lfUnderline = get_bool(buffer, defUnderline);
+        lf.lfUnderline = get_bool(buffer);
 
     sprintf(key, "%s.StrikeOut", fontName);
     count = sizeof(buffer);
     if(!RegQueryValueExA(hkey, key, 0, &type, buffer, &count))
-	font->logfont.lfStrikeOut = get_bool(buffer, defStrikeOut);
-
-    RegCloseKey(hkey);
+        lf.lfStrikeOut = get_bool(buffer);
+    return CreateFontIndirectW( &lf );
 }
 
 
 #define TRACE_SEC(handle,text) \
    TRACE("(%04x): " text " %ld\n", (handle), GDI_level.crst.RecursionCount)
 
+
 /***********************************************************************
  *           GDI_Init
  *
@@ -282,30 +151,57 @@
  */
 BOOL GDI_Init(void)
 {
-    HPALETTE16 hpalette;
     HINSTANCE16 instance;
+    HKEY hkey;
+    GDIOBJHDR *ptr;
+    int i;
+
+    if (RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\Tweak.Fonts", &hkey))
+        hkey = 0;
 
     /* create GDI heap */
     if ((instance = LoadLibrary16( "GDI.EXE" )) < 32) return FALSE;
     GDI_HeapSel = instance | 7;
 
-    /* TWEAK: Initialize font hints */
-    ReadFontInformation("OEMFixed", &OEMFixedFont, 12, 0, 0, 0, 0);
-    ReadFontInformation("AnsiFixed", &AnsiFixedFont, 12, 0, 0, 0, 0);
-    ReadFontInformation("AnsiVar", &AnsiVarFont, 12, 0, 0, 0, 0);
-    ReadFontInformation("System", &SystemFont, 16, 0, 0, 0, 0);
-    ReadFontInformation("DeviceDefault", &DeviceDefaultFont, 16, 0, 0, 0, 0);
-    ReadFontInformation("SystemFixed", &SystemFixedFont, 16, 0, 0, 0, 0);
-    ReadFontInformation("DefaultGui", &DefaultGuiFont, -11, 0, 0, 0, 0);
+    /* create stock objects */
+    stock_objects[WHITE_BRUSH]  = CreateBrushIndirect( &WhiteBrush );
+    stock_objects[LTGRAY_BRUSH] = CreateBrushIndirect( &LtGrayBrush );
+    stock_objects[GRAY_BRUSH]   = CreateBrushIndirect( &GrayBrush );
+    stock_objects[DKGRAY_BRUSH] = CreateBrushIndirect( &DkGrayBrush );
+    stock_objects[BLACK_BRUSH]  = CreateBrushIndirect( &BlackBrush );
+    stock_objects[NULL_BRUSH]   = CreateBrushIndirect( &NullBrush );
 
-    /* Create default palette */
+    stock_objects[WHITE_PEN]    = CreatePenIndirect( &WhitePen );
+    stock_objects[BLACK_PEN]    = CreatePenIndirect( &BlackPen );
+    stock_objects[NULL_PEN]     = CreatePenIndirect( &NullPen );
 
-    /* DR well *this* palette can't be moveable (?) */
-    hpalette = PALETTE_Init();
-    if( !hpalette ) return FALSE;
-    StockObjects[DEFAULT_PALETTE] = (GDIOBJHDR *)LOCAL_Lock( GDI_HeapSel, hpalette );
+    stock_objects[DEFAULT_PALETTE] = PALETTE_Init();
+    stock_objects[DEFAULT_BITMAP]  = CreateBitmap( 1, 1, 1, 1, NULL );
 
-    hPseudoStockBitmap = CreateBitmap( 1, 1, 1, 1, NULL ); 
+    stock_objects[OEM_FIXED_FONT]      = create_stock_font( "OEMFixed", &OEMFixedFont, hkey );
+    stock_objects[ANSI_FIXED_FONT]     = create_stock_font( "AnsiFixed", &AnsiFixedFont, hkey );
+    stock_objects[ANSI_VAR_FONT]       = create_stock_font( "AnsiVar", &AnsiVarFont, hkey );
+    stock_objects[SYSTEM_FONT]         = create_stock_font( "System", &SystemFont, hkey );
+    stock_objects[DEVICE_DEFAULT_FONT] = create_stock_font( "DeviceDefault", &DeviceDefaultFont, hkey );
+    stock_objects[SYSTEM_FIXED_FONT]   = create_stock_font( "SystemFixed", &SystemFixedFont, hkey );
+    stock_objects[DEFAULT_GUI_FONT]    = create_stock_font( "DefaultGui", &DefaultGuiFont, hkey );
+
+
+    /* clear the NOSYSTEM bit on all stock objects*/
+    for (i = 0; i < NB_STOCK_OBJECTS; i++)
+    {
+        if (!stock_objects[i])
+        {
+            if (i == 9) continue;  /* there's no stock object 9 */
+            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] );
+    }
+
+    if (hkey) RegCloseKey( hkey );
     return TRUE;
 }
 
@@ -415,23 +311,19 @@
 {
     GDIOBJHDR *object = ptr;
 
-    /* can't free stock objects */
-    if (handle < FIRST_STOCK_HANDLE)
+    object->wMagic = 0;  /* Mark it as invalid */
+    if (handle & 2)  /* GDI heap handle */
     {
-        object->wMagic = 0;  /* Mark it as invalid */
-        if (handle & 2)  /* GDI heap handle */
+        LOCAL_Unlock( GDI_HeapSel, handle );
+        LOCAL_Free( GDI_HeapSel, handle );
+    }
+    else  /* large heap handle */
+    {
+        int i = (handle >> 2) - FIRST_LARGE_HANDLE;
+        if (i >= 0 && large_handles[i])
         {
-            LOCAL_Unlock( GDI_HeapSel, handle );
-            LOCAL_Free( GDI_HeapSel, handle );
-        }
-        else  /* large heap handle */
-        {
-            int i = (handle >> 2) - FIRST_LARGE_HANDLE;
-            if (i >= 0 && large_handles[i])
-            {
-                HeapFree( GetProcessHeap(), 0, large_handles[i] );
-                large_handles[i] = NULL;
-            }
+            HeapFree( GetProcessHeap(), 0, large_handles[i] );
+            large_handles[i] = NULL;
         }
     }
     TRACE_SEC( handle, "leave" );
@@ -453,17 +345,10 @@
 
     _EnterSysLevel( &GDI_level );
 
-    if (handle >= FIRST_STOCK_HANDLE)
-    {
-        if (handle <= LAST_STOCK_HANDLE) ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
-        if (ptr && (magic != MAGIC_DONTCARE)
-	&& (GDIMAGIC(ptr->wMagic) != magic)) ptr = NULL;
-    }
-    else if (handle & 2)  /* GDI heap handle */
+    if (handle & 2)  /* GDI heap handle */
     {
         ptr = (GDIOBJHDR *)LOCAL_Lock( GDI_HeapSel, handle );
-        if (ptr &&
-	(magic != MAGIC_DONTCARE) && (GDIMAGIC(ptr->wMagic) != magic))
+        if (ptr && (magic != MAGIC_DONTCARE) && (GDIMAGIC(ptr->wMagic) != magic))
         {
             LOCAL_Unlock( GDI_HeapSel, handle );
             ptr = NULL;
@@ -496,7 +381,7 @@
  */
 void GDI_ReleaseObj( HGDIOBJ handle )
 {
-    if (handle < FIRST_STOCK_HANDLE && (handle & 2)) LOCAL_Unlock( GDI_HeapSel, handle );
+    if (handle & 2) LOCAL_Unlock( GDI_HeapSel, handle );
     TRACE_SEC( handle, "leave" );
     _LeaveSysLevel( &GDI_level );
 }
@@ -530,12 +415,7 @@
 
     GDIOBJHDR * header;
     if (HIWORD(obj)) return FALSE;
-    if ((obj >= FIRST_STOCK_HANDLE) && (obj <= LAST_STOCK_HANDLE)) {
-	TRACE("Preserving Stock object %04x\n", obj );
-	/* NOTE: No GDI_Release is necessary */
-        return TRUE;
-    }
-    if (obj == hPseudoStockBitmap) return TRUE;
+
     if (!(header = GDI_GetObjPtr( obj, MAGIC_DONTCARE ))) return FALSE;
 
     if (!(header->wMagic & OBJECT_NOSYSTEM)
@@ -587,8 +467,7 @@
 {
     HGDIOBJ ret;
     if ((obj < 0) || (obj >= NB_STOCK_OBJECTS)) return 0;
-    if (!StockObjects[obj]) return 0;
-    ret = (HGDIOBJ16)(FIRST_STOCK_HANDLE + obj);
+    ret = stock_objects[obj];
     TRACE("returning %4x\n", ret );
     return ret;
 }