4 * Copyright 1993 Alexandre Julliard
16 #include "wine/winbase16.h"
27 #include "debugtools.h"
32 DEFAULT_DEBUG_CHANNEL(gdi
);
34 /**********************************************************************/
36 GDI_DRIVER
*GDI_Driver
= NULL
;
38 /***********************************************************************
42 static BRUSHOBJ WhiteBrush
=
44 { 0, BRUSH_MAGIC
, 1 }, /* header */
45 { BS_SOLID
, RGB(255,255,255), 0 } /* logbrush */
48 static BRUSHOBJ LtGrayBrush
=
50 { 0, BRUSH_MAGIC
, 1 }, /* header */
51 /* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
52 { BS_SOLID
, RGB(192,192,192), 0 } /* logbrush */
55 static BRUSHOBJ GrayBrush
=
57 { 0, BRUSH_MAGIC
, 1 }, /* header */
58 /* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
59 { BS_SOLID
, RGB(128,128,128), 0 } /* logbrush */
62 static BRUSHOBJ DkGrayBrush
=
64 { 0, BRUSH_MAGIC
, 1 }, /* header */
65 /* This is BS_HATCHED, for 1 bitperpixel. This makes the spray work in pbrush */
66 /* NB_HATCH_STYLES is an index into HatchBrushes */
67 { BS_HATCHED
, RGB(0,0,0), NB_HATCH_STYLES
} /* logbrush */
70 static BRUSHOBJ BlackBrush
=
72 { 0, BRUSH_MAGIC
, 1 }, /* header */
73 { BS_SOLID
, RGB(0,0,0), 0 } /* logbrush */
76 static BRUSHOBJ NullBrush
=
78 { 0, BRUSH_MAGIC
, 1 }, /* header */
79 { BS_NULL
, 0, 0 } /* logbrush */
82 static PENOBJ WhitePen
=
84 { 0, PEN_MAGIC
, 1 }, /* header */
85 { PS_SOLID
, { 1, 0 }, RGB(255,255,255) } /* logpen */
88 static PENOBJ BlackPen
=
90 { 0, PEN_MAGIC
, 1 }, /* header */
91 { PS_SOLID
, { 1, 0 }, RGB(0,0,0) } /* logpen */
94 static PENOBJ NullPen
=
96 { 0, PEN_MAGIC
, 1 }, /* header */
97 { PS_NULL
, { 1, 0 }, 0 } /* logpen */
100 static FONTOBJ OEMFixedFont
=
102 { 0, FONT_MAGIC
, 1 }, /* header */
103 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, OEM_CHARSET
,
104 0, 0, DEFAULT_QUALITY
, FIXED_PITCH
| FF_MODERN
, "" }
106 /* Filler to make the location counter dword aligned again. This is necessary
107 since (a) FONTOBJ is packed, (b) gcc places initialised variables in the code
108 segment, and (c) Solaris assembler is stupid. */
109 static UINT16 align_OEMFixedFont
= 1;
111 static FONTOBJ AnsiFixedFont
=
113 { 0, FONT_MAGIC
, 1 }, /* header */
114 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
115 0, 0, DEFAULT_QUALITY
, FIXED_PITCH
| FF_MODERN
, "" }
117 static UINT16 align_AnsiFixedFont
= 1;
119 static FONTOBJ AnsiVarFont
=
121 { 0, FONT_MAGIC
, 1 }, /* header */
122 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
123 0, 0, DEFAULT_QUALITY
, VARIABLE_PITCH
| FF_SWISS
, "MS Sans Serif" }
125 static UINT16 align_AnsiVarFont
= 1;
127 static FONTOBJ SystemFont
=
129 { 0, FONT_MAGIC
, 1 },
130 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
131 0, 0, DEFAULT_QUALITY
, VARIABLE_PITCH
| FF_SWISS
, "System" }
133 static UINT16 align_SystemFont
= 1;
135 static FONTOBJ DeviceDefaultFont
=
137 { 0, FONT_MAGIC
, 1 }, /* header */
138 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
139 0, 0, DEFAULT_QUALITY
, VARIABLE_PITCH
| FF_SWISS
, "" }
141 static UINT16 align_DeviceDefaultFont
= 1;
143 static FONTOBJ SystemFixedFont
=
145 { 0, FONT_MAGIC
, 1 }, /* header */
146 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
147 0, 0, DEFAULT_QUALITY
, FIXED_PITCH
| FF_MODERN
, "" }
149 static UINT16 align_SystemFixedFont
= 1;
151 /* FIXME: Is this correct? */
152 static FONTOBJ DefaultGuiFont
=
154 { 0, FONT_MAGIC
, 1 }, /* header */
155 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
156 0, 0, DEFAULT_QUALITY
, VARIABLE_PITCH
| FF_SWISS
, "MS Sans Serif" }
158 static UINT16 align_DefaultGuiFont
= 1;
161 static GDIOBJHDR
* StockObjects
[NB_STOCK_OBJECTS
] =
163 (GDIOBJHDR
*) &WhiteBrush
,
164 (GDIOBJHDR
*) &LtGrayBrush
,
165 (GDIOBJHDR
*) &GrayBrush
,
166 (GDIOBJHDR
*) &DkGrayBrush
,
167 (GDIOBJHDR
*) &BlackBrush
,
168 (GDIOBJHDR
*) &NullBrush
,
169 (GDIOBJHDR
*) &WhitePen
,
170 (GDIOBJHDR
*) &BlackPen
,
171 (GDIOBJHDR
*) &NullPen
,
173 (GDIOBJHDR
*) &OEMFixedFont
,
174 (GDIOBJHDR
*) &AnsiFixedFont
,
175 (GDIOBJHDR
*) &AnsiVarFont
,
176 (GDIOBJHDR
*) &SystemFont
,
177 (GDIOBJHDR
*) &DeviceDefaultFont
,
178 NULL
, /* DEFAULT_PALETTE created by PALETTE_Init */
179 (GDIOBJHDR
*) &SystemFixedFont
,
180 (GDIOBJHDR
*) &DefaultGuiFont
183 HBITMAP hPseudoStockBitmap
; /* 1x1 bitmap for memory DCs */
185 static SYSLEVEL GDI_level
;
186 static WORD GDI_HeapSel
;
189 /******************************************************************************
191 * void ReadFontInformation(
192 * char const *fontName,
200 * ReadFontInformation() checks the Wine configuration file's Tweak.Fonts
201 * section for entries containing fontName.Height, fontName.Bold, etc.,
202 * where fontName is the name specified in the call (e.g., "System"). It
203 * attempts to be user friendly by accepting 'n', 'N', 'f', 'F', or '0' as
204 * the first character in the boolean attributes (bold, italic, and
206 *****************************************************************************/
208 static void ReadFontInformation(
209 char const *fontName
,
219 /* In order for the stock fonts to be independent of
220 * mapping mode, the height (& width) must be 0
222 sprintf(key
, "%s.Height", fontName
);
223 font
->logfont
.lfHeight
=
224 PROFILE_GetWineIniInt("Tweak.Fonts", key
, defHeight
);
226 sprintf(key
, "%s.Bold", fontName
);
227 font
->logfont
.lfWeight
=
228 (PROFILE_GetWineIniBool("Tweak.Fonts", key
, defBold
)) ?
231 sprintf(key
, "%s.Italic", fontName
);
232 font
->logfont
.lfItalic
=
233 PROFILE_GetWineIniBool("Tweak.Fonts", key
, defItalic
);
235 sprintf(key
, "%s.Underline", fontName
);
236 font
->logfont
.lfUnderline
=
237 PROFILE_GetWineIniBool("Tweak.Fonts", key
, defUnderline
);
239 sprintf(key
, "%s.StrikeOut", fontName
);
240 font
->logfont
.lfStrikeOut
=
241 PROFILE_GetWineIniBool("Tweak.Fonts", key
, defStrikeOut
);
246 /***********************************************************************
247 * Because the stock fonts have their structure initialized with
248 * a height of 0 to keep them independent of mapping mode, simply
249 * returning the LOGFONT as is will not work correctly.
250 * These "FixStockFontSizeXXX()" methods will get the correct
251 * size for the fonts.
253 static void GetFontMetrics(HFONT handle
, LPTEXTMETRICA lptm
)
258 hdc
= CreateDCA("DISPLAY", NULL
, NULL
, NULL
);
260 hOldFont
= (HFONT
)SelectObject(hdc
, handle
);
262 GetTextMetricsA(hdc
, lptm
);
264 SelectObject(hdc
, hOldFont
);
269 static inline void FixStockFontSize16(
275 LOGFONT16
* pLogFont
= (LOGFONT16
*)buffer
;
278 * Was the lfHeight field copied (it's the first field)?
279 * If it was and it was null, replace the height.
281 if ( (count
>= 2*sizeof(INT16
)) &&
282 (pLogFont
->lfHeight
== 0) )
284 GetFontMetrics(handle
, &tm
);
286 pLogFont
->lfHeight
= tm
.tmHeight
;
287 pLogFont
->lfWidth
= tm
.tmAveCharWidth
;
291 static inline void FixStockFontSizeA(
297 LOGFONTA
* pLogFont
= (LOGFONTA
*)buffer
;
300 * Was the lfHeight field copied (it's the first field)?
301 * If it was and it was null, replace the height.
303 if ( (count
>= 2*sizeof(INT
)) &&
304 (pLogFont
->lfHeight
== 0) )
306 GetFontMetrics(handle
, &tm
);
308 pLogFont
->lfHeight
= tm
.tmHeight
;
309 pLogFont
->lfWidth
= tm
.tmAveCharWidth
;
314 * Since the LOGFONTA and LOGFONTW structures are identical up to the
315 * lfHeight member (the one of interest in this case) we simply define
316 * the W version as the A version.
318 #define FixStockFontSizeW FixStockFontSizeA
320 #define TRACE_SEC(handle,text) \
321 TRACE("(%04x): " text " %ld\n", (handle), GDI_level.crst.RecursionCount)
323 /***********************************************************************
326 * GDI initialization.
330 BOOL systemIsBold
= (TWEAK_WineLook
== WIN31_LOOK
);
332 HINSTANCE16 instance
;
334 _CreateSysLevel( &GDI_level
, 3 );
336 /* create GDI heap */
337 if ((instance
= LoadLibrary16( "GDI.EXE" )) < 32) return FALSE
;
338 GDI_HeapSel
= GlobalHandleToSel16( instance
);
340 /* Kill some warnings. */
341 (void)align_OEMFixedFont
;
342 (void)align_AnsiFixedFont
;
343 (void)align_AnsiVarFont
;
344 (void)align_SystemFont
;
345 (void)align_DeviceDefaultFont
;
346 (void)align_SystemFixedFont
;
347 (void)align_DefaultGuiFont
;
349 /* TWEAK: Initialize font hints */
350 ReadFontInformation("OEMFixed", &OEMFixedFont
, 0, 0, 0, 0, 0);
351 ReadFontInformation("AnsiFixed", &AnsiFixedFont
, 0, 0, 0, 0, 0);
352 ReadFontInformation("AnsiVar", &AnsiVarFont
, 0, 0, 0, 0, 0);
353 ReadFontInformation("System", &SystemFont
, 0, systemIsBold
, 0, 0, 0);
354 ReadFontInformation("DeviceDefault", &DeviceDefaultFont
, 0, 0, 0, 0, 0);
355 ReadFontInformation("SystemFixed", &SystemFixedFont
, 0, systemIsBold
, 0, 0, 0);
356 ReadFontInformation("DefaultGui", &DefaultGuiFont
, 0, 0, 0, 0, 0);
358 /* Create default palette */
360 /* DR well *this* palette can't be moveable (?) */
361 hpalette
= PALETTE_Init();
362 if( !hpalette
) return FALSE
;
363 StockObjects
[DEFAULT_PALETTE
] = (GDIOBJHDR
*)LOCAL_Lock( GDI_HeapSel
, hpalette
);
365 hPseudoStockBitmap
= CreateBitmap( 1, 1, 1, 1, NULL
);
370 /***********************************************************************
373 void *GDI_AllocObject( WORD size
, WORD magic
, HGDIOBJ
*handle
)
375 static DWORD count
= 0;
378 _EnterSysLevel( &GDI_level
);
379 if (!(*handle
= LOCAL_Alloc( GDI_HeapSel
, LMEM_MOVEABLE
, size
)))
381 _LeaveSysLevel( &GDI_level
);
384 obj
= (GDIOBJHDR
*)LOCAL_Lock( GDI_HeapSel
, *handle
);
387 obj
->dwCount
= ++count
;
389 TRACE_SEC( *handle
, "enter" );
394 /***********************************************************************
397 * The object ptr must have been obtained with GDI_GetObjPtr.
398 * The new pointer must be released with GDI_ReleaseObj.
400 void *GDI_ReallocObject( WORD size
, HGDIOBJ handle
, void *object
)
404 LOCAL_Unlock( GDI_HeapSel
, handle
);
405 if (!(new_handle
= LOCAL_ReAlloc( GDI_HeapSel
, handle
, size
, LMEM_MOVEABLE
)))
407 TRACE_SEC( handle
, "leave" );
408 _LeaveSysLevel( &GDI_level
);
411 assert( new_handle
== handle
); /* moveable handle cannot change */
412 return LOCAL_Lock( GDI_HeapSel
, handle
);
416 /***********************************************************************
419 BOOL
GDI_FreeObject( HGDIOBJ handle
, void *ptr
)
421 GDIOBJHDR
*object
= ptr
;
423 /* can't free stock objects */
424 if (handle
< FIRST_STOCK_HANDLE
)
426 object
->wMagic
= 0; /* Mark it as invalid */
427 LOCAL_Unlock( GDI_HeapSel
, handle
);
428 LOCAL_Free( GDI_HeapSel
, handle
);
430 TRACE_SEC( handle
, "leave" );
431 _LeaveSysLevel( &GDI_level
);
436 /***********************************************************************
439 * Return a pointer to the GDI object associated to the handle.
440 * Return NULL if the object has the wrong magic number.
441 * The object must be released with GDI_ReleaseObj.
443 void *GDI_GetObjPtr( HGDIOBJ handle
, WORD magic
)
445 GDIOBJHDR
*ptr
= NULL
;
447 _EnterSysLevel( &GDI_level
);
449 if (handle
>= FIRST_STOCK_HANDLE
)
451 if (handle
<= LAST_STOCK_HANDLE
) ptr
= StockObjects
[handle
- FIRST_STOCK_HANDLE
];
452 if (ptr
&& (magic
!= MAGIC_DONTCARE
) && (ptr
->wMagic
!= magic
)) ptr
= NULL
;
456 ptr
= (GDIOBJHDR
*)LOCAL_Lock( GDI_HeapSel
, handle
);
457 if (ptr
&& (magic
!= MAGIC_DONTCARE
) && (ptr
->wMagic
!= magic
))
459 LOCAL_Unlock( GDI_HeapSel
, handle
);
466 _LeaveSysLevel( &GDI_level
);
467 SetLastError( ERROR_INVALID_HANDLE
);
469 else TRACE_SEC( handle
, "enter" );
475 /***********************************************************************
479 void GDI_ReleaseObj( HGDIOBJ handle
)
481 if (handle
< FIRST_STOCK_HANDLE
) LOCAL_Unlock( GDI_HeapSel
, handle
);
482 TRACE_SEC( handle
, "leave" );
483 _LeaveSysLevel( &GDI_level
);
487 /***********************************************************************
488 * DeleteObject16 (GDI.69)
490 BOOL16 WINAPI
DeleteObject16( HGDIOBJ16 obj
)
492 return DeleteObject( obj
);
496 /***********************************************************************
497 * DeleteObject (GDI32.70)
499 BOOL WINAPI
DeleteObject( HGDIOBJ obj
)
501 /* Check if object is valid */
504 if (HIWORD(obj
)) return FALSE
;
505 if ((obj
>= FIRST_STOCK_HANDLE
) && (obj
<= LAST_STOCK_HANDLE
)) {
506 TRACE("Preserving Stock object %04x\n", obj
);
507 /* NOTE: No GDI_Release is necessary */
510 if (!(header
= GDI_GetObjPtr( obj
, MAGIC_DONTCARE
))) return FALSE
;
512 TRACE("%04x\n", obj
);
516 switch(header
->wMagic
)
518 case PEN_MAGIC
: return GDI_FreeObject( obj
, header
);
519 case BRUSH_MAGIC
: return BRUSH_DeleteObject( obj
, (BRUSHOBJ
*)header
);
520 case FONT_MAGIC
: return GDI_FreeObject( obj
, header
);
521 case PALETTE_MAGIC
: return PALETTE_DeleteObject(obj
,(PALETTEOBJ
*)header
);
522 case BITMAP_MAGIC
: return BITMAP_DeleteObject( obj
, (BITMAPOBJ
*)header
);
523 case REGION_MAGIC
: return REGION_DeleteObject( obj
, (RGNOBJ
*)header
);
525 GDI_ReleaseObj( obj
);
526 return DeleteDC(obj
);
528 WARN("Already deleted\n");
531 WARN("Unknown magic number (%d)\n",header
->wMagic
);
533 GDI_ReleaseObj( obj
);
537 /***********************************************************************
538 * GetStockObject16 (GDI.87)
540 HGDIOBJ16 WINAPI
GetStockObject16( INT16 obj
)
542 return (HGDIOBJ16
)GetStockObject( obj
);
546 /***********************************************************************
547 * GetStockObject (GDI32.220)
549 HGDIOBJ WINAPI
GetStockObject( INT obj
)
552 if ((obj
< 0) || (obj
>= NB_STOCK_OBJECTS
)) return 0;
553 if (!StockObjects
[obj
]) return 0;
554 ret
= (HGDIOBJ16
)(FIRST_STOCK_HANDLE
+ obj
);
555 TRACE("returning %4x\n", ret
);
560 /***********************************************************************
561 * GetObject16 (GDI.82)
563 INT16 WINAPI
GetObject16( HANDLE16 handle
, INT16 count
, LPVOID buffer
)
567 TRACE("%04x %d %p\n", handle
, count
, buffer
);
568 if (!count
) return 0;
570 if (!(ptr
= GDI_GetObjPtr( handle
, MAGIC_DONTCARE
))) return 0;
575 result
= PEN_GetObject16( (PENOBJ
*)ptr
, count
, buffer
);
578 result
= BRUSH_GetObject16( (BRUSHOBJ
*)ptr
, count
, buffer
);
581 result
= BITMAP_GetObject16( (BITMAPOBJ
*)ptr
, count
, buffer
);
584 result
= FONT_GetObject16( (FONTOBJ
*)ptr
, count
, buffer
);
587 * Fix the LOGFONT structure for the stock fonts
589 if ( (handle
>= FIRST_STOCK_HANDLE
) &&
590 (handle
<= LAST_STOCK_HANDLE
) )
591 FixStockFontSize16(handle
, count
, buffer
);
594 result
= PALETTE_GetObject( (PALETTEOBJ
*)ptr
, count
, buffer
);
597 GDI_ReleaseObj( handle
);
602 /***********************************************************************
603 * GetObjectA (GDI32.204)
605 INT WINAPI
GetObjectA( HANDLE handle
, INT count
, LPVOID buffer
)
609 TRACE("%08x %d %p\n", handle
, count
, buffer
);
610 if (!count
) return 0;
612 if (!(ptr
= GDI_GetObjPtr( handle
, MAGIC_DONTCARE
))) return 0;
617 result
= PEN_GetObject( (PENOBJ
*)ptr
, count
, buffer
);
620 result
= BRUSH_GetObject( (BRUSHOBJ
*)ptr
, count
, buffer
);
623 result
= BITMAP_GetObject( (BITMAPOBJ
*)ptr
, count
, buffer
);
626 result
= FONT_GetObjectA( (FONTOBJ
*)ptr
, count
, buffer
);
629 * Fix the LOGFONT structure for the stock fonts
631 if ( (handle
>= FIRST_STOCK_HANDLE
) &&
632 (handle
<= LAST_STOCK_HANDLE
) )
633 FixStockFontSizeA(handle
, count
, buffer
);
636 result
= PALETTE_GetObject( (PALETTEOBJ
*)ptr
, count
, buffer
);
641 case DISABLED_DC_MAGIC
:
644 case METAFILE_DC_MAGIC
:
645 case ENHMETAFILE_MAGIC
:
646 case ENHMETAFILE_DC_MAGIC
:
647 FIXME("Magic %04x not implemented\n",
652 ERR("Invalid GDI Magic %04x\n", ptr
->wMagic
);
655 GDI_ReleaseObj( handle
);
659 /***********************************************************************
660 * GetObjectW (GDI32.206)
662 INT WINAPI
GetObjectW( HANDLE handle
, INT count
, LPVOID buffer
)
666 TRACE("%08x %d %p\n", handle
, count
, buffer
);
667 if (!count
) return 0;
669 if (!(ptr
= GDI_GetObjPtr( handle
, MAGIC_DONTCARE
))) return 0;
674 result
= PEN_GetObject( (PENOBJ
*)ptr
, count
, buffer
);
677 result
= BRUSH_GetObject( (BRUSHOBJ
*)ptr
, count
, buffer
);
680 result
= BITMAP_GetObject( (BITMAPOBJ
*)ptr
, count
, buffer
);
683 result
= FONT_GetObjectW( (FONTOBJ
*)ptr
, count
, buffer
);
686 * Fix the LOGFONT structure for the stock fonts
688 if ( (handle
>= FIRST_STOCK_HANDLE
) &&
689 (handle
<= LAST_STOCK_HANDLE
) )
690 FixStockFontSizeW(handle
, count
, buffer
);
693 result
= PALETTE_GetObject( (PALETTEOBJ
*)ptr
, count
, buffer
);
696 FIXME("Magic %04x not implemented\n",
700 GDI_ReleaseObj( handle
);
704 /***********************************************************************
705 * GetObjectType (GDI32.205)
707 DWORD WINAPI
GetObjectType( HANDLE handle
)
711 TRACE("%08x\n", handle
);
713 if (!(ptr
= GDI_GetObjPtr( handle
, MAGIC_DONTCARE
))) return 0;
742 result
= OBJ_METAFILE
;
744 case METAFILE_DC_MAGIC
:
747 case ENHMETAFILE_MAGIC
:
748 result
= OBJ_ENHMETAFILE
;
750 case ENHMETAFILE_DC_MAGIC
:
751 result
= OBJ_ENHMETADC
;
754 FIXME("Magic %04x not implemented\n",
758 GDI_ReleaseObj( handle
);
762 /***********************************************************************
763 * GetCurrentObject (GDI32.166)
765 HANDLE WINAPI
GetCurrentObject(HDC hdc
,UINT type
)
768 DC
* dc
= DC_GetDCPtr( hdc
);
773 case OBJ_PEN
: ret
= dc
->w
.hPen
; break;
774 case OBJ_BRUSH
: ret
= dc
->w
.hBrush
; break;
775 case OBJ_PAL
: ret
= dc
->w
.hPalette
; break;
776 case OBJ_FONT
: ret
= dc
->w
.hFont
; break;
777 case OBJ_BITMAP
: ret
= dc
->w
.hBitmap
; break;
779 /* the SDK only mentions those above */
780 WARN("(%08x,%d): unknown type.\n",hdc
,type
);
783 GDI_ReleaseObj( hdc
);
789 /***********************************************************************
790 * SelectObject16 (GDI.45)
792 HGDIOBJ16 WINAPI
SelectObject16( HDC16 hdc
, HGDIOBJ16 handle
)
794 return (HGDIOBJ16
)SelectObject( hdc
, handle
);
798 /***********************************************************************
799 * SelectObject (GDI32.299)
801 HGDIOBJ WINAPI
SelectObject( HDC hdc
, HGDIOBJ handle
)
804 DC
* dc
= DC_GetDCUpdate( hdc
);
806 TRACE("hdc=%04x %04x\n", hdc
, handle
);
807 if (dc
->funcs
->pSelectObject
)
808 ret
= dc
->funcs
->pSelectObject( dc
, handle
);
809 GDI_ReleaseObj( hdc
);
814 /***********************************************************************
815 * UnrealizeObject16 (GDI.150)
817 BOOL16 WINAPI
UnrealizeObject16( HGDIOBJ16 obj
)
819 return UnrealizeObject( obj
);
823 /***********************************************************************
824 * UnrealizeObject (GDI32.358)
826 BOOL WINAPI
UnrealizeObject( HGDIOBJ obj
)
829 /* Check if object is valid */
831 GDIOBJHDR
* header
= GDI_GetObjPtr( obj
, MAGIC_DONTCARE
);
832 if (!header
) return FALSE
;
834 TRACE("%04x\n", obj
);
836 /* Unrealize object */
838 switch(header
->wMagic
)
841 result
= PALETTE_UnrealizeObject( obj
, (PALETTEOBJ
*)header
);
845 /* Windows resets the brush origin. We don't need to. */
848 GDI_ReleaseObj( obj
);
853 /***********************************************************************
854 * EnumObjects16 (GDI.71)
856 INT16 WINAPI
EnumObjects16( HDC16 hdc
, INT16 nObjType
,
857 GOBJENUMPROC16 lpEnumFunc
, LPARAM lParam
)
859 /* Solid colors to enumerate */
860 static const COLORREF solid_colors
[] =
861 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
862 RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
863 RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
864 RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
865 RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
866 RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
867 RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
868 RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
873 LOGBRUSH16
*brush
= NULL
;
875 TRACE("%04x %d %08lx %08lx\n",
876 hdc
, nObjType
, (DWORD
)lpEnumFunc
, lParam
);
880 /* Enumerate solid pens */
881 if (!(pen
= SEGPTR_NEW(LOGPEN16
))) break;
882 for (i
= 0; i
< sizeof(solid_colors
)/sizeof(solid_colors
[0]); i
++)
884 pen
->lopnStyle
= PS_SOLID
;
885 pen
->lopnWidth
.x
= 1;
886 pen
->lopnWidth
.y
= 0;
887 pen
->lopnColor
= solid_colors
[i
];
888 retval
= lpEnumFunc( SEGPTR_GET(pen
), lParam
);
889 TRACE("solid pen %08lx, ret=%d\n",
890 solid_colors
[i
], retval
);
897 /* Enumerate solid brushes */
898 if (!(brush
= SEGPTR_NEW(LOGBRUSH16
))) break;
899 for (i
= 0; i
< sizeof(solid_colors
)/sizeof(solid_colors
[0]); i
++)
901 brush
->lbStyle
= BS_SOLID
;
902 brush
->lbColor
= solid_colors
[i
];
904 retval
= lpEnumFunc( SEGPTR_GET(brush
), lParam
);
905 TRACE("solid brush %08lx, ret=%d\n",
906 solid_colors
[i
], retval
);
910 /* Now enumerate hatched brushes */
911 if (retval
) for (i
= HS_HORIZONTAL
; i
<= HS_DIAGCROSS
; i
++)
913 brush
->lbStyle
= BS_HATCHED
;
914 brush
->lbColor
= RGB(0,0,0);
916 retval
= lpEnumFunc( SEGPTR_GET(brush
), lParam
);
917 TRACE("hatched brush %d, ret=%d\n",
925 WARN("(%d): Invalid type\n", nObjType
);
932 /***********************************************************************
933 * EnumObjects (GDI32.89)
935 INT WINAPI
EnumObjects( HDC hdc
, INT nObjType
,
936 GOBJENUMPROC lpEnumFunc
, LPARAM lParam
)
938 /* Solid colors to enumerate */
939 static const COLORREF solid_colors
[] =
940 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
941 RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
942 RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
943 RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
944 RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
945 RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
946 RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
947 RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
954 TRACE("%04x %d %08lx %08lx\n",
955 hdc
, nObjType
, (DWORD
)lpEnumFunc
, lParam
);
959 /* Enumerate solid pens */
960 for (i
= 0; i
< sizeof(solid_colors
)/sizeof(solid_colors
[0]); i
++)
962 pen
.lopnStyle
= PS_SOLID
;
965 pen
.lopnColor
= solid_colors
[i
];
966 retval
= lpEnumFunc( &pen
, lParam
);
967 TRACE("solid pen %08lx, ret=%d\n",
968 solid_colors
[i
], retval
);
974 /* Enumerate solid brushes */
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( &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( &brush
, lParam
);
993 TRACE("hatched brush %d, ret=%d\n",
1000 /* FIXME: implement Win32 types */
1001 WARN("(%d): Invalid type\n", nObjType
);
1008 /***********************************************************************
1009 * IsGDIObject (GDI.462)
1011 * returns type of object if valid (W95 system programming secrets p. 264-5)
1013 BOOL16 WINAPI
IsGDIObject16( HGDIOBJ16 handle
)
1017 GDIOBJHDR
*object
= GDI_GetObjPtr( handle
, MAGIC_DONTCARE
);
1020 magic
= object
->wMagic
- PEN_MAGIC
+ 1;
1021 GDI_ReleaseObj( handle
);
1027 /***********************************************************************
1028 * SetObjectOwner16 (GDI.461)
1030 void WINAPI
SetObjectOwner16( HGDIOBJ16 handle
, HANDLE16 owner
)
1036 /***********************************************************************
1037 * SetObjectOwner (GDI32.386)
1039 void WINAPI
SetObjectOwner( HGDIOBJ handle
, HANDLE owner
)
1044 /***********************************************************************
1045 * MakeObjectPrivate (GDI.463)
1047 void WINAPI
MakeObjectPrivate16( HGDIOBJ16 handle
, BOOL16
private )
1053 /***********************************************************************
1054 * GdiFlush (GDI32.128)
1056 BOOL WINAPI
GdiFlush(void)
1058 return TRUE
; /* FIXME */
1062 /***********************************************************************
1063 * GdiGetBatchLimit (GDI32.129)
1065 DWORD WINAPI
GdiGetBatchLimit(void)
1067 return 1; /* FIXME */
1071 /***********************************************************************
1072 * GdiSetBatchLimit (GDI32.139)
1074 DWORD WINAPI
GdiSetBatchLimit( DWORD limit
)
1076 return 1; /* FIXME */
1080 /***********************************************************************
1081 * GdiSeeGdiDo (GDI.452)
1083 DWORD WINAPI
GdiSeeGdiDo16( WORD wReqType
, WORD wParam1
, WORD wParam2
,
1088 case 0x0001: /* LocalAlloc */
1089 return LOCAL_Alloc( GDI_HeapSel
, wParam1
, wParam3
);
1090 case 0x0002: /* LocalFree */
1091 return LOCAL_Free( GDI_HeapSel
, wParam1
);
1092 case 0x0003: /* LocalCompact */
1093 return LOCAL_Compact( GDI_HeapSel
, wParam3
, 0 );
1094 case 0x0103: /* LocalHeap */
1097 WARN("(wReqType=%04x): Unknown\n", wReqType
);
1102 /***********************************************************************
1103 * GdiSignalProc (GDI.610)
1105 WORD WINAPI
GdiSignalProc( UINT uCode
, DWORD dwThreadOrProcessID
,
1106 DWORD dwFlags
, HMODULE16 hModule
)
1111 /***********************************************************************
1112 * FinalGdiInit16 (GDI.405)
1114 void WINAPI
FinalGdiInit16( HANDLE16 unknown
)
1118 /***********************************************************************
1119 * GdiFreeResources (GDI.609)
1121 WORD WINAPI
GdiFreeResources16( DWORD reserve
)
1123 return (WORD
)( (int)LOCAL_CountFree( GDI_HeapSel
) * 100 /
1124 (int)LOCAL_HeapSize( GDI_HeapSel
) );
1127 /***********************************************************************
1128 * MulDiv16 (GDI.128)
1130 INT16 WINAPI
MulDiv16(
1131 INT16 nMultiplicand
,
1136 if (!nDivisor
) return -32768;
1137 /* We want to deal with a positive divisor to simplify the logic. */
1140 nMultiplicand
= - nMultiplicand
;
1141 nDivisor
= -nDivisor
;
1143 /* If the result is positive, we "add" to round. else,
1144 * we subtract to round. */
1145 if ( ( (nMultiplicand
< 0) && (nMultiplier
< 0) ) ||
1146 ( (nMultiplicand
>= 0) && (nMultiplier
>= 0) ) )
1147 ret
= (((int)nMultiplicand
* nMultiplier
) + (nDivisor
/2)) / nDivisor
;
1149 ret
= (((int)nMultiplicand
* nMultiplier
) - (nDivisor
/2)) / nDivisor
;
1150 if ((ret
> 32767) || (ret
< -32767)) return -32768;
1155 /*******************************************************************
1156 * GetColorAdjustment [GDI32.164]
1160 BOOL WINAPI
GetColorAdjustment(HDC hdc
, LPCOLORADJUSTMENT lpca
)
1162 FIXME("GetColorAdjustment, stub\n");
1166 /*******************************************************************
1167 * GetMiterLimit [GDI32.201]
1171 BOOL WINAPI
GetMiterLimit(HDC hdc
, PFLOAT peLimit
)
1173 FIXME("GetMiterLimit, stub\n");
1177 /*******************************************************************
1178 * SetMiterLimit [GDI32.325]
1182 BOOL WINAPI
SetMiterLimit(HDC hdc
, FLOAT eNewLimit
, PFLOAT peOldLimit
)
1184 FIXME("SetMiterLimit, stub\n");
1188 /*******************************************************************
1189 * GdiComment [GDI32.109]
1193 BOOL WINAPI
GdiComment(HDC hdc
, UINT cbSize
, const BYTE
*lpData
)
1195 FIXME("GdiComment, stub\n");
1198 /*******************************************************************
1199 * SetColorAdjustment [GDI32.309]
1203 BOOL WINAPI
SetColorAdjustment(HDC hdc
, const COLORADJUSTMENT
* lpca
)
1205 FIXME("SetColorAdjustment, stub\n");