* 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 "windef.h"
+#include "winbase.h"
#include "wingdi.h"
+#include "winreg.h"
#include "winerror.h"
-#include "wine/winbase16.h"
-#include "bitmap.h"
-#include "brush.h"
-#include "font.h"
-#include "heap.h"
#include "local.h"
-#include "options.h"
-#include "palette.h"
-#include "pen.h"
-#include "region.h"
-#include "debugtools.h"
#include "gdi.h"
-#include "tweak.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))
+
+#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, { 0, 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, { 0, 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, { 0, 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;
-HBITMAP hPseudoStockBitmap; /* 1x1 bitmap for memory DCs */
+ for(n=0;n<(sizeof(default_fonts)/sizeof(default_fonts[0]));n++)
+ {
+ if ( default_fonts[n].charset == charset )
+ return &default_fonts[n];
+ }
-static SYSLEVEL GDI_level = { CRITICAL_SECTION_INIT, 3 };
-static WORD GDI_HeapSel;
+ FIXME( "unhandled charset 0x%08x - use ANSI_CHARSET for default stock objects\n", charset );
+ return &default_fonts[0];
+}
/******************************************************************************
+ * 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);
+#define TRACE_SEC(handle,text) \
+ TRACE("(%p): " text " %ld\n", (handle), GDI_level.crst.RecursionCount)
- GetTextMetricsA(hdc, lptm);
- SelectObject(hdc, hOldFont);
+/***********************************************************************
+ * inc_ref_count
+ *
+ * Increment the reference count of a GDI object.
+ */
+inline static void inc_ref_count( HGDIOBJ handle )
+{
+ GDIOBJHDR *header;
- DeleteDC(hdc);
+ if ((header = GDI_GetObjPtr( handle, MAGIC_DONTCARE )))
+ {
+ header->dwCount++;
+ GDI_ReleaseObj( handle );
+ }
}
-static inline void FixStockFontSize16(
- HFONT handle,
- INT16 count,
- LPVOID buffer)
-{
- 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;
- }
-}
-static inline void FixStockFontSizeA(
- HFONT handle,
- INT count,
- LPVOID buffer)
+/***********************************************************************
+ * dec_ref_count
+ *
+ * Decrement the reference count of a GDI object.
+ */
+inline static void dec_ref_count( HGDIOBJ handle )
{
- 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;
- }
-}
+ GDIOBJHDR *header;
-/**
- * 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.
- */
-#define FixStockFontSizeW FixStockFontSizeA
+ 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 );
+ }
+ }
+}
-#define TRACE_SEC(handle,text) \
- TRACE("(%04x): " text " %ld\n", (handle), GDI_level.crst.RecursionCount)
/***********************************************************************
* GDI_Init
*/
BOOL GDI_Init(void)
{
- BOOL systemIsBold = (TWEAK_WineLook == WIN31_LOOK);
- HPALETTE16 hpalette;
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) return FALSE;
- GDI_HeapSel = GlobalHandleToSel16( instance );
-
- /* 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 (?) */
- hpalette = PALETTE_Init();
- if( !hpalette ) return FALSE;
- StockObjects[DEFAULT_PALETTE] = (GDIOBJHDR *)LOCAL_Lock( GDI_HeapSel, hpalette );
-
- hPseudoStockBitmap = CreateBitmap( 1, 1, 1, 1, NULL );
+ 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++)
+ {
+ 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 );
+
+ WineEngInit();
+
return TRUE;
}
if ((obj = HeapAlloc( GetProcessHeap(), 0, size )))
{
large_handles[i] = obj;
- *handle = (i + FIRST_LARGE_HANDLE) << 2;
+ *handle = (HGDIOBJ)(ULONG_PTR)((i + FIRST_LARGE_HANDLE) << 2);
next_large_handle = i;
}
return obj;
/***********************************************************************
* GDI_AllocObject
*/
-void *GDI_AllocObject( WORD size, WORD magic, HGDIOBJ *handle )
+void *GDI_AllocObject( WORD size, WORD magic, HGDIOBJ *handle, const struct gdi_obj_funcs *funcs )
{
- static DWORD count = 0;
GDIOBJHDR *obj;
+ HLOCAL16 hlocal;
_EnterSysLevel( &GDI_level );
switch(magic)
{
- /* allocate DCs on the larger heap */
+ 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_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;
- default:
- if (!(*handle = LOCAL_Alloc( GDI_HeapSel, LMEM_MOVEABLE, size ))) goto error;
- assert( *handle & 2 );
- obj = (GDIOBJHDR *)LOCAL_Lock( GDI_HeapSel, *handle );
- break;
}
obj->hNext = 0;
obj->wMagic = magic|OBJECT_NOSYSTEM;
- obj->dwCount = ++count;
+ obj->dwCount = 0;
+ obj->funcs = funcs;
+ obj->hdcs = NULL;
TRACE_SEC( *handle, "enter" );
return obj;
{
HGDIOBJ new_handle;
- assert( handle & 2 ); /* no realloc for large handles */
- LOCAL_Unlock( GDI_HeapSel, handle );
- if (!(new_handle = LOCAL_ReAlloc( GDI_HeapSel, handle, size, LMEM_MOVEABLE )))
+ if ((UINT_PTR)handle & 2) /* GDI heap handle */
{
- TRACE_SEC( handle, "leave" );
- _LeaveSysLevel( &GDI_level );
- return NULL;
+ 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 );
}
- assert( new_handle == handle ); /* moveable handle cannot change */
- return LOCAL_Lock( GDI_HeapSel, handle );
+ TRACE_SEC( handle, "leave" );
+ _LeaveSysLevel( &GDI_level );
+ return NULL;
}
-
+
/***********************************************************************
* GDI_FreeObject
{
GDIOBJHDR *object = ptr;
- /* can't free stock objects */
- if (handle < FIRST_STOCK_HANDLE)
+ object->wMagic = 0; /* Mark it as invalid */
+ object->funcs = NULL;
+ if ((UINT_PTR)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 */
+ 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])
{
- 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;
}
+ else ERR( "Invalid handle %p\n", handle );
}
TRACE_SEC( handle, "leave" );
_LeaveSysLevel( &GDI_level );
_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];
- if (ptr && (magic != MAGIC_DONTCARE)
- && (GDIMAGIC(ptr->wMagic) != magic)) ptr = NULL;
- }
- else if (handle & 2) /* GDI heap handle */
- {
- ptr = (GDIOBJHDR *)LOCAL_Lock( GDI_HeapSel, handle );
- if (ptr &&
- (magic != MAGIC_DONTCARE) && (GDIMAGIC(ptr->wMagic) != magic))
+ HLOCAL16 h = LOWORD(handle);
+ ptr = (GDIOBJHDR *)LOCAL_Lock( GDI_HeapSel, h );
+ if (ptr)
{
- LOCAL_Unlock( GDI_HeapSel, handle );
- ptr = NULL;
+ 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 = (handle >> 2) - FIRST_LARGE_HANDLE;
- if (i >= 0)
+ 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;
{
_LeaveSysLevel( &GDI_level );
SetLastError( ERROR_INVALID_HANDLE );
+ WARN( "Invalid handle %p\n", handle );
}
else TRACE_SEC( handle, "enter" );
*/
void GDI_ReleaseObj( HGDIOBJ handle )
{
- if (handle < FIRST_STOCK_HANDLE && (handle & 2)) LOCAL_Unlock( GDI_HeapSel, handle );
+ if ((UINT_PTR)handle & 2) LOCAL_Unlock( GDI_HeapSel, LOWORD(handle) );
TRACE_SEC( handle, "leave" );
_LeaveSysLevel( &GDI_level );
}
/***********************************************************************
- * DeleteObject16 (GDI.69)
+ * GDI_CheckNotLock
*/
-BOOL16 WINAPI DeleteObject16( HGDIOBJ16 obj )
+void GDI_CheckNotLock(void)
{
- return DeleteObject( obj );
+ _CheckNotSysLevel( &GDI_level );
}
/***********************************************************************
- * DeleteObject (GDI32.70)
+ * DeleteObject (GDI32.@)
*/
BOOL WINAPI DeleteObject( HGDIOBJ obj )
{
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)
&& (header->wMagic >= FIRST_MAGIC) && (header->wMagic <= LAST_MAGIC))
{
- TRACE("Preserving system object %04x\n", obj);
+ TRACE("Preserving system object %p\n", obj);
GDI_ReleaseObj( obj );
return TRUE;
}
-
- TRACE("%04x\n", obj );
- /* Delete object */
+ while (header->hdcs)
+ {
+ 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);
+ }
- switch(GDIMAGIC(header->wMagic))
+ if (header->dwCount)
{
- case PEN_MAGIC: return GDI_FreeObject( obj, header );
- case BRUSH_MAGIC: return BRUSH_DeleteObject( obj, (BRUSHOBJ*)header );
- case FONT_MAGIC: return GDI_FreeObject( obj, header );
- 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:
- GDI_ReleaseObj( obj );
- return DeleteDC(obj);
- case 0 :
- WARN("Already deleted\n");
- break;
- default:
- WARN("Unknown magic number (%d)\n",GDIMAGIC(header->wMagic));
+ 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;
+}
/***********************************************************************
- * GetStockObject (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;
- ret = (HGDIOBJ16)(FIRST_STOCK_HANDLE + obj);
- TRACE("returning %4x\n", ret );
+ 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(GDIMAGIC(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;
- }
+
+ if (ptr->funcs && ptr->funcs->pGetObject16)
+ result = ptr->funcs->pGetObject16( handle, ptr, count, buffer );
+ else
+ SetLastError( ERROR_INVALID_HANDLE );
+
GDI_ReleaseObj( handle );
return result;
}
/***********************************************************************
- * GetObjectA (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(GDIMAGIC(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", GDIMAGIC(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", GDIMAGIC(ptr->wMagic));
- break;
- }
GDI_ReleaseObj( handle );
return result;
}
/***********************************************************************
- * GetObjectW (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(GDIMAGIC(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", GDIMAGIC(ptr->wMagic) );
- break;
- }
+ 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(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", GDIMAGIC(ptr->wMagic) );
break;
}
/***********************************************************************
- * GetCurrentObject (GDI32.166)
+ * GetCurrentObject (GDI32.@)
*/
HANDLE WINAPI GetCurrentObject(HDC hdc,UINT type)
{
HANDLE ret = 0;
DC * dc = DC_GetDCPtr( hdc );
- if (dc)
+ if (dc)
{
switch (type) {
case OBJ_PEN: ret = dc->hPen; break;
case OBJ_BITMAP: ret = dc->hBitmap; break;
default:
/* the SDK only mentions those above */
- FIXME("(%08x,%d): unknown type.\n",hdc,type);
+ FIXME("(%p,%d): unknown type.\n",hdc,type);
break;
}
GDI_ReleaseObj( hdc );
/***********************************************************************
- * SelectObject16 (GDI.45)
- */
-HGDIOBJ16 WINAPI SelectObject16( HDC16 hdc, HGDIOBJ16 handle )
-{
- return (HGDIOBJ16)SelectObject( hdc, handle );
-}
-
-
-/***********************************************************************
- * SelectObject (GDI32.299)
+ * SelectObject (GDI32.@)
*/
HGDIOBJ WINAPI SelectObject( HDC hdc, HGDIOBJ handle )
{
HGDIOBJ ret = 0;
- DC * dc = DC_GetDCUpdate( hdc );
- if (!dc) return 0;
- TRACE("hdc=%04x %04x\n", hdc, handle );
- if (dc->funcs->pSelectObject)
- ret = dc->funcs->pSelectObject( dc, handle );
- GDI_ReleaseObj( hdc );
- return ret;
-}
+ 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 )
{
GDIOBJHDR * header = GDI_GetObjPtr( obj, MAGIC_DONTCARE );
if (!header) return FALSE;
- TRACE("%04x\n", obj );
+ TRACE("%p\n", obj );
/* Unrealize object */
- switch(GDIMAGIC(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_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)
+};
/***********************************************************************
- * EnumObjects (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 );
GDIOBJHDR *object = GDI_GetObjPtr( handle, MAGIC_DONTCARE );
if (object)
/***********************************************************************
- * SetObjectOwner16 (GDI.461)
- */
-void WINAPI SetObjectOwner16( HGDIOBJ16 handle, HANDLE16 owner )
-{
- /* Nothing to do */
-}
-
-
-/***********************************************************************
- * SetObjectOwner (GDI32.386)
+ * SetObjectOwner (GDI32.@)
*/
void WINAPI SetObjectOwner( HGDIOBJ handle, HANDLE owner )
{
* 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 )
{
+ HGDIOBJ handle = HGDIOBJ_32( handle16 );
GDIOBJHDR *ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE );
if (!ptr)
{
- ERR("invalid GDI object %04x !\n", handle);
+ ERR("invalid GDI object %p !\n", handle);
return;
}
ptr->wMagic |= OBJECT_PRIVATE;
/***********************************************************************
- * 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 ) );
}
/*******************************************************************
- * 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;
}
-