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 HGDIOBJ
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( HGDIOBJ 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( HGDIOBJ handle
, WORD magic
)
425 GDIOBJHDR
* ptr
= NULL
;
427 if (handle
>= FIRST_STOCK_HANDLE
)
429 if (handle
<= LAST_STOCK_HANDLE
) ptr
= StockObjects
[handle
- FIRST_STOCK_HANDLE
];
432 ptr
= (GDIOBJHDR
*) GDI_HEAP_LOCK( handle
);
433 if (!ptr
) return NULL
;
434 if ((magic
!= MAGIC_DONTCARE
) && (ptr
->wMagic
!= magic
))
436 GDI_HEAP_UNLOCK( handle
);
443 /***********************************************************************
444 * DeleteObject16 (GDI.69)
446 BOOL16 WINAPI
DeleteObject16( HGDIOBJ16 obj
)
448 return DeleteObject( obj
);
452 /***********************************************************************
453 * DeleteObject32 (GDI32.70)
455 BOOL WINAPI
DeleteObject( HGDIOBJ obj
)
457 /* Check if object is valid */
460 if (HIWORD(obj
)) return FALSE
;
461 if ((obj
>= FIRST_STOCK_HANDLE
) && (obj
<= LAST_STOCK_HANDLE
))
463 if (obj
== hPseudoStockBitmap
) return TRUE
;
464 if (!(header
= (GDIOBJHDR
*) GDI_HEAP_LOCK( obj
))) return FALSE
;
466 TRACE("%04x\n", obj
);
470 switch(header
->wMagic
)
472 case PEN_MAGIC
: return GDI_FreeObject( obj
);
473 case BRUSH_MAGIC
: return BRUSH_DeleteObject( obj
, (BRUSHOBJ
*)header
);
474 case FONT_MAGIC
: return GDI_FreeObject( obj
);
475 case PALETTE_MAGIC
: return PALETTE_DeleteObject(obj
,(PALETTEOBJ
*)header
);
476 case BITMAP_MAGIC
: return BITMAP_DeleteObject( obj
, (BITMAPOBJ
*)header
);
477 case REGION_MAGIC
: return REGION_DeleteObject( obj
, (RGNOBJ
*)header
);
478 case DC_MAGIC
: return DeleteDC(obj
);
480 WARN("Already deleted\n");
483 WARN("Unknown magic number (%d)\n",header
->wMagic
);
488 /***********************************************************************
489 * GetStockObject16 (GDI.87)
491 HGDIOBJ16 WINAPI
GetStockObject16( INT16 obj
)
493 return (HGDIOBJ16
)GetStockObject( obj
);
497 /***********************************************************************
498 * GetStockObject32 (GDI32.220)
500 HGDIOBJ WINAPI
GetStockObject( INT obj
)
502 if ((obj
< 0) || (obj
>= NB_STOCK_OBJECTS
)) return 0;
503 if (!StockObjects
[obj
]) return 0;
504 TRACE("returning %d\n",
505 FIRST_STOCK_HANDLE
+ obj
);
506 return (HGDIOBJ16
)(FIRST_STOCK_HANDLE
+ obj
);
510 /***********************************************************************
511 * GetObject16 (GDI.82)
513 INT16 WINAPI
GetObject16( HANDLE16 handle
, INT16 count
, LPVOID buffer
)
517 TRACE("%04x %d %p\n", handle
, count
, buffer
);
518 if (!count
) return 0;
520 if (!(ptr
= GDI_GetObjPtr( handle
, MAGIC_DONTCARE
))) return 0;
525 result
= PEN_GetObject16( (PENOBJ
*)ptr
, count
, buffer
);
528 result
= BRUSH_GetObject16( (BRUSHOBJ
*)ptr
, count
, buffer
);
531 result
= BITMAP_GetObject16( (BITMAPOBJ
*)ptr
, count
, buffer
);
534 result
= FONT_GetObject16( (FONTOBJ
*)ptr
, count
, buffer
);
537 * Fix the LOGFONT structure for the stock fonts
539 if ( (handle
>= FIRST_STOCK_HANDLE
) &&
540 (handle
<= LAST_STOCK_HANDLE
) )
541 FixStockFontSize16(handle
, count
, buffer
);
544 result
= PALETTE_GetObject( (PALETTEOBJ
*)ptr
, count
, buffer
);
547 GDI_HEAP_UNLOCK( handle
);
552 /***********************************************************************
553 * GetObject32A (GDI32.204)
555 INT WINAPI
GetObjectA( HANDLE handle
, INT count
, LPVOID buffer
)
559 TRACE("%08x %d %p\n", handle
, count
, buffer
);
560 if (!count
) return 0;
562 if (!(ptr
= GDI_GetObjPtr( handle
, MAGIC_DONTCARE
))) return 0;
567 result
= PEN_GetObject( (PENOBJ
*)ptr
, count
, buffer
);
570 result
= BRUSH_GetObject( (BRUSHOBJ
*)ptr
, count
, buffer
);
573 result
= BITMAP_GetObject( (BITMAPOBJ
*)ptr
, count
, buffer
);
576 result
= FONT_GetObjectA( (FONTOBJ
*)ptr
, count
, buffer
);
579 * Fix the LOGFONT structure for the stock fonts
581 if ( (handle
>= FIRST_STOCK_HANDLE
) &&
582 (handle
<= LAST_STOCK_HANDLE
) )
583 FixStockFontSizeA(handle
, count
, buffer
);
586 result
= PALETTE_GetObject( (PALETTEOBJ
*)ptr
, count
, buffer
);
591 case DISABLED_DC_MAGIC
:
594 case METAFILE_DC_MAGIC
:
595 case ENHMETAFILE_MAGIC
:
596 case ENHMETAFILE_DC_MAGIC
:
597 FIXME("Magic %04x not implemented\n",
602 ERR("Invalid GDI Magic %04x\n", ptr
->wMagic
);
605 GDI_HEAP_UNLOCK( handle
);
609 /***********************************************************************
610 * GetObject32W (GDI32.206)
612 INT WINAPI
GetObjectW( HANDLE handle
, INT count
, LPVOID buffer
)
616 TRACE("%08x %d %p\n", handle
, count
, buffer
);
617 if (!count
) return 0;
619 if (!(ptr
= GDI_GetObjPtr( handle
, MAGIC_DONTCARE
))) return 0;
624 result
= PEN_GetObject( (PENOBJ
*)ptr
, count
, buffer
);
627 result
= BRUSH_GetObject( (BRUSHOBJ
*)ptr
, count
, buffer
);
630 result
= BITMAP_GetObject( (BITMAPOBJ
*)ptr
, count
, buffer
);
633 result
= FONT_GetObjectW( (FONTOBJ
*)ptr
, count
, buffer
);
636 * Fix the LOGFONT structure for the stock fonts
638 if ( (handle
>= FIRST_STOCK_HANDLE
) &&
639 (handle
<= LAST_STOCK_HANDLE
) )
640 FixStockFontSizeW(handle
, count
, buffer
);
643 result
= PALETTE_GetObject( (PALETTEOBJ
*)ptr
, count
, buffer
);
646 FIXME("Magic %04x not implemented\n",
650 GDI_HEAP_UNLOCK( handle
);
654 /***********************************************************************
655 * GetObjectType (GDI32.205)
657 DWORD WINAPI
GetObjectType( HANDLE handle
)
661 TRACE("%08x\n", handle
);
663 if (!(ptr
= GDI_GetObjPtr( handle
, MAGIC_DONTCARE
))) return 0;
692 result
= OBJ_METAFILE
;
694 case METAFILE_DC_MAGIC
:
697 case ENHMETAFILE_MAGIC
:
698 result
= OBJ_ENHMETAFILE
;
700 case ENHMETAFILE_DC_MAGIC
:
701 result
= OBJ_ENHMETADC
;
704 FIXME("Magic %04x not implemented\n",
708 GDI_HEAP_UNLOCK( handle
);
712 /***********************************************************************
713 * GetCurrentObject (GDI32.166)
715 HANDLE WINAPI
GetCurrentObject(HDC hdc
,UINT type
)
717 DC
* dc
= DC_GetDCPtr( hdc
);
722 case OBJ_PEN
: return dc
->w
.hPen
;
723 case OBJ_BRUSH
: return dc
->w
.hBrush
;
724 case OBJ_PAL
: return dc
->w
.hPalette
;
725 case OBJ_FONT
: return dc
->w
.hFont
;
726 case OBJ_BITMAP
: return dc
->w
.hBitmap
;
728 /* the SDK only mentions those above */
729 WARN("(%08x,%d): unknown type.\n",hdc
,type
);
735 /***********************************************************************
736 * SelectObject16 (GDI.45)
738 HGDIOBJ16 WINAPI
SelectObject16( HDC16 hdc
, HGDIOBJ16 handle
)
740 return (HGDIOBJ16
)SelectObject( hdc
, handle
);
744 /***********************************************************************
745 * SelectObject32 (GDI32.299)
747 HGDIOBJ WINAPI
SelectObject( HDC hdc
, HGDIOBJ handle
)
749 DC
* dc
= DC_GetDCPtr( hdc
);
750 if (!dc
|| !dc
->funcs
->pSelectObject
) return 0;
751 TRACE("hdc=%04x %04x\n", hdc
, handle
);
752 return dc
->funcs
->pSelectObject( dc
, handle
);
756 /***********************************************************************
757 * UnrealizeObject16 (GDI.150)
759 BOOL16 WINAPI
UnrealizeObject16( HGDIOBJ16 obj
)
761 return UnrealizeObject( obj
);
765 /***********************************************************************
766 * UnrealizeObject (GDI32.358)
768 BOOL WINAPI
UnrealizeObject( HGDIOBJ obj
)
771 /* Check if object is valid */
773 GDIOBJHDR
* header
= (GDIOBJHDR
*) GDI_HEAP_LOCK( obj
);
774 if (!header
) return FALSE
;
776 TRACE("%04x\n", obj
);
778 /* Unrealize object */
780 switch(header
->wMagic
)
783 result
= PALETTE_UnrealizeObject( obj
, (PALETTEOBJ
*)header
);
787 /* Windows resets the brush origin. We don't need to. */
790 GDI_HEAP_UNLOCK( obj
);
795 /***********************************************************************
796 * EnumObjects16 (GDI.71)
798 INT16 WINAPI
EnumObjects16( HDC16 hdc
, INT16 nObjType
,
799 GOBJENUMPROC16 lpEnumFunc
, LPARAM lParam
)
801 /* Solid colors to enumerate */
802 static const COLORREF solid_colors
[] =
803 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
804 RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
805 RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
806 RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
807 RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
808 RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
809 RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
810 RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
815 LOGBRUSH16
*brush
= NULL
;
817 TRACE("%04x %d %08lx %08lx\n",
818 hdc
, nObjType
, (DWORD
)lpEnumFunc
, lParam
);
822 /* Enumerate solid pens */
823 if (!(pen
= SEGPTR_NEW(LOGPEN16
))) break;
824 for (i
= 0; i
< sizeof(solid_colors
)/sizeof(solid_colors
[0]); i
++)
826 pen
->lopnStyle
= PS_SOLID
;
827 pen
->lopnWidth
.x
= 1;
828 pen
->lopnWidth
.y
= 0;
829 pen
->lopnColor
= solid_colors
[i
];
830 retval
= lpEnumFunc( SEGPTR_GET(pen
), lParam
);
831 TRACE("solid pen %08lx, ret=%d\n",
832 solid_colors
[i
], retval
);
839 /* Enumerate solid brushes */
840 if (!(brush
= SEGPTR_NEW(LOGBRUSH16
))) break;
841 for (i
= 0; i
< sizeof(solid_colors
)/sizeof(solid_colors
[0]); i
++)
843 brush
->lbStyle
= BS_SOLID
;
844 brush
->lbColor
= solid_colors
[i
];
846 retval
= lpEnumFunc( SEGPTR_GET(brush
), lParam
);
847 TRACE("solid brush %08lx, ret=%d\n",
848 solid_colors
[i
], retval
);
852 /* Now enumerate hatched brushes */
853 if (retval
) for (i
= HS_HORIZONTAL
; i
<= HS_DIAGCROSS
; i
++)
855 brush
->lbStyle
= BS_HATCHED
;
856 brush
->lbColor
= RGB(0,0,0);
858 retval
= lpEnumFunc( SEGPTR_GET(brush
), lParam
);
859 TRACE("hatched brush %d, ret=%d\n",
867 WARN("(%d): Invalid type\n", nObjType
);
874 /***********************************************************************
875 * EnumObjects32 (GDI32.89)
877 INT WINAPI
EnumObjects( HDC hdc
, INT nObjType
,
878 GOBJENUMPROC lpEnumFunc
, LPARAM lParam
)
880 /* Solid colors to enumerate */
881 static const COLORREF solid_colors
[] =
882 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
883 RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
884 RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
885 RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
886 RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
887 RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
888 RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
889 RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
896 TRACE("%04x %d %08lx %08lx\n",
897 hdc
, nObjType
, (DWORD
)lpEnumFunc
, lParam
);
901 /* Enumerate solid pens */
902 for (i
= 0; i
< sizeof(solid_colors
)/sizeof(solid_colors
[0]); i
++)
904 pen
.lopnStyle
= PS_SOLID
;
907 pen
.lopnColor
= solid_colors
[i
];
908 retval
= lpEnumFunc( &pen
, lParam
);
909 TRACE("solid pen %08lx, ret=%d\n",
910 solid_colors
[i
], retval
);
916 /* Enumerate solid brushes */
917 for (i
= 0; i
< sizeof(solid_colors
)/sizeof(solid_colors
[0]); i
++)
919 brush
.lbStyle
= BS_SOLID
;
920 brush
.lbColor
= solid_colors
[i
];
922 retval
= lpEnumFunc( &brush
, lParam
);
923 TRACE("solid brush %08lx, ret=%d\n",
924 solid_colors
[i
], retval
);
928 /* Now enumerate hatched brushes */
929 if (retval
) for (i
= HS_HORIZONTAL
; i
<= HS_DIAGCROSS
; i
++)
931 brush
.lbStyle
= BS_HATCHED
;
932 brush
.lbColor
= RGB(0,0,0);
934 retval
= lpEnumFunc( &brush
, lParam
);
935 TRACE("hatched brush %d, ret=%d\n",
942 /* FIXME: implement Win32 types */
943 WARN("(%d): Invalid type\n", nObjType
);
950 /***********************************************************************
951 * IsGDIObject (GDI.462)
953 * returns type of object if valid (W95 system programming secrets p. 264-5)
955 BOOL16 WINAPI
IsGDIObject16( HGDIOBJ16 handle
)
959 if (handle
>= FIRST_STOCK_HANDLE
)
963 case STOCK_WHITE_BRUSH
:
964 case STOCK_LTGRAY_BRUSH
:
965 case STOCK_GRAY_BRUSH
:
966 case STOCK_DKGRAY_BRUSH
:
967 case STOCK_BLACK_BRUSH
:
968 case STOCK_HOLLOW_BRUSH
:
972 case STOCK_WHITE_PEN
:
973 case STOCK_BLACK_PEN
:
974 case STOCK_NULL_PEN
:
978 case STOCK_OEM_FIXED_FONT
:
979 case STOCK_ANSI_FIXED_FONT
:
980 case STOCK_ANSI_VAR_FONT
:
981 case STOCK_SYSTEM_FONT
:
982 case STOCK_DEVICE_DEFAULT_FONT
:
983 case STOCK_SYSTEM_FIXED_FONT
:
984 case STOCK_DEFAULT_GUI_FONT
:
988 case STOCK_DEFAULT_PALETTE
:
989 magic
= PALETTE_MAGIC
;
995 GDIOBJHDR
*object
= (GDIOBJHDR
*) GDI_HEAP_LOCK( handle
);
998 magic
= object
->wMagic
;
999 GDI_HEAP_UNLOCK( handle
);
1003 if (magic
>= PEN_MAGIC
&& magic
<= METAFILE_DC_MAGIC
)
1004 return magic
- PEN_MAGIC
+ 1;
1010 /***********************************************************************
1011 * SetObjectOwner16 (GDI.461)
1013 void WINAPI
SetObjectOwner16( HGDIOBJ16 handle
, HANDLE16 owner
)
1019 /***********************************************************************
1020 * SetObjectOwner32 (GDI32.386)
1022 void WINAPI
SetObjectOwner( HGDIOBJ handle
, HANDLE owner
)
1027 /***********************************************************************
1028 * MakeObjectPrivate (GDI.463)
1030 void WINAPI
MakeObjectPrivate16( HGDIOBJ16 handle
, BOOL16
private )
1036 /***********************************************************************
1037 * GdiFlush (GDI32.128)
1039 BOOL WINAPI
GdiFlush(void)
1041 return TRUE
; /* FIXME */
1045 /***********************************************************************
1046 * GdiGetBatchLimit (GDI32.129)
1048 DWORD WINAPI
GdiGetBatchLimit(void)
1050 return 1; /* FIXME */
1054 /***********************************************************************
1055 * GdiSetBatchLimit (GDI32.139)
1057 DWORD WINAPI
GdiSetBatchLimit( DWORD limit
)
1059 return 1; /* FIXME */
1063 /***********************************************************************
1064 * GdiSeeGdiDo (GDI.452)
1066 DWORD WINAPI
GdiSeeGdiDo16( WORD wReqType
, WORD wParam1
, WORD wParam2
,
1071 case 0x0001: /* LocalAlloc */
1072 return LOCAL_Alloc( GDI_HeapSel
, wParam1
, wParam3
);
1073 case 0x0002: /* LocalFree */
1074 return LOCAL_Free( GDI_HeapSel
, wParam1
);
1075 case 0x0003: /* LocalCompact */
1076 return LOCAL_Compact( GDI_HeapSel
, wParam3
, 0 );
1077 case 0x0103: /* LocalHeap */
1080 WARN("(wReqType=%04x): Unknown\n", wReqType
);
1085 /***********************************************************************
1086 * GdiSignalProc (GDI.610)
1088 WORD WINAPI
GdiSignalProc( UINT uCode
, DWORD dwThreadOrProcessID
,
1089 DWORD dwFlags
, HMODULE16 hModule
)
1094 /***********************************************************************
1095 * FinalGdiInit16 (GDI.405)
1097 void WINAPI
FinalGdiInit16( HANDLE16 unknown
)
1101 /***********************************************************************
1102 * GdiFreeResources (GDI.609)
1104 WORD WINAPI
GdiFreeResources16( DWORD reserve
)
1106 return (WORD
)( (int)LOCAL_CountFree( GDI_HeapSel
) * 100 /
1107 (int)LOCAL_HeapSize( GDI_HeapSel
) );
1110 /***********************************************************************
1111 * MulDiv16 (GDI.128)
1113 INT16 WINAPI
MulDiv16( INT16 foo
, INT16 bar
, INT16 baz
)
1116 if (!baz
) return -32768;
1117 ret
= (foo
* bar
) / baz
;
1118 if ((ret
> 32767) || (ret
< -32767)) return -32768;
1123 /***********************************************************************
1124 * MulDiv32 (KERNEL32.391)
1126 * Result of multiplication and division
1127 * -1: Overflow occurred or Divisor was 0
1134 #if SIZEOF_LONG_LONG >= 8
1137 if (!nDivisor
) return -1;
1139 /* We want to deal with a positive divisor to simplify the logic. */
1142 nMultiplicand
= - nMultiplicand
;
1143 nDivisor
= -nDivisor
;
1146 /* If the result is positive, we "add" to round. else, we subtract to round. */
1147 if ( ( (nMultiplicand
< 0) && (nMultiplier
< 0) ) ||
1148 ( (nMultiplicand
>= 0) && (nMultiplier
>= 0) ) )
1149 ret
= (((long long)nMultiplicand
* nMultiplier
) + (nDivisor
/2)) / nDivisor
;
1151 ret
= (((long long)nMultiplicand
* nMultiplier
) - (nDivisor
/2)) / nDivisor
;
1153 if ((ret
> 2147483647) || (ret
< -2147483647)) return -1;
1156 if (!nDivisor
) return -1;
1158 /* We want to deal with a positive divisor to simplify the logic. */
1161 nMultiplicand
= - nMultiplicand
;
1162 nDivisor
= -nDivisor
;
1165 /* If the result is positive, we "add" to round. else, we subtract to round. */
1166 if ( ( (nMultiplicand
< 0) && (nMultiplier
< 0) ) ||
1167 ( (nMultiplicand
>= 0) && (nMultiplier
>= 0) ) )
1168 return ((nMultiplicand
* nMultiplier
) + (nDivisor
/2)) / nDivisor
;
1170 return ((nMultiplicand
* nMultiplier
) - (nDivisor
/2)) / nDivisor
;
1174 /*******************************************************************
1175 * GetColorAdjustment [GDI32.164]
1179 BOOL WINAPI
GetColorAdjustment(HDC hdc
, LPCOLORADJUSTMENT lpca
)
1181 FIXME("GetColorAdjustment, stub\n");
1185 /*******************************************************************
1186 * GetMiterLimit [GDI32.201]
1190 BOOL WINAPI
GetMiterLimit(HDC hdc
, PFLOAT peLimit
)
1192 FIXME("GetMiterLimit, stub\n");
1196 /*******************************************************************
1197 * SetMiterLimit [GDI32.325]
1201 BOOL WINAPI
SetMiterLimit(HDC hdc
, FLOAT eNewLimit
, PFLOAT peOldLimit
)
1203 FIXME("SetMiterLimit, stub\n");
1207 /*******************************************************************
1208 * GdiComment [GDI32.109]
1212 BOOL WINAPI
GdiComment(HDC hdc
, UINT cbSize
, const BYTE
*lpData
)
1214 FIXME("GdiComment, stub\n");
1217 /*******************************************************************
1218 * SetColorAdjustment [GDI32.309]
1222 BOOL WINAPI
SetColorAdjustment(HDC hdc
, const COLORADJUSTMENT
* lpca
)
1224 FIXME("SetColorAdjustment, stub\n");