* GDI functions
*
* Copyright 1993 Alexandre Julliard
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
+#include <assert.h>
#include <stdlib.h>
+#include <stdarg.h>
#include <stdio.h>
-#include "bitmap.h"
-#include "brush.h"
-#include "dc.h"
-#include "font.h"
-#include "heap.h"
-#include "options.h"
-#include "palette.h"
-#include "pen.h"
-#include "region.h"
-#include "debugtools.h"
-#include "gdi.h"
-#include "tweak.h"
#include "windef.h"
+#include "winbase.h"
#include "wingdi.h"
-#include "winuser.h"
+#include "winreg.h"
+#include "winerror.h"
+
+#include "local.h"
+#include "gdi.h"
+#include "gdi_private.h"
+#include "wine/debug.h"
-DEFAULT_DEBUG_CHANNEL(gdi)
+WINE_DEFAULT_DEBUG_CHANNEL(gdi);
-/**********************************************************************/
+#define HGDIOBJ_32(h16) ((HGDIOBJ)(ULONG_PTR)(h16))
-GDI_DRIVER *GDI_Driver = NULL;
+#define GDI_HEAP_SIZE 0xffe0
/***********************************************************************
- * GDI stock objects
+ * GDI stock objects
*/
-static BRUSHOBJ WhiteBrush =
-{
- { 0, BRUSH_MAGIC, 1 }, /* header */
- { BS_SOLID, RGB(255,255,255), 0 } /* logbrush */
-};
-
-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 */
-};
+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 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 */
-};
+/* 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 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 */
-};
+/* See HatchBrushes in x11drv for the HS_DIAGCROSS+1 hack */
+static const LOGBRUSH DkGrayBrush = { BS_HATCHED, RGB(0,0,0), (HS_DIAGCROSS+1) };
-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 LOGBRUSH DCBrush = { BS_SOLID, RGB(255,255,255), 0 };
+static const LOGPEN DCPen = { PS_SOLID, { 0, 0 }, RGB(0,0,0) };
-static PENOBJ WhitePen =
-{
- { 0, PEN_MAGIC, 1 }, /* header */
- { PS_SOLID, { 1, 0 }, RGB(255,255,255) } /* logpen */
-};
+/* reserve one extra entry for the stock default bitmap */
+/* this is what Windows does too */
+#define NB_STOCK_OBJECTS (STOCK_LAST+2)
-static PENOBJ BlackPen =
-{
- { 0, PEN_MAGIC, 1 }, /* header */
- { PS_SOLID, { 1, 0 }, RGB(0,0,0) } /* logpen */
-};
+static HGDIOBJ stock_objects[NB_STOCK_OBJECTS];
-static PENOBJ NullPen =
+static SYSLEVEL GDI_level;
+static CRITICAL_SECTION_DEBUG critsect_debug =
{
- { 0, PEN_MAGIC, 1 }, /* header */
- { PS_NULL, { 1, 0 }, 0 } /* logpen */
+ 0, 0, &GDI_level.crst,
+ { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
+ 0, 0, { 0, (DWORD)(__FILE__ ": GDI_level") }
};
+static SYSLEVEL GDI_level = { { &critsect_debug, -1, 0, 0, 0, 0 }, 3 };
-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, "" }
-};
-/* Filler to make the location counter dword aligned again. This is necessary
- since (a) FONTOBJ is packed, (b) gcc places initialised variables in the code
- segment, and (c) Solaris assembler is stupid. */
-static UINT16 align_OEMFixedFont = 1;
+static WORD GDI_HeapSel;
-static FONTOBJ AnsiFixedFont =
+inline static BOOL get_bool(char *buffer)
{
- { 0, FONT_MAGIC, 1 }, /* header */
- { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
- 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" }
-};
-static UINT16 align_AnsiFixedFont = 1;
+ return (buffer[0] == 'y' || buffer[0] == 'Y' ||
+ buffer[0] == 't' || buffer[0] == 'T' ||
+ buffer[0] == '1');
+}
-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, "MS Sans Serif" }
-};
-static UINT16 align_AnsiVarFont = 1;
-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, "System" }
-};
-static UINT16 align_SystemFont = 1;
+/****************************************************************************
+ *
+ * language-independent stock fonts
+ *
+ */
-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, "" }
-};
-static UINT16 align_DeviceDefaultFont = 1;
+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 FONTOBJ SystemFixedFont =
+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 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'} };
+
+/******************************************************************************
+ *
+ * language-dependent stock fonts
+ *
+ * 'ANSI' charset and 'DEFAULT' charset is not same.
+ * The chars in CP_ACP should be drawn with 'DEFAULT' charset.
+ * 'ANSI' charset seems to be identical with ISO-8859-1.
+ * 'DEFAULT' charset is a language-dependent charset.
+ *
+ * 'System' font seems to be an alias for language-dependent font.
+ */
+
+/*
+ * language-dependenet stock fonts for all known charsets
+ * please see TranslateCharsetInfo (objects/font.c) and
+ * CharsetBindingInfo (graphics/x11drv/xfont.c),
+ * and modify entries for your language if needed.
+ */
+struct DefaultFontInfo
{
- { 0, FONT_MAGIC, 1 }, /* header */
- { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
- 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" }
+ UINT charset;
+ LOGFONTW SystemFont;
+ LOGFONTW DeviceDefaultFont;
+ LOGFONTW SystemFixedFont;
+ LOGFONTW DefaultGuiFont;
};
-static UINT16 align_SystemFixedFont = 1;
-/* FIXME: Is this correct? */
-static FONTOBJ DefaultGuiFont =
+static const struct DefaultFontInfo default_fonts[] =
{
- { 0, FONT_MAGIC, 1 }, /* header */
- { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
- 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "MS Sans Serif" }
+ { ANSI_CHARSET,
+ { /* System */
+ 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'}
+ },
+ { /* Device Default */
+ 16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
+ 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
+ {'\0'}
+ },
+ { /* System Fixed */
+ 16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
+ 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN,
+ {'\0'}
+ },
+ { /* 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'}
+ },
+ },
+ { EASTEUROPE_CHARSET,
+ { /* System */
+ 16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, EASTEUROPE_CHARSET,
+ 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
+ {'S','y','s','t','e','m','\0'}
+ },
+ { /* Device Default */
+ 16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, EASTEUROPE_CHARSET,
+ 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
+ {'\0'}
+ },
+ { /* System Fixed */
+ 16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, EASTEUROPE_CHARSET,
+ 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN,
+ {'\0'}
+ },
+ { /* DefaultGuiFont */
+ -11, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, EASTEUROPE_CHARSET,
+ 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
+ {'M','S',' ','S','a','n','s',' ','S','e','r','i','f','\0'}
+ },
+ },
+ { RUSSIAN_CHARSET,
+ { /* System */
+ 16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, RUSSIAN_CHARSET,
+ 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
+ {'S','y','s','t','e','m','\0'}
+ },
+ { /* Device Default */
+ 16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, RUSSIAN_CHARSET,
+ 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
+ {'\0'}
+ },
+ { /* System Fixed */
+ 16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, RUSSIAN_CHARSET,
+ 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN,
+ {'\0'}
+ },
+ { /* DefaultGuiFont */
+ -11, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, RUSSIAN_CHARSET,
+ 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
+ {'M','S',' ','S','a','n','s',' ','S','e','r','i','f','\0'}
+ },
+ },
+ { GREEK_CHARSET,
+ { /* System */
+ 16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, GREEK_CHARSET,
+ 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
+ {'S','y','s','t','e','m','\0'}
+ },
+ { /* Device Default */
+ 16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, GREEK_CHARSET,
+ 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
+ {'\0'}
+ },
+ { /* System Fixed */
+ 16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, GREEK_CHARSET,
+ 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN,
+ {'\0'}
+ },
+ { /* DefaultGuiFont */
+ -11, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, GREEK_CHARSET,
+ 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
+ {'M','S',' ','S','a','n','s',' ','S','e','r','i','f','\0'}
+ },
+ },
+ { TURKISH_CHARSET,
+ { /* System */
+ 16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, TURKISH_CHARSET,
+ 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
+ {'S','y','s','t','e','m','\0'}
+ },
+ { /* Device Default */
+ 16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, TURKISH_CHARSET,
+ 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
+ {'\0'}
+ },
+ { /* System Fixed */
+ 16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, TURKISH_CHARSET,
+ 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN,
+ {'\0'}
+ },
+ { /* DefaultGuiFont */
+ -11, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, TURKISH_CHARSET,
+ 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
+ {'M','S',' ','S','a','n','s',' ','S','e','r','i','f','\0'}
+ },
+ },
+ { HEBREW_CHARSET,
+ { /* System */
+ 16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, HEBREW_CHARSET,
+ 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
+ {'S','y','s','t','e','m','\0'}
+ },
+ { /* Device Default */
+ 16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, HEBREW_CHARSET,
+ 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
+ {'\0'}
+ },
+ { /* System Fixed */
+ 16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, HEBREW_CHARSET,
+ 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN,
+ {'\0'}
+ },
+ { /* DefaultGuiFont */
+ -11, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, HEBREW_CHARSET,
+ 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
+ {'M','S',' ','S','a','n','s',' ','S','e','r','i','f','\0'}
+ },
+ },
+ { ARABIC_CHARSET,
+ { /* System */
+ 16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ARABIC_CHARSET,
+ 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
+ {'S','y','s','t','e','m','\0'}
+ },
+ { /* Device Default */
+ 16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ARABIC_CHARSET,
+ 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
+ {'\0'}
+ },
+ { /* System Fixed */
+ 16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ARABIC_CHARSET,
+ 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN,
+ {'\0'}
+ },
+ { /* DefaultGuiFont */
+ -11, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ARABIC_CHARSET,
+ 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
+ {'M','S',' ','S','a','n','s',' ','S','e','r','i','f','\0'}
+ },
+ },
+ { BALTIC_CHARSET,
+ { /* System */
+ 16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, BALTIC_CHARSET,
+ 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
+ {'S','y','s','t','e','m','\0'}
+ },
+ { /* Device Default */
+ 16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, BALTIC_CHARSET,
+ 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
+ {'\0'}
+ },
+ { /* System Fixed */
+ 16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, BALTIC_CHARSET,
+ 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN,
+ {'\0'}
+ },
+ { /* DefaultGuiFont */
+ -11, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, BALTIC_CHARSET,
+ 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
+ {'M','S',' ','S','a','n','s',' ','S','e','r','i','f','\0'}
+ },
+ },
+ { THAI_CHARSET,
+ { /* System */
+ 16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, THAI_CHARSET,
+ 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
+ {'S','y','s','t','e','m','\0'}
+ },
+ { /* Device Default */
+ 16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, THAI_CHARSET,
+ 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
+ {'\0'}
+ },
+ { /* System Fixed */
+ 16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, THAI_CHARSET,
+ 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN,
+ {'\0'}
+ },
+ { /* DefaultGuiFont */
+ -11, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, THAI_CHARSET,
+ 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
+ {'M','S',' ','S','a','n','s',' ','S','e','r','i','f','\0'}
+ },
+ },
+ { SHIFTJIS_CHARSET,
+ { /* System */
+ 16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, SHIFTJIS_CHARSET,
+ 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
+ {'S','y','s','t','e','m','\0'}
+ },
+ { /* Device Default */
+ 16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, SHIFTJIS_CHARSET,
+ 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
+ {'\0'}
+ },
+ { /* System Fixed */
+ 16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, SHIFTJIS_CHARSET,
+ 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN,
+ {'\0'}
+ },
+ { /* DefaultGuiFont */
+ -11, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, SHIFTJIS_CHARSET,
+ 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
+ {'M','S',' ','U','I',' ','G','o','t','h','i','c','\0'}
+ },
+ },
+ { GB2312_CHARSET,
+ { /* System */
+ 16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, GB2312_CHARSET,
+ 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
+ {'S','y','s','t','e','m','\0'}
+ },
+ { /* Device Default */
+ 16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, GB2312_CHARSET,
+ 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
+ {'\0'}
+ },
+ { /* System Fixed */
+ 16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, GB2312_CHARSET,
+ 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN,
+ {'\0'}
+ },
+ { /* DefaultGuiFont */
+ -11, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, GB2312_CHARSET,
+ 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
+ {'M','S',' ','S','o','n','g','\0'} /* FIXME: Is this correct? */
+ },
+ },
+ { HANGEUL_CHARSET,
+ { /* System */
+ 16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, HANGEUL_CHARSET,
+ 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
+ {'S','y','s','t','e','m','\0'}
+ },
+ { /* Device Default */
+ 16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, HANGEUL_CHARSET,
+ 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
+ {'\0'}
+ },
+ { /* System Fixed */
+ 16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, HANGEUL_CHARSET,
+ 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN,
+ {'\0'}
+ },
+ { /* DefaultGuiFont */
+ -11, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, HANGEUL_CHARSET,
+ 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
+ {'G','u','l','i','m'},
+ },
+ },
+ { CHINESEBIG5_CHARSET,
+ { /* System */
+ 16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, CHINESEBIG5_CHARSET,
+ 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
+ {'S','y','s','t','e','m','\0'}
+ },
+ { /* Device Default */
+ 16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, CHINESEBIG5_CHARSET,
+ 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
+ {'\0'}
+ },
+ { /* System Fixed */
+ 16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, CHINESEBIG5_CHARSET,
+ 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN,
+ {'\0'}
+ },
+ { /* DefaultGuiFont */
+ -11, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, CHINESEBIG5_CHARSET,
+ 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
+ {'\0'} /* FIXME - what is the native font??? */
+ },
+ },
+ { JOHAB_CHARSET,
+ { /* System */
+ 16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, JOHAB_CHARSET,
+ 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
+ {'S','y','s','t','e','m','\0'}
+ },
+ { /* Device Default */
+ 16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, JOHAB_CHARSET,
+ 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
+ {'\0'}
+ },
+ { /* System Fixed */
+ 16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, JOHAB_CHARSET,
+ 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN,
+ {'\0'}
+ },
+ { /* DefaultGuiFont */
+ -11, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, JOHAB_CHARSET,
+ 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
+ {'M','S',' ','M','i','n','g','l','i','u','\0'} /* FIXME: Is this correct? */
+ },
+ },
};
-static UINT16 align_DefaultGuiFont = 1;
-static GDIOBJHDR * StockObjects[NB_STOCK_OBJECTS] =
+/******************************************************************************
+ * get_default_fonts
+ */
+static const struct DefaultFontInfo* get_default_fonts(UINT charset)
{
- (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
-};
+ int n;
+
+ for(n=0;n<(sizeof(default_fonts)/sizeof(default_fonts[0]));n++)
+ {
+ if ( default_fonts[n].charset == charset )
+ return &default_fonts[n];
+ }
+
+ FIXME( "unhandled charset 0x%08x - use ANSI_CHARSET for default stock objects\n", charset );
+ return &default_fonts[0];
+}
-HBITMAP hPseudoStockBitmap; /* 1x1 bitmap for memory DCs */
/******************************************************************************
+ * get_default_charset (internal)
*
- * 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 )
+ * get the language-dependent charset that can handle CP_ACP correctly.
+ */
+static UINT get_default_charset( void )
{
+ CHARSETINFO csi;
+ UINT uACP;
+
+ uACP = GetACP();
+ csi.ciCharset = ANSI_CHARSET;
+ if ( ! TranslateCharsetInfo( (LPDWORD)uACP, &csi, TCI_SRCCODEPAGE ) )
+ {
+ FIXME( "unhandled codepage %u - use ANSI_CHARSET for default stock objects\n", uACP );
+ return ANSI_CHARSET;
+ }
+
+ return csi.ciCharset;
+}
+
+
+/******************************************************************************
+ * 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];
+ DWORD type, count;
+
+ if (!hkey) return CreateFontIndirectW( font );
- /* In order for the stock fonts to be independent of
- * mapping mode, the height (& width) must be 0
- */
+ lf = *font;
sprintf(key, "%s.Height", fontName);
- font->logfont.lfHeight =
- PROFILE_GetWineIniInt("Tweak.Fonts", key, defHeight);
+ count = sizeof(buffer);
+ if(!RegQueryValueExA(hkey, key, 0, &type, buffer, &count))
+ lf.lfHeight = atoi(buffer);
sprintf(key, "%s.Bold", fontName);
- font->logfont.lfWeight =
- (PROFILE_GetWineIniBool("Tweak.Fonts", key, defBold)) ?
- FW_BOLD : FW_NORMAL;
+ count = sizeof(buffer);
+ if(!RegQueryValueExA(hkey, key, 0, &type, buffer, &count))
+ lf.lfWeight = get_bool(buffer) ? FW_BOLD : FW_NORMAL;
sprintf(key, "%s.Italic", fontName);
- font->logfont.lfItalic =
- PROFILE_GetWineIniBool("Tweak.Fonts", key, defItalic);
+ count = sizeof(buffer);
+ if(!RegQueryValueExA(hkey, key, 0, &type, buffer, &count))
+ lf.lfItalic = get_bool(buffer);
sprintf(key, "%s.Underline", fontName);
- font->logfont.lfUnderline =
- PROFILE_GetWineIniBool("Tweak.Fonts", key, defUnderline);
+ count = sizeof(buffer);
+ if(!RegQueryValueExA(hkey, key, 0, &type, buffer, &count))
+ lf.lfUnderline = get_bool(buffer);
sprintf(key, "%s.StrikeOut", fontName);
- font->logfont.lfStrikeOut =
- PROFILE_GetWineIniBool("Tweak.Fonts", key, defStrikeOut);
-
- return;
+ count = sizeof(buffer);
+ if(!RegQueryValueExA(hkey, key, 0, &type, buffer, &count))
+ lf.lfStrikeOut = get_bool(buffer);
+ return CreateFontIndirectW( &lf );
}
-/***********************************************************************
- * Because the stock fonts have their structure initialized with
- * a height of 0 to keep them independent of mapping mode, simply
- * returning the LOGFONT as is will not work correctly.
- * These "FixStockFontSizeXXX()" methods will get the correct
- * size for the fonts.
- */
-static void GetFontMetrics(HFONT handle, LPTEXTMETRICA lptm)
-{
- HDC hdc;
- HFONT hOldFont;
-
- hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
-
- hOldFont = (HFONT)SelectObject(hdc, handle);
- GetTextMetricsA(hdc, lptm);
+#define TRACE_SEC(handle,text) \
+ TRACE("(%p): " text " %ld\n", (handle), GDI_level.crst.RecursionCount)
- SelectObject(hdc, hOldFont);
- DeleteDC(hdc);
-}
-
-static inline void FixStockFontSize16(
- HFONT handle,
- INT16 count,
- LPVOID buffer)
+/***********************************************************************
+ * inc_ref_count
+ *
+ * Increment the reference count of a GDI object.
+ */
+inline static void inc_ref_count( HGDIOBJ handle )
{
- TEXTMETRICA tm;
- LOGFONT16* pLogFont = (LOGFONT16*)buffer;
-
- /*
- * Was the lfHeight field copied (it's the first field)?
- * If it was and it was null, replace the height.
- */
- if ( (count >= 2*sizeof(INT16)) &&
- (pLogFont->lfHeight == 0) )
- {
- GetFontMetrics(handle, &tm);
-
- pLogFont->lfHeight = tm.tmHeight;
- pLogFont->lfWidth = tm.tmAveCharWidth;
- }
-}
+ GDIOBJHDR *header;
-static inline void FixStockFontSizeA(
- HFONT handle,
- INT count,
- LPVOID buffer)
-{
- TEXTMETRICA tm;
- LOGFONTA* pLogFont = (LOGFONTA*)buffer;
-
- /*
- * Was the lfHeight field copied (it's the first field)?
- * If it was and it was null, replace the height.
- */
- if ( (count >= 2*sizeof(INT)) &&
- (pLogFont->lfHeight == 0) )
- {
- GetFontMetrics(handle, &tm);
-
- pLogFont->lfHeight = tm.tmHeight;
- pLogFont->lfWidth = tm.tmAveCharWidth;
- }
+ if ((header = GDI_GetObjPtr( handle, MAGIC_DONTCARE )))
+ {
+ header->dwCount++;
+ GDI_ReleaseObj( handle );
+ }
}
-/**
- * Since the LOGFONTA and LOGFONTW structures are identical up to the
- * lfHeight member (the one of interest in this case) we simply define
- * the W version as the A version.
+
+/***********************************************************************
+ * dec_ref_count
+ *
+ * Decrement the reference count of a GDI object.
*/
-#define FixStockFontSizeW FixStockFontSizeA
+inline static void dec_ref_count( HGDIOBJ handle )
+{
+ GDIOBJHDR *header;
+ if ((header = GDI_GetObjPtr( handle, MAGIC_DONTCARE )))
+ {
+ if (header->dwCount) header->dwCount--;
+ if (header->dwCount != 0x80000000) GDI_ReleaseObj( handle );
+ else
+ {
+ /* handle delayed DeleteObject*/
+ header->dwCount = 0;
+ GDI_ReleaseObj( handle );
+ TRACE( "executing delayed DeleteObject for %p\n", handle );
+ DeleteObject( handle );
+ }
+ }
+}
/***********************************************************************
*/
BOOL GDI_Init(void)
{
- BOOL systemIsBold = (TWEAK_WineLook == WIN31_LOOK);
-
- /* Kill some warnings. */
- (void)align_OEMFixedFont;
- (void)align_AnsiFixedFont;
- (void)align_AnsiVarFont;
- (void)align_SystemFont;
- (void)align_DeviceDefaultFont;
- (void)align_SystemFixedFont;
- (void)align_DefaultGuiFont;
-
- /* TWEAK: Initialize font hints */
- ReadFontInformation("OEMFixed", &OEMFixedFont, 0, 0, 0, 0, 0);
- ReadFontInformation("AnsiFixed", &AnsiFixedFont, 0, 0, 0, 0, 0);
- ReadFontInformation("AnsiVar", &AnsiVarFont, 0, 0, 0, 0, 0);
- ReadFontInformation("System", &SystemFont, 0, systemIsBold, 0, 0, 0);
- ReadFontInformation("DeviceDefault", &DeviceDefaultFont, 0, 0, 0, 0, 0);
- ReadFontInformation("SystemFixed", &SystemFixedFont, 0, systemIsBold, 0, 0, 0);
- ReadFontInformation("DefaultGui", &DefaultGuiFont, 0, 0, 0, 0, 0);
-
- /* Create default palette */
-
- /* DR well *this* palette can't be moveable (?) */
+ HINSTANCE16 instance;
+ HKEY hkey;
+ GDIOBJHDR *ptr;
+ const struct DefaultFontInfo* deffonts;
+ 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) GDI_HeapSel = instance | 7;
+
+ /* 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 );
+
+ stock_objects[WHITE_PEN] = CreatePenIndirect( &WhitePen );
+ stock_objects[BLACK_PEN] = CreatePenIndirect( &BlackPen );
+ stock_objects[NULL_PEN] = CreatePenIndirect( &NullPen );
+
+ stock_objects[DEFAULT_PALETTE] = PALETTE_Init();
+ stock_objects[DEFAULT_BITMAP] = CreateBitmap( 1, 1, 1, 1, NULL );
+
+ /* language-independent stock fonts */
+ 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 );
+
+ /* language-dependent stock fonts */
+ deffonts = get_default_fonts(get_default_charset());
+ stock_objects[SYSTEM_FONT] = create_stock_font( "System", &deffonts->SystemFont, hkey );
+ stock_objects[DEVICE_DEFAULT_FONT] = create_stock_font( "DeviceDefault", &deffonts->DeviceDefaultFont, hkey );
+ stock_objects[SYSTEM_FIXED_FONT] = create_stock_font( "SystemFixed", &deffonts->SystemFixedFont, hkey );
+ stock_objects[DEFAULT_GUI_FONT] = create_stock_font( "DefaultGui", &deffonts->DefaultGuiFont, hkey );
+
+ stock_objects[DC_BRUSH] = CreateBrushIndirect( &DCBrush );
+ stock_objects[DC_PEN] = CreatePenIndirect( &DCPen );
+
+ /* clear the NOSYSTEM bit on all stock objects*/
+ for (i = 0; i < NB_STOCK_OBJECTS; i++)
{
- HPALETTE16 hpalette = PALETTE_Init();
- if( !hpalette )
- return FALSE;
- StockObjects[DEFAULT_PALETTE] = (GDIOBJHDR *)GDI_HEAP_LOCK( hpalette );
+ 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] );
}
- hPseudoStockBitmap = CreateBitmap( 1, 1, 1, 1, NULL );
+ if (hkey) RegCloseKey( hkey );
+
+ WineEngInit();
+
return TRUE;
}
+#define FIRST_LARGE_HANDLE 16
+#define MAX_LARGE_HANDLES ((GDI_HEAP_SIZE >> 2) - FIRST_LARGE_HANDLE)
+static GDIOBJHDR *large_handles[MAX_LARGE_HANDLES];
+static int next_large_handle;
+
+/***********************************************************************
+ * alloc_large_heap
+ *
+ * Allocate a GDI handle from the large heap. Helper for GDI_AllocObject
+ */
+inline static GDIOBJHDR *alloc_large_heap( WORD size, HGDIOBJ *handle )
+{
+ int i;
+ GDIOBJHDR *obj;
+
+ for (i = next_large_handle + 1; i < MAX_LARGE_HANDLES; i++)
+ if (!large_handles[i]) goto found;
+ for (i = 0; i <= next_large_handle; i++)
+ if (!large_handles[i]) goto found;
+ *handle = 0;
+ return NULL;
+
+ found:
+ if ((obj = HeapAlloc( GetProcessHeap(), 0, size )))
+ {
+ large_handles[i] = obj;
+ *handle = (HGDIOBJ)(ULONG_PTR)((i + FIRST_LARGE_HANDLE) << 2);
+ next_large_handle = i;
+ }
+ return obj;
+}
+
/***********************************************************************
* GDI_AllocObject
*/
-HGDIOBJ GDI_AllocObject( WORD size, WORD magic )
+void *GDI_AllocObject( WORD size, WORD magic, HGDIOBJ *handle, const struct gdi_obj_funcs *funcs )
{
- static DWORD count = 0;
- GDIOBJHDR * obj;
- HGDIOBJ16 handle;
- if ( magic == DC_MAGIC || magic == METAFILE_DC_MAGIC )
- handle = GDI_HEAP_ALLOC( size );
- else
- handle = GDI_HEAP_ALLOC_MOVEABLE( size );
- if (!handle) return 0;
- obj = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
+ GDIOBJHDR *obj;
+ HLOCAL16 hlocal;
+
+ _EnterSysLevel( &GDI_level );
+ switch(magic)
+ {
+ default:
+ if (GDI_HeapSel)
+ {
+ if (!(hlocal = LOCAL_Alloc( GDI_HeapSel, LMEM_MOVEABLE, size ))) goto error;
+ assert( hlocal & 2 );
+ obj = (GDIOBJHDR *)LOCAL_Lock( GDI_HeapSel, hlocal );
+ *handle = (HGDIOBJ)(ULONG_PTR)hlocal;
+ break;
+ }
+ /* fall through */
+ case DC_MAGIC:
+ case DISABLED_DC_MAGIC:
+ case META_DC_MAGIC:
+ case METAFILE_MAGIC:
+ case METAFILE_DC_MAGIC:
+ case ENHMETAFILE_MAGIC:
+ case ENHMETAFILE_DC_MAGIC:
+ case MEMORY_DC_MAGIC:
+ case BITMAP_MAGIC:
+ case PALETTE_MAGIC:
+ if (!(obj = alloc_large_heap( size, handle ))) goto error;
+ break;
+ }
+
obj->hNext = 0;
- obj->wMagic = magic;
- obj->dwCount = ++count;
- GDI_HEAP_UNLOCK( handle );
- return handle;
+ obj->wMagic = magic|OBJECT_NOSYSTEM;
+ obj->dwCount = 0;
+ obj->funcs = funcs;
+ obj->hdcs = NULL;
+
+ TRACE_SEC( *handle, "enter" );
+ return obj;
+
+error:
+ _LeaveSysLevel( &GDI_level );
+ *handle = 0;
+ return NULL;
+}
+
+
+/***********************************************************************
+ * GDI_ReallocObject
+ *
+ * The object ptr must have been obtained with GDI_GetObjPtr.
+ * The new pointer must be released with GDI_ReleaseObj.
+ */
+void *GDI_ReallocObject( WORD size, HGDIOBJ handle, void *object )
+{
+ HGDIOBJ new_handle;
+
+ if ((UINT_PTR)handle & 2) /* GDI heap handle */
+ {
+ HLOCAL16 h = LOWORD(handle);
+ LOCAL_Unlock( GDI_HeapSel, h );
+ if ((new_handle = (HGDIOBJ)(ULONG_PTR)LOCAL_ReAlloc( GDI_HeapSel, h, size, LMEM_MOVEABLE )))
+ {
+ assert( new_handle == handle ); /* moveable handle cannot change */
+ return LOCAL_Lock( GDI_HeapSel, h );
+ }
+ }
+ else
+ {
+ int i = ((ULONG_PTR)handle >> 2) - FIRST_LARGE_HANDLE;
+ if (i >= 0 && i < MAX_LARGE_HANDLES && large_handles[i])
+ {
+ void *new_ptr = HeapReAlloc( GetProcessHeap(), 0, large_handles[i], size );
+ if (new_ptr)
+ {
+ large_handles[i] = new_ptr;
+ return new_ptr;
+ }
+ }
+ else ERR( "Invalid handle %p\n", handle );
+ }
+ TRACE_SEC( handle, "leave" );
+ _LeaveSysLevel( &GDI_level );
+ return NULL;
}
/***********************************************************************
* GDI_FreeObject
*/
-BOOL GDI_FreeObject( HGDIOBJ handle )
+BOOL GDI_FreeObject( HGDIOBJ handle, void *ptr )
{
- GDIOBJHDR * object;
+ GDIOBJHDR *object = ptr;
- /* Can't free stock objects */
- if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
- return TRUE;
-
- object = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
- if (!object) return FALSE;
object->wMagic = 0; /* Mark it as invalid */
-
- /* Free object */
-
- GDI_HEAP_FREE( handle );
+ object->funcs = NULL;
+ if ((UINT_PTR)handle & 2) /* GDI heap handle */
+ {
+ HLOCAL16 h = LOWORD(handle);
+ LOCAL_Unlock( GDI_HeapSel, h );
+ LOCAL_Free( GDI_HeapSel, h );
+ }
+ else /* large heap handle */
+ {
+ int i = ((ULONG_PTR)handle >> 2) - FIRST_LARGE_HANDLE;
+ if (i >= 0 && i < MAX_LARGE_HANDLES && large_handles[i])
+ {
+ HeapFree( GetProcessHeap(), 0, large_handles[i] );
+ large_handles[i] = NULL;
+ }
+ else ERR( "Invalid handle %p\n", handle );
+ }
+ TRACE_SEC( handle, "leave" );
+ _LeaveSysLevel( &GDI_level );
return TRUE;
}
+
/***********************************************************************
* GDI_GetObjPtr
*
* Return a pointer to the GDI object associated to the handle.
* Return NULL if the object has the wrong magic number.
- * Movable GDI objects are locked in memory: it is up to the caller to unlock
- * it after the caller is done with the pointer.
+ * The object must be released with GDI_ReleaseObj.
*/
-GDIOBJHDR * GDI_GetObjPtr( HGDIOBJ handle, WORD magic )
+void *GDI_GetObjPtr( HGDIOBJ handle, WORD magic )
{
- GDIOBJHDR * ptr = NULL;
+ GDIOBJHDR *ptr = NULL;
+
+ _EnterSysLevel( &GDI_level );
- if (handle >= FIRST_STOCK_HANDLE)
+ if ((UINT_PTR)handle & 2) /* GDI heap handle */
{
- if (handle <= LAST_STOCK_HANDLE) ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
+ HLOCAL16 h = LOWORD(handle);
+ ptr = (GDIOBJHDR *)LOCAL_Lock( GDI_HeapSel, h );
+ if (ptr)
+ {
+ if (((magic != MAGIC_DONTCARE) && (GDIMAGIC(ptr->wMagic) != magic)) ||
+ (GDIMAGIC(ptr->wMagic) < FIRST_MAGIC) ||
+ (GDIMAGIC(ptr->wMagic) > LAST_MAGIC))
+ {
+ LOCAL_Unlock( GDI_HeapSel, h );
+ ptr = NULL;
+ }
+ }
+ }
+ else /* large heap handle */
+ {
+ int i = ((UINT_PTR)handle >> 2) - FIRST_LARGE_HANDLE;
+ if (i >= 0 && i < MAX_LARGE_HANDLES)
+ {
+ ptr = large_handles[i];
+ if (ptr && (magic != MAGIC_DONTCARE) && (GDIMAGIC(ptr->wMagic) != magic)) ptr = NULL;
+ }
}
- else
- ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
- if (!ptr) return NULL;
- if ((magic != MAGIC_DONTCARE) && (ptr->wMagic != magic))
+
+ if (!ptr)
{
- GDI_HEAP_UNLOCK( handle );
- return NULL;
+ _LeaveSysLevel( &GDI_level );
+ SetLastError( ERROR_INVALID_HANDLE );
+ WARN( "Invalid handle %p\n", handle );
}
+ else TRACE_SEC( handle, "enter" );
+
return ptr;
}
/***********************************************************************
- * DeleteObject16 (GDI.69)
+ * GDI_ReleaseObj
+ *
*/
-BOOL16 WINAPI DeleteObject16( HGDIOBJ16 obj )
+void GDI_ReleaseObj( HGDIOBJ handle )
{
- return DeleteObject( obj );
+ if ((UINT_PTR)handle & 2) LOCAL_Unlock( GDI_HeapSel, LOWORD(handle) );
+ TRACE_SEC( handle, "leave" );
+ _LeaveSysLevel( &GDI_level );
}
/***********************************************************************
- * DeleteObject32 (GDI32.70)
+ * GDI_CheckNotLock
+ */
+void GDI_CheckNotLock(void)
+{
+ _CheckNotSysLevel( &GDI_level );
+}
+
+
+/***********************************************************************
+ * DeleteObject (GDI32.@)
*/
BOOL WINAPI DeleteObject( HGDIOBJ obj )
{
GDIOBJHDR * header;
if (HIWORD(obj)) return FALSE;
- if ((obj >= FIRST_STOCK_HANDLE) && (obj <= LAST_STOCK_HANDLE))
- return TRUE;
- if (obj == hPseudoStockBitmap) return TRUE;
- if (!(header = (GDIOBJHDR *) GDI_HEAP_LOCK( obj ))) return FALSE;
- TRACE("%04x\n", obj );
+ if (!(header = GDI_GetObjPtr( obj, MAGIC_DONTCARE ))) return FALSE;
- /* Delete object */
+ if (!(header->wMagic & OBJECT_NOSYSTEM)
+ && (header->wMagic >= FIRST_MAGIC) && (header->wMagic <= LAST_MAGIC))
+ {
+ TRACE("Preserving system object %p\n", obj);
+ GDI_ReleaseObj( obj );
+ return TRUE;
+ }
- switch(header->wMagic)
+ while (header->hdcs)
{
- case PEN_MAGIC: return GDI_FreeObject( obj );
- case BRUSH_MAGIC: return BRUSH_DeleteObject( obj, (BRUSHOBJ*)header );
- case FONT_MAGIC: return GDI_FreeObject( obj );
- case PALETTE_MAGIC: return PALETTE_DeleteObject(obj,(PALETTEOBJ*)header);
- case BITMAP_MAGIC: return BITMAP_DeleteObject( obj, (BITMAPOBJ*)header);
- case REGION_MAGIC: return REGION_DeleteObject( obj, (RGNOBJ*)header );
- case DC_MAGIC: return DeleteDC(obj);
- case 0 :
- WARN("Already deleted\n");
- break;
- default:
- WARN("Unknown magic number (%d)\n",header->wMagic);
+ DC *dc = DC_GetDCPtr(header->hdcs->hdc);
+ struct hdc_list *tmp;
+
+ TRACE("hdc %p has interest in %p\n", header->hdcs->hdc, obj);
+ if(dc)
+ {
+ if(dc->funcs->pDeleteObject)
+ dc->funcs->pDeleteObject( dc->physDev, obj );
+ GDI_ReleaseObj( header->hdcs->hdc );
+ }
+ tmp = header->hdcs;
+ header->hdcs = header->hdcs->next;
+ HeapFree(GetProcessHeap(), 0, tmp);
+ }
+
+ if (header->dwCount)
+ {
+ TRACE("delayed for %p because object in use, count %ld\n", obj, header->dwCount );
+ header->dwCount |= 0x80000000; /* mark for delete */
+ GDI_ReleaseObj( obj );
+ return TRUE;
}
+
+ TRACE("%p\n", obj );
+
+ /* Delete object */
+
+ if (header->funcs && header->funcs->pDeleteObject)
+ return header->funcs->pDeleteObject( obj, header );
+
+ GDI_ReleaseObj( obj );
return FALSE;
}
/***********************************************************************
- * GetStockObject16 (GDI.87)
+ * GDI_hdc_using_object
+ *
+ * Call this if the dc requires DeleteObject notification
*/
-HGDIOBJ16 WINAPI GetStockObject16( INT16 obj )
+BOOL GDI_hdc_using_object(HGDIOBJ obj, HDC hdc)
{
- return (HGDIOBJ16)GetStockObject( obj );
+ GDIOBJHDR * header;
+ struct hdc_list **pphdc;
+
+ TRACE("obj %p hdc %p\n", obj, hdc);
+
+ if (!(header = GDI_GetObjPtr( obj, MAGIC_DONTCARE ))) return FALSE;
+
+ if (!(header->wMagic & OBJECT_NOSYSTEM) &&
+ (header->wMagic >= FIRST_MAGIC) && (header->wMagic <= LAST_MAGIC))
+ {
+ GDI_ReleaseObj(obj);
+ return FALSE;
+ }
+
+ for(pphdc = &header->hdcs; *pphdc; pphdc = &(*pphdc)->next)
+ if((*pphdc)->hdc == hdc)
+ break;
+
+ if(!*pphdc) {
+ *pphdc = HeapAlloc(GetProcessHeap(), 0, sizeof(**pphdc));
+ (*pphdc)->hdc = hdc;
+ (*pphdc)->next = NULL;
+ }
+
+ GDI_ReleaseObj(obj);
+ return TRUE;
}
+/***********************************************************************
+ * GDI_hdc_not_using_object
+ *
+ */
+BOOL GDI_hdc_not_using_object(HGDIOBJ obj, HDC hdc)
+{
+ GDIOBJHDR * header;
+ struct hdc_list *phdc, **prev;
+
+ TRACE("obj %p hdc %p\n", obj, hdc);
+
+ if (!(header = GDI_GetObjPtr( obj, MAGIC_DONTCARE ))) return FALSE;
+
+ if (!(header->wMagic & OBJECT_NOSYSTEM) &&
+ (header->wMagic >= FIRST_MAGIC) && (header->wMagic <= LAST_MAGIC))
+ {
+ GDI_ReleaseObj(obj);
+ return FALSE;
+ }
+
+ phdc = header->hdcs;
+ prev = &header->hdcs;
+
+ while(phdc) {
+ if(phdc->hdc == hdc) {
+ *prev = phdc->next;
+ HeapFree(GetProcessHeap(), 0, phdc);
+ phdc = *prev;
+ } else {
+ prev = &phdc->next;
+ phdc = phdc->next;
+ }
+ }
+
+ GDI_ReleaseObj(obj);
+ return TRUE;
+}
/***********************************************************************
- * GetStockObject32 (GDI32.220)
+ * GetStockObject (GDI32.@)
*/
HGDIOBJ WINAPI GetStockObject( INT obj )
{
+ HGDIOBJ ret;
if ((obj < 0) || (obj >= NB_STOCK_OBJECTS)) return 0;
- if (!StockObjects[obj]) return 0;
- TRACE("returning %d\n",
- FIRST_STOCK_HANDLE + obj );
- return (HGDIOBJ16)(FIRST_STOCK_HANDLE + obj);
+ ret = stock_objects[obj];
+ TRACE("returning %p\n", ret );
+ return ret;
}
/***********************************************************************
- * GetObject16 (GDI.82)
+ * GetObject (GDI.82)
*/
-INT16 WINAPI GetObject16( HANDLE16 handle, INT16 count, LPVOID buffer )
+INT16 WINAPI GetObject16( HANDLE16 handle16, INT16 count, LPVOID buffer )
{
GDIOBJHDR * ptr;
+ HGDIOBJ handle = HGDIOBJ_32( handle16 );
INT16 result = 0;
- TRACE("%04x %d %p\n", handle, count, buffer );
+
+ TRACE("%p %d %p\n", handle, count, buffer );
if (!count) return 0;
if (!(ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE ))) return 0;
-
- switch(ptr->wMagic)
- {
- case PEN_MAGIC:
- result = PEN_GetObject16( (PENOBJ *)ptr, count, buffer );
- break;
- case BRUSH_MAGIC:
- result = BRUSH_GetObject16( (BRUSHOBJ *)ptr, count, buffer );
- break;
- case BITMAP_MAGIC:
- result = BITMAP_GetObject16( (BITMAPOBJ *)ptr, count, buffer );
- break;
- case FONT_MAGIC:
- result = FONT_GetObject16( (FONTOBJ *)ptr, count, buffer );
-
- /*
- * Fix the LOGFONT structure for the stock fonts
- */
- if ( (handle >= FIRST_STOCK_HANDLE) &&
- (handle <= LAST_STOCK_HANDLE) )
- FixStockFontSize16(handle, count, buffer);
- break;
- case PALETTE_MAGIC:
- result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer );
- break;
- }
- GDI_HEAP_UNLOCK( handle );
+
+ if (ptr->funcs && ptr->funcs->pGetObject16)
+ result = ptr->funcs->pGetObject16( handle, ptr, count, buffer );
+ else
+ SetLastError( ERROR_INVALID_HANDLE );
+
+ GDI_ReleaseObj( handle );
return result;
}
/***********************************************************************
- * GetObject32A (GDI32.204)
+ * GetObjectA (GDI32.@)
*/
INT WINAPI GetObjectA( HANDLE handle, INT count, LPVOID buffer )
{
GDIOBJHDR * ptr;
INT result = 0;
- TRACE("%08x %d %p\n", handle, count, buffer );
- if (!count) return 0;
+ TRACE("%p %d %p\n", handle, count, buffer );
if (!(ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE ))) return 0;
- switch(ptr->wMagic)
- {
- case PEN_MAGIC:
- result = PEN_GetObject( (PENOBJ *)ptr, count, buffer );
- break;
- case BRUSH_MAGIC:
- result = BRUSH_GetObject( (BRUSHOBJ *)ptr, count, buffer );
- break;
- case BITMAP_MAGIC:
- result = BITMAP_GetObject( (BITMAPOBJ *)ptr, count, buffer );
- break;
- case FONT_MAGIC:
- result = FONT_GetObjectA( (FONTOBJ *)ptr, count, buffer );
-
- /*
- * Fix the LOGFONT structure for the stock fonts
- */
- if ( (handle >= FIRST_STOCK_HANDLE) &&
- (handle <= LAST_STOCK_HANDLE) )
- FixStockFontSizeA(handle, count, buffer);
- break;
- case PALETTE_MAGIC:
- result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer );
- break;
-
- case REGION_MAGIC:
- case DC_MAGIC:
- case DISABLED_DC_MAGIC:
- case META_DC_MAGIC:
- case METAFILE_MAGIC:
- case METAFILE_DC_MAGIC:
- case ENHMETAFILE_MAGIC:
- case ENHMETAFILE_DC_MAGIC:
- FIXME("Magic %04x not implemented\n",
- ptr->wMagic );
- break;
+ if (ptr->funcs && ptr->funcs->pGetObjectA)
+ result = ptr->funcs->pGetObjectA( handle, ptr, count, buffer );
+ else
+ SetLastError( ERROR_INVALID_HANDLE );
- default:
- ERR("Invalid GDI Magic %04x\n", ptr->wMagic);
- return 0;
- }
- GDI_HEAP_UNLOCK( handle );
+ GDI_ReleaseObj( handle );
return result;
}
/***********************************************************************
- * GetObject32W (GDI32.206)
+ * GetObjectW (GDI32.@)
*/
INT WINAPI GetObjectW( HANDLE handle, INT count, LPVOID buffer )
{
GDIOBJHDR * ptr;
INT result = 0;
- TRACE("%08x %d %p\n", handle, count, buffer );
- if (!count) return 0;
+ TRACE("%p %d %p\n", handle, count, buffer );
if (!(ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE ))) return 0;
- switch(ptr->wMagic)
- {
- case PEN_MAGIC:
- result = PEN_GetObject( (PENOBJ *)ptr, count, buffer );
- break;
- case BRUSH_MAGIC:
- result = BRUSH_GetObject( (BRUSHOBJ *)ptr, count, buffer );
- break;
- case BITMAP_MAGIC:
- result = BITMAP_GetObject( (BITMAPOBJ *)ptr, count, buffer );
- break;
- case FONT_MAGIC:
- result = FONT_GetObjectW( (FONTOBJ *)ptr, count, buffer );
-
- /*
- * Fix the LOGFONT structure for the stock fonts
- */
- if ( (handle >= FIRST_STOCK_HANDLE) &&
- (handle <= LAST_STOCK_HANDLE) )
- FixStockFontSizeW(handle, count, buffer);
- break;
- case PALETTE_MAGIC:
- result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer );
- break;
- default:
- FIXME("Magic %04x not implemented\n",
- ptr->wMagic );
- break;
- }
- GDI_HEAP_UNLOCK( handle );
+ if (ptr->funcs && ptr->funcs->pGetObjectW)
+ result = ptr->funcs->pGetObjectW( handle, ptr, count, buffer );
+ else
+ SetLastError( ERROR_INVALID_HANDLE );
+
+ GDI_ReleaseObj( handle );
return result;
}
/***********************************************************************
- * GetObjectType (GDI32.205)
+ * GetObjectType (GDI32.@)
*/
DWORD WINAPI GetObjectType( HANDLE handle )
{
GDIOBJHDR * ptr;
INT result = 0;
- TRACE("%08x\n", handle );
+ TRACE("%p\n", handle );
if (!(ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE ))) return 0;
-
- switch(ptr->wMagic)
+
+ switch(GDIMAGIC(ptr->wMagic))
{
case PEN_MAGIC:
result = OBJ_PEN;
break;
- case BRUSH_MAGIC:
+ case BRUSH_MAGIC:
result = OBJ_BRUSH;
break;
- case BITMAP_MAGIC:
+ case BITMAP_MAGIC:
result = OBJ_BITMAP;
break;
case FONT_MAGIC:
case ENHMETAFILE_DC_MAGIC:
result = OBJ_ENHMETADC;
break;
+ case MEMORY_DC_MAGIC:
+ result = OBJ_MEMDC;
+ break;
default:
- FIXME("Magic %04x not implemented\n",
- ptr->wMagic );
+ FIXME("Magic %04x not implemented\n", GDIMAGIC(ptr->wMagic) );
break;
}
- GDI_HEAP_UNLOCK( handle );
+ GDI_ReleaseObj( handle );
return result;
}
/***********************************************************************
- * GetCurrentObject (GDI32.166)
+ * GetCurrentObject (GDI32.@)
*/
HANDLE WINAPI GetCurrentObject(HDC hdc,UINT type)
{
+ HANDLE ret = 0;
DC * dc = DC_GetDCPtr( hdc );
- if (!dc)
- return 0;
+ if (dc)
+ {
switch (type) {
- case OBJ_PEN: return dc->w.hPen;
- case OBJ_BRUSH: return dc->w.hBrush;
- case OBJ_PAL: return dc->w.hPalette;
- case OBJ_FONT: return dc->w.hFont;
- case OBJ_BITMAP: return dc->w.hBitmap;
+ case OBJ_PEN: ret = dc->hPen; break;
+ case OBJ_BRUSH: ret = dc->hBrush; break;
+ case OBJ_PAL: ret = dc->hPalette; break;
+ case OBJ_FONT: ret = dc->hFont; break;
+ case OBJ_BITMAP: ret = dc->hBitmap; break;
default:
/* the SDK only mentions those above */
- WARN("(%08x,%d): unknown type.\n",hdc,type);
- return 0;
+ FIXME("(%p,%d): unknown type.\n",hdc,type);
+ break;
+ }
+ GDI_ReleaseObj( hdc );
}
+ return ret;
}
/***********************************************************************
- * SelectObject16 (GDI.45)
- */
-HGDIOBJ16 WINAPI SelectObject16( HDC16 hdc, HGDIOBJ16 handle )
-{
- return (HGDIOBJ16)SelectObject( hdc, handle );
-}
-
-
-/***********************************************************************
- * SelectObject32 (GDI32.299)
+ * SelectObject (GDI32.@)
*/
HGDIOBJ WINAPI SelectObject( HDC hdc, HGDIOBJ handle )
{
- DC * dc = DC_GetDCPtr( hdc );
- if (!dc || !dc->funcs->pSelectObject) return 0;
- TRACE("hdc=%04x %04x\n", hdc, handle );
- return dc->funcs->pSelectObject( dc, handle );
-}
+ HGDIOBJ ret = 0;
+ GDIOBJHDR *header = GDI_GetObjPtr( handle, MAGIC_DONTCARE );
+ if (!header) return 0;
+ TRACE("hdc=%p %p\n", hdc, handle );
-/***********************************************************************
- * UnrealizeObject16 (GDI.150)
- */
-BOOL16 WINAPI UnrealizeObject16( HGDIOBJ16 obj )
-{
- return UnrealizeObject( obj );
+ if (header->funcs && header->funcs->pSelectObject)
+ {
+ ret = header->funcs->pSelectObject( handle, header, hdc );
+ if (ret && ret != handle && (INT)ret > COMPLEXREGION)
+ {
+ inc_ref_count( handle );
+ dec_ref_count( ret );
+ }
+ }
+ GDI_ReleaseObj( handle );
+ return ret;
}
/***********************************************************************
- * UnrealizeObject (GDI32.358)
+ * UnrealizeObject (GDI32.@)
*/
BOOL WINAPI UnrealizeObject( HGDIOBJ obj )
{
BOOL result = TRUE;
/* Check if object is valid */
- GDIOBJHDR * header = (GDIOBJHDR *) GDI_HEAP_LOCK( obj );
+ GDIOBJHDR * header = GDI_GetObjPtr( obj, MAGIC_DONTCARE );
if (!header) return FALSE;
- TRACE("%04x\n", obj );
+ TRACE("%p\n", obj );
/* Unrealize object */
- switch(header->wMagic)
- {
- case PALETTE_MAGIC:
- result = PALETTE_UnrealizeObject( obj, (PALETTEOBJ *)header );
- break;
+ if (header->funcs && header->funcs->pUnrealizeObject)
+ result = header->funcs->pUnrealizeObject( obj, header );
- case BRUSH_MAGIC:
- /* Windows resets the brush origin. We don't need to. */
- break;
- }
- GDI_HEAP_UNLOCK( obj );
+ GDI_ReleaseObj( obj );
return result;
}
-/***********************************************************************
- * EnumObjects16 (GDI.71)
- */
-INT16 WINAPI EnumObjects16( HDC16 hdc, INT16 nObjType,
- GOBJENUMPROC16 lpEnumFunc, LPARAM lParam )
-{
- /* Solid colors to enumerate */
- static const COLORREF solid_colors[] =
- { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
- RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
- RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
- RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
- RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
- RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
- RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
- RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
- };
-
- INT16 i, retval = 0;
- LOGPEN16 *pen;
- LOGBRUSH16 *brush = NULL;
-
- TRACE("%04x %d %08lx %08lx\n",
- hdc, nObjType, (DWORD)lpEnumFunc, lParam );
- switch(nObjType)
- {
- case OBJ_PEN:
- /* Enumerate solid pens */
- if (!(pen = SEGPTR_NEW(LOGPEN16))) break;
- for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
- {
- pen->lopnStyle = PS_SOLID;
- pen->lopnWidth.x = 1;
- pen->lopnWidth.y = 0;
- pen->lopnColor = solid_colors[i];
- retval = lpEnumFunc( SEGPTR_GET(pen), lParam );
- TRACE("solid pen %08lx, ret=%d\n",
- solid_colors[i], retval);
- if (!retval) break;
- }
- SEGPTR_FREE(pen);
- break;
-
- case OBJ_BRUSH:
- /* Enumerate solid brushes */
- if (!(brush = SEGPTR_NEW(LOGBRUSH16))) break;
- for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
- {
- brush->lbStyle = BS_SOLID;
- brush->lbColor = solid_colors[i];
- brush->lbHatch = 0;
- retval = lpEnumFunc( SEGPTR_GET(brush), lParam );
- TRACE("solid brush %08lx, ret=%d\n",
- solid_colors[i], retval);
- if (!retval) break;
- }
-
- /* Now enumerate hatched brushes */
- if (retval) for (i = HS_HORIZONTAL; i <= HS_DIAGCROSS; i++)
- {
- brush->lbStyle = BS_HATCHED;
- brush->lbColor = RGB(0,0,0);
- brush->lbHatch = i;
- retval = lpEnumFunc( SEGPTR_GET(brush), lParam );
- TRACE("hatched brush %d, ret=%d\n",
- i, retval);
- if (!retval) break;
- }
- SEGPTR_FREE(brush);
- break;
-
- default:
- WARN("(%d): Invalid type\n", nObjType );
- break;
- }
- return retval;
-}
+/* Solid colors to enumerate */
+static const COLORREF solid_colors[] =
+{ RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
+RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
+RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
+RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
+RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
+RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
+RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
+RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
+};
/***********************************************************************
- * EnumObjects32 (GDI32.89)
+ * EnumObjects (GDI32.@)
*/
INT WINAPI EnumObjects( HDC hdc, INT nObjType,
GOBJENUMPROC lpEnumFunc, LPARAM lParam )
{
- /* Solid colors to enumerate */
- static const COLORREF solid_colors[] =
- { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
- RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
- RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
- RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
- RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
- RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
- RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
- RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
- };
-
INT i, retval = 0;
LOGPEN pen;
LOGBRUSH brush;
- TRACE("%04x %d %08lx %08lx\n",
- hdc, nObjType, (DWORD)lpEnumFunc, lParam );
+ TRACE("%p %d %p %08lx\n", hdc, nObjType, lpEnumFunc, lParam );
switch(nObjType)
{
case OBJ_PEN:
/***********************************************************************
* IsGDIObject (GDI.462)
- *
+ *
* returns type of object if valid (W95 system programming secrets p. 264-5)
*/
-BOOL16 WINAPI IsGDIObject16( HGDIOBJ16 handle )
+BOOL16 WINAPI IsGDIObject16( HGDIOBJ16 handle16 )
{
UINT16 magic = 0;
+ HGDIOBJ handle = HGDIOBJ_32( handle16 );
- if (handle >= FIRST_STOCK_HANDLE )
+ GDIOBJHDR *object = GDI_GetObjPtr( handle, MAGIC_DONTCARE );
+ if (object)
{
- switch (handle)
- {
- case STOCK_WHITE_BRUSH:
- case STOCK_LTGRAY_BRUSH:
- case STOCK_GRAY_BRUSH:
- case STOCK_DKGRAY_BRUSH:
- case STOCK_BLACK_BRUSH:
- case STOCK_HOLLOW_BRUSH:
- magic = BRUSH_MAGIC;
- break;
-
- case STOCK_WHITE_PEN:
- case STOCK_BLACK_PEN:
- case STOCK_NULL_PEN :
- magic = PEN_MAGIC;
- break;
-
- case STOCK_OEM_FIXED_FONT:
- case STOCK_ANSI_FIXED_FONT:
- case STOCK_ANSI_VAR_FONT:
- case STOCK_SYSTEM_FONT:
- case STOCK_DEVICE_DEFAULT_FONT:
- case STOCK_SYSTEM_FIXED_FONT:
- case STOCK_DEFAULT_GUI_FONT:
- magic = FONT_MAGIC;
- break;
-
- case STOCK_DEFAULT_PALETTE:
- magic = PALETTE_MAGIC;
- break;
- }
+ magic = GDIMAGIC(object->wMagic) - PEN_MAGIC + 1;
+ GDI_ReleaseObj( handle );
}
- else
- {
- GDIOBJHDR *object = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
- if (object)
- {
- magic = object->wMagic;
- GDI_HEAP_UNLOCK( handle );
- }
- }
-
- if (magic >= PEN_MAGIC && magic <= METAFILE_DC_MAGIC)
- return magic - PEN_MAGIC + 1;
- else
- return FALSE;
-}
-
-
-/***********************************************************************
- * SetObjectOwner16 (GDI.461)
- */
-void WINAPI SetObjectOwner16( HGDIOBJ16 handle, HANDLE16 owner )
-{
- /* Nothing to do */
+ return magic;
}
/***********************************************************************
- * SetObjectOwner32 (GDI32.386)
+ * SetObjectOwner (GDI32.@)
*/
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 )
+void WINAPI MakeObjectPrivate16( HGDIOBJ16 handle16, BOOL16 private )
{
- /* FIXME */
+ HGDIOBJ handle = HGDIOBJ_32( handle16 );
+ GDIOBJHDR *ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE );
+ if (!ptr)
+ {
+ ERR("invalid GDI object %p !\n", handle);
+ return;
+ }
+ ptr->wMagic |= OBJECT_PRIVATE;
+ GDI_ReleaseObj( handle );
}
/***********************************************************************
- * GdiFlush (GDI32.128)
+ * GdiFlush (GDI32.@)
*/
BOOL WINAPI GdiFlush(void)
{
/***********************************************************************
- * GdiGetBatchLimit (GDI32.129)
+ * GdiGetBatchLimit (GDI32.@)
*/
DWORD WINAPI GdiGetBatchLimit(void)
{
/***********************************************************************
- * GdiSetBatchLimit (GDI32.139)
+ * GdiSetBatchLimit (GDI32.@)
*/
DWORD WINAPI GdiSetBatchLimit( DWORD limit )
{
return GDI_HeapSel;
default:
WARN("(wReqType=%04x): Unknown\n", wReqType);
- return (DWORD)-1;
+ return ~0UL;
}
}
/***********************************************************************
- * GdiSignalProc (GDI.610)
+ * GdiSignalProc32 (GDI.610)
*/
WORD WINAPI GdiSignalProc( UINT uCode, DWORD dwThreadOrProcessID,
DWORD dwFlags, HMODULE16 hModule )
}
/***********************************************************************
- * FinalGdiInit16 (GDI.405)
+ * GdiInit2 (GDI.403)
+ *
+ * See "Undocumented Windows"
*/
-void WINAPI FinalGdiInit16( HANDLE16 unknown )
+HANDLE16 WINAPI GdiInit216(
+ HANDLE16 h1, /* [in] GDI object */
+ HANDLE16 h2 /* [in] global data */
+)
{
+ FIXME("(%04x, %04x), stub.\n", h1, h2);
+ if (h2 == 0xffff)
+ return 0xffff; /* undefined return value */
+ return h1; /* FIXME: should be the memory handle of h1 */
}
/***********************************************************************
- * GdiFreeResources (GDI.609)
+ * FinalGdiInit (GDI.405)
*/
-WORD WINAPI GdiFreeResources16( DWORD reserve )
+void WINAPI FinalGdiInit16( HBRUSH16 hPattern /* [in] fill pattern of desktop */ )
{
- return (WORD)( (int)LOCAL_CountFree( GDI_HeapSel ) * 100 /
- (int)LOCAL_HeapSize( GDI_HeapSel ) );
}
/***********************************************************************
- * MulDiv16 (GDI.128)
+ * GdiFreeResources (GDI.609)
*/
-INT16 WINAPI MulDiv16(
- INT16 nMultiplicand,
- INT16 nMultiplier,
- INT16 nDivisor)
+WORD WINAPI GdiFreeResources16( DWORD reserve )
{
- INT ret;
- if (!nDivisor) return -32768;
- /* We want to deal with a positive divisor to simplify the logic. */
- if (nDivisor < 0)
- {
- nMultiplicand = - nMultiplicand;
- nDivisor = -nDivisor;
- }
- /* If the result is positive, we "add" to round. else,
- * we subtract to round. */
- if ( ( (nMultiplicand < 0) && (nMultiplier < 0) ) ||
- ( (nMultiplicand >= 0) && (nMultiplier >= 0) ) )
- ret = (((int)nMultiplicand * nMultiplier) + (nDivisor/2)) / nDivisor;
- else
- ret = (((int)nMultiplicand * nMultiplier) - (nDivisor/2)) / nDivisor;
- if ((ret > 32767) || (ret < -32767)) return -32768;
- return (INT16) ret;
+ return (WORD)( (int)LOCAL_CountFree( GDI_HeapSel ) * 100 /
+ (int)LOCAL_HeapSize( GDI_HeapSel ) );
}
-/***********************************************************************
- * MulDiv32 (KERNEL32.391)
- * RETURNS
- * Result of multiplication and division
- * -1: Overflow occurred or Divisor was 0
- */
-INT WINAPI MulDiv(
- INT nMultiplicand,
- INT nMultiplier,
- INT nDivisor)
-{
-#if SIZEOF_LONG_LONG >= 8
- long long ret;
-
- if (!nDivisor) return -1;
-
- /* We want to deal with a positive divisor to simplify the logic. */
- if (nDivisor < 0)
- {
- nMultiplicand = - nMultiplicand;
- nDivisor = -nDivisor;
- }
-
- /* If the result is positive, we "add" to round. else, we subtract to round. */
- if ( ( (nMultiplicand < 0) && (nMultiplier < 0) ) ||
- ( (nMultiplicand >= 0) && (nMultiplier >= 0) ) )
- ret = (((long long)nMultiplicand * nMultiplier) + (nDivisor/2)) / nDivisor;
- else
- ret = (((long long)nMultiplicand * nMultiplier) - (nDivisor/2)) / nDivisor;
-
- if ((ret > 2147483647) || (ret < -2147483647)) return -1;
- return ret;
-#else
- if (!nDivisor) return -1;
-
- /* We want to deal with a positive divisor to simplify the logic. */
- if (nDivisor < 0)
- {
- nMultiplicand = - nMultiplicand;
- nDivisor = -nDivisor;
- }
-
- /* If the result is positive, we "add" to round. else, we subtract to round. */
- if ( ( (nMultiplicand < 0) && (nMultiplier < 0) ) ||
- ( (nMultiplicand >= 0) && (nMultiplier >= 0) ) )
- return ((nMultiplicand * nMultiplier) + (nDivisor/2)) / nDivisor;
-
- return ((nMultiplicand * nMultiplier) - (nDivisor/2)) / nDivisor;
-
-#endif
-}
/*******************************************************************
- * GetColorAdjustment [GDI32.164]
+ * GetColorAdjustment [GDI32.@]
*
*
*/
}
/*******************************************************************
- * GetMiterLimit [GDI32.201]
+ * GetMiterLimit [GDI32.@]
*
*
*/
}
/*******************************************************************
- * SetMiterLimit [GDI32.325]
+ * SetMiterLimit [GDI32.@]
*
*
*/
}
/*******************************************************************
- * GdiComment [GDI32.109]
+ * GdiComment [GDI32.@]
*
*
*/
BOOL WINAPI GdiComment(HDC hdc, UINT cbSize, const BYTE *lpData)
{
- FIXME("GdiComment, stub\n");
- return 0;
+ DC *dc = DC_GetDCPtr(hdc);
+ BOOL ret = FALSE;
+ if(dc)
+ {
+ if (dc->funcs->pGdiComment)
+ ret = dc->funcs->pGdiComment( dc->physDev, cbSize, lpData );
+ }
+ GDI_ReleaseObj( hdc );
+ return ret;
}
+
/*******************************************************************
- * SetColorAdjustment [GDI32.309]
+ * SetColorAdjustment [GDI32.@]
*
*
*/
FIXME("SetColorAdjustment, stub\n");
return 0;
}
-