blob: 58d21a1a758a3d4e4b0ce05815f2ee2dc68d099f [file] [log] [blame]
Alexandre Julliard401710d1993-09-04 10:09:32 +00001/*
2 * GDI functions
3 *
4 * Copyright 1993 Alexandre Julliard
Alexandre Julliarda2f2e011995-06-06 16:40:35 +00005 */
Alexandre Julliard401710d1993-09-04 10:09:32 +00006
Patrik Stridvalld96e1f11999-07-04 13:31:03 +00007#include "config.h"
8
Alexandre Julliard2a2321b2000-08-19 21:38:55 +00009#include <assert.h>
Alexandre Julliard8d24ae61994-04-05 21:42:43 +000010#include <stdlib.h>
Jeremy Whited3e22d92000-02-10 19:03:02 +000011#include <stdio.h>
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +000012
Alexandre Julliard2a2321b2000-08-19 21:38:55 +000013#include "windef.h"
14#include "wingdi.h"
15#include "winerror.h"
16#include "wine/winbase16.h"
17
Alexandre Julliard234bc241994-12-10 13:02:28 +000018#include "bitmap.h"
Alexandre Julliard7cbe6571995-01-09 18:21:16 +000019#include "brush.h"
Alexandre Julliard234bc241994-12-10 13:02:28 +000020#include "font.h"
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +000021#include "heap.h"
Alexandre Julliardd37eb361997-07-20 16:23:21 +000022#include "options.h"
Alexandre Julliard7cbe6571995-01-09 18:21:16 +000023#include "palette.h"
24#include "pen.h"
25#include "region.h"
Alexandre Julliard15657091999-05-23 10:25:25 +000026#include "debugtools.h"
Alexandre Julliard491502b1997-11-01 19:08:16 +000027#include "gdi.h"
Richard Cohen05bf5341999-09-03 15:16:23 +000028#include "tweak.h"
Alexandre Julliard2a2321b2000-08-19 21:38:55 +000029#include "syslevel.h"
Alexandre Julliard401710d1993-09-04 10:09:32 +000030
Alexandre Julliard58d5a0a2000-07-29 21:58:17 +000031DEFAULT_DEBUG_CHANNEL(gdi);
Patrik Stridvallb4b9fae1999-04-19 14:56:29 +000032
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +000033
Alexandre Julliard401710d1993-09-04 10:09:32 +000034/***********************************************************************
35 * GDI stock objects
36 */
37
38static BRUSHOBJ WhiteBrush =
39{
Alexandre Julliard0e270f41996-08-24 18:26:35 +000040 { 0, BRUSH_MAGIC, 1 }, /* header */
Alexandre Julliard401710d1993-09-04 10:09:32 +000041 { BS_SOLID, RGB(255,255,255), 0 } /* logbrush */
42};
43
44static BRUSHOBJ LtGrayBrush =
45{
Alexandre Julliard0e270f41996-08-24 18:26:35 +000046 { 0, BRUSH_MAGIC, 1 }, /* header */
Alexandre Julliard33072e11997-06-29 18:08:02 +000047/* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
Alexandre Julliard401710d1993-09-04 10:09:32 +000048 { BS_SOLID, RGB(192,192,192), 0 } /* logbrush */
49};
50
51static BRUSHOBJ GrayBrush =
52{
Alexandre Julliard0e270f41996-08-24 18:26:35 +000053 { 0, BRUSH_MAGIC, 1 }, /* header */
Alexandre Julliard33072e11997-06-29 18:08:02 +000054/* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
Alexandre Julliard401710d1993-09-04 10:09:32 +000055 { BS_SOLID, RGB(128,128,128), 0 } /* logbrush */
56};
57
58static BRUSHOBJ DkGrayBrush =
59{
Alexandre Julliard0e270f41996-08-24 18:26:35 +000060 { 0, BRUSH_MAGIC, 1 }, /* header */
Alexandre Julliard33072e11997-06-29 18:08:02 +000061/* This is BS_HATCHED, for 1 bitperpixel. This makes the spray work in pbrush */
62/* NB_HATCH_STYLES is an index into HatchBrushes */
63 { BS_HATCHED, RGB(0,0,0), NB_HATCH_STYLES } /* logbrush */
Alexandre Julliard401710d1993-09-04 10:09:32 +000064};
65
66static BRUSHOBJ BlackBrush =
67{
Alexandre Julliard0e270f41996-08-24 18:26:35 +000068 { 0, BRUSH_MAGIC, 1 }, /* header */
Alexandre Julliard401710d1993-09-04 10:09:32 +000069 { BS_SOLID, RGB(0,0,0), 0 } /* logbrush */
70};
71
72static BRUSHOBJ NullBrush =
73{
Alexandre Julliard0e270f41996-08-24 18:26:35 +000074 { 0, BRUSH_MAGIC, 1 }, /* header */
75 { BS_NULL, 0, 0 } /* logbrush */
Alexandre Julliard401710d1993-09-04 10:09:32 +000076};
77
78static PENOBJ WhitePen =
79{
Alexandre Julliard0e270f41996-08-24 18:26:35 +000080 { 0, PEN_MAGIC, 1 }, /* header */
Francois Gouget78767e62000-10-31 01:36:09 +000081 { PS_SOLID, { 0, 0 }, RGB(255,255,255) } /* logpen */
Alexandre Julliard401710d1993-09-04 10:09:32 +000082};
83
84static PENOBJ BlackPen =
85{
Alexandre Julliard0e270f41996-08-24 18:26:35 +000086 { 0, PEN_MAGIC, 1 }, /* header */
Francois Gouget78767e62000-10-31 01:36:09 +000087 { PS_SOLID, { 0, 0 }, RGB(0,0,0) } /* logpen */
Alexandre Julliard401710d1993-09-04 10:09:32 +000088};
89
90static PENOBJ NullPen =
91{
Alexandre Julliard0e270f41996-08-24 18:26:35 +000092 { 0, PEN_MAGIC, 1 }, /* header */
Francois Gouget78767e62000-10-31 01:36:09 +000093 { PS_NULL, { 0, 0 }, 0 } /* logpen */
Alexandre Julliard401710d1993-09-04 10:09:32 +000094};
95
96static FONTOBJ OEMFixedFont =
97{
Alexandre Julliard0e270f41996-08-24 18:26:35 +000098 { 0, FONT_MAGIC, 1 }, /* header */
Richard Cohen05bf5341999-09-03 15:16:23 +000099 { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, OEM_CHARSET,
Alexandre Julliard401710d1993-09-04 10:09:32 +0000100 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" }
101};
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000102/* Filler to make the location counter dword aligned again. This is necessary
103 since (a) FONTOBJ is packed, (b) gcc places initialised variables in the code
104 segment, and (c) Solaris assembler is stupid. */
105static UINT16 align_OEMFixedFont = 1;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000106
107static FONTOBJ AnsiFixedFont =
108{
Alexandre Julliard0e270f41996-08-24 18:26:35 +0000109 { 0, FONT_MAGIC, 1 }, /* header */
Richard Cohen05bf5341999-09-03 15:16:23 +0000110 { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
Alexandre Julliard401710d1993-09-04 10:09:32 +0000111 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" }
112};
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000113static UINT16 align_AnsiFixedFont = 1;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000114
115static FONTOBJ AnsiVarFont =
116{
Alexandre Julliard0e270f41996-08-24 18:26:35 +0000117 { 0, FONT_MAGIC, 1 }, /* header */
Richard Cohen05bf5341999-09-03 15:16:23 +0000118 { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
Alexandre Julliard23946ad1997-06-16 17:43:53 +0000119 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "MS Sans Serif" }
Alexandre Julliard401710d1993-09-04 10:09:32 +0000120};
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000121static UINT16 align_AnsiVarFont = 1;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000122
123static FONTOBJ SystemFont =
124{
Alexandre Julliard23946ad1997-06-16 17:43:53 +0000125 { 0, FONT_MAGIC, 1 },
Richard Cohen05bf5341999-09-03 15:16:23 +0000126 { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
Alexandre Julliard23946ad1997-06-16 17:43:53 +0000127 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "System" }
Alexandre Julliard401710d1993-09-04 10:09:32 +0000128};
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000129static UINT16 align_SystemFont = 1;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000130
131static FONTOBJ DeviceDefaultFont =
132{
Alexandre Julliard0e270f41996-08-24 18:26:35 +0000133 { 0, FONT_MAGIC, 1 }, /* header */
Richard Cohen05bf5341999-09-03 15:16:23 +0000134 { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
Alexandre Julliard401710d1993-09-04 10:09:32 +0000135 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "" }
136};
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000137static UINT16 align_DeviceDefaultFont = 1;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000138
139static FONTOBJ SystemFixedFont =
140{
Alexandre Julliard0e270f41996-08-24 18:26:35 +0000141 { 0, FONT_MAGIC, 1 }, /* header */
Richard Cohen05bf5341999-09-03 15:16:23 +0000142 { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
Alexandre Julliard401710d1993-09-04 10:09:32 +0000143 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" }
144};
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000145static UINT16 align_SystemFixedFont = 1;
146
147/* FIXME: Is this correct? */
148static FONTOBJ DefaultGuiFont =
149{
Richard Cohen05bf5341999-09-03 15:16:23 +0000150 { 0, FONT_MAGIC, 1 }, /* header */
151 { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000152 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "MS Sans Serif" }
153};
154static UINT16 align_DefaultGuiFont = 1;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000155
156
157static GDIOBJHDR * StockObjects[NB_STOCK_OBJECTS] =
158{
159 (GDIOBJHDR *) &WhiteBrush,
160 (GDIOBJHDR *) &LtGrayBrush,
161 (GDIOBJHDR *) &GrayBrush,
162 (GDIOBJHDR *) &DkGrayBrush,
163 (GDIOBJHDR *) &BlackBrush,
164 (GDIOBJHDR *) &NullBrush,
165 (GDIOBJHDR *) &WhitePen,
166 (GDIOBJHDR *) &BlackPen,
167 (GDIOBJHDR *) &NullPen,
168 NULL,
169 (GDIOBJHDR *) &OEMFixedFont,
170 (GDIOBJHDR *) &AnsiFixedFont,
171 (GDIOBJHDR *) &AnsiVarFont,
172 (GDIOBJHDR *) &SystemFont,
173 (GDIOBJHDR *) &DeviceDefaultFont,
Alexandre Julliard23946ad1997-06-16 17:43:53 +0000174 NULL, /* DEFAULT_PALETTE created by PALETTE_Init */
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000175 (GDIOBJHDR *) &SystemFixedFont,
176 (GDIOBJHDR *) &DefaultGuiFont
Alexandre Julliard401710d1993-09-04 10:09:32 +0000177};
178
Gerard Pateld1795f62000-01-09 20:52:53 +0000179HBITMAP hPseudoStockBitmap; /* 1x1 bitmap for memory DCs */
180
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000181static SYSLEVEL GDI_level;
182static WORD GDI_HeapSel;
183
184
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000185/******************************************************************************
186 *
187 * void ReadFontInformation(
188 * char const *fontName,
189 * FONTOBJ *font,
190 * int defHeight,
191 * int defBold,
192 * int defItalic,
193 * int defUnderline,
194 * int defStrikeOut )
195 *
196 * ReadFontInformation() checks the Wine configuration file's Tweak.Fonts
197 * section for entries containing fontName.Height, fontName.Bold, etc.,
198 * where fontName is the name specified in the call (e.g., "System"). It
199 * attempts to be user friendly by accepting 'n', 'N', 'f', 'F', or '0' as
200 * the first character in the boolean attributes (bold, italic, and
201 * underline).
202 *****************************************************************************/
203
204static void ReadFontInformation(
205 char const *fontName,
206 FONTOBJ *font,
207 int defHeight,
208 int defBold,
209 int defItalic,
210 int defUnderline,
211 int defStrikeOut )
212{
213 char key[256];
214
Richard Cohen05bf5341999-09-03 15:16:23 +0000215 /* In order for the stock fonts to be independent of
216 * mapping mode, the height (& width) must be 0
217 */
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000218 sprintf(key, "%s.Height", fontName);
219 font->logfont.lfHeight =
220 PROFILE_GetWineIniInt("Tweak.Fonts", key, defHeight);
221
222 sprintf(key, "%s.Bold", fontName);
223 font->logfont.lfWeight =
224 (PROFILE_GetWineIniBool("Tweak.Fonts", key, defBold)) ?
225 FW_BOLD : FW_NORMAL;
226
227 sprintf(key, "%s.Italic", fontName);
228 font->logfont.lfItalic =
229 PROFILE_GetWineIniBool("Tweak.Fonts", key, defItalic);
230
231 sprintf(key, "%s.Underline", fontName);
232 font->logfont.lfUnderline =
233 PROFILE_GetWineIniBool("Tweak.Fonts", key, defUnderline);
234
235 sprintf(key, "%s.StrikeOut", fontName);
236 font->logfont.lfStrikeOut =
237 PROFILE_GetWineIniBool("Tweak.Fonts", key, defStrikeOut);
238
239 return;
240}
241
Alexandre Julliard401710d1993-09-04 10:09:32 +0000242/***********************************************************************
Francis Beaudet12668f51999-10-31 17:32:26 +0000243 * Because the stock fonts have their structure initialized with
244 * a height of 0 to keep them independent of mapping mode, simply
245 * returning the LOGFONT as is will not work correctly.
246 * These "FixStockFontSizeXXX()" methods will get the correct
247 * size for the fonts.
248 */
249static void GetFontMetrics(HFONT handle, LPTEXTMETRICA lptm)
250{
Ian Schmidte04b3e91999-11-04 01:45:53 +0000251 HDC hdc;
Francis Beaudet12668f51999-10-31 17:32:26 +0000252 HFONT hOldFont;
253
Ian Schmidte04b3e91999-11-04 01:45:53 +0000254 hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
255
Francis Beaudet12668f51999-10-31 17:32:26 +0000256 hOldFont = (HFONT)SelectObject(hdc, handle);
257
258 GetTextMetricsA(hdc, lptm);
259
260 SelectObject(hdc, hOldFont);
261
Ian Schmidte04b3e91999-11-04 01:45:53 +0000262 DeleteDC(hdc);
Francis Beaudet12668f51999-10-31 17:32:26 +0000263}
264
265static inline void FixStockFontSize16(
266 HFONT handle,
267 INT16 count,
268 LPVOID buffer)
269{
270 TEXTMETRICA tm;
271 LOGFONT16* pLogFont = (LOGFONT16*)buffer;
272
273 /*
274 * Was the lfHeight field copied (it's the first field)?
275 * If it was and it was null, replace the height.
276 */
277 if ( (count >= 2*sizeof(INT16)) &&
278 (pLogFont->lfHeight == 0) )
279 {
280 GetFontMetrics(handle, &tm);
281
282 pLogFont->lfHeight = tm.tmHeight;
283 pLogFont->lfWidth = tm.tmAveCharWidth;
284 }
285}
286
287static inline void FixStockFontSizeA(
288 HFONT handle,
289 INT count,
290 LPVOID buffer)
291{
292 TEXTMETRICA tm;
293 LOGFONTA* pLogFont = (LOGFONTA*)buffer;
294
295 /*
296 * Was the lfHeight field copied (it's the first field)?
297 * If it was and it was null, replace the height.
298 */
299 if ( (count >= 2*sizeof(INT)) &&
300 (pLogFont->lfHeight == 0) )
301 {
302 GetFontMetrics(handle, &tm);
303
304 pLogFont->lfHeight = tm.tmHeight;
305 pLogFont->lfWidth = tm.tmAveCharWidth;
306 }
307}
308
309/**
310 * Since the LOGFONTA and LOGFONTW structures are identical up to the
311 * lfHeight member (the one of interest in this case) we simply define
312 * the W version as the A version.
313 */
314#define FixStockFontSizeW FixStockFontSizeA
315
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000316#define TRACE_SEC(handle,text) \
317 TRACE("(%04x): " text " %ld\n", (handle), GDI_level.crst.RecursionCount)
Francis Beaudet12668f51999-10-31 17:32:26 +0000318
319/***********************************************************************
Alexandre Julliard401710d1993-09-04 10:09:32 +0000320 * GDI_Init
321 *
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000322 * GDI initialization.
Alexandre Julliard401710d1993-09-04 10:09:32 +0000323 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000324BOOL GDI_Init(void)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000325{
Richard Cohen05bf5341999-09-03 15:16:23 +0000326 BOOL systemIsBold = (TWEAK_WineLook == WIN31_LOOK);
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000327 HPALETTE16 hpalette;
328 HINSTANCE16 instance;
329
330 _CreateSysLevel( &GDI_level, 3 );
331
332 /* create GDI heap */
333 if ((instance = LoadLibrary16( "GDI.EXE" )) < 32) return FALSE;
334 GDI_HeapSel = GlobalHandleToSel16( instance );
Richard Cohen05bf5341999-09-03 15:16:23 +0000335
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000336 /* Kill some warnings. */
337 (void)align_OEMFixedFont;
338 (void)align_AnsiFixedFont;
339 (void)align_AnsiVarFont;
340 (void)align_SystemFont;
341 (void)align_DeviceDefaultFont;
342 (void)align_SystemFixedFont;
343 (void)align_DefaultGuiFont;
344
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000345 /* TWEAK: Initialize font hints */
Richard Cohen05bf5341999-09-03 15:16:23 +0000346 ReadFontInformation("OEMFixed", &OEMFixedFont, 0, 0, 0, 0, 0);
347 ReadFontInformation("AnsiFixed", &AnsiFixedFont, 0, 0, 0, 0, 0);
348 ReadFontInformation("AnsiVar", &AnsiVarFont, 0, 0, 0, 0, 0);
349 ReadFontInformation("System", &SystemFont, 0, systemIsBold, 0, 0, 0);
350 ReadFontInformation("DeviceDefault", &DeviceDefaultFont, 0, 0, 0, 0, 0);
351 ReadFontInformation("SystemFixed", &SystemFixedFont, 0, systemIsBold, 0, 0, 0);
352 ReadFontInformation("DefaultGui", &DefaultGuiFont, 0, 0, 0, 0, 0);
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000353
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +0000354 /* Create default palette */
355
356 /* DR well *this* palette can't be moveable (?) */
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000357 hpalette = PALETTE_Init();
358 if( !hpalette ) return FALSE;
359 StockObjects[DEFAULT_PALETTE] = (GDIOBJHDR *)LOCAL_Lock( GDI_HeapSel, hpalette );
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000360
Gerard Pateld1795f62000-01-09 20:52:53 +0000361 hPseudoStockBitmap = CreateBitmap( 1, 1, 1, 1, NULL );
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000362 return TRUE;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000363}
364
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000365#define FIRST_LARGE_HANDLE 16
366#define MAX_LARGE_HANDLES ((GDI_HEAP_SIZE - FIRST_LARGE_HANDLE) >> 2)
367static GDIOBJHDR *large_handles[MAX_LARGE_HANDLES];
368static int next_large_handle;
369
370/***********************************************************************
371 * alloc_large_heap
372 *
373 * Allocate a GDI handle from the large heap. Helper for GDI_AllocObject
374 */
375inline static GDIOBJHDR *alloc_large_heap( WORD size, HGDIOBJ *handle )
376{
377 int i;
378 GDIOBJHDR *obj;
379
380 for (i = next_large_handle + 1; i < MAX_LARGE_HANDLES; i++)
381 if (!large_handles[i]) goto found;
382 for (i = 0; i <= next_large_handle; i++)
383 if (!large_handles[i]) goto found;
384 *handle = 0;
385 return NULL;
386
387 found:
388 if ((obj = HeapAlloc( GetProcessHeap(), 0, size )))
389 {
390 large_handles[i] = obj;
391 *handle = (i + FIRST_LARGE_HANDLE) << 2;
392 next_large_handle = i;
393 }
394 return obj;
395}
396
Alexandre Julliard401710d1993-09-04 10:09:32 +0000397
398/***********************************************************************
Alexandre Julliard401710d1993-09-04 10:09:32 +0000399 * GDI_AllocObject
400 */
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000401void *GDI_AllocObject( WORD size, WORD magic, HGDIOBJ *handle )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000402{
403 static DWORD count = 0;
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000404 GDIOBJHDR *obj;
405
406 _EnterSysLevel( &GDI_level );
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000407 switch(magic)
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000408 {
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000409 /* allocate DCs on the larger heap */
410 case DC_MAGIC:
411 case DISABLED_DC_MAGIC:
412 case META_DC_MAGIC:
413 case METAFILE_MAGIC:
414 case METAFILE_DC_MAGIC:
415 case ENHMETAFILE_MAGIC:
416 case ENHMETAFILE_DC_MAGIC:
417 if (!(obj = alloc_large_heap( size, handle ))) goto error;
418 break;
419 default:
420 if (!(*handle = LOCAL_Alloc( GDI_HeapSel, LMEM_MOVEABLE, size ))) goto error;
421 assert( *handle & 2 );
422 obj = (GDIOBJHDR *)LOCAL_Lock( GDI_HeapSel, *handle );
423 break;
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000424 }
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000425
Alexandre Julliard401710d1993-09-04 10:09:32 +0000426 obj->hNext = 0;
Andreas Mohr007fb242000-09-16 20:53:51 +0000427 obj->wMagic = magic|OBJECT_NOSYSTEM;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000428 obj->dwCount = ++count;
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000429
430 TRACE_SEC( *handle, "enter" );
431 return obj;
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000432
433error:
434 _LeaveSysLevel( &GDI_level );
435 *handle = 0;
436 return NULL;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000437}
438
439
440/***********************************************************************
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000441 * GDI_ReallocObject
442 *
443 * The object ptr must have been obtained with GDI_GetObjPtr.
444 * The new pointer must be released with GDI_ReleaseObj.
445 */
446void *GDI_ReallocObject( WORD size, HGDIOBJ handle, void *object )
447{
448 HGDIOBJ new_handle;
449
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000450 assert( handle & 2 ); /* no realloc for large handles */
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000451 LOCAL_Unlock( GDI_HeapSel, handle );
452 if (!(new_handle = LOCAL_ReAlloc( GDI_HeapSel, handle, size, LMEM_MOVEABLE )))
453 {
454 TRACE_SEC( handle, "leave" );
455 _LeaveSysLevel( &GDI_level );
456 return NULL;
457 }
458 assert( new_handle == handle ); /* moveable handle cannot change */
459 return LOCAL_Lock( GDI_HeapSel, handle );
460}
461
462
463/***********************************************************************
Alexandre Julliard401710d1993-09-04 10:09:32 +0000464 * GDI_FreeObject
465 */
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000466BOOL GDI_FreeObject( HGDIOBJ handle, void *ptr )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000467{
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000468 GDIOBJHDR *object = ptr;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000469
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000470 /* can't free stock objects */
471 if (handle < FIRST_STOCK_HANDLE)
472 {
473 object->wMagic = 0; /* Mark it as invalid */
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000474 if (handle & 2) /* GDI heap handle */
475 {
476 LOCAL_Unlock( GDI_HeapSel, handle );
477 LOCAL_Free( GDI_HeapSel, handle );
478 }
479 else /* large heap handle */
480 {
481 int i = (handle >> 2) - FIRST_LARGE_HANDLE;
482 if (i >= 0 && large_handles[i])
483 {
484 HeapFree( GetProcessHeap(), 0, large_handles[i] );
485 large_handles[i] = NULL;
486 }
487 }
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000488 }
489 TRACE_SEC( handle, "leave" );
490 _LeaveSysLevel( &GDI_level );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000491 return TRUE;
492}
493
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000494
Alexandre Julliard401710d1993-09-04 10:09:32 +0000495/***********************************************************************
496 * GDI_GetObjPtr
497 *
498 * Return a pointer to the GDI object associated to the handle.
499 * Return NULL if the object has the wrong magic number.
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000500 * The object must be released with GDI_ReleaseObj.
Alexandre Julliard401710d1993-09-04 10:09:32 +0000501 */
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000502void *GDI_GetObjPtr( HGDIOBJ handle, WORD magic )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000503{
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000504 GDIOBJHDR *ptr = NULL;
505
506 _EnterSysLevel( &GDI_level );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000507
Matthew Cline20512fd2000-02-13 16:00:17 +0000508 if (handle >= FIRST_STOCK_HANDLE)
509 {
510 if (handle <= LAST_STOCK_HANDLE) ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
Andreas Mohr007fb242000-09-16 20:53:51 +0000511 if (ptr && (magic != MAGIC_DONTCARE)
512 && (GDIMAGIC(ptr->wMagic) != magic)) ptr = NULL;
Matthew Cline20512fd2000-02-13 16:00:17 +0000513 }
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000514 else if (handle & 2) /* GDI heap handle */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000515 {
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000516 ptr = (GDIOBJHDR *)LOCAL_Lock( GDI_HeapSel, handle );
Andreas Mohr007fb242000-09-16 20:53:51 +0000517 if (ptr &&
518 (magic != MAGIC_DONTCARE) && (GDIMAGIC(ptr->wMagic) != magic))
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000519 {
520 LOCAL_Unlock( GDI_HeapSel, handle );
521 ptr = NULL;
522 }
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000523 }
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000524 else /* large heap handle */
525 {
526 int i = (handle >> 2) - FIRST_LARGE_HANDLE;
527 if (i >= 0)
528 {
529 ptr = large_handles[i];
530 if (ptr && (magic != MAGIC_DONTCARE) && (GDIMAGIC(ptr->wMagic) != magic)) ptr = NULL;
531 }
532 }
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000533
534 if (!ptr)
535 {
536 _LeaveSysLevel( &GDI_level );
537 SetLastError( ERROR_INVALID_HANDLE );
538 }
539 else TRACE_SEC( handle, "enter" );
540
Alexandre Julliard401710d1993-09-04 10:09:32 +0000541 return ptr;
542}
543
544
545/***********************************************************************
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000546 * GDI_ReleaseObj
547 *
548 */
549void GDI_ReleaseObj( HGDIOBJ handle )
550{
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000551 if (handle < FIRST_STOCK_HANDLE && (handle & 2)) LOCAL_Unlock( GDI_HeapSel, handle );
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000552 TRACE_SEC( handle, "leave" );
553 _LeaveSysLevel( &GDI_level );
554}
555
556
557/***********************************************************************
Alexandre Julliard139a4b11996-11-02 14:24:07 +0000558 * DeleteObject16 (GDI.69)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000559 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000560BOOL16 WINAPI DeleteObject16( HGDIOBJ16 obj )
Alexandre Julliard139a4b11996-11-02 14:24:07 +0000561{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000562 return DeleteObject( obj );
Alexandre Julliard139a4b11996-11-02 14:24:07 +0000563}
564
565
566/***********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +0000567 * DeleteObject (GDI32.70)
Alexandre Julliard139a4b11996-11-02 14:24:07 +0000568 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000569BOOL WINAPI DeleteObject( HGDIOBJ obj )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000570{
571 /* Check if object is valid */
572
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000573 GDIOBJHDR * header;
574 if (HIWORD(obj)) return FALSE;
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000575 if ((obj >= FIRST_STOCK_HANDLE) && (obj <= LAST_STOCK_HANDLE)) {
576 TRACE("Preserving Stock object %04x\n", obj );
577 /* NOTE: No GDI_Release is necessary */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000578 return TRUE;
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000579 }
Gerard Patel5faa5d72000-08-25 21:54:23 +0000580 if (obj == hPseudoStockBitmap) return TRUE;
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000581 if (!(header = GDI_GetObjPtr( obj, MAGIC_DONTCARE ))) return FALSE;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000582
Andreas Mohr007fb242000-09-16 20:53:51 +0000583 if (!(header->wMagic & OBJECT_NOSYSTEM)
584 && (header->wMagic >= FIRST_MAGIC) && (header->wMagic <= LAST_MAGIC))
585 {
586 TRACE("Preserving system object %04x\n", obj);
587 GDI_ReleaseObj( obj );
588 return TRUE;
589 }
590
Alexandre Julliard15657091999-05-23 10:25:25 +0000591 TRACE("%04x\n", obj );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000592
593 /* Delete object */
594
Andreas Mohr007fb242000-09-16 20:53:51 +0000595 switch(GDIMAGIC(header->wMagic))
Alexandre Julliard401710d1993-09-04 10:09:32 +0000596 {
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000597 case PEN_MAGIC: return GDI_FreeObject( obj, header );
Alexandre Julliard7cbe6571995-01-09 18:21:16 +0000598 case BRUSH_MAGIC: return BRUSH_DeleteObject( obj, (BRUSHOBJ*)header );
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000599 case FONT_MAGIC: return GDI_FreeObject( obj, header );
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000600 case PALETTE_MAGIC: return PALETTE_DeleteObject(obj,(PALETTEOBJ*)header);
Alexandre Julliard7cbe6571995-01-09 18:21:16 +0000601 case BITMAP_MAGIC: return BITMAP_DeleteObject( obj, (BITMAPOBJ*)header);
602 case REGION_MAGIC: return REGION_DeleteObject( obj, (RGNOBJ*)header );
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000603 case DC_MAGIC:
604 GDI_ReleaseObj( obj );
605 return DeleteDC(obj);
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000606 case 0 :
Alexandre Julliard15657091999-05-23 10:25:25 +0000607 WARN("Already deleted\n");
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000608 break;
609 default:
Andreas Mohr007fb242000-09-16 20:53:51 +0000610 WARN("Unknown magic number (%d)\n",GDIMAGIC(header->wMagic));
Alexandre Julliard401710d1993-09-04 10:09:32 +0000611 }
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000612 GDI_ReleaseObj( obj );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000613 return FALSE;
614}
615
Alexandre Julliard401710d1993-09-04 10:09:32 +0000616/***********************************************************************
Alexandre Julliard139a4b11996-11-02 14:24:07 +0000617 * GetStockObject16 (GDI.87)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000618 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000619HGDIOBJ16 WINAPI GetStockObject16( INT16 obj )
Alexandre Julliard139a4b11996-11-02 14:24:07 +0000620{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000621 return (HGDIOBJ16)GetStockObject( obj );
Alexandre Julliard139a4b11996-11-02 14:24:07 +0000622}
623
624
625/***********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +0000626 * GetStockObject (GDI32.220)
Alexandre Julliard139a4b11996-11-02 14:24:07 +0000627 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000628HGDIOBJ WINAPI GetStockObject( INT obj )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000629{
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000630 HGDIOBJ ret;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000631 if ((obj < 0) || (obj >= NB_STOCK_OBJECTS)) return 0;
632 if (!StockObjects[obj]) return 0;
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000633 ret = (HGDIOBJ16)(FIRST_STOCK_HANDLE + obj);
634 TRACE("returning %4x\n", ret );
635 return ret;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000636}
637
638
639/***********************************************************************
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000640 * GetObject16 (GDI.82)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000641 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000642INT16 WINAPI GetObject16( HANDLE16 handle, INT16 count, LPVOID buffer )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000643{
Matthew Cline20512fd2000-02-13 16:00:17 +0000644 GDIOBJHDR * ptr;
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000645 INT16 result = 0;
Alexandre Julliard15657091999-05-23 10:25:25 +0000646 TRACE("%04x %d %p\n", handle, count, buffer );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000647 if (!count) return 0;
648
Matthew Cline20512fd2000-02-13 16:00:17 +0000649 if (!(ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE ))) return 0;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000650
Andreas Mohr007fb242000-09-16 20:53:51 +0000651 switch(GDIMAGIC(ptr->wMagic))
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000652 {
Alexandre Julliard401710d1993-09-04 10:09:32 +0000653 case PEN_MAGIC:
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000654 result = PEN_GetObject16( (PENOBJ *)ptr, count, buffer );
655 break;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000656 case BRUSH_MAGIC:
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000657 result = BRUSH_GetObject16( (BRUSHOBJ *)ptr, count, buffer );
658 break;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000659 case BITMAP_MAGIC:
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000660 result = BITMAP_GetObject16( (BITMAPOBJ *)ptr, count, buffer );
661 break;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000662 case FONT_MAGIC:
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000663 result = FONT_GetObject16( (FONTOBJ *)ptr, count, buffer );
Francis Beaudet12668f51999-10-31 17:32:26 +0000664
665 /*
666 * Fix the LOGFONT structure for the stock fonts
667 */
668 if ( (handle >= FIRST_STOCK_HANDLE) &&
669 (handle <= LAST_STOCK_HANDLE) )
670 FixStockFontSize16(handle, count, buffer);
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000671 break;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000672 case PALETTE_MAGIC:
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000673 result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer );
674 break;
675 }
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000676 GDI_ReleaseObj( handle );
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000677 return result;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000678}
679
680
681/***********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +0000682 * GetObjectA (GDI32.204)
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000683 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000684INT WINAPI GetObjectA( HANDLE handle, INT count, LPVOID buffer )
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000685{
Matthew Cline20512fd2000-02-13 16:00:17 +0000686 GDIOBJHDR * ptr;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000687 INT result = 0;
Alexandre Julliard15657091999-05-23 10:25:25 +0000688 TRACE("%08x %d %p\n", handle, count, buffer );
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000689 if (!count) return 0;
690
Matthew Cline20512fd2000-02-13 16:00:17 +0000691 if (!(ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE ))) return 0;
692
Andreas Mohr007fb242000-09-16 20:53:51 +0000693 switch(GDIMAGIC(ptr->wMagic))
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000694 {
Alexandre Julliard139a4b11996-11-02 14:24:07 +0000695 case PEN_MAGIC:
Alexandre Julliarda3960291999-02-26 11:11:13 +0000696 result = PEN_GetObject( (PENOBJ *)ptr, count, buffer );
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000697 break;
Alexandre Julliard139a4b11996-11-02 14:24:07 +0000698 case BRUSH_MAGIC:
Alexandre Julliarda3960291999-02-26 11:11:13 +0000699 result = BRUSH_GetObject( (BRUSHOBJ *)ptr, count, buffer );
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000700 break;
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000701 case BITMAP_MAGIC:
Alexandre Julliarda3960291999-02-26 11:11:13 +0000702 result = BITMAP_GetObject( (BITMAPOBJ *)ptr, count, buffer );
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000703 break;
Alexandre Julliard0e270f41996-08-24 18:26:35 +0000704 case FONT_MAGIC:
Alexandre Julliarda3960291999-02-26 11:11:13 +0000705 result = FONT_GetObjectA( (FONTOBJ *)ptr, count, buffer );
Francis Beaudet12668f51999-10-31 17:32:26 +0000706
707 /*
708 * Fix the LOGFONT structure for the stock fonts
709 */
710 if ( (handle >= FIRST_STOCK_HANDLE) &&
711 (handle <= LAST_STOCK_HANDLE) )
712 FixStockFontSizeA(handle, count, buffer);
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000713 break;
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000714 case PALETTE_MAGIC:
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000715 result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer );
716 break;
Matthew Cline20512fd2000-02-13 16:00:17 +0000717
718 case REGION_MAGIC:
719 case DC_MAGIC:
720 case DISABLED_DC_MAGIC:
721 case META_DC_MAGIC:
722 case METAFILE_MAGIC:
723 case METAFILE_DC_MAGIC:
724 case ENHMETAFILE_MAGIC:
725 case ENHMETAFILE_DC_MAGIC:
Andreas Mohr007fb242000-09-16 20:53:51 +0000726 FIXME("Magic %04x not implemented\n", GDIMAGIC(ptr->wMagic) );
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000727 break;
Matthew Cline20512fd2000-02-13 16:00:17 +0000728
729 default:
Andreas Mohr007fb242000-09-16 20:53:51 +0000730 ERR("Invalid GDI Magic %04x\n", GDIMAGIC(ptr->wMagic));
Andreas Mohr024e8812000-08-25 21:30:34 +0000731 break;
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000732 }
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000733 GDI_ReleaseObj( handle );
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000734 return result;
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000735}
Matthew Cline20512fd2000-02-13 16:00:17 +0000736
Juergen Schmiedcba84881998-10-23 13:27:36 +0000737/***********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +0000738 * GetObjectW (GDI32.206)
Juergen Schmiedcba84881998-10-23 13:27:36 +0000739 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000740INT WINAPI GetObjectW( HANDLE handle, INT count, LPVOID buffer )
Juergen Schmiedcba84881998-10-23 13:27:36 +0000741{
Matthew Cline20512fd2000-02-13 16:00:17 +0000742 GDIOBJHDR * ptr;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000743 INT result = 0;
Alexandre Julliard15657091999-05-23 10:25:25 +0000744 TRACE("%08x %d %p\n", handle, count, buffer );
Juergen Schmiedcba84881998-10-23 13:27:36 +0000745 if (!count) return 0;
746
Matthew Cline20512fd2000-02-13 16:00:17 +0000747 if (!(ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE ))) return 0;
748
Andreas Mohr007fb242000-09-16 20:53:51 +0000749 switch(GDIMAGIC(ptr->wMagic))
Juergen Schmiedcba84881998-10-23 13:27:36 +0000750 {
751 case PEN_MAGIC:
Alexandre Julliarda3960291999-02-26 11:11:13 +0000752 result = PEN_GetObject( (PENOBJ *)ptr, count, buffer );
Juergen Schmiedcba84881998-10-23 13:27:36 +0000753 break;
754 case BRUSH_MAGIC:
Alexandre Julliarda3960291999-02-26 11:11:13 +0000755 result = BRUSH_GetObject( (BRUSHOBJ *)ptr, count, buffer );
Juergen Schmiedcba84881998-10-23 13:27:36 +0000756 break;
757 case BITMAP_MAGIC:
Alexandre Julliarda3960291999-02-26 11:11:13 +0000758 result = BITMAP_GetObject( (BITMAPOBJ *)ptr, count, buffer );
Juergen Schmiedcba84881998-10-23 13:27:36 +0000759 break;
760 case FONT_MAGIC:
Alexandre Julliarda3960291999-02-26 11:11:13 +0000761 result = FONT_GetObjectW( (FONTOBJ *)ptr, count, buffer );
Francis Beaudet12668f51999-10-31 17:32:26 +0000762
763 /*
764 * Fix the LOGFONT structure for the stock fonts
765 */
766 if ( (handle >= FIRST_STOCK_HANDLE) &&
767 (handle <= LAST_STOCK_HANDLE) )
768 FixStockFontSizeW(handle, count, buffer);
Juergen Schmiedcba84881998-10-23 13:27:36 +0000769 break;
770 case PALETTE_MAGIC:
771 result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer );
772 break;
773 default:
Andreas Mohr007fb242000-09-16 20:53:51 +0000774 FIXME("Magic %04x not implemented\n", GDIMAGIC(ptr->wMagic) );
Juergen Schmiedcba84881998-10-23 13:27:36 +0000775 break;
776 }
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000777 GDI_ReleaseObj( handle );
Juergen Schmiedcba84881998-10-23 13:27:36 +0000778 return result;
779}
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000780
Alexandre Julliard491502b1997-11-01 19:08:16 +0000781/***********************************************************************
782 * GetObjectType (GDI32.205)
783 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000784DWORD WINAPI GetObjectType( HANDLE handle )
Alexandre Julliard491502b1997-11-01 19:08:16 +0000785{
Matthew Cline20512fd2000-02-13 16:00:17 +0000786 GDIOBJHDR * ptr;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000787 INT result = 0;
Alexandre Julliard15657091999-05-23 10:25:25 +0000788 TRACE("%08x\n", handle );
Alexandre Julliard491502b1997-11-01 19:08:16 +0000789
Matthew Cline20512fd2000-02-13 16:00:17 +0000790 if (!(ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE ))) return 0;
Alexandre Julliard491502b1997-11-01 19:08:16 +0000791
Andreas Mohr007fb242000-09-16 20:53:51 +0000792 switch(GDIMAGIC(ptr->wMagic))
Alexandre Julliard491502b1997-11-01 19:08:16 +0000793 {
794 case PEN_MAGIC:
795 result = OBJ_PEN;
796 break;
797 case BRUSH_MAGIC:
798 result = OBJ_BRUSH;
799 break;
800 case BITMAP_MAGIC:
801 result = OBJ_BITMAP;
802 break;
803 case FONT_MAGIC:
804 result = OBJ_FONT;
805 break;
806 case PALETTE_MAGIC:
807 result = OBJ_PAL;
808 break;
809 case REGION_MAGIC:
810 result = OBJ_REGION;
811 break;
812 case DC_MAGIC:
813 result = OBJ_DC;
814 break;
815 case META_DC_MAGIC:
816 result = OBJ_METADC;
817 break;
818 case METAFILE_MAGIC:
819 result = OBJ_METAFILE;
820 break;
821 case METAFILE_DC_MAGIC:
822 result = OBJ_METADC;
823 break;
Huw D M Davies7603dea1999-04-25 09:24:23 +0000824 case ENHMETAFILE_MAGIC:
825 result = OBJ_ENHMETAFILE;
826 break;
827 case ENHMETAFILE_DC_MAGIC:
828 result = OBJ_ENHMETADC;
829 break;
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000830 default:
Andreas Mohr007fb242000-09-16 20:53:51 +0000831 FIXME("Magic %04x not implemented\n", GDIMAGIC(ptr->wMagic) );
Alexandre Julliard491502b1997-11-01 19:08:16 +0000832 break;
833 }
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000834 GDI_ReleaseObj( handle );
Alexandre Julliard491502b1997-11-01 19:08:16 +0000835 return result;
836}
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000837
838/***********************************************************************
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000839 * GetCurrentObject (GDI32.166)
840 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000841HANDLE WINAPI GetCurrentObject(HDC hdc,UINT type)
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000842{
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000843 HANDLE ret = 0;
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000844 DC * dc = DC_GetDCPtr( hdc );
845
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000846 if (dc)
847 {
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000848 switch (type) {
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000849 case OBJ_PEN: ret = dc->hPen; break;
850 case OBJ_BRUSH: ret = dc->hBrush; break;
851 case OBJ_PAL: ret = dc->hPalette; break;
852 case OBJ_FONT: ret = dc->hFont; break;
853 case OBJ_BITMAP: ret = dc->hBitmap; break;
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000854 default:
855 /* the SDK only mentions those above */
Andreas Mohr007fb242000-09-16 20:53:51 +0000856 FIXME("(%08x,%d): unknown type.\n",hdc,type);
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000857 break;
858 }
859 GDI_ReleaseObj( hdc );
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000860 }
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000861 return ret;
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000862}
863
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000864
865/***********************************************************************
Alexandre Julliard139a4b11996-11-02 14:24:07 +0000866 * SelectObject16 (GDI.45)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000867 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000868HGDIOBJ16 WINAPI SelectObject16( HDC16 hdc, HGDIOBJ16 handle )
Alexandre Julliard139a4b11996-11-02 14:24:07 +0000869{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000870 return (HGDIOBJ16)SelectObject( hdc, handle );
Alexandre Julliard139a4b11996-11-02 14:24:07 +0000871}
872
873
874/***********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +0000875 * SelectObject (GDI32.299)
Alexandre Julliard139a4b11996-11-02 14:24:07 +0000876 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000877HGDIOBJ WINAPI SelectObject( HDC hdc, HGDIOBJ handle )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000878{
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000879 HGDIOBJ ret = 0;
880 DC * dc = DC_GetDCUpdate( hdc );
881 if (!dc) return 0;
Alexandre Julliard15657091999-05-23 10:25:25 +0000882 TRACE("hdc=%04x %04x\n", hdc, handle );
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000883 if (dc->funcs->pSelectObject)
884 ret = dc->funcs->pSelectObject( dc, handle );
885 GDI_ReleaseObj( hdc );
886 return ret;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000887}
888
889
890/***********************************************************************
Alexandre Julliard139a4b11996-11-02 14:24:07 +0000891 * UnrealizeObject16 (GDI.150)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000892 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000893BOOL16 WINAPI UnrealizeObject16( HGDIOBJ16 obj )
Alexandre Julliard139a4b11996-11-02 14:24:07 +0000894{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000895 return UnrealizeObject( obj );
Alexandre Julliard139a4b11996-11-02 14:24:07 +0000896}
897
898
899/***********************************************************************
900 * UnrealizeObject (GDI32.358)
901 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000902BOOL WINAPI UnrealizeObject( HGDIOBJ obj )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000903{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000904 BOOL result = TRUE;
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000905 /* Check if object is valid */
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000906
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000907 GDIOBJHDR * header = GDI_GetObjPtr( obj, MAGIC_DONTCARE );
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000908 if (!header) return FALSE;
909
Alexandre Julliard15657091999-05-23 10:25:25 +0000910 TRACE("%04x\n", obj );
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000911
912 /* Unrealize object */
913
Andreas Mohr007fb242000-09-16 20:53:51 +0000914 switch(GDIMAGIC(header->wMagic))
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000915 {
916 case PALETTE_MAGIC:
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000917 result = PALETTE_UnrealizeObject( obj, (PALETTEOBJ *)header );
918 break;
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000919
920 case BRUSH_MAGIC:
921 /* Windows resets the brush origin. We don't need to. */
922 break;
923 }
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000924 GDI_ReleaseObj( obj );
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000925 return result;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000926}
Alexandre Julliard1f579291994-05-25 16:25:21 +0000927
928
929/***********************************************************************
Alexandre Julliard139a4b11996-11-02 14:24:07 +0000930 * EnumObjects16 (GDI.71)
Alexandre Julliard1f579291994-05-25 16:25:21 +0000931 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000932INT16 WINAPI EnumObjects16( HDC16 hdc, INT16 nObjType,
933 GOBJENUMPROC16 lpEnumFunc, LPARAM lParam )
Alexandre Julliard1f579291994-05-25 16:25:21 +0000934{
Alexandre Julliardd7d4fdf1995-12-26 15:05:24 +0000935 /* Solid colors to enumerate */
936 static const COLORREF solid_colors[] =
937 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
938 RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
939 RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
940 RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
941 RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
942 RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
943 RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
944 RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
945 };
946
Alexandre Julliard139a4b11996-11-02 14:24:07 +0000947 INT16 i, retval = 0;
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000948 LOGPEN16 *pen;
949 LOGBRUSH16 *brush = NULL;
Alexandre Julliardd7d4fdf1995-12-26 15:05:24 +0000950
Alexandre Julliard15657091999-05-23 10:25:25 +0000951 TRACE("%04x %d %08lx %08lx\n",
Alexandre Julliardd7d4fdf1995-12-26 15:05:24 +0000952 hdc, nObjType, (DWORD)lpEnumFunc, lParam );
953 switch(nObjType)
954 {
955 case OBJ_PEN:
956 /* Enumerate solid pens */
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000957 if (!(pen = SEGPTR_NEW(LOGPEN16))) break;
Alexandre Julliardd7d4fdf1995-12-26 15:05:24 +0000958 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
959 {
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000960 pen->lopnStyle = PS_SOLID;
961 pen->lopnWidth.x = 1;
962 pen->lopnWidth.y = 0;
963 pen->lopnColor = solid_colors[i];
Alexandre Julliardf1aa3031996-08-05 17:42:43 +0000964 retval = lpEnumFunc( SEGPTR_GET(pen), lParam );
Alexandre Julliard15657091999-05-23 10:25:25 +0000965 TRACE("solid pen %08lx, ret=%d\n",
Alexandre Julliardd7d4fdf1995-12-26 15:05:24 +0000966 solid_colors[i], retval);
967 if (!retval) break;
968 }
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000969 SEGPTR_FREE(pen);
Alexandre Julliardd7d4fdf1995-12-26 15:05:24 +0000970 break;
971
972 case OBJ_BRUSH:
973 /* Enumerate solid brushes */
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000974 if (!(brush = SEGPTR_NEW(LOGBRUSH16))) break;
Alexandre Julliardd7d4fdf1995-12-26 15:05:24 +0000975 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
976 {
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000977 brush->lbStyle = BS_SOLID;
978 brush->lbColor = solid_colors[i];
979 brush->lbHatch = 0;
Alexandre Julliardf1aa3031996-08-05 17:42:43 +0000980 retval = lpEnumFunc( SEGPTR_GET(brush), lParam );
Alexandre Julliard15657091999-05-23 10:25:25 +0000981 TRACE("solid brush %08lx, ret=%d\n",
Alexandre Julliardd7d4fdf1995-12-26 15:05:24 +0000982 solid_colors[i], retval);
983 if (!retval) break;
984 }
Alexandre Julliardd7d4fdf1995-12-26 15:05:24 +0000985
986 /* Now enumerate hatched brushes */
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000987 if (retval) for (i = HS_HORIZONTAL; i <= HS_DIAGCROSS; i++)
Alexandre Julliardd7d4fdf1995-12-26 15:05:24 +0000988 {
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000989 brush->lbStyle = BS_HATCHED;
990 brush->lbColor = RGB(0,0,0);
991 brush->lbHatch = i;
Alexandre Julliardf1aa3031996-08-05 17:42:43 +0000992 retval = lpEnumFunc( SEGPTR_GET(brush), lParam );
Alexandre Julliard15657091999-05-23 10:25:25 +0000993 TRACE("hatched brush %d, ret=%d\n",
Alexandre Julliardd7d4fdf1995-12-26 15:05:24 +0000994 i, retval);
995 if (!retval) break;
996 }
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000997 SEGPTR_FREE(brush);
Alexandre Julliardd7d4fdf1995-12-26 15:05:24 +0000998 break;
999
1000 default:
Alexandre Julliard15657091999-05-23 10:25:25 +00001001 WARN("(%d): Invalid type\n", nObjType );
Alexandre Julliard139a4b11996-11-02 14:24:07 +00001002 break;
1003 }
1004 return retval;
1005}
1006
1007
1008/***********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00001009 * EnumObjects (GDI32.89)
Alexandre Julliard139a4b11996-11-02 14:24:07 +00001010 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001011INT WINAPI EnumObjects( HDC hdc, INT nObjType,
1012 GOBJENUMPROC lpEnumFunc, LPARAM lParam )
Alexandre Julliard139a4b11996-11-02 14:24:07 +00001013{
1014 /* Solid colors to enumerate */
1015 static const COLORREF solid_colors[] =
1016 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
1017 RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
1018 RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
1019 RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
1020 RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
1021 RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
1022 RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
1023 RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
1024 };
1025
Alexandre Julliarda3960291999-02-26 11:11:13 +00001026 INT i, retval = 0;
1027 LOGPEN pen;
1028 LOGBRUSH brush;
Alexandre Julliard139a4b11996-11-02 14:24:07 +00001029
Alexandre Julliard15657091999-05-23 10:25:25 +00001030 TRACE("%04x %d %08lx %08lx\n",
Alexandre Julliard139a4b11996-11-02 14:24:07 +00001031 hdc, nObjType, (DWORD)lpEnumFunc, lParam );
1032 switch(nObjType)
1033 {
1034 case OBJ_PEN:
1035 /* Enumerate solid pens */
1036 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
1037 {
1038 pen.lopnStyle = PS_SOLID;
1039 pen.lopnWidth.x = 1;
1040 pen.lopnWidth.y = 0;
1041 pen.lopnColor = solid_colors[i];
1042 retval = lpEnumFunc( &pen, lParam );
Alexandre Julliard15657091999-05-23 10:25:25 +00001043 TRACE("solid pen %08lx, ret=%d\n",
Alexandre Julliard139a4b11996-11-02 14:24:07 +00001044 solid_colors[i], retval);
1045 if (!retval) break;
1046 }
1047 break;
1048
1049 case OBJ_BRUSH:
1050 /* Enumerate solid brushes */
1051 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
1052 {
1053 brush.lbStyle = BS_SOLID;
1054 brush.lbColor = solid_colors[i];
1055 brush.lbHatch = 0;
1056 retval = lpEnumFunc( &brush, lParam );
Alexandre Julliard15657091999-05-23 10:25:25 +00001057 TRACE("solid brush %08lx, ret=%d\n",
Alexandre Julliard139a4b11996-11-02 14:24:07 +00001058 solid_colors[i], retval);
1059 if (!retval) break;
1060 }
1061
1062 /* Now enumerate hatched brushes */
1063 if (retval) for (i = HS_HORIZONTAL; i <= HS_DIAGCROSS; i++)
1064 {
1065 brush.lbStyle = BS_HATCHED;
1066 brush.lbColor = RGB(0,0,0);
1067 brush.lbHatch = i;
1068 retval = lpEnumFunc( &brush, lParam );
Alexandre Julliard15657091999-05-23 10:25:25 +00001069 TRACE("hatched brush %d, ret=%d\n",
Alexandre Julliard139a4b11996-11-02 14:24:07 +00001070 i, retval);
1071 if (!retval) break;
1072 }
1073 break;
1074
1075 default:
1076 /* FIXME: implement Win32 types */
Alexandre Julliard15657091999-05-23 10:25:25 +00001077 WARN("(%d): Invalid type\n", nObjType );
Alexandre Julliardd7d4fdf1995-12-26 15:05:24 +00001078 break;
1079 }
1080 return retval;
Alexandre Julliard1f579291994-05-25 16:25:21 +00001081}
Alexandre Julliard7cc9c0c1994-06-15 15:45:11 +00001082
Alexandre Julliardd7d4fdf1995-12-26 15:05:24 +00001083
Alexandre Julliard7cc9c0c1994-06-15 15:45:11 +00001084/***********************************************************************
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001085 * IsGDIObject (GDI.462)
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001086 *
1087 * returns type of object if valid (W95 system programming secrets p. 264-5)
Alexandre Julliard7cc9c0c1994-06-15 15:45:11 +00001088 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001089BOOL16 WINAPI IsGDIObject16( HGDIOBJ16 handle )
Alexandre Julliard7cc9c0c1994-06-15 15:45:11 +00001090{
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001091 UINT16 magic = 0;
1092
Alexandre Julliard2a2321b2000-08-19 21:38:55 +00001093 GDIOBJHDR *object = GDI_GetObjPtr( handle, MAGIC_DONTCARE );
1094 if (object)
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001095 {
Andreas Mohr007fb242000-09-16 20:53:51 +00001096 magic = GDIMAGIC(object->wMagic) - PEN_MAGIC + 1;
Alexandre Julliard2a2321b2000-08-19 21:38:55 +00001097 GDI_ReleaseObj( handle );
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001098 }
Alexandre Julliard2a2321b2000-08-19 21:38:55 +00001099 return magic;
Alexandre Julliard7cc9c0c1994-06-15 15:45:11 +00001100}
Alexandre Julliard1285c2f1996-05-06 16:06:24 +00001101
1102
1103/***********************************************************************
Alexandre Julliard17216f51997-10-12 16:30:17 +00001104 * SetObjectOwner16 (GDI.461)
1105 */
1106void WINAPI SetObjectOwner16( HGDIOBJ16 handle, HANDLE16 owner )
1107{
1108 /* Nothing to do */
1109}
1110
1111
1112/***********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00001113 * SetObjectOwner (GDI32.386)
Alexandre Julliard17216f51997-10-12 16:30:17 +00001114 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001115void WINAPI SetObjectOwner( HGDIOBJ handle, HANDLE owner )
Alexandre Julliard17216f51997-10-12 16:30:17 +00001116{
1117 /* Nothing to do */
1118}
1119
Andreas Mohr007fb242000-09-16 20:53:51 +00001120
Alexandre Julliard491502b1997-11-01 19:08:16 +00001121/***********************************************************************
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001122 * MakeObjectPrivate (GDI.463)
Andreas Mohr007fb242000-09-16 20:53:51 +00001123 *
1124 * What does that mean ?
1125 * Some little docu can be found in "Undocumented Windows",
1126 * but this is basically useless.
1127 * At least we know that this flags the GDI object's wMagic
1128 * with 0x2000 (OBJECT_PRIVATE), so we just do it.
1129 * But Wine doesn't react on that yet.
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001130 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001131void WINAPI MakeObjectPrivate16( HGDIOBJ16 handle, BOOL16 private )
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001132{
Andreas Mohr007fb242000-09-16 20:53:51 +00001133 GDIOBJHDR *ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE );
1134 if (!ptr)
1135 {
1136 ERR("invalid GDI object %04x !\n", handle);
1137 return;
1138 }
1139 ptr->wMagic |= OBJECT_PRIVATE;
1140 GDI_ReleaseObj( handle );
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001141}
1142
1143
1144/***********************************************************************
Alexandre Julliard491502b1997-11-01 19:08:16 +00001145 * GdiFlush (GDI32.128)
1146 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001147BOOL WINAPI GdiFlush(void)
Alexandre Julliard491502b1997-11-01 19:08:16 +00001148{
1149 return TRUE; /* FIXME */
1150}
1151
Alexandre Julliard17216f51997-10-12 16:30:17 +00001152
1153/***********************************************************************
1154 * GdiGetBatchLimit (GDI32.129)
1155 */
1156DWORD WINAPI GdiGetBatchLimit(void)
1157{
1158 return 1; /* FIXME */
1159}
1160
1161
1162/***********************************************************************
1163 * GdiSetBatchLimit (GDI32.139)
1164 */
1165DWORD WINAPI GdiSetBatchLimit( DWORD limit )
1166{
1167 return 1; /* FIXME */
1168}
1169
1170
1171/***********************************************************************
Alexandre Julliard03468f71998-02-15 19:40:49 +00001172 * GdiSeeGdiDo (GDI.452)
1173 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001174DWORD WINAPI GdiSeeGdiDo16( WORD wReqType, WORD wParam1, WORD wParam2,
Alexandre Julliard03468f71998-02-15 19:40:49 +00001175 WORD wParam3 )
1176{
1177 switch (wReqType)
1178 {
1179 case 0x0001: /* LocalAlloc */
1180 return LOCAL_Alloc( GDI_HeapSel, wParam1, wParam3 );
1181 case 0x0002: /* LocalFree */
1182 return LOCAL_Free( GDI_HeapSel, wParam1 );
1183 case 0x0003: /* LocalCompact */
1184 return LOCAL_Compact( GDI_HeapSel, wParam3, 0 );
1185 case 0x0103: /* LocalHeap */
1186 return GDI_HeapSel;
1187 default:
Alexandre Julliard15657091999-05-23 10:25:25 +00001188 WARN("(wReqType=%04x): Unknown\n", wReqType);
Alexandre Julliard03468f71998-02-15 19:40:49 +00001189 return (DWORD)-1;
1190 }
1191}
1192
1193/***********************************************************************
Ulrich Weigand466cd441999-04-01 11:46:02 +00001194 * GdiSignalProc (GDI.610)
1195 */
1196WORD WINAPI GdiSignalProc( UINT uCode, DWORD dwThreadOrProcessID,
1197 DWORD dwFlags, HMODULE16 hModule )
1198{
1199 return 0;
1200}
1201
Ulrich Weigand98c30531999-07-27 17:10:06 +00001202/***********************************************************************
1203 * FinalGdiInit16 (GDI.405)
1204 */
1205void WINAPI FinalGdiInit16( HANDLE16 unknown )
1206{
1207}
Ulrich Weigand466cd441999-04-01 11:46:02 +00001208
1209/***********************************************************************
Ulrich Weigand87dbaa91998-12-01 13:00:05 +00001210 * GdiFreeResources (GDI.609)
1211 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001212WORD WINAPI GdiFreeResources16( DWORD reserve )
Ulrich Weigand87dbaa91998-12-01 13:00:05 +00001213{
1214 return (WORD)( (int)LOCAL_CountFree( GDI_HeapSel ) * 100 /
1215 (int)LOCAL_HeapSize( GDI_HeapSel ) );
1216}
1217
1218/***********************************************************************
Alexandre Julliard1285c2f1996-05-06 16:06:24 +00001219 * MulDiv16 (GDI.128)
1220 */
Rein Klazesad5d10f2000-03-12 21:12:38 +00001221INT16 WINAPI MulDiv16(
1222 INT16 nMultiplicand,
1223 INT16 nMultiplier,
1224 INT16 nDivisor)
Alexandre Julliard1285c2f1996-05-06 16:06:24 +00001225{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001226 INT ret;
Rein Klazesad5d10f2000-03-12 21:12:38 +00001227 if (!nDivisor) return -32768;
1228 /* We want to deal with a positive divisor to simplify the logic. */
1229 if (nDivisor < 0)
1230 {
1231 nMultiplicand = - nMultiplicand;
1232 nDivisor = -nDivisor;
1233 }
1234 /* If the result is positive, we "add" to round. else,
1235 * we subtract to round. */
1236 if ( ( (nMultiplicand < 0) && (nMultiplier < 0) ) ||
1237 ( (nMultiplicand >= 0) && (nMultiplier >= 0) ) )
1238 ret = (((int)nMultiplicand * nMultiplier) + (nDivisor/2)) / nDivisor;
1239 else
1240 ret = (((int)nMultiplicand * nMultiplier) - (nDivisor/2)) / nDivisor;
Alexandre Julliard1285c2f1996-05-06 16:06:24 +00001241 if ((ret > 32767) || (ret < -32767)) return -32768;
Rein Klazesad5d10f2000-03-12 21:12:38 +00001242 return (INT16) ret;
Alexandre Julliard1285c2f1996-05-06 16:06:24 +00001243}
1244
1245
Paul Quinn1beaae51998-12-15 15:38:36 +00001246/*******************************************************************
1247 * GetColorAdjustment [GDI32.164]
1248 *
1249 *
1250 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001251BOOL WINAPI GetColorAdjustment(HDC hdc, LPCOLORADJUSTMENT lpca)
Paul Quinn1beaae51998-12-15 15:38:36 +00001252{
Alexandre Julliard15657091999-05-23 10:25:25 +00001253 FIXME("GetColorAdjustment, stub\n");
Paul Quinn1beaae51998-12-15 15:38:36 +00001254 return 0;
1255}
1256
1257/*******************************************************************
1258 * GetMiterLimit [GDI32.201]
1259 *
1260 *
1261 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001262BOOL WINAPI GetMiterLimit(HDC hdc, PFLOAT peLimit)
Paul Quinn1beaae51998-12-15 15:38:36 +00001263{
Alexandre Julliard15657091999-05-23 10:25:25 +00001264 FIXME("GetMiterLimit, stub\n");
Paul Quinn1beaae51998-12-15 15:38:36 +00001265 return 0;
1266}
1267
1268/*******************************************************************
1269 * SetMiterLimit [GDI32.325]
1270 *
1271 *
1272 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001273BOOL WINAPI SetMiterLimit(HDC hdc, FLOAT eNewLimit, PFLOAT peOldLimit)
Paul Quinn1beaae51998-12-15 15:38:36 +00001274{
Alexandre Julliard15657091999-05-23 10:25:25 +00001275 FIXME("SetMiterLimit, stub\n");
Paul Quinn1beaae51998-12-15 15:38:36 +00001276 return 0;
1277}
1278
1279/*******************************************************************
1280 * GdiComment [GDI32.109]
1281 *
1282 *
1283 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001284BOOL WINAPI GdiComment(HDC hdc, UINT cbSize, const BYTE *lpData)
Paul Quinn1beaae51998-12-15 15:38:36 +00001285{
Alexandre Julliard15657091999-05-23 10:25:25 +00001286 FIXME("GdiComment, stub\n");
Paul Quinn1beaae51998-12-15 15:38:36 +00001287 return 0;
1288}
1289/*******************************************************************
1290 * SetColorAdjustment [GDI32.309]
1291 *
1292 *
1293 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001294BOOL WINAPI SetColorAdjustment(HDC hdc, const COLORADJUSTMENT* lpca)
Paul Quinn1beaae51998-12-15 15:38:36 +00001295{
Alexandre Julliard15657091999-05-23 10:25:25 +00001296 FIXME("SetColorAdjustment, stub\n");
Paul Quinn1beaae51998-12-15 15:38:36 +00001297 return 0;
1298}
1299