4 * Copyright 1993 Alexandre Julliard
16 #include "wine/winbase16.h"
27 #include "debugtools.h"
30 DEFAULT_DEBUG_CHANNEL(gdi
);
33 /***********************************************************************
37 static BRUSHOBJ WhiteBrush
=
39 { 0, BRUSH_MAGIC
, 1 }, /* header */
40 { BS_SOLID
, RGB(255,255,255), 0 } /* logbrush */
43 static BRUSHOBJ LtGrayBrush
=
45 { 0, BRUSH_MAGIC
, 1 }, /* header */
46 /* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
47 { BS_SOLID
, RGB(192,192,192), 0 } /* logbrush */
50 static BRUSHOBJ GrayBrush
=
52 { 0, BRUSH_MAGIC
, 1 }, /* header */
53 /* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
54 { BS_SOLID
, RGB(128,128,128), 0 } /* logbrush */
57 static BRUSHOBJ DkGrayBrush
=
59 { 0, BRUSH_MAGIC
, 1 }, /* header */
60 /* This is BS_HATCHED, for 1 bitperpixel. This makes the spray work in pbrush */
61 /* NB_HATCH_STYLES is an index into HatchBrushes */
62 { BS_HATCHED
, RGB(0,0,0), NB_HATCH_STYLES
} /* logbrush */
65 static BRUSHOBJ BlackBrush
=
67 { 0, BRUSH_MAGIC
, 1 }, /* header */
68 { BS_SOLID
, RGB(0,0,0), 0 } /* logbrush */
71 static BRUSHOBJ NullBrush
=
73 { 0, BRUSH_MAGIC
, 1 }, /* header */
74 { BS_NULL
, 0, 0 } /* logbrush */
77 static PENOBJ WhitePen
=
79 { 0, PEN_MAGIC
, 1 }, /* header */
80 { PS_SOLID
, { 0, 0 }, RGB(255,255,255) } /* logpen */
83 static PENOBJ BlackPen
=
85 { 0, PEN_MAGIC
, 1 }, /* header */
86 { PS_SOLID
, { 0, 0 }, RGB(0,0,0) } /* logpen */
89 static PENOBJ NullPen
=
91 { 0, PEN_MAGIC
, 1 }, /* header */
92 { PS_NULL
, { 0, 0 }, 0 } /* logpen */
95 static FONTOBJ OEMFixedFont
=
97 { 0, FONT_MAGIC
, 1 }, /* header */
98 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, OEM_CHARSET
,
99 0, 0, DEFAULT_QUALITY
, FIXED_PITCH
| FF_MODERN
, "" }
101 /* Filler to make the location counter dword aligned again. This is necessary
102 since (a) FONTOBJ is packed, (b) gcc places initialised variables in the code
103 segment, and (c) Solaris assembler is stupid. */
104 static UINT16 align_OEMFixedFont
= 1;
106 static FONTOBJ AnsiFixedFont
=
108 { 0, FONT_MAGIC
, 1 }, /* header */
109 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
110 0, 0, DEFAULT_QUALITY
, FIXED_PITCH
| FF_MODERN
, "" }
112 static UINT16 align_AnsiFixedFont
= 1;
114 static FONTOBJ AnsiVarFont
=
116 { 0, FONT_MAGIC
, 1 }, /* header */
117 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
118 0, 0, DEFAULT_QUALITY
, VARIABLE_PITCH
| FF_SWISS
, "MS Sans Serif" }
120 static UINT16 align_AnsiVarFont
= 1;
122 static FONTOBJ SystemFont
=
124 { 0, FONT_MAGIC
, 1 },
125 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
126 0, 0, DEFAULT_QUALITY
, VARIABLE_PITCH
| FF_SWISS
, "System" }
128 static UINT16 align_SystemFont
= 1;
130 static FONTOBJ DeviceDefaultFont
=
132 { 0, FONT_MAGIC
, 1 }, /* header */
133 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
134 0, 0, DEFAULT_QUALITY
, VARIABLE_PITCH
| FF_SWISS
, "" }
136 static UINT16 align_DeviceDefaultFont
= 1;
138 static FONTOBJ SystemFixedFont
=
140 { 0, FONT_MAGIC
, 1 }, /* header */
141 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
142 0, 0, DEFAULT_QUALITY
, FIXED_PITCH
| FF_MODERN
, "" }
144 static UINT16 align_SystemFixedFont
= 1;
146 /* FIXME: Is this correct? */
147 static FONTOBJ DefaultGuiFont
=
149 { 0, FONT_MAGIC
, 1 }, /* header */
150 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
151 0, 0, DEFAULT_QUALITY
, VARIABLE_PITCH
| FF_SWISS
, "MS Sans Serif" }
153 static UINT16 align_DefaultGuiFont
= 1;
156 static GDIOBJHDR
* StockObjects
[NB_STOCK_OBJECTS
] =
158 (GDIOBJHDR
*) &WhiteBrush
,
159 (GDIOBJHDR
*) &LtGrayBrush
,
160 (GDIOBJHDR
*) &GrayBrush
,
161 (GDIOBJHDR
*) &DkGrayBrush
,
162 (GDIOBJHDR
*) &BlackBrush
,
163 (GDIOBJHDR
*) &NullBrush
,
164 (GDIOBJHDR
*) &WhitePen
,
165 (GDIOBJHDR
*) &BlackPen
,
166 (GDIOBJHDR
*) &NullPen
,
168 (GDIOBJHDR
*) &OEMFixedFont
,
169 (GDIOBJHDR
*) &AnsiFixedFont
,
170 (GDIOBJHDR
*) &AnsiVarFont
,
171 (GDIOBJHDR
*) &SystemFont
,
172 (GDIOBJHDR
*) &DeviceDefaultFont
,
173 NULL
, /* DEFAULT_PALETTE created by PALETTE_Init */
174 (GDIOBJHDR
*) &SystemFixedFont
,
175 (GDIOBJHDR
*) &DefaultGuiFont
178 HBITMAP hPseudoStockBitmap
; /* 1x1 bitmap for memory DCs */
180 static SYSLEVEL GDI_level
= { CRITICAL_SECTION_INIT
, 3 };
181 static WORD GDI_HeapSel
;
184 /******************************************************************************
186 * void ReadFontInformation(
187 * char const *fontName,
195 * ReadFontInformation() checks the Wine configuration file's Tweak.Fonts
196 * section for entries containing fontName.Height, fontName.Bold, etc.,
197 * where fontName is the name specified in the call (e.g., "System"). It
198 * attempts to be user friendly by accepting 'n', 'N', 'f', 'F', or '0' as
199 * the first character in the boolean attributes (bold, italic, and
201 *****************************************************************************/
203 static void ReadFontInformation(
204 char const *fontName
,
214 /* In order for the stock fonts to be independent of
215 * mapping mode, the height (& width) must be 0
217 sprintf(key
, "%s.Height", fontName
);
218 font
->logfont
.lfHeight
=
219 PROFILE_GetWineIniInt("Tweak.Fonts", key
, defHeight
);
221 sprintf(key
, "%s.Bold", fontName
);
222 font
->logfont
.lfWeight
=
223 (PROFILE_GetWineIniBool("Tweak.Fonts", key
, defBold
)) ?
226 sprintf(key
, "%s.Italic", fontName
);
227 font
->logfont
.lfItalic
=
228 PROFILE_GetWineIniBool("Tweak.Fonts", key
, defItalic
);
230 sprintf(key
, "%s.Underline", fontName
);
231 font
->logfont
.lfUnderline
=
232 PROFILE_GetWineIniBool("Tweak.Fonts", key
, defUnderline
);
234 sprintf(key
, "%s.StrikeOut", fontName
);
235 font
->logfont
.lfStrikeOut
=
236 PROFILE_GetWineIniBool("Tweak.Fonts", key
, defStrikeOut
);
241 /***********************************************************************
242 * Because the stock fonts have their structure initialized with
243 * a height of 0 to keep them independent of mapping mode, simply
244 * returning the LOGFONT as is will not work correctly.
245 * These "FixStockFontSizeXXX()" methods will get the correct
246 * size for the fonts.
248 static void GetFontMetrics(HFONT handle
, LPTEXTMETRICA lptm
)
253 hdc
= CreateDCA("DISPLAY", NULL
, NULL
, NULL
);
255 hOldFont
= (HFONT
)SelectObject(hdc
, handle
);
257 GetTextMetricsA(hdc
, lptm
);
259 SelectObject(hdc
, hOldFont
);
264 static inline void FixStockFontSize16(
270 LOGFONT16
* pLogFont
= (LOGFONT16
*)buffer
;
273 * Was the lfHeight field copied (it's the first field)?
274 * If it was and it was null, replace the height.
276 if ( (count
>= 2*sizeof(INT16
)) &&
277 (pLogFont
->lfHeight
== 0) )
279 GetFontMetrics(handle
, &tm
);
281 pLogFont
->lfHeight
= tm
.tmHeight
;
282 pLogFont
->lfWidth
= tm
.tmAveCharWidth
;
286 static inline void FixStockFontSizeA(
292 LOGFONTA
* pLogFont
= (LOGFONTA
*)buffer
;
295 * Was the lfHeight field copied (it's the first field)?
296 * If it was and it was null, replace the height.
298 if ( (count
>= 2*sizeof(INT
)) &&
299 (pLogFont
->lfHeight
== 0) )
301 GetFontMetrics(handle
, &tm
);
303 pLogFont
->lfHeight
= tm
.tmHeight
;
304 pLogFont
->lfWidth
= tm
.tmAveCharWidth
;
309 * Since the LOGFONTA and LOGFONTW structures are identical up to the
310 * lfHeight member (the one of interest in this case) we simply define
311 * the W version as the A version.
313 #define FixStockFontSizeW FixStockFontSizeA
315 #define TRACE_SEC(handle,text) \
316 TRACE("(%04x): " text " %ld\n", (handle), GDI_level.crst.RecursionCount)
318 /***********************************************************************
321 * GDI initialization.
326 HINSTANCE16 instance
;
328 /* create GDI heap */
329 if ((instance
= LoadLibrary16( "GDI.EXE" )) < 32) return FALSE
;
330 GDI_HeapSel
= GlobalHandleToSel16( instance
);
332 /* Kill some warnings. */
333 (void)align_OEMFixedFont
;
334 (void)align_AnsiFixedFont
;
335 (void)align_AnsiVarFont
;
336 (void)align_SystemFont
;
337 (void)align_DeviceDefaultFont
;
338 (void)align_SystemFixedFont
;
339 (void)align_DefaultGuiFont
;
341 /* TWEAK: Initialize font hints */
342 ReadFontInformation("OEMFixed", &OEMFixedFont
, 0, 0, 0, 0, 0);
343 ReadFontInformation("AnsiFixed", &AnsiFixedFont
, 0, 0, 0, 0, 0);
344 ReadFontInformation("AnsiVar", &AnsiVarFont
, 0, 0, 0, 0, 0);
345 ReadFontInformation("System", &SystemFont
, 0, 0, 0, 0, 0);
346 ReadFontInformation("DeviceDefault", &DeviceDefaultFont
, 0, 0, 0, 0, 0);
347 ReadFontInformation("SystemFixed", &SystemFixedFont
, 0, 0, 0, 0, 0);
348 ReadFontInformation("DefaultGui", &DefaultGuiFont
, 0, 0, 0, 0, 0);
350 /* Create default palette */
352 /* DR well *this* palette can't be moveable (?) */
353 hpalette
= PALETTE_Init();
354 if( !hpalette
) return FALSE
;
355 StockObjects
[DEFAULT_PALETTE
] = (GDIOBJHDR
*)LOCAL_Lock( GDI_HeapSel
, hpalette
);
357 hPseudoStockBitmap
= CreateBitmap( 1, 1, 1, 1, NULL
);
361 #define FIRST_LARGE_HANDLE 16
362 #define MAX_LARGE_HANDLES ((GDI_HEAP_SIZE >> 2) - FIRST_LARGE_HANDLE)
363 static GDIOBJHDR
*large_handles
[MAX_LARGE_HANDLES
];
364 static int next_large_handle
;
366 /***********************************************************************
369 * Allocate a GDI handle from the large heap. Helper for GDI_AllocObject
371 inline static GDIOBJHDR
*alloc_large_heap( WORD size
, HGDIOBJ
*handle
)
376 for (i
= next_large_handle
+ 1; i
< MAX_LARGE_HANDLES
; i
++)
377 if (!large_handles
[i
]) goto found
;
378 for (i
= 0; i
<= next_large_handle
; i
++)
379 if (!large_handles
[i
]) goto found
;
384 if ((obj
= HeapAlloc( GetProcessHeap(), 0, size
)))
386 large_handles
[i
] = obj
;
387 *handle
= (i
+ FIRST_LARGE_HANDLE
) << 2;
388 next_large_handle
= i
;
394 /***********************************************************************
397 void *GDI_AllocObject( WORD size
, WORD magic
, HGDIOBJ
*handle
)
399 static DWORD count
= 0;
402 _EnterSysLevel( &GDI_level
);
405 /* allocate DCs on the larger heap */
407 case DISABLED_DC_MAGIC
:
410 case METAFILE_DC_MAGIC
:
411 case ENHMETAFILE_MAGIC
:
412 case ENHMETAFILE_DC_MAGIC
:
413 if (!(obj
= alloc_large_heap( size
, handle
))) goto error
;
416 if (!(*handle
= LOCAL_Alloc( GDI_HeapSel
, LMEM_MOVEABLE
, size
))) goto error
;
417 assert( *handle
& 2 );
418 obj
= (GDIOBJHDR
*)LOCAL_Lock( GDI_HeapSel
, *handle
);
423 obj
->wMagic
= magic
|OBJECT_NOSYSTEM
;
424 obj
->dwCount
= ++count
;
426 TRACE_SEC( *handle
, "enter" );
430 _LeaveSysLevel( &GDI_level
);
436 /***********************************************************************
439 * The object ptr must have been obtained with GDI_GetObjPtr.
440 * The new pointer must be released with GDI_ReleaseObj.
442 void *GDI_ReallocObject( WORD size
, HGDIOBJ handle
, void *object
)
446 assert( handle
& 2 ); /* no realloc for large handles */
447 LOCAL_Unlock( GDI_HeapSel
, handle
);
448 if (!(new_handle
= LOCAL_ReAlloc( GDI_HeapSel
, handle
, size
, LMEM_MOVEABLE
)))
450 TRACE_SEC( handle
, "leave" );
451 _LeaveSysLevel( &GDI_level
);
454 assert( new_handle
== handle
); /* moveable handle cannot change */
455 return LOCAL_Lock( GDI_HeapSel
, handle
);
459 /***********************************************************************
462 BOOL
GDI_FreeObject( HGDIOBJ handle
, void *ptr
)
464 GDIOBJHDR
*object
= ptr
;
466 /* can't free stock objects */
467 if (handle
< FIRST_STOCK_HANDLE
)
469 object
->wMagic
= 0; /* Mark it as invalid */
470 if (handle
& 2) /* GDI heap handle */
472 LOCAL_Unlock( GDI_HeapSel
, handle
);
473 LOCAL_Free( GDI_HeapSel
, handle
);
475 else /* large heap handle */
477 int i
= (handle
>> 2) - FIRST_LARGE_HANDLE
;
478 if (i
>= 0 && large_handles
[i
])
480 HeapFree( GetProcessHeap(), 0, large_handles
[i
] );
481 large_handles
[i
] = NULL
;
485 TRACE_SEC( handle
, "leave" );
486 _LeaveSysLevel( &GDI_level
);
491 /***********************************************************************
494 * Return a pointer to the GDI object associated to the handle.
495 * Return NULL if the object has the wrong magic number.
496 * The object must be released with GDI_ReleaseObj.
498 void *GDI_GetObjPtr( HGDIOBJ handle
, WORD magic
)
500 GDIOBJHDR
*ptr
= NULL
;
502 _EnterSysLevel( &GDI_level
);
504 if (handle
>= FIRST_STOCK_HANDLE
)
506 if (handle
<= LAST_STOCK_HANDLE
) ptr
= StockObjects
[handle
- FIRST_STOCK_HANDLE
];
507 if (ptr
&& (magic
!= MAGIC_DONTCARE
)
508 && (GDIMAGIC(ptr
->wMagic
) != magic
)) ptr
= NULL
;
510 else if (handle
& 2) /* GDI heap handle */
512 ptr
= (GDIOBJHDR
*)LOCAL_Lock( GDI_HeapSel
, handle
);
514 (magic
!= MAGIC_DONTCARE
) && (GDIMAGIC(ptr
->wMagic
) != magic
))
516 LOCAL_Unlock( GDI_HeapSel
, handle
);
520 else /* large heap handle */
522 int i
= (handle
>> 2) - FIRST_LARGE_HANDLE
;
525 ptr
= large_handles
[i
];
526 if (ptr
&& (magic
!= MAGIC_DONTCARE
) && (GDIMAGIC(ptr
->wMagic
) != magic
)) ptr
= NULL
;
532 _LeaveSysLevel( &GDI_level
);
533 SetLastError( ERROR_INVALID_HANDLE
);
535 else TRACE_SEC( handle
, "enter" );
541 /***********************************************************************
545 void GDI_ReleaseObj( HGDIOBJ handle
)
547 if (handle
< FIRST_STOCK_HANDLE
&& (handle
& 2)) LOCAL_Unlock( GDI_HeapSel
, handle
);
548 TRACE_SEC( handle
, "leave" );
549 _LeaveSysLevel( &GDI_level
);
553 /***********************************************************************
554 * DeleteObject16 (GDI.69)
556 BOOL16 WINAPI
DeleteObject16( HGDIOBJ16 obj
)
558 return DeleteObject( obj
);
562 /***********************************************************************
563 * DeleteObject (GDI32.70)
565 BOOL WINAPI
DeleteObject( HGDIOBJ obj
)
567 /* Check if object is valid */
570 if (HIWORD(obj
)) return FALSE
;
571 if ((obj
>= FIRST_STOCK_HANDLE
) && (obj
<= LAST_STOCK_HANDLE
)) {
572 TRACE("Preserving Stock object %04x\n", obj
);
573 /* NOTE: No GDI_Release is necessary */
576 if (obj
== hPseudoStockBitmap
) return TRUE
;
577 if (!(header
= GDI_GetObjPtr( obj
, MAGIC_DONTCARE
))) return FALSE
;
579 if (!(header
->wMagic
& OBJECT_NOSYSTEM
)
580 && (header
->wMagic
>= FIRST_MAGIC
) && (header
->wMagic
<= LAST_MAGIC
))
582 TRACE("Preserving system object %04x\n", obj
);
583 GDI_ReleaseObj( obj
);
587 TRACE("%04x\n", obj
);
591 switch(GDIMAGIC(header
->wMagic
))
593 case PEN_MAGIC
: return GDI_FreeObject( obj
, header
);
594 case BRUSH_MAGIC
: return BRUSH_DeleteObject( obj
, (BRUSHOBJ
*)header
);
595 case FONT_MAGIC
: return GDI_FreeObject( obj
, header
);
596 case PALETTE_MAGIC
: return PALETTE_DeleteObject(obj
,(PALETTEOBJ
*)header
);
597 case BITMAP_MAGIC
: return BITMAP_DeleteObject( obj
, (BITMAPOBJ
*)header
);
598 case REGION_MAGIC
: return REGION_DeleteObject( obj
, (RGNOBJ
*)header
);
600 GDI_ReleaseObj( obj
);
601 return DeleteDC(obj
);
603 WARN("Already deleted\n");
606 WARN("Unknown magic number (%d)\n",GDIMAGIC(header
->wMagic
));
608 GDI_ReleaseObj( obj
);
612 /***********************************************************************
613 * GetStockObject16 (GDI.87)
615 HGDIOBJ16 WINAPI
GetStockObject16( INT16 obj
)
617 return (HGDIOBJ16
)GetStockObject( obj
);
621 /***********************************************************************
622 * GetStockObject (GDI32.220)
624 HGDIOBJ WINAPI
GetStockObject( INT obj
)
627 if ((obj
< 0) || (obj
>= NB_STOCK_OBJECTS
)) return 0;
628 if (!StockObjects
[obj
]) return 0;
629 ret
= (HGDIOBJ16
)(FIRST_STOCK_HANDLE
+ obj
);
630 TRACE("returning %4x\n", ret
);
635 /***********************************************************************
636 * GetObject16 (GDI.82)
638 INT16 WINAPI
GetObject16( HANDLE16 handle
, INT16 count
, LPVOID buffer
)
642 TRACE("%04x %d %p\n", handle
, count
, buffer
);
643 if (!count
) return 0;
645 if (!(ptr
= GDI_GetObjPtr( handle
, MAGIC_DONTCARE
))) return 0;
647 switch(GDIMAGIC(ptr
->wMagic
))
650 result
= PEN_GetObject16( (PENOBJ
*)ptr
, count
, buffer
);
653 result
= BRUSH_GetObject16( (BRUSHOBJ
*)ptr
, count
, buffer
);
656 result
= BITMAP_GetObject16( (BITMAPOBJ
*)ptr
, count
, buffer
);
659 result
= FONT_GetObject16( (FONTOBJ
*)ptr
, count
, buffer
);
662 * Fix the LOGFONT structure for the stock fonts
664 if ( (handle
>= FIRST_STOCK_HANDLE
) &&
665 (handle
<= LAST_STOCK_HANDLE
) )
666 FixStockFontSize16(handle
, count
, buffer
);
669 result
= PALETTE_GetObject( (PALETTEOBJ
*)ptr
, count
, buffer
);
672 GDI_ReleaseObj( handle
);
677 /***********************************************************************
678 * GetObjectA (GDI32.204)
680 INT WINAPI
GetObjectA( HANDLE handle
, INT count
, LPVOID buffer
)
684 TRACE("%08x %d %p\n", handle
, count
, buffer
);
685 if (!count
) return 0;
687 if (!(ptr
= GDI_GetObjPtr( handle
, MAGIC_DONTCARE
))) return 0;
689 switch(GDIMAGIC(ptr
->wMagic
))
692 result
= PEN_GetObject( (PENOBJ
*)ptr
, count
, buffer
);
695 result
= BRUSH_GetObject( (BRUSHOBJ
*)ptr
, count
, buffer
);
698 result
= BITMAP_GetObject( (BITMAPOBJ
*)ptr
, count
, buffer
);
701 result
= FONT_GetObjectA( (FONTOBJ
*)ptr
, count
, buffer
);
704 * Fix the LOGFONT structure for the stock fonts
706 if ( (handle
>= FIRST_STOCK_HANDLE
) &&
707 (handle
<= LAST_STOCK_HANDLE
) )
708 FixStockFontSizeA(handle
, count
, buffer
);
711 result
= PALETTE_GetObject( (PALETTEOBJ
*)ptr
, count
, buffer
);
716 case DISABLED_DC_MAGIC
:
719 case METAFILE_DC_MAGIC
:
720 case ENHMETAFILE_MAGIC
:
721 case ENHMETAFILE_DC_MAGIC
:
722 FIXME("Magic %04x not implemented\n", GDIMAGIC(ptr
->wMagic
) );
726 ERR("Invalid GDI Magic %04x\n", GDIMAGIC(ptr
->wMagic
));
729 GDI_ReleaseObj( handle
);
733 /***********************************************************************
734 * GetObjectW (GDI32.206)
736 INT WINAPI
GetObjectW( HANDLE handle
, INT count
, LPVOID buffer
)
740 TRACE("%08x %d %p\n", handle
, count
, buffer
);
741 if (!count
) return 0;
743 if (!(ptr
= GDI_GetObjPtr( handle
, MAGIC_DONTCARE
))) return 0;
745 switch(GDIMAGIC(ptr
->wMagic
))
748 result
= PEN_GetObject( (PENOBJ
*)ptr
, count
, buffer
);
751 result
= BRUSH_GetObject( (BRUSHOBJ
*)ptr
, count
, buffer
);
754 result
= BITMAP_GetObject( (BITMAPOBJ
*)ptr
, count
, buffer
);
757 result
= FONT_GetObjectW( (FONTOBJ
*)ptr
, count
, buffer
);
760 * Fix the LOGFONT structure for the stock fonts
762 if ( (handle
>= FIRST_STOCK_HANDLE
) &&
763 (handle
<= LAST_STOCK_HANDLE
) )
764 FixStockFontSizeW(handle
, count
, buffer
);
767 result
= PALETTE_GetObject( (PALETTEOBJ
*)ptr
, count
, buffer
);
770 FIXME("Magic %04x not implemented\n", GDIMAGIC(ptr
->wMagic
) );
773 GDI_ReleaseObj( handle
);
777 /***********************************************************************
778 * GetObjectType (GDI32.205)
780 DWORD WINAPI
GetObjectType( HANDLE handle
)
784 TRACE("%08x\n", handle
);
786 if (!(ptr
= GDI_GetObjPtr( handle
, MAGIC_DONTCARE
))) return 0;
788 switch(GDIMAGIC(ptr
->wMagic
))
815 result
= OBJ_METAFILE
;
817 case METAFILE_DC_MAGIC
:
820 case ENHMETAFILE_MAGIC
:
821 result
= OBJ_ENHMETAFILE
;
823 case ENHMETAFILE_DC_MAGIC
:
824 result
= OBJ_ENHMETADC
;
827 FIXME("Magic %04x not implemented\n", GDIMAGIC(ptr
->wMagic
) );
830 GDI_ReleaseObj( handle
);
834 /***********************************************************************
835 * GetCurrentObject (GDI32.166)
837 HANDLE WINAPI
GetCurrentObject(HDC hdc
,UINT type
)
840 DC
* dc
= DC_GetDCPtr( hdc
);
845 case OBJ_PEN
: ret
= dc
->hPen
; break;
846 case OBJ_BRUSH
: ret
= dc
->hBrush
; break;
847 case OBJ_PAL
: ret
= dc
->hPalette
; break;
848 case OBJ_FONT
: ret
= dc
->hFont
; break;
849 case OBJ_BITMAP
: ret
= dc
->hBitmap
; break;
851 /* the SDK only mentions those above */
852 FIXME("(%08x,%d): unknown type.\n",hdc
,type
);
855 GDI_ReleaseObj( hdc
);
861 /***********************************************************************
862 * SelectObject16 (GDI.45)
864 HGDIOBJ16 WINAPI
SelectObject16( HDC16 hdc
, HGDIOBJ16 handle
)
866 return (HGDIOBJ16
)SelectObject( hdc
, handle
);
870 /***********************************************************************
871 * SelectObject (GDI32.299)
873 HGDIOBJ WINAPI
SelectObject( HDC hdc
, HGDIOBJ handle
)
876 DC
* dc
= DC_GetDCUpdate( hdc
);
878 TRACE("hdc=%04x %04x\n", hdc
, handle
);
879 if (dc
->funcs
->pSelectObject
)
880 ret
= dc
->funcs
->pSelectObject( dc
, handle
);
881 GDI_ReleaseObj( hdc
);
886 /***********************************************************************
887 * UnrealizeObject16 (GDI.150)
889 BOOL16 WINAPI
UnrealizeObject16( HGDIOBJ16 obj
)
891 return UnrealizeObject( obj
);
895 /***********************************************************************
896 * UnrealizeObject (GDI32.358)
898 BOOL WINAPI
UnrealizeObject( HGDIOBJ obj
)
901 /* Check if object is valid */
903 GDIOBJHDR
* header
= GDI_GetObjPtr( obj
, MAGIC_DONTCARE
);
904 if (!header
) return FALSE
;
906 TRACE("%04x\n", obj
);
908 /* Unrealize object */
910 switch(GDIMAGIC(header
->wMagic
))
913 result
= PALETTE_UnrealizeObject( obj
, (PALETTEOBJ
*)header
);
917 /* Windows resets the brush origin. We don't need to. */
920 GDI_ReleaseObj( obj
);
925 /***********************************************************************
926 * EnumObjects16 (GDI.71)
928 INT16 WINAPI
EnumObjects16( HDC16 hdc
, INT16 nObjType
,
929 GOBJENUMPROC16 lpEnumFunc
, LPARAM lParam
)
931 /* Solid colors to enumerate */
932 static const COLORREF solid_colors
[] =
933 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
934 RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
935 RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
936 RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
937 RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
938 RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
939 RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
940 RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
945 LOGBRUSH16
*brush
= NULL
;
947 TRACE("%04x %d %08lx %08lx\n",
948 hdc
, nObjType
, (DWORD
)lpEnumFunc
, lParam
);
952 /* Enumerate solid pens */
953 if (!(pen
= SEGPTR_NEW(LOGPEN16
))) break;
954 for (i
= 0; i
< sizeof(solid_colors
)/sizeof(solid_colors
[0]); i
++)
956 pen
->lopnStyle
= PS_SOLID
;
957 pen
->lopnWidth
.x
= 1;
958 pen
->lopnWidth
.y
= 0;
959 pen
->lopnColor
= solid_colors
[i
];
960 retval
= lpEnumFunc( SEGPTR_GET(pen
), lParam
);
961 TRACE("solid pen %08lx, ret=%d\n",
962 solid_colors
[i
], retval
);
969 /* Enumerate solid brushes */
970 if (!(brush
= SEGPTR_NEW(LOGBRUSH16
))) break;
971 for (i
= 0; i
< sizeof(solid_colors
)/sizeof(solid_colors
[0]); i
++)
973 brush
->lbStyle
= BS_SOLID
;
974 brush
->lbColor
= solid_colors
[i
];
976 retval
= lpEnumFunc( SEGPTR_GET(brush
), lParam
);
977 TRACE("solid brush %08lx, ret=%d\n",
978 solid_colors
[i
], retval
);
982 /* Now enumerate hatched brushes */
983 if (retval
) for (i
= HS_HORIZONTAL
; i
<= HS_DIAGCROSS
; i
++)
985 brush
->lbStyle
= BS_HATCHED
;
986 brush
->lbColor
= RGB(0,0,0);
988 retval
= lpEnumFunc( SEGPTR_GET(brush
), lParam
);
989 TRACE("hatched brush %d, ret=%d\n",
997 WARN("(%d): Invalid type\n", nObjType
);
1004 /***********************************************************************
1005 * EnumObjects (GDI32.89)
1007 INT WINAPI
EnumObjects( HDC hdc
, INT nObjType
,
1008 GOBJENUMPROC lpEnumFunc
, LPARAM lParam
)
1010 /* Solid colors to enumerate */
1011 static const COLORREF solid_colors
[] =
1012 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
1013 RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
1014 RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
1015 RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
1016 RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
1017 RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
1018 RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
1019 RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
1026 TRACE("%04x %d %08lx %08lx\n",
1027 hdc
, nObjType
, (DWORD
)lpEnumFunc
, lParam
);
1031 /* Enumerate solid pens */
1032 for (i
= 0; i
< sizeof(solid_colors
)/sizeof(solid_colors
[0]); i
++)
1034 pen
.lopnStyle
= PS_SOLID
;
1035 pen
.lopnWidth
.x
= 1;
1036 pen
.lopnWidth
.y
= 0;
1037 pen
.lopnColor
= solid_colors
[i
];
1038 retval
= lpEnumFunc( &pen
, lParam
);
1039 TRACE("solid pen %08lx, ret=%d\n",
1040 solid_colors
[i
], retval
);
1046 /* Enumerate solid brushes */
1047 for (i
= 0; i
< sizeof(solid_colors
)/sizeof(solid_colors
[0]); i
++)
1049 brush
.lbStyle
= BS_SOLID
;
1050 brush
.lbColor
= solid_colors
[i
];
1052 retval
= lpEnumFunc( &brush
, lParam
);
1053 TRACE("solid brush %08lx, ret=%d\n",
1054 solid_colors
[i
], retval
);
1058 /* Now enumerate hatched brushes */
1059 if (retval
) for (i
= HS_HORIZONTAL
; i
<= HS_DIAGCROSS
; i
++)
1061 brush
.lbStyle
= BS_HATCHED
;
1062 brush
.lbColor
= RGB(0,0,0);
1064 retval
= lpEnumFunc( &brush
, lParam
);
1065 TRACE("hatched brush %d, ret=%d\n",
1072 /* FIXME: implement Win32 types */
1073 WARN("(%d): Invalid type\n", nObjType
);
1080 /***********************************************************************
1081 * IsGDIObject (GDI.462)
1083 * returns type of object if valid (W95 system programming secrets p. 264-5)
1085 BOOL16 WINAPI
IsGDIObject16( HGDIOBJ16 handle
)
1089 GDIOBJHDR
*object
= GDI_GetObjPtr( handle
, MAGIC_DONTCARE
);
1092 magic
= GDIMAGIC(object
->wMagic
) - PEN_MAGIC
+ 1;
1093 GDI_ReleaseObj( handle
);
1099 /***********************************************************************
1100 * SetObjectOwner16 (GDI.461)
1102 void WINAPI
SetObjectOwner16( HGDIOBJ16 handle
, HANDLE16 owner
)
1108 /***********************************************************************
1109 * SetObjectOwner (GDI32.386)
1111 void WINAPI
SetObjectOwner( HGDIOBJ handle
, HANDLE owner
)
1117 /***********************************************************************
1118 * MakeObjectPrivate (GDI.463)
1120 * What does that mean ?
1121 * Some little docu can be found in "Undocumented Windows",
1122 * but this is basically useless.
1123 * At least we know that this flags the GDI object's wMagic
1124 * with 0x2000 (OBJECT_PRIVATE), so we just do it.
1125 * But Wine doesn't react on that yet.
1127 void WINAPI
MakeObjectPrivate16( HGDIOBJ16 handle
, BOOL16
private )
1129 GDIOBJHDR
*ptr
= GDI_GetObjPtr( handle
, MAGIC_DONTCARE
);
1132 ERR("invalid GDI object %04x !\n", handle
);
1135 ptr
->wMagic
|= OBJECT_PRIVATE
;
1136 GDI_ReleaseObj( handle
);
1140 /***********************************************************************
1141 * GdiFlush (GDI32.128)
1143 BOOL WINAPI
GdiFlush(void)
1145 return TRUE
; /* FIXME */
1149 /***********************************************************************
1150 * GdiGetBatchLimit (GDI32.129)
1152 DWORD WINAPI
GdiGetBatchLimit(void)
1154 return 1; /* FIXME */
1158 /***********************************************************************
1159 * GdiSetBatchLimit (GDI32.139)
1161 DWORD WINAPI
GdiSetBatchLimit( DWORD limit
)
1163 return 1; /* FIXME */
1167 /***********************************************************************
1168 * GdiSeeGdiDo (GDI.452)
1170 DWORD WINAPI
GdiSeeGdiDo16( WORD wReqType
, WORD wParam1
, WORD wParam2
,
1175 case 0x0001: /* LocalAlloc */
1176 return LOCAL_Alloc( GDI_HeapSel
, wParam1
, wParam3
);
1177 case 0x0002: /* LocalFree */
1178 return LOCAL_Free( GDI_HeapSel
, wParam1
);
1179 case 0x0003: /* LocalCompact */
1180 return LOCAL_Compact( GDI_HeapSel
, wParam3
, 0 );
1181 case 0x0103: /* LocalHeap */
1184 WARN("(wReqType=%04x): Unknown\n", wReqType
);
1189 /***********************************************************************
1190 * GdiSignalProc (GDI.610)
1192 WORD WINAPI
GdiSignalProc( UINT uCode
, DWORD dwThreadOrProcessID
,
1193 DWORD dwFlags
, HMODULE16 hModule
)
1198 /***********************************************************************
1199 * FinalGdiInit16 (GDI.405)
1201 void WINAPI
FinalGdiInit16( HANDLE16 unknown
)
1205 /***********************************************************************
1206 * GdiFreeResources (GDI.609)
1208 WORD WINAPI
GdiFreeResources16( DWORD reserve
)
1210 return (WORD
)( (int)LOCAL_CountFree( GDI_HeapSel
) * 100 /
1211 (int)LOCAL_HeapSize( GDI_HeapSel
) );
1214 /***********************************************************************
1215 * MulDiv16 (GDI.128)
1217 INT16 WINAPI
MulDiv16(
1218 INT16 nMultiplicand
,
1223 if (!nDivisor
) return -32768;
1224 /* We want to deal with a positive divisor to simplify the logic. */
1227 nMultiplicand
= - nMultiplicand
;
1228 nDivisor
= -nDivisor
;
1230 /* If the result is positive, we "add" to round. else,
1231 * we subtract to round. */
1232 if ( ( (nMultiplicand
< 0) && (nMultiplier
< 0) ) ||
1233 ( (nMultiplicand
>= 0) && (nMultiplier
>= 0) ) )
1234 ret
= (((int)nMultiplicand
* nMultiplier
) + (nDivisor
/2)) / nDivisor
;
1236 ret
= (((int)nMultiplicand
* nMultiplier
) - (nDivisor
/2)) / nDivisor
;
1237 if ((ret
> 32767) || (ret
< -32767)) return -32768;
1242 /*******************************************************************
1243 * GetColorAdjustment [GDI32.164]
1247 BOOL WINAPI
GetColorAdjustment(HDC hdc
, LPCOLORADJUSTMENT lpca
)
1249 FIXME("GetColorAdjustment, stub\n");
1253 /*******************************************************************
1254 * GetMiterLimit [GDI32.201]
1258 BOOL WINAPI
GetMiterLimit(HDC hdc
, PFLOAT peLimit
)
1260 FIXME("GetMiterLimit, stub\n");
1264 /*******************************************************************
1265 * SetMiterLimit [GDI32.325]
1269 BOOL WINAPI
SetMiterLimit(HDC hdc
, FLOAT eNewLimit
, PFLOAT peOldLimit
)
1271 FIXME("SetMiterLimit, stub\n");
1275 /*******************************************************************
1276 * GdiComment [GDI32.109]
1280 BOOL WINAPI
GdiComment(HDC hdc
, UINT cbSize
, const BYTE
*lpData
)
1282 FIXME("GdiComment, stub\n");
1285 /*******************************************************************
1286 * SetColorAdjustment [GDI32.309]
1290 BOOL WINAPI
SetColorAdjustment(HDC hdc
, const COLORADJUSTMENT
* lpca
)
1292 FIXME("SetColorAdjustment, stub\n");