4 * Copyright 1993 Alexandre Julliard
9 #ifndef X_DISPLAY_MISSING
11 #else /* !defined(X_DISPLAY_MISSING) */
13 #endif /* !defined(X_DISPLAY_MISSING */
27 #include "debugtools.h"
34 DEFAULT_DEBUG_CHANNEL(gdi)
36 /**********************************************************************/
38 GDI_DRIVER *GDI_Driver = NULL;
40 /***********************************************************************
44 static BRUSHOBJ WhiteBrush =
46 { 0, BRUSH_MAGIC, 1 }, /* header */
47 { BS_SOLID, RGB(255,255,255), 0 } /* logbrush */
50 static BRUSHOBJ LtGrayBrush =
52 { 0, BRUSH_MAGIC, 1 }, /* header */
53 /* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
54 { BS_SOLID, RGB(192,192,192), 0 } /* logbrush */
57 static BRUSHOBJ GrayBrush =
59 { 0, BRUSH_MAGIC, 1 }, /* header */
60 /* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
61 { BS_SOLID, RGB(128,128,128), 0 } /* logbrush */
64 static BRUSHOBJ DkGrayBrush =
66 { 0, BRUSH_MAGIC, 1 }, /* header */
67 /* This is BS_HATCHED, for 1 bitperpixel. This makes the spray work in pbrush */
68 /* NB_HATCH_STYLES is an index into HatchBrushes */
69 { BS_HATCHED, RGB(0,0,0), NB_HATCH_STYLES } /* logbrush */
72 static BRUSHOBJ BlackBrush =
74 { 0, BRUSH_MAGIC, 1 }, /* header */
75 { BS_SOLID, RGB(0,0,0), 0 } /* logbrush */
78 static BRUSHOBJ NullBrush =
80 { 0, BRUSH_MAGIC, 1 }, /* header */
81 { BS_NULL, 0, 0 } /* logbrush */
84 static PENOBJ WhitePen =
86 { 0, PEN_MAGIC, 1 }, /* header */
87 { PS_SOLID, { 1, 0 }, RGB(255,255,255) } /* logpen */
90 static PENOBJ BlackPen =
92 { 0, PEN_MAGIC, 1 }, /* header */
93 { PS_SOLID, { 1, 0 }, RGB(0,0,0) } /* logpen */
96 static PENOBJ NullPen =
98 { 0, PEN_MAGIC, 1 }, /* header */
99 { PS_NULL, { 1, 0 }, 0 } /* logpen */
102 static FONTOBJ OEMFixedFont =
104 { 0, FONT_MAGIC, 1 }, /* header */
105 { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, OEM_CHARSET,
106 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" }
108 /* Filler to make the location counter dword aligned again. This is necessary
109 since (a) FONTOBJ is packed, (b) gcc places initialised variables in the code
110 segment, and (c) Solaris assembler is stupid. */
111 static UINT16 align_OEMFixedFont = 1;
113 static FONTOBJ AnsiFixedFont =
115 { 0, FONT_MAGIC, 1 }, /* header */
116 { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
117 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" }
119 static UINT16 align_AnsiFixedFont = 1;
121 static FONTOBJ AnsiVarFont =
123 { 0, FONT_MAGIC, 1 }, /* header */
124 { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
125 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "MS Sans Serif" }
127 static UINT16 align_AnsiVarFont = 1;
129 static FONTOBJ SystemFont =
131 { 0, FONT_MAGIC, 1 },
132 { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
133 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "System" }
135 static UINT16 align_SystemFont = 1;
137 static FONTOBJ DeviceDefaultFont =
139 { 0, FONT_MAGIC, 1 }, /* header */
140 { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
141 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "" }
143 static UINT16 align_DeviceDefaultFont = 1;
145 static FONTOBJ SystemFixedFont =
147 { 0, FONT_MAGIC, 1 }, /* header */
148 { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
149 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" }
151 static UINT16 align_SystemFixedFont = 1;
153 /* FIXME: Is this correct? */
154 static FONTOBJ DefaultGuiFont =
156 { 0, FONT_MAGIC, 1 }, /* header */
157 { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
158 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "MS Sans Serif" }
160 static UINT16 align_DefaultGuiFont = 1;
163 static GDIOBJHDR * StockObjects[NB_STOCK_OBJECTS] =
165 (GDIOBJHDR *) &WhiteBrush,
166 (GDIOBJHDR *) &LtGrayBrush,
167 (GDIOBJHDR *) &GrayBrush,
168 (GDIOBJHDR *) &DkGrayBrush,
169 (GDIOBJHDR *) &BlackBrush,
170 (GDIOBJHDR *) &NullBrush,
171 (GDIOBJHDR *) &WhitePen,
172 (GDIOBJHDR *) &BlackPen,
173 (GDIOBJHDR *) &NullPen,
175 (GDIOBJHDR *) &OEMFixedFont,
176 (GDIOBJHDR *) &AnsiFixedFont,
177 (GDIOBJHDR *) &AnsiVarFont,
178 (GDIOBJHDR *) &SystemFont,
179 (GDIOBJHDR *) &DeviceDefaultFont,
180 NULL, /* DEFAULT_PALETTE created by PALETTE_Init */
181 (GDIOBJHDR *) &SystemFixedFont,
182 (GDIOBJHDR *) &DefaultGuiFont
185 HBITMAP hPseudoStockBitmap; /* 1x1 bitmap for memory DCs */
187 /******************************************************************************
189 * void ReadFontInformation(
190 * char const *fontName,
198 * ReadFontInformation() checks the Wine configuration file's Tweak.Fonts
199 * section for entries containing fontName.Height, fontName.Bold, etc.,
200 * where fontName is the name specified in the call (e.g., "System"). It
201 * attempts to be user friendly by accepting 'n', 'N', 'f', 'F', or '0' as
202 * the first character in the boolean attributes (bold, italic, and
204 *****************************************************************************/
206 static void ReadFontInformation(
207 char const *fontName,
217 /* In order for the stock fonts to be independent of
218 * mapping mode, the height (& width) must be 0
220 sprintf(key, "%s.Height", fontName);
221 font->logfont.lfHeight =
222 PROFILE_GetWineIniInt("Tweak.Fonts", key, defHeight);
224 sprintf(key, "%s.Bold", fontName);
225 font->logfont.lfWeight =
226 (PROFILE_GetWineIniBool("Tweak.Fonts", key, defBold)) ?
229 sprintf(key, "%s.Italic", fontName);
230 font->logfont.lfItalic =
231 PROFILE_GetWineIniBool("Tweak.Fonts", key, defItalic);
233 sprintf(key, "%s.Underline", fontName);
234 font->logfont.lfUnderline =
235 PROFILE_GetWineIniBool("Tweak.Fonts", key, defUnderline);
237 sprintf(key, "%s.StrikeOut", fontName);
238 font->logfont.lfStrikeOut =
239 PROFILE_GetWineIniBool("Tweak.Fonts", key, defStrikeOut);
244 /***********************************************************************
245 * Because the stock fonts have their structure initialized with
246 * a height of 0 to keep them independent of mapping mode, simply
247 * returning the LOGFONT as is will not work correctly.
248 * These "FixStockFontSizeXXX()" methods will get the correct
249 * size for the fonts.
251 static void GetFontMetrics(HFONT handle, LPTEXTMETRICA lptm)
256 hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
258 hOldFont = (HFONT)SelectObject(hdc, handle);
260 GetTextMetricsA(hdc, lptm);
262 SelectObject(hdc, hOldFont);
267 static inline void FixStockFontSize16(
273 LOGFONT16* pLogFont = (LOGFONT16*)buffer;
276 * Was the lfHeight field copied (it's the first field)?
277 * If it was and it was null, replace the height.
279 if ( (count >= 2*sizeof(INT16)) &&
280 (pLogFont->lfHeight == 0) )
282 GetFontMetrics(handle, &tm);
284 pLogFont->lfHeight = tm.tmHeight;
285 pLogFont->lfWidth = tm.tmAveCharWidth;
289 static inline void FixStockFontSizeA(
295 LOGFONTA* pLogFont = (LOGFONTA*)buffer;
298 * Was the lfHeight field copied (it's the first field)?
299 * If it was and it was null, replace the height.
301 if ( (count >= 2*sizeof(INT)) &&
302 (pLogFont->lfHeight == 0) )
304 GetFontMetrics(handle, &tm);
306 pLogFont->lfHeight = tm.tmHeight;
307 pLogFont->lfWidth = tm.tmAveCharWidth;
312 * Since the LOGFONTA and LOGFONTW structures are identical up to the
313 * lfHeight member (the one of interest in this case) we simply define
314 * the W version as the A version.
316 #define FixStockFontSizeW FixStockFontSizeA
320 /***********************************************************************
323 * GDI initialization.
327 BOOL systemIsBold = (TWEAK_WineLook == WIN31_LOOK);
329 /* Kill some warnings. */
330 (void)align_OEMFixedFont;
331 (void)align_AnsiFixedFont;
332 (void)align_AnsiVarFont;
333 (void)align_SystemFont;
334 (void)align_DeviceDefaultFont;
335 (void)align_SystemFixedFont;
336 (void)align_DefaultGuiFont;
338 /* TWEAK: Initialize font hints */
339 ReadFontInformation("OEMFixed", &OEMFixedFont, 0, 0, 0, 0, 0);
340 ReadFontInformation("AnsiFixed", &AnsiFixedFont, 0, 0, 0, 0, 0);
341 ReadFontInformation("AnsiVar", &AnsiVarFont, 0, 0, 0, 0, 0);
342 ReadFontInformation("System", &SystemFont, 0, systemIsBold, 0, 0, 0);
343 ReadFontInformation("DeviceDefault", &DeviceDefaultFont, 0, 0, 0, 0, 0);
344 ReadFontInformation("SystemFixed", &SystemFixedFont, 0, systemIsBold, 0, 0, 0);
345 ReadFontInformation("DefaultGui", &DefaultGuiFont, 0, 0, 0, 0, 0);
347 /* Initialize drivers */
349 #ifndef X_DISPLAY_MISSING
350 GDI_Driver = &X11DRV_GDI_Driver;
351 #else /* !defined(X_DISPLAY_MISSING) */
352 GDI_Driver = &TTYDRV_GDI_Driver;
353 #endif /* !defined(X_DISPLAY_MISSING */
355 GDI_Driver->pInitialize();
357 /* Create default palette */
359 /* DR well *this* palette can't be moveable (?) */
361 HPALETTE16 hpalette = PALETTE_Init();
364 StockObjects[DEFAULT_PALETTE] = (GDIOBJHDR *)GDI_HEAP_LOCK( hpalette );
367 hPseudoStockBitmap = CreateBitmap( 1, 1, 1, 1, NULL );
372 /***********************************************************************
375 HGDIOBJ16 GDI_AllocObject( WORD size, WORD magic )
377 static DWORD count = 0;
380 if ( magic == DC_MAGIC || magic == METAFILE_DC_MAGIC )
381 handle = GDI_HEAP_ALLOC( size );
383 handle = GDI_HEAP_ALLOC_MOVEABLE( size );
384 if (!handle) return 0;
385 obj = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
388 obj->dwCount = ++count;
389 GDI_HEAP_UNLOCK( handle );
394 /***********************************************************************
397 BOOL GDI_FreeObject( HGDIOBJ16 handle )
401 /* Can't free stock objects */
402 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
405 object = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
406 if (!object) return FALSE;
407 object->wMagic = 0; /* Mark it as invalid */
411 GDI_HEAP_FREE( handle );
415 /***********************************************************************
418 * Return a pointer to the GDI object associated to the handle.
419 * Return NULL if the object has the wrong magic number.
420 * Movable GDI objects are locked in memory: it is up to the caller to unlock
421 * it after the caller is done with the pointer.
423 GDIOBJHDR * GDI_GetObjPtr( HGDIOBJ16 handle, WORD magic )
425 GDIOBJHDR * ptr = NULL;
427 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
428 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
430 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
431 if (!ptr) return NULL;
432 if ((magic != MAGIC_DONTCARE) && (ptr->wMagic != magic))
434 GDI_HEAP_UNLOCK( handle );
441 /***********************************************************************
442 * DeleteObject16 (GDI.69)
444 BOOL16 WINAPI DeleteObject16( HGDIOBJ16 obj )
446 return DeleteObject( obj );
450 /***********************************************************************
451 * DeleteObject32 (GDI32.70)
453 BOOL WINAPI DeleteObject( HGDIOBJ obj )
455 /* Check if object is valid */
458 if (HIWORD(obj)) return FALSE;
459 if ((obj >= FIRST_STOCK_HANDLE) && (obj <= LAST_STOCK_HANDLE))
461 if (obj == hPseudoStockBitmap) return TRUE;
462 if (!(header = (GDIOBJHDR *) GDI_HEAP_LOCK( obj ))) return FALSE;
464 TRACE("%04x\n", obj );
468 switch(header->wMagic)
470 case PEN_MAGIC: return GDI_FreeObject( obj );
471 case BRUSH_MAGIC: return BRUSH_DeleteObject( obj, (BRUSHOBJ*)header );
472 case FONT_MAGIC: return GDI_FreeObject( obj );
473 case PALETTE_MAGIC: return PALETTE_DeleteObject(obj,(PALETTEOBJ*)header);
474 case BITMAP_MAGIC: return BITMAP_DeleteObject( obj, (BITMAPOBJ*)header);
475 case REGION_MAGIC: return REGION_DeleteObject( obj, (RGNOBJ*)header );
476 case DC_MAGIC: return DeleteDC(obj);
478 WARN("Already deleted\n");
481 WARN("Unknown magic number (%d)\n",header->wMagic);
486 /***********************************************************************
487 * GetStockObject16 (GDI.87)
489 HGDIOBJ16 WINAPI GetStockObject16( INT16 obj )
491 return (HGDIOBJ16)GetStockObject( obj );
495 /***********************************************************************
496 * GetStockObject32 (GDI32.220)
498 HGDIOBJ WINAPI GetStockObject( INT obj )
500 if ((obj < 0) || (obj >= NB_STOCK_OBJECTS)) return 0;
501 if (!StockObjects[obj]) return 0;
502 TRACE("returning %d\n",
503 FIRST_STOCK_HANDLE + obj );
504 return (HGDIOBJ16)(FIRST_STOCK_HANDLE + obj);
508 /***********************************************************************
509 * GetObject16 (GDI.82)
511 INT16 WINAPI GetObject16( HANDLE16 handle, INT16 count, LPVOID buffer )
513 GDIOBJHDR * ptr = NULL;
515 TRACE("%04x %d %p\n", handle, count, buffer );
516 if (!count) return 0;
518 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
519 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
521 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
527 result = PEN_GetObject16( (PENOBJ *)ptr, count, buffer );
530 result = BRUSH_GetObject16( (BRUSHOBJ *)ptr, count, buffer );
533 result = BITMAP_GetObject16( (BITMAPOBJ *)ptr, count, buffer );
536 result = FONT_GetObject16( (FONTOBJ *)ptr, count, buffer );
539 * Fix the LOGFONT structure for the stock fonts
541 if ( (handle >= FIRST_STOCK_HANDLE) &&
542 (handle <= LAST_STOCK_HANDLE) )
543 FixStockFontSize16(handle, count, buffer);
546 result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer );
549 GDI_HEAP_UNLOCK( handle );
554 /***********************************************************************
555 * GetObject32A (GDI32.204)
557 INT WINAPI GetObjectA( HANDLE handle, INT count, LPVOID buffer )
559 GDIOBJHDR * ptr = NULL;
561 TRACE("%08x %d %p\n", handle, count, buffer );
562 if (!count) return 0;
564 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
565 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
567 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
573 result = PEN_GetObject( (PENOBJ *)ptr, count, buffer );
576 result = BRUSH_GetObject( (BRUSHOBJ *)ptr, count, buffer );
579 result = BITMAP_GetObject( (BITMAPOBJ *)ptr, count, buffer );
582 result = FONT_GetObjectA( (FONTOBJ *)ptr, count, buffer );
585 * Fix the LOGFONT structure for the stock fonts
587 if ( (handle >= FIRST_STOCK_HANDLE) &&
588 (handle <= LAST_STOCK_HANDLE) )
589 FixStockFontSizeA(handle, count, buffer);
592 result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer );
595 FIXME("Magic %04x not implemented\n",
599 GDI_HEAP_UNLOCK( handle );
602 /***********************************************************************
603 * GetObject32W (GDI32.206)
605 INT WINAPI GetObjectW( HANDLE handle, INT count, LPVOID buffer )
607 GDIOBJHDR * ptr = NULL;
609 TRACE("%08x %d %p\n", handle, count, buffer );
610 if (!count) return 0;
612 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
613 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
615 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
621 result = PEN_GetObject( (PENOBJ *)ptr, count, buffer );
624 result = BRUSH_GetObject( (BRUSHOBJ *)ptr, count, buffer );
627 result = BITMAP_GetObject( (BITMAPOBJ *)ptr, count, buffer );
630 result = FONT_GetObjectW( (FONTOBJ *)ptr, count, buffer );
633 * Fix the LOGFONT structure for the stock fonts
635 if ( (handle >= FIRST_STOCK_HANDLE) &&
636 (handle <= LAST_STOCK_HANDLE) )
637 FixStockFontSizeW(handle, count, buffer);
640 result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer );
643 FIXME("Magic %04x not implemented\n",
647 GDI_HEAP_UNLOCK( handle );
651 /***********************************************************************
652 * GetObjectType (GDI32.205)
654 DWORD WINAPI GetObjectType( HANDLE handle )
656 GDIOBJHDR * ptr = NULL;
658 TRACE("%08x\n", handle );
660 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
661 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
663 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
693 result = OBJ_METAFILE;
695 case METAFILE_DC_MAGIC:
698 case ENHMETAFILE_MAGIC:
699 result = OBJ_ENHMETAFILE;
701 case ENHMETAFILE_DC_MAGIC:
702 result = OBJ_ENHMETADC;
705 FIXME("Magic %04x not implemented\n",
709 GDI_HEAP_UNLOCK( handle );
713 /***********************************************************************
714 * GetCurrentObject (GDI32.166)
716 HANDLE WINAPI GetCurrentObject(HDC hdc,UINT type)
718 DC * dc = DC_GetDCPtr( hdc );
723 case OBJ_PEN: return dc->w.hPen;
724 case OBJ_BRUSH: return dc->w.hBrush;
725 case OBJ_PAL: return dc->w.hPalette;
726 case OBJ_FONT: return dc->w.hFont;
727 case OBJ_BITMAP: return dc->w.hBitmap;
729 /* the SDK only mentions those above */
730 WARN("(%08x,%d): unknown type.\n",hdc,type);
736 /***********************************************************************
737 * SelectObject16 (GDI.45)
739 HGDIOBJ16 WINAPI SelectObject16( HDC16 hdc, HGDIOBJ16 handle )
741 return (HGDIOBJ16)SelectObject( hdc, handle );
745 /***********************************************************************
746 * SelectObject32 (GDI32.299)
748 HGDIOBJ WINAPI SelectObject( HDC hdc, HGDIOBJ handle )
750 DC * dc = DC_GetDCPtr( hdc );
751 if (!dc || !dc->funcs->pSelectObject) return 0;
752 TRACE("hdc=%04x %04x\n", hdc, handle );
753 return dc->funcs->pSelectObject( dc, handle );
757 /***********************************************************************
758 * UnrealizeObject16 (GDI.150)
760 BOOL16 WINAPI UnrealizeObject16( HGDIOBJ16 obj )
762 return UnrealizeObject( obj );
766 /***********************************************************************
767 * UnrealizeObject (GDI32.358)
769 BOOL WINAPI UnrealizeObject( HGDIOBJ obj )
772 /* Check if object is valid */
774 GDIOBJHDR * header = (GDIOBJHDR *) GDI_HEAP_LOCK( obj );
775 if (!header) return FALSE;
777 TRACE("%04x\n", obj );
779 /* Unrealize object */
781 switch(header->wMagic)
784 result = PALETTE_UnrealizeObject( obj, (PALETTEOBJ *)header );
788 /* Windows resets the brush origin. We don't need to. */
791 GDI_HEAP_UNLOCK( obj );
796 /***********************************************************************
797 * EnumObjects16 (GDI.71)
799 INT16 WINAPI EnumObjects16( HDC16 hdc, INT16 nObjType,
800 GOBJENUMPROC16 lpEnumFunc, LPARAM lParam )
802 /* Solid colors to enumerate */
803 static const COLORREF solid_colors[] =
804 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
805 RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
806 RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
807 RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
808 RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
809 RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
810 RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
811 RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
816 LOGBRUSH16 *brush = NULL;
818 TRACE("%04x %d %08lx %08lx\n",
819 hdc, nObjType, (DWORD)lpEnumFunc, lParam );
823 /* Enumerate solid pens */
824 if (!(pen = SEGPTR_NEW(LOGPEN16))) break;
825 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
827 pen->lopnStyle = PS_SOLID;
828 pen->lopnWidth.x = 1;
829 pen->lopnWidth.y = 0;
830 pen->lopnColor = solid_colors[i];
831 retval = lpEnumFunc( SEGPTR_GET(pen), lParam );
832 TRACE("solid pen %08lx, ret=%d\n",
833 solid_colors[i], retval);
840 /* Enumerate solid brushes */
841 if (!(brush = SEGPTR_NEW(LOGBRUSH16))) break;
842 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
844 brush->lbStyle = BS_SOLID;
845 brush->lbColor = solid_colors[i];
847 retval = lpEnumFunc( SEGPTR_GET(brush), lParam );
848 TRACE("solid brush %08lx, ret=%d\n",
849 solid_colors[i], retval);
853 /* Now enumerate hatched brushes */
854 if (retval) for (i = HS_HORIZONTAL; i <= HS_DIAGCROSS; i++)
856 brush->lbStyle = BS_HATCHED;
857 brush->lbColor = RGB(0,0,0);
859 retval = lpEnumFunc( SEGPTR_GET(brush), lParam );
860 TRACE("hatched brush %d, ret=%d\n",
868 WARN("(%d): Invalid type\n", nObjType );
875 /***********************************************************************
876 * EnumObjects32 (GDI32.89)
878 INT WINAPI EnumObjects( HDC hdc, INT nObjType,
879 GOBJENUMPROC lpEnumFunc, LPARAM lParam )
881 /* Solid colors to enumerate */
882 static const COLORREF solid_colors[] =
883 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
884 RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
885 RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
886 RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
887 RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
888 RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
889 RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
890 RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
897 TRACE("%04x %d %08lx %08lx\n",
898 hdc, nObjType, (DWORD)lpEnumFunc, lParam );
902 /* Enumerate solid pens */
903 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
905 pen.lopnStyle = PS_SOLID;
908 pen.lopnColor = solid_colors[i];
909 retval = lpEnumFunc( &pen, lParam );
910 TRACE("solid pen %08lx, ret=%d\n",
911 solid_colors[i], retval);
917 /* Enumerate solid brushes */
918 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
920 brush.lbStyle = BS_SOLID;
921 brush.lbColor = solid_colors[i];
923 retval = lpEnumFunc( &brush, lParam );
924 TRACE("solid brush %08lx, ret=%d\n",
925 solid_colors[i], retval);
929 /* Now enumerate hatched brushes */
930 if (retval) for (i = HS_HORIZONTAL; i <= HS_DIAGCROSS; i++)
932 brush.lbStyle = BS_HATCHED;
933 brush.lbColor = RGB(0,0,0);
935 retval = lpEnumFunc( &brush, lParam );
936 TRACE("hatched brush %d, ret=%d\n",
943 /* FIXME: implement Win32 types */
944 WARN("(%d): Invalid type\n", nObjType );
951 /***********************************************************************
952 * IsGDIObject (GDI.462)
954 * returns type of object if valid (W95 system programming secrets p. 264-5)
956 BOOL16 WINAPI IsGDIObject16( HGDIOBJ16 handle )
960 if (handle >= FIRST_STOCK_HANDLE )
964 case STOCK_WHITE_BRUSH:
965 case STOCK_LTGRAY_BRUSH:
966 case STOCK_GRAY_BRUSH:
967 case STOCK_DKGRAY_BRUSH:
968 case STOCK_BLACK_BRUSH:
969 case STOCK_HOLLOW_BRUSH:
973 case STOCK_WHITE_PEN:
974 case STOCK_BLACK_PEN:
975 case STOCK_NULL_PEN :
979 case STOCK_OEM_FIXED_FONT:
980 case STOCK_ANSI_FIXED_FONT:
981 case STOCK_ANSI_VAR_FONT:
982 case STOCK_SYSTEM_FONT:
983 case STOCK_DEVICE_DEFAULT_FONT:
984 case STOCK_SYSTEM_FIXED_FONT:
985 case STOCK_DEFAULT_GUI_FONT:
989 case STOCK_DEFAULT_PALETTE:
990 magic = PALETTE_MAGIC;
996 GDIOBJHDR *object = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
999 magic = object->wMagic;
1000 GDI_HEAP_UNLOCK( handle );
1004 if (magic >= PEN_MAGIC && magic <= METAFILE_DC_MAGIC)
1005 return magic - PEN_MAGIC + 1;
1011 /***********************************************************************
1012 * SetObjectOwner16 (GDI.461)
1014 void WINAPI SetObjectOwner16( HGDIOBJ16 handle, HANDLE16 owner )
1020 /***********************************************************************
1021 * SetObjectOwner32 (GDI32.386)
1023 void WINAPI SetObjectOwner( HGDIOBJ handle, HANDLE owner )
1028 /***********************************************************************
1029 * MakeObjectPrivate (GDI.463)
1031 void WINAPI MakeObjectPrivate16( HGDIOBJ16 handle, BOOL16 private )
1037 /***********************************************************************
1038 * GdiFlush (GDI32.128)
1040 BOOL WINAPI GdiFlush(void)
1042 return TRUE; /* FIXME */
1046 /***********************************************************************
1047 * GdiGetBatchLimit (GDI32.129)
1049 DWORD WINAPI GdiGetBatchLimit(void)
1051 return 1; /* FIXME */
1055 /***********************************************************************
1056 * GdiSetBatchLimit (GDI32.139)
1058 DWORD WINAPI GdiSetBatchLimit( DWORD limit )
1060 return 1; /* FIXME */
1064 /***********************************************************************
1065 * GdiSeeGdiDo (GDI.452)
1067 DWORD WINAPI GdiSeeGdiDo16( WORD wReqType, WORD wParam1, WORD wParam2,
1072 case 0x0001: /* LocalAlloc */
1073 return LOCAL_Alloc( GDI_HeapSel, wParam1, wParam3 );
1074 case 0x0002: /* LocalFree */
1075 return LOCAL_Free( GDI_HeapSel, wParam1 );
1076 case 0x0003: /* LocalCompact */
1077 return LOCAL_Compact( GDI_HeapSel, wParam3, 0 );
1078 case 0x0103: /* LocalHeap */
1081 WARN("(wReqType=%04x): Unknown\n", wReqType);
1086 /***********************************************************************
1087 * GdiSignalProc (GDI.610)
1089 WORD WINAPI GdiSignalProc( UINT uCode, DWORD dwThreadOrProcessID,
1090 DWORD dwFlags, HMODULE16 hModule )
1095 /***********************************************************************
1096 * FinalGdiInit16 (GDI.405)
1098 void WINAPI FinalGdiInit16( HANDLE16 unknown )
1102 /***********************************************************************
1103 * GdiFreeResources (GDI.609)
1105 WORD WINAPI GdiFreeResources16( DWORD reserve )
1107 return (WORD)( (int)LOCAL_CountFree( GDI_HeapSel ) * 100 /
1108 (int)LOCAL_HeapSize( GDI_HeapSel ) );
1111 /***********************************************************************
1112 * MulDiv16 (GDI.128)
1114 INT16 WINAPI MulDiv16( INT16 foo, INT16 bar, INT16 baz )
1117 if (!baz) return -32768;
1118 ret = (foo * bar) / baz;
1119 if ((ret > 32767) || (ret < -32767)) return -32768;
1124 /***********************************************************************
1125 * MulDiv32 (KERNEL32.391)
1127 * Result of multiplication and division
1128 * -1: Overflow occurred or Divisor was 0
1135 #if SIZEOF_LONG_LONG >= 8
1138 if (!nDivisor) return -1;
1140 /* We want to deal with a positive divisor to simplify the logic. */
1143 nMultiplicand = - nMultiplicand;
1144 nDivisor = -nDivisor;
1147 /* If the result is positive, we "add" to round. else, we subtract to round. */
1148 if ( ( (nMultiplicand < 0) && (nMultiplier < 0) ) ||
1149 ( (nMultiplicand >= 0) && (nMultiplier >= 0) ) )
1150 ret = (((long long)nMultiplicand * nMultiplier) + (nDivisor/2)) / nDivisor;
1152 ret = (((long long)nMultiplicand * nMultiplier) - (nDivisor/2)) / nDivisor;
1154 if ((ret > 2147483647) || (ret < -2147483647)) return -1;
1157 if (!nDivisor) return -1;
1159 /* We want to deal with a positive divisor to simplify the logic. */
1162 nMultiplicand = - nMultiplicand;
1163 nDivisor = -nDivisor;
1166 /* If the result is positive, we "add" to round. else, we subtract to round. */
1167 if ( ( (nMultiplicand < 0) && (nMultiplier < 0) ) ||
1168 ( (nMultiplicand >= 0) && (nMultiplier >= 0) ) )
1169 return ((nMultiplicand * nMultiplier) + (nDivisor/2)) / nDivisor;
1171 return ((nMultiplicand * nMultiplier) - (nDivisor/2)) / nDivisor;
1175 /*******************************************************************
1176 * GetColorAdjustment [GDI32.164]
1180 BOOL WINAPI GetColorAdjustment(HDC hdc, LPCOLORADJUSTMENT lpca)
1182 FIXME("GetColorAdjustment, stub\n");
1186 /*******************************************************************
1187 * GetMiterLimit [GDI32.201]
1191 BOOL WINAPI GetMiterLimit(HDC hdc, PFLOAT peLimit)
1193 FIXME("GetMiterLimit, stub\n");
1197 /*******************************************************************
1198 * SetMiterLimit [GDI32.325]
1202 BOOL WINAPI SetMiterLimit(HDC hdc, FLOAT eNewLimit, PFLOAT peOldLimit)
1204 FIXME("SetMiterLimit, stub\n");
1208 /*******************************************************************
1209 * GdiComment [GDI32.109]
1213 BOOL WINAPI GdiComment(HDC hdc, UINT cbSize, const BYTE *lpData)
1215 FIXME("GdiComment, stub\n");
1218 /*******************************************************************
1219 * SetColorAdjustment [GDI32.309]
1223 BOOL WINAPI SetColorAdjustment(HDC hdc, const COLORADJUSTMENT* lpca)
1225 FIXME("SetColorAdjustment, stub\n");