4 * Copyright 1993 Alexandre Julliard
16 #include "wine/winbase16.h"
26 #include "debugtools.h"
31 DEFAULT_DEBUG_CHANNEL(gdi
);
34 /***********************************************************************
38 static BRUSHOBJ WhiteBrush
=
40 { 0, BRUSH_MAGIC
, 1 }, /* header */
41 { BS_SOLID
, RGB(255,255,255), 0 } /* logbrush */
44 static BRUSHOBJ LtGrayBrush
=
46 { 0, BRUSH_MAGIC
, 1 }, /* header */
47 /* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
48 { BS_SOLID
, RGB(192,192,192), 0 } /* logbrush */
51 static BRUSHOBJ GrayBrush
=
53 { 0, BRUSH_MAGIC
, 1 }, /* header */
54 /* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
55 { BS_SOLID
, RGB(128,128,128), 0 } /* logbrush */
58 static BRUSHOBJ DkGrayBrush
=
60 { 0, BRUSH_MAGIC
, 1 }, /* header */
61 /* 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 */
66 static BRUSHOBJ BlackBrush
=
68 { 0, BRUSH_MAGIC
, 1 }, /* header */
69 { BS_SOLID
, RGB(0,0,0), 0 } /* logbrush */
72 static BRUSHOBJ NullBrush
=
74 { 0, BRUSH_MAGIC
, 1 }, /* header */
75 { BS_NULL
, 0, 0 } /* logbrush */
78 static PENOBJ WhitePen
=
80 { 0, PEN_MAGIC
, 1 }, /* header */
81 { PS_SOLID
, { 0, 0 }, RGB(255,255,255) } /* logpen */
84 static PENOBJ BlackPen
=
86 { 0, PEN_MAGIC
, 1 }, /* header */
87 { PS_SOLID
, { 0, 0 }, RGB(0,0,0) } /* logpen */
90 static PENOBJ NullPen
=
92 { 0, PEN_MAGIC
, 1 }, /* header */
93 { PS_NULL
, { 0, 0 }, 0 } /* logpen */
96 static FONTOBJ OEMFixedFont
=
98 { 0, FONT_MAGIC
, 1 }, /* header */
99 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, OEM_CHARSET
,
100 0, 0, DEFAULT_QUALITY
, FIXED_PITCH
| FF_MODERN
, "" }
102 /* 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. */
105 static UINT16 align_OEMFixedFont
= 1;
107 static FONTOBJ AnsiFixedFont
=
109 { 0, FONT_MAGIC
, 1 }, /* header */
110 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
111 0, 0, DEFAULT_QUALITY
, FIXED_PITCH
| FF_MODERN
, "" }
113 static UINT16 align_AnsiFixedFont
= 1;
115 static FONTOBJ AnsiVarFont
=
117 { 0, FONT_MAGIC
, 1 }, /* header */
118 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
119 0, 0, DEFAULT_QUALITY
, VARIABLE_PITCH
| FF_SWISS
, "MS Sans Serif" }
121 static UINT16 align_AnsiVarFont
= 1;
123 static FONTOBJ SystemFont
=
125 { 0, FONT_MAGIC
, 1 },
126 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
127 0, 0, DEFAULT_QUALITY
, VARIABLE_PITCH
| FF_SWISS
, "System" }
129 static UINT16 align_SystemFont
= 1;
131 static FONTOBJ DeviceDefaultFont
=
133 { 0, FONT_MAGIC
, 1 }, /* header */
134 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
135 0, 0, DEFAULT_QUALITY
, VARIABLE_PITCH
| FF_SWISS
, "" }
137 static UINT16 align_DeviceDefaultFont
= 1;
139 static FONTOBJ SystemFixedFont
=
141 { 0, FONT_MAGIC
, 1 }, /* header */
142 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
143 0, 0, DEFAULT_QUALITY
, FIXED_PITCH
| FF_MODERN
, "" }
145 static UINT16 align_SystemFixedFont
= 1;
147 /* FIXME: Is this correct? */
148 static FONTOBJ DefaultGuiFont
=
150 { 0, FONT_MAGIC
, 1 }, /* header */
151 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
152 0, 0, DEFAULT_QUALITY
, VARIABLE_PITCH
| FF_SWISS
, "MS Sans Serif" }
154 static UINT16 align_DefaultGuiFont
= 1;
157 static GDIOBJHDR
* StockObjects
[NB_STOCK_OBJECTS
] =
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
,
169 (GDIOBJHDR
*) &OEMFixedFont
,
170 (GDIOBJHDR
*) &AnsiFixedFont
,
171 (GDIOBJHDR
*) &AnsiVarFont
,
172 (GDIOBJHDR
*) &SystemFont
,
173 (GDIOBJHDR
*) &DeviceDefaultFont
,
174 NULL
, /* DEFAULT_PALETTE created by PALETTE_Init */
175 (GDIOBJHDR
*) &SystemFixedFont
,
176 (GDIOBJHDR
*) &DefaultGuiFont
179 HBITMAP hPseudoStockBitmap
; /* 1x1 bitmap for memory DCs */
181 static SYSLEVEL GDI_level
;
182 static WORD GDI_HeapSel
;
185 /******************************************************************************
187 * void ReadFontInformation(
188 * char const *fontName,
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
202 *****************************************************************************/
204 static void ReadFontInformation(
205 char const *fontName
,
215 /* In order for the stock fonts to be independent of
216 * mapping mode, the height (& width) must be 0
218 sprintf(key
, "%s.Height", fontName
);
219 font
->logfont
.lfHeight
=
220 PROFILE_GetWineIniInt("Tweak.Fonts", key
, defHeight
);
222 sprintf(key
, "%s.Bold", fontName
);
223 font
->logfont
.lfWeight
=
224 (PROFILE_GetWineIniBool("Tweak.Fonts", key
, defBold
)) ?
227 sprintf(key
, "%s.Italic", fontName
);
228 font
->logfont
.lfItalic
=
229 PROFILE_GetWineIniBool("Tweak.Fonts", key
, defItalic
);
231 sprintf(key
, "%s.Underline", fontName
);
232 font
->logfont
.lfUnderline
=
233 PROFILE_GetWineIniBool("Tweak.Fonts", key
, defUnderline
);
235 sprintf(key
, "%s.StrikeOut", fontName
);
236 font
->logfont
.lfStrikeOut
=
237 PROFILE_GetWineIniBool("Tweak.Fonts", key
, defStrikeOut
);
242 /***********************************************************************
243 * 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.
249 static void GetFontMetrics(HFONT handle
, LPTEXTMETRICA lptm
)
254 hdc
= CreateDCA("DISPLAY", NULL
, NULL
, NULL
);
256 hOldFont
= (HFONT
)SelectObject(hdc
, handle
);
258 GetTextMetricsA(hdc
, lptm
);
260 SelectObject(hdc
, hOldFont
);
265 static inline void FixStockFontSize16(
271 LOGFONT16
* pLogFont
= (LOGFONT16
*)buffer
;
274 * Was the lfHeight field copied (it's the first field)?
275 * If it was and it was null, replace the height.
277 if ( (count
>= 2*sizeof(INT16
)) &&
278 (pLogFont
->lfHeight
== 0) )
280 GetFontMetrics(handle
, &tm
);
282 pLogFont
->lfHeight
= tm
.tmHeight
;
283 pLogFont
->lfWidth
= tm
.tmAveCharWidth
;
287 static inline void FixStockFontSizeA(
293 LOGFONTA
* pLogFont
= (LOGFONTA
*)buffer
;
296 * Was the lfHeight field copied (it's the first field)?
297 * If it was and it was null, replace the height.
299 if ( (count
>= 2*sizeof(INT
)) &&
300 (pLogFont
->lfHeight
== 0) )
302 GetFontMetrics(handle
, &tm
);
304 pLogFont
->lfHeight
= tm
.tmHeight
;
305 pLogFont
->lfWidth
= tm
.tmAveCharWidth
;
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.
314 #define FixStockFontSizeW FixStockFontSizeA
316 #define TRACE_SEC(handle,text) \
317 TRACE("(%04x): " text " %ld\n", (handle), GDI_level.crst.RecursionCount)
319 /***********************************************************************
322 * GDI initialization.
326 BOOL systemIsBold
= (TWEAK_WineLook
== WIN31_LOOK
);
328 HINSTANCE16 instance
;
330 _CreateSysLevel( &GDI_level
, 3 );
332 /* create GDI heap */
333 if ((instance
= LoadLibrary16( "GDI.EXE" )) < 32) return FALSE
;
334 GDI_HeapSel
= GlobalHandleToSel16( instance
);
336 /* 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
;
345 /* TWEAK: Initialize font hints */
346 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);
354 /* Create default palette */
356 /* DR well *this* palette can't be moveable (?) */
357 hpalette
= PALETTE_Init();
358 if( !hpalette
) return FALSE
;
359 StockObjects
[DEFAULT_PALETTE
] = (GDIOBJHDR
*)LOCAL_Lock( GDI_HeapSel
, hpalette
);
361 hPseudoStockBitmap
= CreateBitmap( 1, 1, 1, 1, NULL
);
365 #define FIRST_LARGE_HANDLE 16
366 #define MAX_LARGE_HANDLES ((GDI_HEAP_SIZE - FIRST_LARGE_HANDLE) >> 2)
367 static GDIOBJHDR
*large_handles
[MAX_LARGE_HANDLES
];
368 static int next_large_handle
;
370 /***********************************************************************
373 * Allocate a GDI handle from the large heap. Helper for GDI_AllocObject
375 inline static GDIOBJHDR
*alloc_large_heap( WORD size
, HGDIOBJ
*handle
)
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
;
388 if ((obj
= HeapAlloc( GetProcessHeap(), 0, size
)))
390 large_handles
[i
] = obj
;
391 *handle
= (i
+ FIRST_LARGE_HANDLE
) << 2;
392 next_large_handle
= i
;
398 /***********************************************************************
401 void *GDI_AllocObject( WORD size
, WORD magic
, HGDIOBJ
*handle
)
403 static DWORD count
= 0;
406 _EnterSysLevel( &GDI_level
);
409 /* allocate DCs on the larger heap */
411 case DISABLED_DC_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
;
420 if (!(*handle
= LOCAL_Alloc( GDI_HeapSel
, LMEM_MOVEABLE
, size
))) goto error
;
421 assert( *handle
& 2 );
422 obj
= (GDIOBJHDR
*)LOCAL_Lock( GDI_HeapSel
, *handle
);
427 obj
->wMagic
= magic
|OBJECT_NOSYSTEM
;
428 obj
->dwCount
= ++count
;
430 TRACE_SEC( *handle
, "enter" );
434 _LeaveSysLevel( &GDI_level
);
440 /***********************************************************************
443 * The object ptr must have been obtained with GDI_GetObjPtr.
444 * The new pointer must be released with GDI_ReleaseObj.
446 void *GDI_ReallocObject( WORD size
, HGDIOBJ handle
, void *object
)
450 assert( handle
& 2 ); /* no realloc for large handles */
451 LOCAL_Unlock( GDI_HeapSel
, handle
);
452 if (!(new_handle
= LOCAL_ReAlloc( GDI_HeapSel
, handle
, size
, LMEM_MOVEABLE
)))
454 TRACE_SEC( handle
, "leave" );
455 _LeaveSysLevel( &GDI_level
);
458 assert( new_handle
== handle
); /* moveable handle cannot change */
459 return LOCAL_Lock( GDI_HeapSel
, handle
);
463 /***********************************************************************
466 BOOL
GDI_FreeObject( HGDIOBJ handle
, void *ptr
)
468 GDIOBJHDR
*object
= ptr
;
470 /* can't free stock objects */
471 if (handle
< FIRST_STOCK_HANDLE
)
473 object
->wMagic
= 0; /* Mark it as invalid */
474 if (handle
& 2) /* GDI heap handle */
476 LOCAL_Unlock( GDI_HeapSel
, handle
);
477 LOCAL_Free( GDI_HeapSel
, handle
);
479 else /* large heap handle */
481 int i
= (handle
>> 2) - FIRST_LARGE_HANDLE
;
482 if (i
>= 0 && large_handles
[i
])
484 HeapFree( GetProcessHeap(), 0, large_handles
[i
] );
485 large_handles
[i
] = NULL
;
489 TRACE_SEC( handle
, "leave" );
490 _LeaveSysLevel( &GDI_level
);
495 /***********************************************************************
498 * Return a pointer to the GDI object associated to the handle.
499 * Return NULL if the object has the wrong magic number.
500 * The object must be released with GDI_ReleaseObj.
502 void *GDI_GetObjPtr( HGDIOBJ handle
, WORD magic
)
504 GDIOBJHDR
*ptr
= NULL
;
506 _EnterSysLevel( &GDI_level
);
508 if (handle
>= FIRST_STOCK_HANDLE
)
510 if (handle
<= LAST_STOCK_HANDLE
) ptr
= StockObjects
[handle
- FIRST_STOCK_HANDLE
];
511 if (ptr
&& (magic
!= MAGIC_DONTCARE
)
512 && (GDIMAGIC(ptr
->wMagic
) != magic
)) ptr
= NULL
;
514 else if (handle
& 2) /* GDI heap handle */
516 ptr
= (GDIOBJHDR
*)LOCAL_Lock( GDI_HeapSel
, handle
);
518 (magic
!= MAGIC_DONTCARE
) && (GDIMAGIC(ptr
->wMagic
) != magic
))
520 LOCAL_Unlock( GDI_HeapSel
, handle
);
524 else /* large heap handle */
526 int i
= (handle
>> 2) - FIRST_LARGE_HANDLE
;
529 ptr
= large_handles
[i
];
530 if (ptr
&& (magic
!= MAGIC_DONTCARE
) && (GDIMAGIC(ptr
->wMagic
) != magic
)) ptr
= NULL
;
536 _LeaveSysLevel( &GDI_level
);
537 SetLastError( ERROR_INVALID_HANDLE
);
539 else TRACE_SEC( handle
, "enter" );
545 /***********************************************************************
549 void GDI_ReleaseObj( HGDIOBJ handle
)
551 if (handle
< FIRST_STOCK_HANDLE
&& (handle
& 2)) LOCAL_Unlock( GDI_HeapSel
, handle
);
552 TRACE_SEC( handle
, "leave" );
553 _LeaveSysLevel( &GDI_level
);
557 /***********************************************************************
558 * DeleteObject16 (GDI.69)
560 BOOL16 WINAPI
DeleteObject16( HGDIOBJ16 obj
)
562 return DeleteObject( obj
);
566 /***********************************************************************
567 * DeleteObject (GDI32.70)
569 BOOL WINAPI
DeleteObject( HGDIOBJ obj
)
571 /* Check if object is valid */
574 if (HIWORD(obj
)) return FALSE
;
575 if ((obj
>= FIRST_STOCK_HANDLE
) && (obj
<= LAST_STOCK_HANDLE
)) {
576 TRACE("Preserving Stock object %04x\n", obj
);
577 /* NOTE: No GDI_Release is necessary */
580 if (obj
== hPseudoStockBitmap
) return TRUE
;
581 if (!(header
= GDI_GetObjPtr( obj
, MAGIC_DONTCARE
))) return FALSE
;
583 if (!(header
->wMagic
& OBJECT_NOSYSTEM
)
584 && (header
->wMagic
>= FIRST_MAGIC
) && (header
->wMagic
<= LAST_MAGIC
))
586 TRACE("Preserving system object %04x\n", obj
);
587 GDI_ReleaseObj( obj
);
591 TRACE("%04x\n", obj
);
595 switch(GDIMAGIC(header
->wMagic
))
597 case PEN_MAGIC
: return GDI_FreeObject( obj
, header
);
598 case BRUSH_MAGIC
: return BRUSH_DeleteObject( obj
, (BRUSHOBJ
*)header
);
599 case FONT_MAGIC
: return GDI_FreeObject( obj
, header
);
600 case PALETTE_MAGIC
: return PALETTE_DeleteObject(obj
,(PALETTEOBJ
*)header
);
601 case BITMAP_MAGIC
: return BITMAP_DeleteObject( obj
, (BITMAPOBJ
*)header
);
602 case REGION_MAGIC
: return REGION_DeleteObject( obj
, (RGNOBJ
*)header
);
604 GDI_ReleaseObj( obj
);
605 return DeleteDC(obj
);
607 WARN("Already deleted\n");
610 WARN("Unknown magic number (%d)\n",GDIMAGIC(header
->wMagic
));
612 GDI_ReleaseObj( obj
);
616 /***********************************************************************
617 * GetStockObject16 (GDI.87)
619 HGDIOBJ16 WINAPI
GetStockObject16( INT16 obj
)
621 return (HGDIOBJ16
)GetStockObject( obj
);
625 /***********************************************************************
626 * GetStockObject (GDI32.220)
628 HGDIOBJ WINAPI
GetStockObject( INT obj
)
631 if ((obj
< 0) || (obj
>= NB_STOCK_OBJECTS
)) return 0;
632 if (!StockObjects
[obj
]) return 0;
633 ret
= (HGDIOBJ16
)(FIRST_STOCK_HANDLE
+ obj
);
634 TRACE("returning %4x\n", ret
);
639 /***********************************************************************
640 * GetObject16 (GDI.82)
642 INT16 WINAPI
GetObject16( HANDLE16 handle
, INT16 count
, LPVOID buffer
)
646 TRACE("%04x %d %p\n", handle
, count
, buffer
);
647 if (!count
) return 0;
649 if (!(ptr
= GDI_GetObjPtr( handle
, MAGIC_DONTCARE
))) return 0;
651 switch(GDIMAGIC(ptr
->wMagic
))
654 result
= PEN_GetObject16( (PENOBJ
*)ptr
, count
, buffer
);
657 result
= BRUSH_GetObject16( (BRUSHOBJ
*)ptr
, count
, buffer
);
660 result
= BITMAP_GetObject16( (BITMAPOBJ
*)ptr
, count
, buffer
);
663 result
= FONT_GetObject16( (FONTOBJ
*)ptr
, count
, buffer
);
666 * Fix the LOGFONT structure for the stock fonts
668 if ( (handle
>= FIRST_STOCK_HANDLE
) &&
669 (handle
<= LAST_STOCK_HANDLE
) )
670 FixStockFontSize16(handle
, count
, buffer
);
673 result
= PALETTE_GetObject( (PALETTEOBJ
*)ptr
, count
, buffer
);
676 GDI_ReleaseObj( handle
);
681 /***********************************************************************
682 * GetObjectA (GDI32.204)
684 INT WINAPI
GetObjectA( HANDLE handle
, INT count
, LPVOID buffer
)
688 TRACE("%08x %d %p\n", handle
, count
, buffer
);
689 if (!count
) return 0;
691 if (!(ptr
= GDI_GetObjPtr( handle
, MAGIC_DONTCARE
))) return 0;
693 switch(GDIMAGIC(ptr
->wMagic
))
696 result
= PEN_GetObject( (PENOBJ
*)ptr
, count
, buffer
);
699 result
= BRUSH_GetObject( (BRUSHOBJ
*)ptr
, count
, buffer
);
702 result
= BITMAP_GetObject( (BITMAPOBJ
*)ptr
, count
, buffer
);
705 result
= FONT_GetObjectA( (FONTOBJ
*)ptr
, count
, buffer
);
708 * Fix the LOGFONT structure for the stock fonts
710 if ( (handle
>= FIRST_STOCK_HANDLE
) &&
711 (handle
<= LAST_STOCK_HANDLE
) )
712 FixStockFontSizeA(handle
, count
, buffer
);
715 result
= PALETTE_GetObject( (PALETTEOBJ
*)ptr
, count
, buffer
);
720 case DISABLED_DC_MAGIC
:
723 case METAFILE_DC_MAGIC
:
724 case ENHMETAFILE_MAGIC
:
725 case ENHMETAFILE_DC_MAGIC
:
726 FIXME("Magic %04x not implemented\n", GDIMAGIC(ptr
->wMagic
) );
730 ERR("Invalid GDI Magic %04x\n", GDIMAGIC(ptr
->wMagic
));
733 GDI_ReleaseObj( handle
);
737 /***********************************************************************
738 * GetObjectW (GDI32.206)
740 INT WINAPI
GetObjectW( HANDLE handle
, INT count
, LPVOID buffer
)
744 TRACE("%08x %d %p\n", handle
, count
, buffer
);
745 if (!count
) return 0;
747 if (!(ptr
= GDI_GetObjPtr( handle
, MAGIC_DONTCARE
))) return 0;
749 switch(GDIMAGIC(ptr
->wMagic
))
752 result
= PEN_GetObject( (PENOBJ
*)ptr
, count
, buffer
);
755 result
= BRUSH_GetObject( (BRUSHOBJ
*)ptr
, count
, buffer
);
758 result
= BITMAP_GetObject( (BITMAPOBJ
*)ptr
, count
, buffer
);
761 result
= FONT_GetObjectW( (FONTOBJ
*)ptr
, count
, buffer
);
764 * Fix the LOGFONT structure for the stock fonts
766 if ( (handle
>= FIRST_STOCK_HANDLE
) &&
767 (handle
<= LAST_STOCK_HANDLE
) )
768 FixStockFontSizeW(handle
, count
, buffer
);
771 result
= PALETTE_GetObject( (PALETTEOBJ
*)ptr
, count
, buffer
);
774 FIXME("Magic %04x not implemented\n", GDIMAGIC(ptr
->wMagic
) );
777 GDI_ReleaseObj( handle
);
781 /***********************************************************************
782 * GetObjectType (GDI32.205)
784 DWORD WINAPI
GetObjectType( HANDLE handle
)
788 TRACE("%08x\n", handle
);
790 if (!(ptr
= GDI_GetObjPtr( handle
, MAGIC_DONTCARE
))) return 0;
792 switch(GDIMAGIC(ptr
->wMagic
))
819 result
= OBJ_METAFILE
;
821 case METAFILE_DC_MAGIC
:
824 case ENHMETAFILE_MAGIC
:
825 result
= OBJ_ENHMETAFILE
;
827 case ENHMETAFILE_DC_MAGIC
:
828 result
= OBJ_ENHMETADC
;
831 FIXME("Magic %04x not implemented\n", GDIMAGIC(ptr
->wMagic
) );
834 GDI_ReleaseObj( handle
);
838 /***********************************************************************
839 * GetCurrentObject (GDI32.166)
841 HANDLE WINAPI
GetCurrentObject(HDC hdc
,UINT type
)
844 DC
* dc
= DC_GetDCPtr( hdc
);
849 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;
855 /* the SDK only mentions those above */
856 FIXME("(%08x,%d): unknown type.\n",hdc
,type
);
859 GDI_ReleaseObj( hdc
);
865 /***********************************************************************
866 * SelectObject16 (GDI.45)
868 HGDIOBJ16 WINAPI
SelectObject16( HDC16 hdc
, HGDIOBJ16 handle
)
870 return (HGDIOBJ16
)SelectObject( hdc
, handle
);
874 /***********************************************************************
875 * SelectObject (GDI32.299)
877 HGDIOBJ WINAPI
SelectObject( HDC hdc
, HGDIOBJ handle
)
880 DC
* dc
= DC_GetDCUpdate( hdc
);
882 TRACE("hdc=%04x %04x\n", hdc
, handle
);
883 if (dc
->funcs
->pSelectObject
)
884 ret
= dc
->funcs
->pSelectObject( dc
, handle
);
885 GDI_ReleaseObj( hdc
);
890 /***********************************************************************
891 * UnrealizeObject16 (GDI.150)
893 BOOL16 WINAPI
UnrealizeObject16( HGDIOBJ16 obj
)
895 return UnrealizeObject( obj
);
899 /***********************************************************************
900 * UnrealizeObject (GDI32.358)
902 BOOL WINAPI
UnrealizeObject( HGDIOBJ obj
)
905 /* Check if object is valid */
907 GDIOBJHDR
* header
= GDI_GetObjPtr( obj
, MAGIC_DONTCARE
);
908 if (!header
) return FALSE
;
910 TRACE("%04x\n", obj
);
912 /* Unrealize object */
914 switch(GDIMAGIC(header
->wMagic
))
917 result
= PALETTE_UnrealizeObject( obj
, (PALETTEOBJ
*)header
);
921 /* Windows resets the brush origin. We don't need to. */
924 GDI_ReleaseObj( obj
);
929 /***********************************************************************
930 * EnumObjects16 (GDI.71)
932 INT16 WINAPI
EnumObjects16( HDC16 hdc
, INT16 nObjType
,
933 GOBJENUMPROC16 lpEnumFunc
, LPARAM lParam
)
935 /* 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)
949 LOGBRUSH16
*brush
= NULL
;
951 TRACE("%04x %d %08lx %08lx\n",
952 hdc
, nObjType
, (DWORD
)lpEnumFunc
, lParam
);
956 /* Enumerate solid pens */
957 if (!(pen
= SEGPTR_NEW(LOGPEN16
))) break;
958 for (i
= 0; i
< sizeof(solid_colors
)/sizeof(solid_colors
[0]); i
++)
960 pen
->lopnStyle
= PS_SOLID
;
961 pen
->lopnWidth
.x
= 1;
962 pen
->lopnWidth
.y
= 0;
963 pen
->lopnColor
= solid_colors
[i
];
964 retval
= lpEnumFunc( SEGPTR_GET(pen
), lParam
);
965 TRACE("solid pen %08lx, ret=%d\n",
966 solid_colors
[i
], retval
);
973 /* Enumerate solid brushes */
974 if (!(brush
= SEGPTR_NEW(LOGBRUSH16
))) break;
975 for (i
= 0; i
< sizeof(solid_colors
)/sizeof(solid_colors
[0]); i
++)
977 brush
->lbStyle
= BS_SOLID
;
978 brush
->lbColor
= solid_colors
[i
];
980 retval
= lpEnumFunc( SEGPTR_GET(brush
), lParam
);
981 TRACE("solid brush %08lx, ret=%d\n",
982 solid_colors
[i
], retval
);
986 /* Now enumerate hatched brushes */
987 if (retval
) for (i
= HS_HORIZONTAL
; i
<= HS_DIAGCROSS
; i
++)
989 brush
->lbStyle
= BS_HATCHED
;
990 brush
->lbColor
= RGB(0,0,0);
992 retval
= lpEnumFunc( SEGPTR_GET(brush
), lParam
);
993 TRACE("hatched brush %d, ret=%d\n",
1001 WARN("(%d): Invalid type\n", nObjType
);
1008 /***********************************************************************
1009 * EnumObjects (GDI32.89)
1011 INT WINAPI
EnumObjects( HDC hdc
, INT nObjType
,
1012 GOBJENUMPROC lpEnumFunc
, LPARAM lParam
)
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)
1030 TRACE("%04x %d %08lx %08lx\n",
1031 hdc
, nObjType
, (DWORD
)lpEnumFunc
, lParam
);
1035 /* Enumerate solid pens */
1036 for (i
= 0; i
< sizeof(solid_colors
)/sizeof(solid_colors
[0]); i
++)
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
);
1043 TRACE("solid pen %08lx, ret=%d\n",
1044 solid_colors
[i
], retval
);
1050 /* Enumerate solid brushes */
1051 for (i
= 0; i
< sizeof(solid_colors
)/sizeof(solid_colors
[0]); i
++)
1053 brush
.lbStyle
= BS_SOLID
;
1054 brush
.lbColor
= solid_colors
[i
];
1056 retval
= lpEnumFunc( &brush
, lParam
);
1057 TRACE("solid brush %08lx, ret=%d\n",
1058 solid_colors
[i
], retval
);
1062 /* Now enumerate hatched brushes */
1063 if (retval
) for (i
= HS_HORIZONTAL
; i
<= HS_DIAGCROSS
; i
++)
1065 brush
.lbStyle
= BS_HATCHED
;
1066 brush
.lbColor
= RGB(0,0,0);
1068 retval
= lpEnumFunc( &brush
, lParam
);
1069 TRACE("hatched brush %d, ret=%d\n",
1076 /* FIXME: implement Win32 types */
1077 WARN("(%d): Invalid type\n", nObjType
);
1084 /***********************************************************************
1085 * IsGDIObject (GDI.462)
1087 * returns type of object if valid (W95 system programming secrets p. 264-5)
1089 BOOL16 WINAPI
IsGDIObject16( HGDIOBJ16 handle
)
1093 GDIOBJHDR
*object
= GDI_GetObjPtr( handle
, MAGIC_DONTCARE
);
1096 magic
= GDIMAGIC(object
->wMagic
) - PEN_MAGIC
+ 1;
1097 GDI_ReleaseObj( handle
);
1103 /***********************************************************************
1104 * SetObjectOwner16 (GDI.461)
1106 void WINAPI
SetObjectOwner16( HGDIOBJ16 handle
, HANDLE16 owner
)
1112 /***********************************************************************
1113 * SetObjectOwner (GDI32.386)
1115 void WINAPI
SetObjectOwner( HGDIOBJ handle
, HANDLE owner
)
1121 /***********************************************************************
1122 * MakeObjectPrivate (GDI.463)
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.
1131 void WINAPI
MakeObjectPrivate16( HGDIOBJ16 handle
, BOOL16
private )
1133 GDIOBJHDR
*ptr
= GDI_GetObjPtr( handle
, MAGIC_DONTCARE
);
1136 ERR("invalid GDI object %04x !\n", handle
);
1139 ptr
->wMagic
|= OBJECT_PRIVATE
;
1140 GDI_ReleaseObj( handle
);
1144 /***********************************************************************
1145 * GdiFlush (GDI32.128)
1147 BOOL WINAPI
GdiFlush(void)
1149 return TRUE
; /* FIXME */
1153 /***********************************************************************
1154 * GdiGetBatchLimit (GDI32.129)
1156 DWORD WINAPI
GdiGetBatchLimit(void)
1158 return 1; /* FIXME */
1162 /***********************************************************************
1163 * GdiSetBatchLimit (GDI32.139)
1165 DWORD WINAPI
GdiSetBatchLimit( DWORD limit
)
1167 return 1; /* FIXME */
1171 /***********************************************************************
1172 * GdiSeeGdiDo (GDI.452)
1174 DWORD WINAPI
GdiSeeGdiDo16( WORD wReqType
, WORD wParam1
, WORD wParam2
,
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 */
1188 WARN("(wReqType=%04x): Unknown\n", wReqType
);
1193 /***********************************************************************
1194 * GdiSignalProc (GDI.610)
1196 WORD WINAPI
GdiSignalProc( UINT uCode
, DWORD dwThreadOrProcessID
,
1197 DWORD dwFlags
, HMODULE16 hModule
)
1202 /***********************************************************************
1203 * FinalGdiInit16 (GDI.405)
1205 void WINAPI
FinalGdiInit16( HANDLE16 unknown
)
1209 /***********************************************************************
1210 * GdiFreeResources (GDI.609)
1212 WORD WINAPI
GdiFreeResources16( DWORD reserve
)
1214 return (WORD
)( (int)LOCAL_CountFree( GDI_HeapSel
) * 100 /
1215 (int)LOCAL_HeapSize( GDI_HeapSel
) );
1218 /***********************************************************************
1219 * MulDiv16 (GDI.128)
1221 INT16 WINAPI
MulDiv16(
1222 INT16 nMultiplicand
,
1227 if (!nDivisor
) return -32768;
1228 /* We want to deal with a positive divisor to simplify the logic. */
1231 nMultiplicand
= - nMultiplicand
;
1232 nDivisor
= -nDivisor
;
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
;
1240 ret
= (((int)nMultiplicand
* nMultiplier
) - (nDivisor
/2)) / nDivisor
;
1241 if ((ret
> 32767) || (ret
< -32767)) return -32768;
1246 /*******************************************************************
1247 * GetColorAdjustment [GDI32.164]
1251 BOOL WINAPI
GetColorAdjustment(HDC hdc
, LPCOLORADJUSTMENT lpca
)
1253 FIXME("GetColorAdjustment, stub\n");
1257 /*******************************************************************
1258 * GetMiterLimit [GDI32.201]
1262 BOOL WINAPI
GetMiterLimit(HDC hdc
, PFLOAT peLimit
)
1264 FIXME("GetMiterLimit, stub\n");
1268 /*******************************************************************
1269 * SetMiterLimit [GDI32.325]
1273 BOOL WINAPI
SetMiterLimit(HDC hdc
, FLOAT eNewLimit
, PFLOAT peOldLimit
)
1275 FIXME("SetMiterLimit, stub\n");
1279 /*******************************************************************
1280 * GdiComment [GDI32.109]
1284 BOOL WINAPI
GdiComment(HDC hdc
, UINT cbSize
, const BYTE
*lpData
)
1286 FIXME("GdiComment, stub\n");
1289 /*******************************************************************
1290 * SetColorAdjustment [GDI32.309]
1294 BOOL WINAPI
SetColorAdjustment(HDC hdc
, const COLORADJUSTMENT
* lpca
)
1296 FIXME("SetColorAdjustment, stub\n");