4 * Copyright 1993 Alexandre Julliard
16 #include "wine/winbase16.h"
26 #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.
325 BOOL systemIsBold = (TWEAK_WineLook == WIN31_LOOK);
327 HINSTANCE16 instance;
329 /* create GDI heap */
330 if ((instance = LoadLibrary16( "GDI.EXE" )) < 32) return FALSE;
331 GDI_HeapSel = GlobalHandleToSel16( instance );
333 /* Kill some warnings. */
334 (void)align_OEMFixedFont;
335 (void)align_AnsiFixedFont;
336 (void)align_AnsiVarFont;
337 (void)align_SystemFont;
338 (void)align_DeviceDefaultFont;
339 (void)align_SystemFixedFont;
340 (void)align_DefaultGuiFont;
342 /* TWEAK: Initialize font hints */
343 ReadFontInformation("OEMFixed", &OEMFixedFont, 0, 0, 0, 0, 0);
344 ReadFontInformation("AnsiFixed", &AnsiFixedFont, 0, 0, 0, 0, 0);
345 ReadFontInformation("AnsiVar", &AnsiVarFont, 0, 0, 0, 0, 0);
346 ReadFontInformation("System", &SystemFont, 0, systemIsBold, 0, 0, 0);
347 ReadFontInformation("DeviceDefault", &DeviceDefaultFont, 0, 0, 0, 0, 0);
348 ReadFontInformation("SystemFixed", &SystemFixedFont, 0, systemIsBold, 0, 0, 0);
349 ReadFontInformation("DefaultGui", &DefaultGuiFont, 0, 0, 0, 0, 0);
351 /* Create default palette */
353 /* DR well *this* palette can't be moveable (?) */
354 hpalette = PALETTE_Init();
355 if( !hpalette ) return FALSE;
356 StockObjects[DEFAULT_PALETTE] = (GDIOBJHDR *)LOCAL_Lock( GDI_HeapSel, hpalette );
358 hPseudoStockBitmap = CreateBitmap( 1, 1, 1, 1, NULL );
362 #define FIRST_LARGE_HANDLE 16
363 #define MAX_LARGE_HANDLES ((GDI_HEAP_SIZE - FIRST_LARGE_HANDLE) >> 2)
364 static GDIOBJHDR *large_handles[MAX_LARGE_HANDLES];
365 static int next_large_handle;
367 /***********************************************************************
370 * Allocate a GDI handle from the large heap. Helper for GDI_AllocObject
372 inline static GDIOBJHDR *alloc_large_heap( WORD size, HGDIOBJ *handle )
377 for (i = next_large_handle + 1; i < MAX_LARGE_HANDLES; i++)
378 if (!large_handles[i]) goto found;
379 for (i = 0; i <= next_large_handle; i++)
380 if (!large_handles[i]) goto found;
385 if ((obj = HeapAlloc( GetProcessHeap(), 0, size )))
387 large_handles[i] = obj;
388 *handle = (i + FIRST_LARGE_HANDLE) << 2;
389 next_large_handle = i;
395 /***********************************************************************
398 void *GDI_AllocObject( WORD size, WORD magic, HGDIOBJ *handle )
400 static DWORD count = 0;
403 _EnterSysLevel( &GDI_level );
406 /* allocate DCs on the larger heap */
408 case DISABLED_DC_MAGIC:
411 case METAFILE_DC_MAGIC:
412 case ENHMETAFILE_MAGIC:
413 case ENHMETAFILE_DC_MAGIC:
414 if (!(obj = alloc_large_heap( size, handle ))) goto error;
417 if (!(*handle = LOCAL_Alloc( GDI_HeapSel, LMEM_MOVEABLE, size ))) goto error;
418 assert( *handle & 2 );
419 obj = (GDIOBJHDR *)LOCAL_Lock( GDI_HeapSel, *handle );
424 obj->wMagic = magic|OBJECT_NOSYSTEM;
425 obj->dwCount = ++count;
427 TRACE_SEC( *handle, "enter" );
431 _LeaveSysLevel( &GDI_level );
437 /***********************************************************************
440 * The object ptr must have been obtained with GDI_GetObjPtr.
441 * The new pointer must be released with GDI_ReleaseObj.
443 void *GDI_ReallocObject( WORD size, HGDIOBJ handle, void *object )
447 assert( handle & 2 ); /* no realloc for large handles */
448 LOCAL_Unlock( GDI_HeapSel, handle );
449 if (!(new_handle = LOCAL_ReAlloc( GDI_HeapSel, handle, size, LMEM_MOVEABLE )))
451 TRACE_SEC( handle, "leave" );
452 _LeaveSysLevel( &GDI_level );
455 assert( new_handle == handle ); /* moveable handle cannot change */
456 return LOCAL_Lock( GDI_HeapSel, handle );
460 /***********************************************************************
463 BOOL GDI_FreeObject( HGDIOBJ handle, void *ptr )
465 GDIOBJHDR *object = ptr;
467 /* can't free stock objects */
468 if (handle < FIRST_STOCK_HANDLE)
470 object->wMagic = 0; /* Mark it as invalid */
471 if (handle & 2) /* GDI heap handle */
473 LOCAL_Unlock( GDI_HeapSel, handle );
474 LOCAL_Free( GDI_HeapSel, handle );
476 else /* large heap handle */
478 int i = (handle >> 2) - FIRST_LARGE_HANDLE;
479 if (i >= 0 && large_handles[i])
481 HeapFree( GetProcessHeap(), 0, large_handles[i] );
482 large_handles[i] = NULL;
486 TRACE_SEC( handle, "leave" );
487 _LeaveSysLevel( &GDI_level );
492 /***********************************************************************
495 * Return a pointer to the GDI object associated to the handle.
496 * Return NULL if the object has the wrong magic number.
497 * The object must be released with GDI_ReleaseObj.
499 void *GDI_GetObjPtr( HGDIOBJ handle, WORD magic )
501 GDIOBJHDR *ptr = NULL;
503 _EnterSysLevel( &GDI_level );
505 if (handle >= FIRST_STOCK_HANDLE)
507 if (handle <= LAST_STOCK_HANDLE) ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
508 if (ptr && (magic != MAGIC_DONTCARE)
509 && (GDIMAGIC(ptr->wMagic) != magic)) ptr = NULL;
511 else if (handle & 2) /* GDI heap handle */
513 ptr = (GDIOBJHDR *)LOCAL_Lock( GDI_HeapSel, handle );
515 (magic != MAGIC_DONTCARE) && (GDIMAGIC(ptr->wMagic) != magic))
517 LOCAL_Unlock( GDI_HeapSel, handle );
521 else /* large heap handle */
523 int i = (handle >> 2) - FIRST_LARGE_HANDLE;
526 ptr = large_handles[i];
527 if (ptr && (magic != MAGIC_DONTCARE) && (GDIMAGIC(ptr->wMagic) != magic)) ptr = NULL;
533 _LeaveSysLevel( &GDI_level );
534 SetLastError( ERROR_INVALID_HANDLE );
536 else TRACE_SEC( handle, "enter" );
542 /***********************************************************************
546 void GDI_ReleaseObj( HGDIOBJ handle )
548 if (handle < FIRST_STOCK_HANDLE && (handle & 2)) LOCAL_Unlock( GDI_HeapSel, handle );
549 TRACE_SEC( handle, "leave" );
550 _LeaveSysLevel( &GDI_level );
554 /***********************************************************************
555 * DeleteObject16 (GDI.69)
557 BOOL16 WINAPI DeleteObject16( HGDIOBJ16 obj )
559 return DeleteObject( obj );
563 /***********************************************************************
564 * DeleteObject (GDI32.70)
566 BOOL WINAPI DeleteObject( HGDIOBJ obj )
568 /* Check if object is valid */
571 if (HIWORD(obj)) return FALSE;
572 if ((obj >= FIRST_STOCK_HANDLE) && (obj <= LAST_STOCK_HANDLE)) {
573 TRACE("Preserving Stock object %04x\n", obj );
574 /* NOTE: No GDI_Release is necessary */
577 if (obj == hPseudoStockBitmap) return TRUE;
578 if (!(header = GDI_GetObjPtr( obj, MAGIC_DONTCARE ))) return FALSE;
580 if (!(header->wMagic & OBJECT_NOSYSTEM)
581 && (header->wMagic >= FIRST_MAGIC) && (header->wMagic <= LAST_MAGIC))
583 TRACE("Preserving system object %04x\n", obj);
584 GDI_ReleaseObj( obj );
588 TRACE("%04x\n", obj );
592 switch(GDIMAGIC(header->wMagic))
594 case PEN_MAGIC: return GDI_FreeObject( obj, header );
595 case BRUSH_MAGIC: return BRUSH_DeleteObject( obj, (BRUSHOBJ*)header );
596 case FONT_MAGIC: return GDI_FreeObject( obj, header );
597 case PALETTE_MAGIC: return PALETTE_DeleteObject(obj,(PALETTEOBJ*)header);
598 case BITMAP_MAGIC: return BITMAP_DeleteObject( obj, (BITMAPOBJ*)header);
599 case REGION_MAGIC: return REGION_DeleteObject( obj, (RGNOBJ*)header );
601 GDI_ReleaseObj( obj );
602 return DeleteDC(obj);
604 WARN("Already deleted\n");
607 WARN("Unknown magic number (%d)\n",GDIMAGIC(header->wMagic));
609 GDI_ReleaseObj( obj );
613 /***********************************************************************
614 * GetStockObject16 (GDI.87)
616 HGDIOBJ16 WINAPI GetStockObject16( INT16 obj )
618 return (HGDIOBJ16)GetStockObject( obj );
622 /***********************************************************************
623 * GetStockObject (GDI32.220)
625 HGDIOBJ WINAPI GetStockObject( INT obj )
628 if ((obj < 0) || (obj >= NB_STOCK_OBJECTS)) return 0;
629 if (!StockObjects[obj]) return 0;
630 ret = (HGDIOBJ16)(FIRST_STOCK_HANDLE + obj);
631 TRACE("returning %4x\n", ret );
636 /***********************************************************************
637 * GetObject16 (GDI.82)
639 INT16 WINAPI GetObject16( HANDLE16 handle, INT16 count, LPVOID buffer )
643 TRACE("%04x %d %p\n", handle, count, buffer );
644 if (!count) return 0;
646 if (!(ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE ))) return 0;
648 switch(GDIMAGIC(ptr->wMagic))
651 result = PEN_GetObject16( (PENOBJ *)ptr, count, buffer );
654 result = BRUSH_GetObject16( (BRUSHOBJ *)ptr, count, buffer );
657 result = BITMAP_GetObject16( (BITMAPOBJ *)ptr, count, buffer );
660 result = FONT_GetObject16( (FONTOBJ *)ptr, count, buffer );
663 * Fix the LOGFONT structure for the stock fonts
665 if ( (handle >= FIRST_STOCK_HANDLE) &&
666 (handle <= LAST_STOCK_HANDLE) )
667 FixStockFontSize16(handle, count, buffer);
670 result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer );
673 GDI_ReleaseObj( handle );
678 /***********************************************************************
679 * GetObjectA (GDI32.204)
681 INT WINAPI GetObjectA( HANDLE handle, INT count, LPVOID buffer )
685 TRACE("%08x %d %p\n", handle, count, buffer );
686 if (!count) return 0;
688 if (!(ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE ))) return 0;
690 switch(GDIMAGIC(ptr->wMagic))
693 result = PEN_GetObject( (PENOBJ *)ptr, count, buffer );
696 result = BRUSH_GetObject( (BRUSHOBJ *)ptr, count, buffer );
699 result = BITMAP_GetObject( (BITMAPOBJ *)ptr, count, buffer );
702 result = FONT_GetObjectA( (FONTOBJ *)ptr, count, buffer );
705 * Fix the LOGFONT structure for the stock fonts
707 if ( (handle >= FIRST_STOCK_HANDLE) &&
708 (handle <= LAST_STOCK_HANDLE) )
709 FixStockFontSizeA(handle, count, buffer);
712 result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer );
717 case DISABLED_DC_MAGIC:
720 case METAFILE_DC_MAGIC:
721 case ENHMETAFILE_MAGIC:
722 case ENHMETAFILE_DC_MAGIC:
723 FIXME("Magic %04x not implemented\n", GDIMAGIC(ptr->wMagic) );
727 ERR("Invalid GDI Magic %04x\n", GDIMAGIC(ptr->wMagic));
730 GDI_ReleaseObj( handle );
734 /***********************************************************************
735 * GetObjectW (GDI32.206)
737 INT WINAPI GetObjectW( HANDLE handle, INT count, LPVOID buffer )
741 TRACE("%08x %d %p\n", handle, count, buffer );
742 if (!count) return 0;
744 if (!(ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE ))) return 0;
746 switch(GDIMAGIC(ptr->wMagic))
749 result = PEN_GetObject( (PENOBJ *)ptr, count, buffer );
752 result = BRUSH_GetObject( (BRUSHOBJ *)ptr, count, buffer );
755 result = BITMAP_GetObject( (BITMAPOBJ *)ptr, count, buffer );
758 result = FONT_GetObjectW( (FONTOBJ *)ptr, count, buffer );
761 * Fix the LOGFONT structure for the stock fonts
763 if ( (handle >= FIRST_STOCK_HANDLE) &&
764 (handle <= LAST_STOCK_HANDLE) )
765 FixStockFontSizeW(handle, count, buffer);
768 result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer );
771 FIXME("Magic %04x not implemented\n", GDIMAGIC(ptr->wMagic) );
774 GDI_ReleaseObj( handle );
778 /***********************************************************************
779 * GetObjectType (GDI32.205)
781 DWORD WINAPI GetObjectType( HANDLE handle )
785 TRACE("%08x\n", handle );
787 if (!(ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE ))) return 0;
789 switch(GDIMAGIC(ptr->wMagic))
816 result = OBJ_METAFILE;
818 case METAFILE_DC_MAGIC:
821 case ENHMETAFILE_MAGIC:
822 result = OBJ_ENHMETAFILE;
824 case ENHMETAFILE_DC_MAGIC:
825 result = OBJ_ENHMETADC;
828 FIXME("Magic %04x not implemented\n", GDIMAGIC(ptr->wMagic) );
831 GDI_ReleaseObj( handle );
835 /***********************************************************************
836 * GetCurrentObject (GDI32.166)
838 HANDLE WINAPI GetCurrentObject(HDC hdc,UINT type)
841 DC * dc = DC_GetDCPtr( hdc );
846 case OBJ_PEN: ret = dc->hPen; break;
847 case OBJ_BRUSH: ret = dc->hBrush; break;
848 case OBJ_PAL: ret = dc->hPalette; break;
849 case OBJ_FONT: ret = dc->hFont; break;
850 case OBJ_BITMAP: ret = dc->hBitmap; break;
852 /* the SDK only mentions those above */
853 FIXME("(%08x,%d): unknown type.\n",hdc,type);
856 GDI_ReleaseObj( hdc );
862 /***********************************************************************
863 * SelectObject16 (GDI.45)
865 HGDIOBJ16 WINAPI SelectObject16( HDC16 hdc, HGDIOBJ16 handle )
867 return (HGDIOBJ16)SelectObject( hdc, handle );
871 /***********************************************************************
872 * SelectObject (GDI32.299)
874 HGDIOBJ WINAPI SelectObject( HDC hdc, HGDIOBJ handle )
877 DC * dc = DC_GetDCUpdate( hdc );
879 TRACE("hdc=%04x %04x\n", hdc, handle );
880 if (dc->funcs->pSelectObject)
881 ret = dc->funcs->pSelectObject( dc, handle );
882 GDI_ReleaseObj( hdc );
887 /***********************************************************************
888 * UnrealizeObject16 (GDI.150)
890 BOOL16 WINAPI UnrealizeObject16( HGDIOBJ16 obj )
892 return UnrealizeObject( obj );
896 /***********************************************************************
897 * UnrealizeObject (GDI32.358)
899 BOOL WINAPI UnrealizeObject( HGDIOBJ obj )
902 /* Check if object is valid */
904 GDIOBJHDR * header = GDI_GetObjPtr( obj, MAGIC_DONTCARE );
905 if (!header) return FALSE;
907 TRACE("%04x\n", obj );
909 /* Unrealize object */
911 switch(GDIMAGIC(header->wMagic))
914 result = PALETTE_UnrealizeObject( obj, (PALETTEOBJ *)header );
918 /* Windows resets the brush origin. We don't need to. */
921 GDI_ReleaseObj( obj );
926 /***********************************************************************
927 * EnumObjects16 (GDI.71)
929 INT16 WINAPI EnumObjects16( HDC16 hdc, INT16 nObjType,
930 GOBJENUMPROC16 lpEnumFunc, LPARAM lParam )
932 /* Solid colors to enumerate */
933 static const COLORREF solid_colors[] =
934 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
935 RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
936 RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
937 RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
938 RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
939 RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
940 RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
941 RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
946 LOGBRUSH16 *brush = NULL;
948 TRACE("%04x %d %08lx %08lx\n",
949 hdc, nObjType, (DWORD)lpEnumFunc, lParam );
953 /* Enumerate solid pens */
954 if (!(pen = SEGPTR_NEW(LOGPEN16))) break;
955 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
957 pen->lopnStyle = PS_SOLID;
958 pen->lopnWidth.x = 1;
959 pen->lopnWidth.y = 0;
960 pen->lopnColor = solid_colors[i];
961 retval = lpEnumFunc( SEGPTR_GET(pen), lParam );
962 TRACE("solid pen %08lx, ret=%d\n",
963 solid_colors[i], retval);
970 /* Enumerate solid brushes */
971 if (!(brush = SEGPTR_NEW(LOGBRUSH16))) break;
972 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
974 brush->lbStyle = BS_SOLID;
975 brush->lbColor = solid_colors[i];
977 retval = lpEnumFunc( SEGPTR_GET(brush), lParam );
978 TRACE("solid brush %08lx, ret=%d\n",
979 solid_colors[i], retval);
983 /* Now enumerate hatched brushes */
984 if (retval) for (i = HS_HORIZONTAL; i <= HS_DIAGCROSS; i++)
986 brush->lbStyle = BS_HATCHED;
987 brush->lbColor = RGB(0,0,0);
989 retval = lpEnumFunc( SEGPTR_GET(brush), lParam );
990 TRACE("hatched brush %d, ret=%d\n",
998 WARN("(%d): Invalid type\n", nObjType );
1005 /***********************************************************************
1006 * EnumObjects (GDI32.89)
1008 INT WINAPI EnumObjects( HDC hdc, INT nObjType,
1009 GOBJENUMPROC lpEnumFunc, LPARAM lParam )
1011 /* Solid colors to enumerate */
1012 static const COLORREF solid_colors[] =
1013 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
1014 RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
1015 RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
1016 RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
1017 RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
1018 RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
1019 RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
1020 RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
1027 TRACE("%04x %d %08lx %08lx\n",
1028 hdc, nObjType, (DWORD)lpEnumFunc, lParam );
1032 /* Enumerate solid pens */
1033 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
1035 pen.lopnStyle = PS_SOLID;
1036 pen.lopnWidth.x = 1;
1037 pen.lopnWidth.y = 0;
1038 pen.lopnColor = solid_colors[i];
1039 retval = lpEnumFunc( &pen, lParam );
1040 TRACE("solid pen %08lx, ret=%d\n",
1041 solid_colors[i], retval);
1047 /* Enumerate solid brushes */
1048 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
1050 brush.lbStyle = BS_SOLID;
1051 brush.lbColor = solid_colors[i];
1053 retval = lpEnumFunc( &brush, lParam );
1054 TRACE("solid brush %08lx, ret=%d\n",
1055 solid_colors[i], retval);
1059 /* Now enumerate hatched brushes */
1060 if (retval) for (i = HS_HORIZONTAL; i <= HS_DIAGCROSS; i++)
1062 brush.lbStyle = BS_HATCHED;
1063 brush.lbColor = RGB(0,0,0);
1065 retval = lpEnumFunc( &brush, lParam );
1066 TRACE("hatched brush %d, ret=%d\n",
1073 /* FIXME: implement Win32 types */
1074 WARN("(%d): Invalid type\n", nObjType );
1081 /***********************************************************************
1082 * IsGDIObject (GDI.462)
1084 * returns type of object if valid (W95 system programming secrets p. 264-5)
1086 BOOL16 WINAPI IsGDIObject16( HGDIOBJ16 handle )
1090 GDIOBJHDR *object = GDI_GetObjPtr( handle, MAGIC_DONTCARE );
1093 magic = GDIMAGIC(object->wMagic) - PEN_MAGIC + 1;
1094 GDI_ReleaseObj( handle );
1100 /***********************************************************************
1101 * SetObjectOwner16 (GDI.461)
1103 void WINAPI SetObjectOwner16( HGDIOBJ16 handle, HANDLE16 owner )
1109 /***********************************************************************
1110 * SetObjectOwner (GDI32.386)
1112 void WINAPI SetObjectOwner( HGDIOBJ handle, HANDLE owner )
1118 /***********************************************************************
1119 * MakeObjectPrivate (GDI.463)
1121 * What does that mean ?
1122 * Some little docu can be found in "Undocumented Windows",
1123 * but this is basically useless.
1124 * At least we know that this flags the GDI object's wMagic
1125 * with 0x2000 (OBJECT_PRIVATE), so we just do it.
1126 * But Wine doesn't react on that yet.
1128 void WINAPI MakeObjectPrivate16( HGDIOBJ16 handle, BOOL16 private )
1130 GDIOBJHDR *ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE );
1133 ERR("invalid GDI object %04x !\n", handle);
1136 ptr->wMagic |= OBJECT_PRIVATE;
1137 GDI_ReleaseObj( handle );
1141 /***********************************************************************
1142 * GdiFlush (GDI32.128)
1144 BOOL WINAPI GdiFlush(void)
1146 return TRUE; /* FIXME */
1150 /***********************************************************************
1151 * GdiGetBatchLimit (GDI32.129)
1153 DWORD WINAPI GdiGetBatchLimit(void)
1155 return 1; /* FIXME */
1159 /***********************************************************************
1160 * GdiSetBatchLimit (GDI32.139)
1162 DWORD WINAPI GdiSetBatchLimit( DWORD limit )
1164 return 1; /* FIXME */
1168 /***********************************************************************
1169 * GdiSeeGdiDo (GDI.452)
1171 DWORD WINAPI GdiSeeGdiDo16( WORD wReqType, WORD wParam1, WORD wParam2,
1176 case 0x0001: /* LocalAlloc */
1177 return LOCAL_Alloc( GDI_HeapSel, wParam1, wParam3 );
1178 case 0x0002: /* LocalFree */
1179 return LOCAL_Free( GDI_HeapSel, wParam1 );
1180 case 0x0003: /* LocalCompact */
1181 return LOCAL_Compact( GDI_HeapSel, wParam3, 0 );
1182 case 0x0103: /* LocalHeap */
1185 WARN("(wReqType=%04x): Unknown\n", wReqType);
1190 /***********************************************************************
1191 * GdiSignalProc (GDI.610)
1193 WORD WINAPI GdiSignalProc( UINT uCode, DWORD dwThreadOrProcessID,
1194 DWORD dwFlags, HMODULE16 hModule )
1199 /***********************************************************************
1200 * FinalGdiInit16 (GDI.405)
1202 void WINAPI FinalGdiInit16( HANDLE16 unknown )
1206 /***********************************************************************
1207 * GdiFreeResources (GDI.609)
1209 WORD WINAPI GdiFreeResources16( DWORD reserve )
1211 return (WORD)( (int)LOCAL_CountFree( GDI_HeapSel ) * 100 /
1212 (int)LOCAL_HeapSize( GDI_HeapSel ) );
1215 /***********************************************************************
1216 * MulDiv16 (GDI.128)
1218 INT16 WINAPI MulDiv16(
1219 INT16 nMultiplicand,
1224 if (!nDivisor) return -32768;
1225 /* We want to deal with a positive divisor to simplify the logic. */
1228 nMultiplicand = - nMultiplicand;
1229 nDivisor = -nDivisor;
1231 /* If the result is positive, we "add" to round. else,
1232 * we subtract to round. */
1233 if ( ( (nMultiplicand < 0) && (nMultiplier < 0) ) ||
1234 ( (nMultiplicand >= 0) && (nMultiplier >= 0) ) )
1235 ret = (((int)nMultiplicand * nMultiplier) + (nDivisor/2)) / nDivisor;
1237 ret = (((int)nMultiplicand * nMultiplier) - (nDivisor/2)) / nDivisor;
1238 if ((ret > 32767) || (ret < -32767)) return -32768;
1243 /*******************************************************************
1244 * GetColorAdjustment [GDI32.164]
1248 BOOL WINAPI GetColorAdjustment(HDC hdc, LPCOLORADJUSTMENT lpca)
1250 FIXME("GetColorAdjustment, stub\n");
1254 /*******************************************************************
1255 * GetMiterLimit [GDI32.201]
1259 BOOL WINAPI GetMiterLimit(HDC hdc, PFLOAT peLimit)
1261 FIXME("GetMiterLimit, stub\n");
1265 /*******************************************************************
1266 * SetMiterLimit [GDI32.325]
1270 BOOL WINAPI SetMiterLimit(HDC hdc, FLOAT eNewLimit, PFLOAT peOldLimit)
1272 FIXME("SetMiterLimit, stub\n");
1276 /*******************************************************************
1277 * GdiComment [GDI32.109]
1281 BOOL WINAPI GdiComment(HDC hdc, UINT cbSize, const BYTE *lpData)
1283 FIXME("GdiComment, stub\n");
1286 /*******************************************************************
1287 * SetColorAdjustment [GDI32.309]
1291 BOOL WINAPI SetColorAdjustment(HDC hdc, const COLORADJUSTMENT* lpca)
1293 FIXME("SetColorAdjustment, stub\n");