4 * Copyright 1993 Alexandre Julliard
9 #ifndef X_DISPLAY_MISSING
11 #else /* !defined(X_DISPLAY_MISSING) */
13 #endif /* !defined(X_DISPLAY_MISSING */
26 #include "debugtools.h"
31 DEFAULT_DEBUG_CHANNEL(gdi
)
33 /**********************************************************************/
35 GDI_DRIVER
*GDI_Driver
= NULL
;
37 /***********************************************************************
41 static BRUSHOBJ WhiteBrush
=
43 { 0, BRUSH_MAGIC
, 1 }, /* header */
44 { BS_SOLID
, RGB(255,255,255), 0 } /* logbrush */
47 static BRUSHOBJ LtGrayBrush
=
49 { 0, BRUSH_MAGIC
, 1 }, /* header */
50 /* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
51 { BS_SOLID
, RGB(192,192,192), 0 } /* logbrush */
54 static BRUSHOBJ GrayBrush
=
56 { 0, BRUSH_MAGIC
, 1 }, /* header */
57 /* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
58 { BS_SOLID
, RGB(128,128,128), 0 } /* logbrush */
61 static BRUSHOBJ DkGrayBrush
=
63 { 0, BRUSH_MAGIC
, 1 }, /* header */
64 /* This is BS_HATCHED, for 1 bitperpixel. This makes the spray work in pbrush */
65 /* NB_HATCH_STYLES is an index into HatchBrushes */
66 { BS_HATCHED
, RGB(0,0,0), NB_HATCH_STYLES
} /* logbrush */
69 static BRUSHOBJ BlackBrush
=
71 { 0, BRUSH_MAGIC
, 1 }, /* header */
72 { BS_SOLID
, RGB(0,0,0), 0 } /* logbrush */
75 static BRUSHOBJ NullBrush
=
77 { 0, BRUSH_MAGIC
, 1 }, /* header */
78 { BS_NULL
, 0, 0 } /* logbrush */
81 static PENOBJ WhitePen
=
83 { 0, PEN_MAGIC
, 1 }, /* header */
84 { PS_SOLID
, { 1, 0 }, RGB(255,255,255) } /* logpen */
87 static PENOBJ BlackPen
=
89 { 0, PEN_MAGIC
, 1 }, /* header */
90 { PS_SOLID
, { 1, 0 }, RGB(0,0,0) } /* logpen */
93 static PENOBJ NullPen
=
95 { 0, PEN_MAGIC
, 1 }, /* header */
96 { PS_NULL
, { 1, 0 }, 0 } /* logpen */
99 static FONTOBJ OEMFixedFont
=
101 { 0, FONT_MAGIC
, 1 }, /* header */
102 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, OEM_CHARSET
,
103 0, 0, DEFAULT_QUALITY
, FIXED_PITCH
| FF_MODERN
, "" }
105 /* Filler to make the location counter dword aligned again. This is necessary
106 since (a) FONTOBJ is packed, (b) gcc places initialised variables in the code
107 segment, and (c) Solaris assembler is stupid. */
108 static UINT16 align_OEMFixedFont
= 1;
110 static FONTOBJ AnsiFixedFont
=
112 { 0, FONT_MAGIC
, 1 }, /* header */
113 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
114 0, 0, DEFAULT_QUALITY
, FIXED_PITCH
| FF_MODERN
, "" }
116 static UINT16 align_AnsiFixedFont
= 1;
118 static FONTOBJ AnsiVarFont
=
120 { 0, FONT_MAGIC
, 1 }, /* header */
121 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
122 0, 0, DEFAULT_QUALITY
, VARIABLE_PITCH
| FF_SWISS
, "MS Sans Serif" }
124 static UINT16 align_AnsiVarFont
= 1;
126 static FONTOBJ SystemFont
=
128 { 0, FONT_MAGIC
, 1 },
129 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
130 0, 0, DEFAULT_QUALITY
, VARIABLE_PITCH
| FF_SWISS
, "System" }
132 static UINT16 align_SystemFont
= 1;
134 static FONTOBJ DeviceDefaultFont
=
136 { 0, FONT_MAGIC
, 1 }, /* header */
137 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
138 0, 0, DEFAULT_QUALITY
, VARIABLE_PITCH
| FF_SWISS
, "" }
140 static UINT16 align_DeviceDefaultFont
= 1;
142 static FONTOBJ SystemFixedFont
=
144 { 0, FONT_MAGIC
, 1 }, /* header */
145 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
146 0, 0, DEFAULT_QUALITY
, FIXED_PITCH
| FF_MODERN
, "" }
148 static UINT16 align_SystemFixedFont
= 1;
150 /* FIXME: Is this correct? */
151 static FONTOBJ DefaultGuiFont
=
153 { 0, FONT_MAGIC
, 1 }, /* header */
154 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
155 0, 0, DEFAULT_QUALITY
, VARIABLE_PITCH
| FF_SWISS
, "MS Sans Serif" }
157 static UINT16 align_DefaultGuiFont
= 1;
160 static GDIOBJHDR
* StockObjects
[NB_STOCK_OBJECTS
] =
162 (GDIOBJHDR
*) &WhiteBrush
,
163 (GDIOBJHDR
*) &LtGrayBrush
,
164 (GDIOBJHDR
*) &GrayBrush
,
165 (GDIOBJHDR
*) &DkGrayBrush
,
166 (GDIOBJHDR
*) &BlackBrush
,
167 (GDIOBJHDR
*) &NullBrush
,
168 (GDIOBJHDR
*) &WhitePen
,
169 (GDIOBJHDR
*) &BlackPen
,
170 (GDIOBJHDR
*) &NullPen
,
172 (GDIOBJHDR
*) &OEMFixedFont
,
173 (GDIOBJHDR
*) &AnsiFixedFont
,
174 (GDIOBJHDR
*) &AnsiVarFont
,
175 (GDIOBJHDR
*) &SystemFont
,
176 (GDIOBJHDR
*) &DeviceDefaultFont
,
177 NULL
, /* DEFAULT_PALETTE created by PALETTE_Init */
178 (GDIOBJHDR
*) &SystemFixedFont
,
179 (GDIOBJHDR
*) &DefaultGuiFont
182 /******************************************************************************
184 * void ReadFontInformation(
185 * char const *fontName,
193 * ReadFontInformation() checks the Wine configuration file's Tweak.Fonts
194 * section for entries containing fontName.Height, fontName.Bold, etc.,
195 * where fontName is the name specified in the call (e.g., "System"). It
196 * attempts to be user friendly by accepting 'n', 'N', 'f', 'F', or '0' as
197 * the first character in the boolean attributes (bold, italic, and
199 *****************************************************************************/
201 static void ReadFontInformation(
202 char const *fontName
,
212 /* In order for the stock fonts to be independent of
213 * mapping mode, the height (& width) must be 0
215 sprintf(key
, "%s.Height", fontName
);
216 font
->logfont
.lfHeight
=
217 PROFILE_GetWineIniInt("Tweak.Fonts", key
, defHeight
);
219 sprintf(key
, "%s.Bold", fontName
);
220 font
->logfont
.lfWeight
=
221 (PROFILE_GetWineIniBool("Tweak.Fonts", key
, defBold
)) ?
224 sprintf(key
, "%s.Italic", fontName
);
225 font
->logfont
.lfItalic
=
226 PROFILE_GetWineIniBool("Tweak.Fonts", key
, defItalic
);
228 sprintf(key
, "%s.Underline", fontName
);
229 font
->logfont
.lfUnderline
=
230 PROFILE_GetWineIniBool("Tweak.Fonts", key
, defUnderline
);
232 sprintf(key
, "%s.StrikeOut", fontName
);
233 font
->logfont
.lfStrikeOut
=
234 PROFILE_GetWineIniBool("Tweak.Fonts", key
, defStrikeOut
);
239 /***********************************************************************
240 * Because the stock fonts have their structure initialized with
241 * a height of 0 to keep them independent of mapping mode, simply
242 * returning the LOGFONT as is will not work correctly.
243 * These "FixStockFontSizeXXX()" methods will get the correct
244 * size for the fonts.
246 static void GetFontMetrics(HFONT handle
, LPTEXTMETRICA lptm
)
251 hdc
= CreateDCA("DISPLAY", NULL
, NULL
, NULL
);
253 hOldFont
= (HFONT
)SelectObject(hdc
, handle
);
255 GetTextMetricsA(hdc
, lptm
);
257 SelectObject(hdc
, hOldFont
);
262 static inline void FixStockFontSize16(
268 LOGFONT16
* pLogFont
= (LOGFONT16
*)buffer
;
271 * Was the lfHeight field copied (it's the first field)?
272 * If it was and it was null, replace the height.
274 if ( (count
>= 2*sizeof(INT16
)) &&
275 (pLogFont
->lfHeight
== 0) )
277 GetFontMetrics(handle
, &tm
);
279 pLogFont
->lfHeight
= tm
.tmHeight
;
280 pLogFont
->lfWidth
= tm
.tmAveCharWidth
;
284 static inline void FixStockFontSizeA(
290 LOGFONTA
* pLogFont
= (LOGFONTA
*)buffer
;
293 * Was the lfHeight field copied (it's the first field)?
294 * If it was and it was null, replace the height.
296 if ( (count
>= 2*sizeof(INT
)) &&
297 (pLogFont
->lfHeight
== 0) )
299 GetFontMetrics(handle
, &tm
);
301 pLogFont
->lfHeight
= tm
.tmHeight
;
302 pLogFont
->lfWidth
= tm
.tmAveCharWidth
;
307 * Since the LOGFONTA and LOGFONTW structures are identical up to the
308 * lfHeight member (the one of interest in this case) we simply define
309 * the W version as the A version.
311 #define FixStockFontSizeW FixStockFontSizeA
315 /***********************************************************************
318 * GDI initialization.
322 BOOL systemIsBold
= (TWEAK_WineLook
== WIN31_LOOK
);
324 /* Kill some warnings. */
325 (void)align_OEMFixedFont
;
326 (void)align_AnsiFixedFont
;
327 (void)align_AnsiVarFont
;
328 (void)align_SystemFont
;
329 (void)align_DeviceDefaultFont
;
330 (void)align_SystemFixedFont
;
331 (void)align_DefaultGuiFont
;
333 /* TWEAK: Initialize font hints */
334 ReadFontInformation("OEMFixed", &OEMFixedFont
, 0, 0, 0, 0, 0);
335 ReadFontInformation("AnsiFixed", &AnsiFixedFont
, 0, 0, 0, 0, 0);
336 ReadFontInformation("AnsiVar", &AnsiVarFont
, 0, 0, 0, 0, 0);
337 ReadFontInformation("System", &SystemFont
, 0, systemIsBold
, 0, 0, 0);
338 ReadFontInformation("DeviceDefault", &DeviceDefaultFont
, 0, 0, 0, 0, 0);
339 ReadFontInformation("SystemFixed", &SystemFixedFont
, 0, systemIsBold
, 0, 0, 0);
340 ReadFontInformation("DefaultGui", &DefaultGuiFont
, 0, 0, 0, 0, 0);
342 /* Initialize drivers */
344 #ifndef X_DISPLAY_MISSING
345 GDI_Driver
= &X11DRV_GDI_Driver
;
346 #else /* !defined(X_DISPLAY_MISSING) */
347 GDI_Driver
= &TTYDRV_GDI_Driver
;
348 #endif /* !defined(X_DISPLAY_MISSING */
350 GDI_Driver
->pInitialize();
352 /* Create default palette */
354 /* DR well *this* palette can't be moveable (?) */
356 HPALETTE16 hpalette
= PALETTE_Init();
359 StockObjects
[DEFAULT_PALETTE
] = (GDIOBJHDR
*)GDI_HEAP_LOCK( hpalette
);
366 /***********************************************************************
369 HGDIOBJ16
GDI_AllocObject( WORD size
, WORD magic
)
371 static DWORD count
= 0;
374 if ( magic
== DC_MAGIC
|| magic
== METAFILE_DC_MAGIC
)
375 handle
= GDI_HEAP_ALLOC( size
);
377 handle
= GDI_HEAP_ALLOC_MOVEABLE( size
);
378 if (!handle
) return 0;
379 obj
= (GDIOBJHDR
*) GDI_HEAP_LOCK( handle
);
382 obj
->dwCount
= ++count
;
383 GDI_HEAP_UNLOCK( handle
);
388 /***********************************************************************
391 BOOL
GDI_FreeObject( HGDIOBJ16 handle
)
395 /* Can't free stock objects */
396 if ((handle
>= FIRST_STOCK_HANDLE
) && (handle
<= LAST_STOCK_HANDLE
))
399 object
= (GDIOBJHDR
*) GDI_HEAP_LOCK( handle
);
400 if (!object
) return FALSE
;
401 object
->wMagic
= 0; /* Mark it as invalid */
405 GDI_HEAP_FREE( handle
);
409 /***********************************************************************
412 * Return a pointer to the GDI object associated to the handle.
413 * Return NULL if the object has the wrong magic number.
414 * Movable GDI objects are locked in memory: it is up to the caller to unlock
415 * it after the caller is done with the pointer.
417 GDIOBJHDR
* GDI_GetObjPtr( HGDIOBJ16 handle
, WORD magic
)
419 GDIOBJHDR
* ptr
= NULL
;
421 if ((handle
>= FIRST_STOCK_HANDLE
) && (handle
<= LAST_STOCK_HANDLE
))
422 ptr
= StockObjects
[handle
- FIRST_STOCK_HANDLE
];
424 ptr
= (GDIOBJHDR
*) GDI_HEAP_LOCK( handle
);
425 if (!ptr
) return NULL
;
426 if ((magic
!= MAGIC_DONTCARE
) && (ptr
->wMagic
!= magic
))
428 GDI_HEAP_UNLOCK( handle
);
435 /***********************************************************************
436 * DeleteObject16 (GDI.69)
438 BOOL16 WINAPI
DeleteObject16( HGDIOBJ16 obj
)
440 return DeleteObject( obj
);
444 /***********************************************************************
445 * DeleteObject32 (GDI32.70)
447 BOOL WINAPI
DeleteObject( HGDIOBJ obj
)
449 /* Check if object is valid */
452 if (HIWORD(obj
)) return FALSE
;
453 if ((obj
>= FIRST_STOCK_HANDLE
) && (obj
<= LAST_STOCK_HANDLE
))
455 if (!(header
= (GDIOBJHDR
*) GDI_HEAP_LOCK( obj
))) return FALSE
;
457 TRACE("%04x\n", obj
);
461 switch(header
->wMagic
)
463 case PEN_MAGIC
: return GDI_FreeObject( obj
);
464 case BRUSH_MAGIC
: return BRUSH_DeleteObject( obj
, (BRUSHOBJ
*)header
);
465 case FONT_MAGIC
: return GDI_FreeObject( obj
);
466 case PALETTE_MAGIC
: return PALETTE_DeleteObject(obj
,(PALETTEOBJ
*)header
);
467 case BITMAP_MAGIC
: return BITMAP_DeleteObject( obj
, (BITMAPOBJ
*)header
);
468 case REGION_MAGIC
: return REGION_DeleteObject( obj
, (RGNOBJ
*)header
);
469 case DC_MAGIC
: return DeleteDC(obj
);
471 WARN("Already deleted\n");
474 WARN("Unknown magic number (%d)\n",header
->wMagic
);
479 /***********************************************************************
480 * GetStockObject16 (GDI.87)
482 HGDIOBJ16 WINAPI
GetStockObject16( INT16 obj
)
484 return (HGDIOBJ16
)GetStockObject( obj
);
488 /***********************************************************************
489 * GetStockObject32 (GDI32.220)
491 HGDIOBJ WINAPI
GetStockObject( INT obj
)
493 if ((obj
< 0) || (obj
>= NB_STOCK_OBJECTS
)) return 0;
494 if (!StockObjects
[obj
]) return 0;
495 TRACE("returning %d\n",
496 FIRST_STOCK_HANDLE
+ obj
);
497 return (HGDIOBJ16
)(FIRST_STOCK_HANDLE
+ obj
);
501 /***********************************************************************
502 * GetObject16 (GDI.82)
504 INT16 WINAPI
GetObject16( HANDLE16 handle
, INT16 count
, LPVOID buffer
)
506 GDIOBJHDR
* ptr
= NULL
;
508 TRACE("%04x %d %p\n", handle
, count
, buffer
);
509 if (!count
) return 0;
511 if ((handle
>= FIRST_STOCK_HANDLE
) && (handle
<= LAST_STOCK_HANDLE
))
512 ptr
= StockObjects
[handle
- FIRST_STOCK_HANDLE
];
514 ptr
= (GDIOBJHDR
*) GDI_HEAP_LOCK( handle
);
520 result
= PEN_GetObject16( (PENOBJ
*)ptr
, count
, buffer
);
523 result
= BRUSH_GetObject16( (BRUSHOBJ
*)ptr
, count
, buffer
);
526 result
= BITMAP_GetObject16( (BITMAPOBJ
*)ptr
, count
, buffer
);
529 result
= FONT_GetObject16( (FONTOBJ
*)ptr
, count
, buffer
);
532 * Fix the LOGFONT structure for the stock fonts
534 if ( (handle
>= FIRST_STOCK_HANDLE
) &&
535 (handle
<= LAST_STOCK_HANDLE
) )
536 FixStockFontSize16(handle
, count
, buffer
);
539 result
= PALETTE_GetObject( (PALETTEOBJ
*)ptr
, count
, buffer
);
542 GDI_HEAP_UNLOCK( handle
);
547 /***********************************************************************
548 * GetObject32A (GDI32.204)
550 INT WINAPI
GetObjectA( HANDLE handle
, INT count
, LPVOID buffer
)
552 GDIOBJHDR
* ptr
= NULL
;
554 TRACE("%08x %d %p\n", handle
, count
, buffer
);
555 if (!count
) return 0;
557 if ((handle
>= FIRST_STOCK_HANDLE
) && (handle
<= LAST_STOCK_HANDLE
))
558 ptr
= StockObjects
[handle
- FIRST_STOCK_HANDLE
];
560 ptr
= (GDIOBJHDR
*) GDI_HEAP_LOCK( handle
);
566 result
= PEN_GetObject( (PENOBJ
*)ptr
, count
, buffer
);
569 result
= BRUSH_GetObject( (BRUSHOBJ
*)ptr
, count
, buffer
);
572 result
= BITMAP_GetObject( (BITMAPOBJ
*)ptr
, count
, buffer
);
575 result
= FONT_GetObjectA( (FONTOBJ
*)ptr
, count
, buffer
);
578 * Fix the LOGFONT structure for the stock fonts
580 if ( (handle
>= FIRST_STOCK_HANDLE
) &&
581 (handle
<= LAST_STOCK_HANDLE
) )
582 FixStockFontSizeA(handle
, count
, buffer
);
585 result
= PALETTE_GetObject( (PALETTEOBJ
*)ptr
, count
, buffer
);
588 FIXME("Magic %04x not implemented\n",
592 GDI_HEAP_UNLOCK( handle
);
595 /***********************************************************************
596 * GetObject32W (GDI32.206)
598 INT WINAPI
GetObjectW( HANDLE handle
, INT count
, LPVOID buffer
)
600 GDIOBJHDR
* ptr
= NULL
;
602 TRACE("%08x %d %p\n", handle
, count
, buffer
);
603 if (!count
) return 0;
605 if ((handle
>= FIRST_STOCK_HANDLE
) && (handle
<= LAST_STOCK_HANDLE
))
606 ptr
= StockObjects
[handle
- FIRST_STOCK_HANDLE
];
608 ptr
= (GDIOBJHDR
*) GDI_HEAP_LOCK( handle
);
614 result
= PEN_GetObject( (PENOBJ
*)ptr
, count
, buffer
);
617 result
= BRUSH_GetObject( (BRUSHOBJ
*)ptr
, count
, buffer
);
620 result
= BITMAP_GetObject( (BITMAPOBJ
*)ptr
, count
, buffer
);
623 result
= FONT_GetObjectW( (FONTOBJ
*)ptr
, count
, buffer
);
626 * Fix the LOGFONT structure for the stock fonts
628 if ( (handle
>= FIRST_STOCK_HANDLE
) &&
629 (handle
<= LAST_STOCK_HANDLE
) )
630 FixStockFontSizeW(handle
, count
, buffer
);
633 result
= PALETTE_GetObject( (PALETTEOBJ
*)ptr
, count
, buffer
);
636 FIXME("Magic %04x not implemented\n",
640 GDI_HEAP_UNLOCK( handle
);
644 /***********************************************************************
645 * GetObjectType (GDI32.205)
647 DWORD WINAPI
GetObjectType( HANDLE handle
)
649 GDIOBJHDR
* ptr
= NULL
;
651 TRACE("%08x\n", handle
);
653 if ((handle
>= FIRST_STOCK_HANDLE
) && (handle
<= LAST_STOCK_HANDLE
))
654 ptr
= StockObjects
[handle
- FIRST_STOCK_HANDLE
];
656 ptr
= (GDIOBJHDR
*) GDI_HEAP_LOCK( handle
);
686 result
= OBJ_METAFILE
;
688 case METAFILE_DC_MAGIC
:
691 case ENHMETAFILE_MAGIC
:
692 result
= OBJ_ENHMETAFILE
;
694 case ENHMETAFILE_DC_MAGIC
:
695 result
= OBJ_ENHMETADC
;
698 FIXME("Magic %04x not implemented\n",
702 GDI_HEAP_UNLOCK( handle
);
706 /***********************************************************************
707 * GetCurrentObject (GDI32.166)
709 HANDLE WINAPI
GetCurrentObject(HDC hdc
,UINT type
)
711 DC
* dc
= DC_GetDCPtr( hdc
);
716 case OBJ_PEN
: return dc
->w
.hPen
;
717 case OBJ_BRUSH
: return dc
->w
.hBrush
;
718 case OBJ_PAL
: return dc
->w
.hPalette
;
719 case OBJ_FONT
: return dc
->w
.hFont
;
720 case OBJ_BITMAP
: return dc
->w
.hBitmap
;
722 /* the SDK only mentions those above */
723 WARN("(%08x,%d): unknown type.\n",hdc
,type
);
729 /***********************************************************************
730 * SelectObject16 (GDI.45)
732 HGDIOBJ16 WINAPI
SelectObject16( HDC16 hdc
, HGDIOBJ16 handle
)
734 return (HGDIOBJ16
)SelectObject( hdc
, handle
);
738 /***********************************************************************
739 * SelectObject32 (GDI32.299)
741 HGDIOBJ WINAPI
SelectObject( HDC hdc
, HGDIOBJ handle
)
743 DC
* dc
= DC_GetDCPtr( hdc
);
744 if (!dc
|| !dc
->funcs
->pSelectObject
) return 0;
745 TRACE("hdc=%04x %04x\n", hdc
, handle
);
746 return dc
->funcs
->pSelectObject( dc
, handle
);
750 /***********************************************************************
751 * UnrealizeObject16 (GDI.150)
753 BOOL16 WINAPI
UnrealizeObject16( HGDIOBJ16 obj
)
755 return UnrealizeObject( obj
);
759 /***********************************************************************
760 * UnrealizeObject (GDI32.358)
762 BOOL WINAPI
UnrealizeObject( HGDIOBJ obj
)
765 /* Check if object is valid */
767 GDIOBJHDR
* header
= (GDIOBJHDR
*) GDI_HEAP_LOCK( obj
);
768 if (!header
) return FALSE
;
770 TRACE("%04x\n", obj
);
772 /* Unrealize object */
774 switch(header
->wMagic
)
777 result
= PALETTE_UnrealizeObject( obj
, (PALETTEOBJ
*)header
);
781 /* Windows resets the brush origin. We don't need to. */
784 GDI_HEAP_UNLOCK( obj
);
789 /***********************************************************************
790 * EnumObjects16 (GDI.71)
792 INT16 WINAPI
EnumObjects16( HDC16 hdc
, INT16 nObjType
,
793 GOBJENUMPROC16 lpEnumFunc
, LPARAM lParam
)
795 /* Solid colors to enumerate */
796 static const COLORREF solid_colors
[] =
797 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
798 RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
799 RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
800 RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
801 RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
802 RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
803 RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
804 RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
809 LOGBRUSH16
*brush
= NULL
;
811 TRACE("%04x %d %08lx %08lx\n",
812 hdc
, nObjType
, (DWORD
)lpEnumFunc
, lParam
);
816 /* Enumerate solid pens */
817 if (!(pen
= SEGPTR_NEW(LOGPEN16
))) break;
818 for (i
= 0; i
< sizeof(solid_colors
)/sizeof(solid_colors
[0]); i
++)
820 pen
->lopnStyle
= PS_SOLID
;
821 pen
->lopnWidth
.x
= 1;
822 pen
->lopnWidth
.y
= 0;
823 pen
->lopnColor
= solid_colors
[i
];
824 retval
= lpEnumFunc( SEGPTR_GET(pen
), lParam
);
825 TRACE("solid pen %08lx, ret=%d\n",
826 solid_colors
[i
], retval
);
833 /* Enumerate solid brushes */
834 if (!(brush
= SEGPTR_NEW(LOGBRUSH16
))) break;
835 for (i
= 0; i
< sizeof(solid_colors
)/sizeof(solid_colors
[0]); i
++)
837 brush
->lbStyle
= BS_SOLID
;
838 brush
->lbColor
= solid_colors
[i
];
840 retval
= lpEnumFunc( SEGPTR_GET(brush
), lParam
);
841 TRACE("solid brush %08lx, ret=%d\n",
842 solid_colors
[i
], retval
);
846 /* Now enumerate hatched brushes */
847 if (retval
) for (i
= HS_HORIZONTAL
; i
<= HS_DIAGCROSS
; i
++)
849 brush
->lbStyle
= BS_HATCHED
;
850 brush
->lbColor
= RGB(0,0,0);
852 retval
= lpEnumFunc( SEGPTR_GET(brush
), lParam
);
853 TRACE("hatched brush %d, ret=%d\n",
861 WARN("(%d): Invalid type\n", nObjType
);
868 /***********************************************************************
869 * EnumObjects32 (GDI32.89)
871 INT WINAPI
EnumObjects( HDC hdc
, INT nObjType
,
872 GOBJENUMPROC lpEnumFunc
, LPARAM lParam
)
874 /* Solid colors to enumerate */
875 static const COLORREF solid_colors
[] =
876 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
877 RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
878 RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
879 RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
880 RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
881 RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
882 RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
883 RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
890 TRACE("%04x %d %08lx %08lx\n",
891 hdc
, nObjType
, (DWORD
)lpEnumFunc
, lParam
);
895 /* Enumerate solid pens */
896 for (i
= 0; i
< sizeof(solid_colors
)/sizeof(solid_colors
[0]); i
++)
898 pen
.lopnStyle
= PS_SOLID
;
901 pen
.lopnColor
= solid_colors
[i
];
902 retval
= lpEnumFunc( &pen
, lParam
);
903 TRACE("solid pen %08lx, ret=%d\n",
904 solid_colors
[i
], retval
);
910 /* Enumerate solid brushes */
911 for (i
= 0; i
< sizeof(solid_colors
)/sizeof(solid_colors
[0]); i
++)
913 brush
.lbStyle
= BS_SOLID
;
914 brush
.lbColor
= solid_colors
[i
];
916 retval
= lpEnumFunc( &brush
, lParam
);
917 TRACE("solid brush %08lx, ret=%d\n",
918 solid_colors
[i
], retval
);
922 /* Now enumerate hatched brushes */
923 if (retval
) for (i
= HS_HORIZONTAL
; i
<= HS_DIAGCROSS
; i
++)
925 brush
.lbStyle
= BS_HATCHED
;
926 brush
.lbColor
= RGB(0,0,0);
928 retval
= lpEnumFunc( &brush
, lParam
);
929 TRACE("hatched brush %d, ret=%d\n",
936 /* FIXME: implement Win32 types */
937 WARN("(%d): Invalid type\n", nObjType
);
944 /***********************************************************************
945 * IsGDIObject (GDI.462)
947 * returns type of object if valid (W95 system programming secrets p. 264-5)
949 BOOL16 WINAPI
IsGDIObject16( HGDIOBJ16 handle
)
953 if (handle
>= FIRST_STOCK_HANDLE
)
957 case STOCK_WHITE_BRUSH
:
958 case STOCK_LTGRAY_BRUSH
:
959 case STOCK_GRAY_BRUSH
:
960 case STOCK_DKGRAY_BRUSH
:
961 case STOCK_BLACK_BRUSH
:
962 case STOCK_HOLLOW_BRUSH
:
966 case STOCK_WHITE_PEN
:
967 case STOCK_BLACK_PEN
:
968 case STOCK_NULL_PEN
:
972 case STOCK_OEM_FIXED_FONT
:
973 case STOCK_ANSI_FIXED_FONT
:
974 case STOCK_ANSI_VAR_FONT
:
975 case STOCK_SYSTEM_FONT
:
976 case STOCK_DEVICE_DEFAULT_FONT
:
977 case STOCK_SYSTEM_FIXED_FONT
:
978 case STOCK_DEFAULT_GUI_FONT
:
982 case STOCK_DEFAULT_PALETTE
:
983 magic
= PALETTE_MAGIC
;
989 GDIOBJHDR
*object
= (GDIOBJHDR
*) GDI_HEAP_LOCK( handle
);
992 magic
= object
->wMagic
;
993 GDI_HEAP_UNLOCK( handle
);
997 if (magic
>= PEN_MAGIC
&& magic
<= METAFILE_DC_MAGIC
)
998 return magic
- PEN_MAGIC
+ 1;
1004 /***********************************************************************
1005 * SetObjectOwner16 (GDI.461)
1007 void WINAPI
SetObjectOwner16( HGDIOBJ16 handle
, HANDLE16 owner
)
1013 /***********************************************************************
1014 * SetObjectOwner32 (GDI32.386)
1016 void WINAPI
SetObjectOwner( HGDIOBJ handle
, HANDLE owner
)
1021 /***********************************************************************
1022 * MakeObjectPrivate (GDI.463)
1024 void WINAPI
MakeObjectPrivate16( HGDIOBJ16 handle
, BOOL16
private )
1030 /***********************************************************************
1031 * GdiFlush (GDI32.128)
1033 BOOL WINAPI
GdiFlush(void)
1035 return TRUE
; /* FIXME */
1039 /***********************************************************************
1040 * GdiGetBatchLimit (GDI32.129)
1042 DWORD WINAPI
GdiGetBatchLimit(void)
1044 return 1; /* FIXME */
1048 /***********************************************************************
1049 * GdiSetBatchLimit (GDI32.139)
1051 DWORD WINAPI
GdiSetBatchLimit( DWORD limit
)
1053 return 1; /* FIXME */
1057 /***********************************************************************
1058 * GdiSeeGdiDo (GDI.452)
1060 DWORD WINAPI
GdiSeeGdiDo16( WORD wReqType
, WORD wParam1
, WORD wParam2
,
1065 case 0x0001: /* LocalAlloc */
1066 return LOCAL_Alloc( GDI_HeapSel
, wParam1
, wParam3
);
1067 case 0x0002: /* LocalFree */
1068 return LOCAL_Free( GDI_HeapSel
, wParam1
);
1069 case 0x0003: /* LocalCompact */
1070 return LOCAL_Compact( GDI_HeapSel
, wParam3
, 0 );
1071 case 0x0103: /* LocalHeap */
1074 WARN("(wReqType=%04x): Unknown\n", wReqType
);
1079 /***********************************************************************
1080 * GdiSignalProc (GDI.610)
1082 WORD WINAPI
GdiSignalProc( UINT uCode
, DWORD dwThreadOrProcessID
,
1083 DWORD dwFlags
, HMODULE16 hModule
)
1088 /***********************************************************************
1089 * FinalGdiInit16 (GDI.405)
1091 void WINAPI
FinalGdiInit16( HANDLE16 unknown
)
1095 /***********************************************************************
1096 * GdiFreeResources (GDI.609)
1098 WORD WINAPI
GdiFreeResources16( DWORD reserve
)
1100 return (WORD
)( (int)LOCAL_CountFree( GDI_HeapSel
) * 100 /
1101 (int)LOCAL_HeapSize( GDI_HeapSel
) );
1104 /***********************************************************************
1105 * MulDiv16 (GDI.128)
1107 INT16 WINAPI
MulDiv16( INT16 foo
, INT16 bar
, INT16 baz
)
1110 if (!baz
) return -32768;
1111 ret
= (foo
* bar
) / baz
;
1112 if ((ret
> 32767) || (ret
< -32767)) return -32768;
1117 /***********************************************************************
1118 * MulDiv32 (KERNEL32.391)
1120 * Result of multiplication and division
1121 * -1: Overflow occurred or Divisor was 0
1128 #if SIZEOF_LONG_LONG >= 8
1131 if (!nDivisor
) return -1;
1133 /* We want to deal with a positive divisor to simplify the logic. */
1136 nMultiplicand
= - nMultiplicand
;
1137 nDivisor
= -nDivisor
;
1140 /* If the result is positive, we "add" to round. else, we subtract to round. */
1141 if ( ( (nMultiplicand
< 0) && (nMultiplier
< 0) ) ||
1142 ( (nMultiplicand
>= 0) && (nMultiplier
>= 0) ) )
1143 ret
= (((long long)nMultiplicand
* nMultiplier
) + (nDivisor
/2)) / nDivisor
;
1145 ret
= (((long long)nMultiplicand
* nMultiplier
) - (nDivisor
/2)) / nDivisor
;
1147 if ((ret
> 2147483647) || (ret
< -2147483647)) return -1;
1150 if (!nDivisor
) return -1;
1152 /* We want to deal with a positive divisor to simplify the logic. */
1155 nMultiplicand
= - nMultiplicand
;
1156 nDivisor
= -nDivisor
;
1159 /* If the result is positive, we "add" to round. else, we subtract to round. */
1160 if ( ( (nMultiplicand
< 0) && (nMultiplier
< 0) ) ||
1161 ( (nMultiplicand
>= 0) && (nMultiplier
>= 0) ) )
1162 return ((nMultiplicand
* nMultiplier
) + (nDivisor
/2)) / nDivisor
;
1164 return ((nMultiplicand
* nMultiplier
) - (nDivisor
/2)) / nDivisor
;
1168 /*******************************************************************
1169 * GetColorAdjustment [GDI32.164]
1173 BOOL WINAPI
GetColorAdjustment(HDC hdc
, LPCOLORADJUSTMENT lpca
)
1175 FIXME("GetColorAdjustment, stub\n");
1179 /*******************************************************************
1180 * GetMiterLimit [GDI32.201]
1184 BOOL WINAPI
GetMiterLimit(HDC hdc
, PFLOAT peLimit
)
1186 FIXME("GetMiterLimit, stub\n");
1190 /*******************************************************************
1191 * SetMiterLimit [GDI32.325]
1195 BOOL WINAPI
SetMiterLimit(HDC hdc
, FLOAT eNewLimit
, PFLOAT peOldLimit
)
1197 FIXME("SetMiterLimit, stub\n");
1201 /*******************************************************************
1202 * GdiComment [GDI32.109]
1206 BOOL WINAPI
GdiComment(HDC hdc
, UINT cbSize
, const BYTE
*lpData
)
1208 FIXME("GdiComment, stub\n");
1211 /*******************************************************************
1212 * SetColorAdjustment [GDI32.309]
1216 BOOL WINAPI
SetColorAdjustment(HDC hdc
, const COLORADJUSTMENT
* lpca
)
1218 FIXME("SetColorAdjustment, stub\n");