Release 990226.
[wine/gsoc-2012-control.git] / objects / gdiobj.c
blob0996f85b712e42e8088d85b3cdce1aa98bd5b02a
1 /*
2 * GDI functions
4 * Copyright 1993 Alexandre Julliard
5 */
7 #include "config.h"
9 #ifndef X_DISPLAY_MISSING
10 #include "x11drv.h"
11 #else /* !defined(X_DISPLAY_MISSING) */
12 #include "ttydrv.h"
13 #endif /* !defined(X_DISPLAY_MISSING) */
15 #include <stdlib.h>
16 #include "bitmap.h"
17 #include "brush.h"
18 #include "dc.h"
19 #include "font.h"
20 #include "heap.h"
21 #include "options.h"
22 #include "palette.h"
23 #include "pen.h"
24 #include "region.h"
25 #include "debug.h"
26 #include "gdi.h"
28 /***********************************************************************
29 * GDI stock objects
32 static BRUSHOBJ WhiteBrush =
34 { 0, BRUSH_MAGIC, 1 }, /* header */
35 { BS_SOLID, RGB(255,255,255), 0 } /* logbrush */
38 static BRUSHOBJ LtGrayBrush =
40 { 0, BRUSH_MAGIC, 1 }, /* header */
41 /* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
42 { BS_SOLID, RGB(192,192,192), 0 } /* logbrush */
45 static BRUSHOBJ GrayBrush =
47 { 0, BRUSH_MAGIC, 1 }, /* header */
48 /* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
49 { BS_SOLID, RGB(128,128,128), 0 } /* logbrush */
52 static BRUSHOBJ DkGrayBrush =
54 { 0, BRUSH_MAGIC, 1 }, /* header */
55 /* This is BS_HATCHED, for 1 bitperpixel. This makes the spray work in pbrush */
56 /* NB_HATCH_STYLES is an index into HatchBrushes */
57 { BS_HATCHED, RGB(0,0,0), NB_HATCH_STYLES } /* logbrush */
60 static BRUSHOBJ BlackBrush =
62 { 0, BRUSH_MAGIC, 1 }, /* header */
63 { BS_SOLID, RGB(0,0,0), 0 } /* logbrush */
66 static BRUSHOBJ NullBrush =
68 { 0, BRUSH_MAGIC, 1 }, /* header */
69 { BS_NULL, 0, 0 } /* logbrush */
72 static PENOBJ WhitePen =
74 { 0, PEN_MAGIC, 1 }, /* header */
75 { PS_SOLID, { 1, 0 }, RGB(255,255,255) } /* logpen */
78 static PENOBJ BlackPen =
80 { 0, PEN_MAGIC, 1 }, /* header */
81 { PS_SOLID, { 1, 0 }, RGB(0,0,0) } /* logpen */
84 static PENOBJ NullPen =
86 { 0, PEN_MAGIC, 1 }, /* header */
87 { PS_NULL, { 1, 0 }, 0 } /* logpen */
90 static FONTOBJ OEMFixedFont =
92 { 0, FONT_MAGIC, 1 }, /* header */
93 { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, OEM_CHARSET,
94 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" }
96 /* Filler to make the location counter dword aligned again. This is necessary
97 since (a) FONTOBJ is packed, (b) gcc places initialised variables in the code
98 segment, and (c) Solaris assembler is stupid. */
99 static UINT16 align_OEMFixedFont = 1;
101 static FONTOBJ AnsiFixedFont =
103 { 0, FONT_MAGIC, 1 }, /* header */
104 { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
105 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" }
107 static UINT16 align_AnsiFixedFont = 1;
109 static FONTOBJ AnsiVarFont =
111 { 0, FONT_MAGIC, 1 }, /* header */
112 { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
113 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "MS Sans Serif" }
115 static UINT16 align_AnsiVarFont = 1;
117 static FONTOBJ SystemFont =
119 { 0, FONT_MAGIC, 1 },
120 { 16, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, ANSI_CHARSET,
121 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "System" }
123 static UINT16 align_SystemFont = 1;
125 static FONTOBJ DeviceDefaultFont =
127 { 0, FONT_MAGIC, 1 }, /* header */
128 { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
129 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "" }
131 static UINT16 align_DeviceDefaultFont = 1;
133 static FONTOBJ SystemFixedFont =
135 { 0, FONT_MAGIC, 1 }, /* header */
136 { 12, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, ANSI_CHARSET,
137 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" }
139 static UINT16 align_SystemFixedFont = 1;
141 /* FIXME: Is this correct? */
142 static FONTOBJ DefaultGuiFont =
144 { 9, FONT_MAGIC, 1 }, /* header */
145 { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
146 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "MS Sans Serif" }
148 static UINT16 align_DefaultGuiFont = 1;
151 static GDIOBJHDR * StockObjects[NB_STOCK_OBJECTS] =
153 (GDIOBJHDR *) &WhiteBrush,
154 (GDIOBJHDR *) &LtGrayBrush,
155 (GDIOBJHDR *) &GrayBrush,
156 (GDIOBJHDR *) &DkGrayBrush,
157 (GDIOBJHDR *) &BlackBrush,
158 (GDIOBJHDR *) &NullBrush,
159 (GDIOBJHDR *) &WhitePen,
160 (GDIOBJHDR *) &BlackPen,
161 (GDIOBJHDR *) &NullPen,
162 NULL,
163 (GDIOBJHDR *) &OEMFixedFont,
164 (GDIOBJHDR *) &AnsiFixedFont,
165 (GDIOBJHDR *) &AnsiVarFont,
166 (GDIOBJHDR *) &SystemFont,
167 (GDIOBJHDR *) &DeviceDefaultFont,
168 NULL, /* DEFAULT_PALETTE created by PALETTE_Init */
169 (GDIOBJHDR *) &SystemFixedFont,
170 (GDIOBJHDR *) &DefaultGuiFont
173 /******************************************************************************
175 * void ReadFontInformation(
176 * char const *fontName,
177 * FONTOBJ *font,
178 * int defHeight,
179 * int defBold,
180 * int defItalic,
181 * int defUnderline,
182 * int defStrikeOut )
184 * ReadFontInformation() checks the Wine configuration file's Tweak.Fonts
185 * section for entries containing fontName.Height, fontName.Bold, etc.,
186 * where fontName is the name specified in the call (e.g., "System"). It
187 * attempts to be user friendly by accepting 'n', 'N', 'f', 'F', or '0' as
188 * the first character in the boolean attributes (bold, italic, and
189 * underline).
190 *****************************************************************************/
192 static void ReadFontInformation(
193 char const *fontName,
194 FONTOBJ *font,
195 int defHeight,
196 int defBold,
197 int defItalic,
198 int defUnderline,
199 int defStrikeOut )
201 char key[256];
203 sprintf(key, "%s.Height", fontName);
204 font->logfont.lfHeight =
205 PROFILE_GetWineIniInt("Tweak.Fonts", key, defHeight);
207 sprintf(key, "%s.Bold", fontName);
208 font->logfont.lfWeight =
209 (PROFILE_GetWineIniBool("Tweak.Fonts", key, defBold)) ?
210 FW_BOLD : FW_NORMAL;
212 sprintf(key, "%s.Italic", fontName);
213 font->logfont.lfItalic =
214 PROFILE_GetWineIniBool("Tweak.Fonts", key, defItalic);
216 sprintf(key, "%s.Underline", fontName);
217 font->logfont.lfUnderline =
218 PROFILE_GetWineIniBool("Tweak.Fonts", key, defUnderline);
220 sprintf(key, "%s.StrikeOut", fontName);
221 font->logfont.lfStrikeOut =
222 PROFILE_GetWineIniBool("Tweak.Fonts", key, defStrikeOut);
224 return;
228 /***********************************************************************
229 * GDI_Init
231 * GDI initialization.
233 BOOL GDI_Init(void)
235 /* Kill some warnings. */
236 (void)align_OEMFixedFont;
237 (void)align_AnsiFixedFont;
238 (void)align_AnsiVarFont;
239 (void)align_SystemFont;
240 (void)align_DeviceDefaultFont;
241 (void)align_SystemFixedFont;
242 (void)align_DefaultGuiFont;
244 /* TWEAK: Initialize font hints */
245 ReadFontInformation("OEMFixed", &OEMFixedFont, 12, 0, 0, 0, 0);
246 ReadFontInformation("AnsiFixed", &AnsiFixedFont, 12, 0, 0, 0, 0);
247 ReadFontInformation("AnsiVar", &AnsiVarFont, 12, 0, 0, 0, 0);
248 ReadFontInformation("System", &SystemFont, 16, 1, 0, 0, 0);
249 ReadFontInformation("SystemFixed", &SystemFixedFont, 12, 1, 0, 0, 0);
251 /* Initialize drivers */
253 #ifndef X_DISPLAY_MISSING
254 if( ! X11DRV_Init() )
255 return FALSE;
256 #else /* !defined(X_DISPLAY_MISSING) */
257 if( ! TTYDRV_GDI_Initialize() )
258 return FALSE;
259 #endif /* !defined(X_DISPLAY_MISSING) */
261 /* Create default palette */
263 /* DR well *this* palette can't be moveable (?) */
265 HPALETTE16 hpalette = PALETTE_Init();
266 if( !hpalette )
267 return FALSE;
268 StockObjects[DEFAULT_PALETTE] = (GDIOBJHDR *)GDI_HEAP_LOCK( hpalette );
271 return TRUE;
275 /***********************************************************************
276 * GDI_AllocObject
278 HGDIOBJ16 GDI_AllocObject( WORD size, WORD magic )
280 static DWORD count = 0;
281 GDIOBJHDR * obj;
282 HGDIOBJ16 handle;
283 if ( magic == DC_MAGIC || magic == METAFILE_DC_MAGIC )
284 handle = GDI_HEAP_ALLOC( size );
285 else
286 handle = GDI_HEAP_ALLOC_MOVEABLE( size );
287 if (!handle) return 0;
288 obj = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
289 obj->hNext = 0;
290 obj->wMagic = magic;
291 obj->dwCount = ++count;
292 GDI_HEAP_UNLOCK( handle );
293 return handle;
297 /***********************************************************************
298 * GDI_FreeObject
300 BOOL GDI_FreeObject( HGDIOBJ16 handle )
302 GDIOBJHDR * object;
304 /* Can't free stock objects */
305 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
306 return TRUE;
308 object = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
309 if (!object) return FALSE;
310 object->wMagic = 0; /* Mark it as invalid */
312 /* Free object */
314 GDI_HEAP_FREE( handle );
315 return TRUE;
318 /***********************************************************************
319 * GDI_GetObjPtr
321 * Return a pointer to the GDI object associated to the handle.
322 * Return NULL if the object has the wrong magic number.
323 * Movable GDI objects are locked in memory: it is up to the caller to unlock
324 * it after the caller is done with the pointer.
326 GDIOBJHDR * GDI_GetObjPtr( HGDIOBJ16 handle, WORD magic )
328 GDIOBJHDR * ptr = NULL;
330 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
331 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
332 else
333 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
334 if (!ptr) return NULL;
335 if ((magic != MAGIC_DONTCARE) && (ptr->wMagic != magic))
337 GDI_HEAP_UNLOCK( handle );
338 return NULL;
340 return ptr;
344 /***********************************************************************
345 * DeleteObject16 (GDI.69)
347 BOOL16 WINAPI DeleteObject16( HGDIOBJ16 obj )
349 return DeleteObject( obj );
353 /***********************************************************************
354 * DeleteObject32 (GDI32.70)
356 BOOL WINAPI DeleteObject( HGDIOBJ obj )
358 /* Check if object is valid */
360 GDIOBJHDR * header;
361 if (HIWORD(obj)) return FALSE;
362 if ((obj >= FIRST_STOCK_HANDLE) && (obj <= LAST_STOCK_HANDLE))
363 return TRUE;
364 if (!(header = (GDIOBJHDR *) GDI_HEAP_LOCK( obj ))) return FALSE;
366 TRACE(gdi, "%04x\n", obj );
368 /* Delete object */
370 switch(header->wMagic)
372 case PEN_MAGIC: return GDI_FreeObject( obj );
373 case BRUSH_MAGIC: return BRUSH_DeleteObject( obj, (BRUSHOBJ*)header );
374 case FONT_MAGIC: return GDI_FreeObject( obj );
375 case PALETTE_MAGIC: return PALETTE_DeleteObject(obj,(PALETTEOBJ*)header);
376 case BITMAP_MAGIC: return BITMAP_DeleteObject( obj, (BITMAPOBJ*)header);
377 case REGION_MAGIC: return REGION_DeleteObject( obj, (RGNOBJ*)header );
378 case DC_MAGIC: return DeleteDC(obj);
379 case 0 :
380 WARN(gdi, "Already deleted\n");
381 break;
382 default:
383 WARN(gdi, "Unknown magic number (%d)\n",header->wMagic);
385 return FALSE;
388 /***********************************************************************
389 * GetStockObject16 (GDI.87)
391 HGDIOBJ16 WINAPI GetStockObject16( INT16 obj )
393 return (HGDIOBJ16)GetStockObject( obj );
397 /***********************************************************************
398 * GetStockObject32 (GDI32.220)
400 HGDIOBJ WINAPI GetStockObject( INT obj )
402 if ((obj < 0) || (obj >= NB_STOCK_OBJECTS)) return 0;
403 if (!StockObjects[obj]) return 0;
404 TRACE(gdi, "returning %d\n",
405 FIRST_STOCK_HANDLE + obj );
406 return (HGDIOBJ16)(FIRST_STOCK_HANDLE + obj);
410 /***********************************************************************
411 * GetObject16 (GDI.82)
413 INT16 WINAPI GetObject16( HANDLE16 handle, INT16 count, LPVOID buffer )
415 GDIOBJHDR * ptr = NULL;
416 INT16 result = 0;
417 TRACE(gdi, "%04x %d %p\n", handle, count, buffer );
418 if (!count) return 0;
420 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
421 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
422 else
423 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
424 if (!ptr) return 0;
426 switch(ptr->wMagic)
428 case PEN_MAGIC:
429 result = PEN_GetObject16( (PENOBJ *)ptr, count, buffer );
430 break;
431 case BRUSH_MAGIC:
432 result = BRUSH_GetObject16( (BRUSHOBJ *)ptr, count, buffer );
433 break;
434 case BITMAP_MAGIC:
435 result = BITMAP_GetObject16( (BITMAPOBJ *)ptr, count, buffer );
436 break;
437 case FONT_MAGIC:
438 result = FONT_GetObject16( (FONTOBJ *)ptr, count, buffer );
439 break;
440 case PALETTE_MAGIC:
441 result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer );
442 break;
444 GDI_HEAP_UNLOCK( handle );
445 return result;
449 /***********************************************************************
450 * GetObject32A (GDI32.204)
452 INT WINAPI GetObjectA( HANDLE handle, INT count, LPVOID buffer )
454 GDIOBJHDR * ptr = NULL;
455 INT result = 0;
456 TRACE(gdi, "%08x %d %p\n", handle, count, buffer );
457 if (!count) return 0;
459 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
460 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
461 else
462 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
463 if (!ptr) return 0;
465 switch(ptr->wMagic)
467 case PEN_MAGIC:
468 result = PEN_GetObject( (PENOBJ *)ptr, count, buffer );
469 break;
470 case BRUSH_MAGIC:
471 result = BRUSH_GetObject( (BRUSHOBJ *)ptr, count, buffer );
472 break;
473 case BITMAP_MAGIC:
474 result = BITMAP_GetObject( (BITMAPOBJ *)ptr, count, buffer );
475 break;
476 case FONT_MAGIC:
477 result = FONT_GetObjectA( (FONTOBJ *)ptr, count, buffer );
478 break;
479 case PALETTE_MAGIC:
480 result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer );
481 break;
482 default:
483 FIXME(gdi, "Magic %04x not implemented\n",
484 ptr->wMagic );
485 break;
487 GDI_HEAP_UNLOCK( handle );
488 return result;
490 /***********************************************************************
491 * GetObject32W (GDI32.206)
493 INT WINAPI GetObjectW( HANDLE handle, INT count, LPVOID buffer )
495 GDIOBJHDR * ptr = NULL;
496 INT result = 0;
497 TRACE(gdi, "%08x %d %p\n", handle, count, buffer );
498 if (!count) return 0;
500 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
501 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
502 else
503 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
504 if (!ptr) return 0;
506 switch(ptr->wMagic)
508 case PEN_MAGIC:
509 result = PEN_GetObject( (PENOBJ *)ptr, count, buffer );
510 break;
511 case BRUSH_MAGIC:
512 result = BRUSH_GetObject( (BRUSHOBJ *)ptr, count, buffer );
513 break;
514 case BITMAP_MAGIC:
515 result = BITMAP_GetObject( (BITMAPOBJ *)ptr, count, buffer );
516 break;
517 case FONT_MAGIC:
518 result = FONT_GetObjectW( (FONTOBJ *)ptr, count, buffer );
519 break;
520 case PALETTE_MAGIC:
521 result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer );
522 break;
523 default:
524 FIXME(gdi, "Magic %04x not implemented\n",
525 ptr->wMagic );
526 break;
528 GDI_HEAP_UNLOCK( handle );
529 return result;
532 /***********************************************************************
533 * GetObjectType (GDI32.205)
535 DWORD WINAPI GetObjectType( HANDLE handle )
537 GDIOBJHDR * ptr = NULL;
538 INT result = 0;
539 TRACE(gdi, "%08x\n", handle );
541 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
542 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
543 else
544 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
545 if (!ptr) return 0;
547 switch(ptr->wMagic)
549 case PEN_MAGIC:
550 result = OBJ_PEN;
551 break;
552 case BRUSH_MAGIC:
553 result = OBJ_BRUSH;
554 break;
555 case BITMAP_MAGIC:
556 result = OBJ_BITMAP;
557 break;
558 case FONT_MAGIC:
559 result = OBJ_FONT;
560 break;
561 case PALETTE_MAGIC:
562 result = OBJ_PAL;
563 break;
564 case REGION_MAGIC:
565 result = OBJ_REGION;
566 break;
567 case DC_MAGIC:
568 result = OBJ_DC;
569 break;
570 case META_DC_MAGIC:
571 result = OBJ_METADC;
572 break;
573 case METAFILE_MAGIC:
574 result = OBJ_METAFILE;
575 break;
576 case METAFILE_DC_MAGIC:
577 result = OBJ_METADC;
578 break;
580 default:
581 FIXME(gdi, "Magic %04x not implemented\n",
582 ptr->wMagic );
583 break;
585 GDI_HEAP_UNLOCK( handle );
586 return result;
589 /***********************************************************************
590 * GetCurrentObject (GDI32.166)
592 HANDLE WINAPI GetCurrentObject(HDC hdc,UINT type)
594 DC * dc = DC_GetDCPtr( hdc );
596 if (!dc)
597 return 0;
598 switch (type) {
599 case OBJ_PEN: return dc->w.hPen;
600 case OBJ_BRUSH: return dc->w.hBrush;
601 case OBJ_PAL: return dc->w.hPalette;
602 case OBJ_FONT: return dc->w.hFont;
603 case OBJ_BITMAP: return dc->w.hBitmap;
604 default:
605 /* the SDK only mentions those above */
606 WARN(gdi,"(%08x,%d): unknown type.\n",hdc,type);
607 return 0;
612 /***********************************************************************
613 * SelectObject16 (GDI.45)
615 HGDIOBJ16 WINAPI SelectObject16( HDC16 hdc, HGDIOBJ16 handle )
617 return (HGDIOBJ16)SelectObject( hdc, handle );
621 /***********************************************************************
622 * SelectObject32 (GDI32.299)
624 HGDIOBJ WINAPI SelectObject( HDC hdc, HGDIOBJ handle )
626 DC * dc = DC_GetDCPtr( hdc );
627 if (!dc || !dc->funcs->pSelectObject) return 0;
628 TRACE(gdi, "hdc=%04x %04x\n", hdc, handle );
629 return dc->funcs->pSelectObject( dc, handle );
633 /***********************************************************************
634 * UnrealizeObject16 (GDI.150)
636 BOOL16 WINAPI UnrealizeObject16( HGDIOBJ16 obj )
638 return UnrealizeObject( obj );
642 /***********************************************************************
643 * UnrealizeObject (GDI32.358)
645 BOOL WINAPI UnrealizeObject( HGDIOBJ obj )
647 BOOL result = TRUE;
648 /* Check if object is valid */
650 GDIOBJHDR * header = (GDIOBJHDR *) GDI_HEAP_LOCK( obj );
651 if (!header) return FALSE;
653 TRACE(gdi, "%04x\n", obj );
655 /* Unrealize object */
657 switch(header->wMagic)
659 case PALETTE_MAGIC:
660 result = PALETTE_UnrealizeObject( obj, (PALETTEOBJ *)header );
661 break;
663 case BRUSH_MAGIC:
664 /* Windows resets the brush origin. We don't need to. */
665 break;
667 GDI_HEAP_UNLOCK( obj );
668 return result;
672 /***********************************************************************
673 * EnumObjects16 (GDI.71)
675 INT16 WINAPI EnumObjects16( HDC16 hdc, INT16 nObjType,
676 GOBJENUMPROC16 lpEnumFunc, LPARAM lParam )
678 /* Solid colors to enumerate */
679 static const COLORREF solid_colors[] =
680 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
681 RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
682 RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
683 RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
684 RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
685 RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
686 RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
687 RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
690 INT16 i, retval = 0;
691 LOGPEN16 *pen;
692 LOGBRUSH16 *brush = NULL;
694 TRACE(gdi, "%04x %d %08lx %08lx\n",
695 hdc, nObjType, (DWORD)lpEnumFunc, lParam );
696 switch(nObjType)
698 case OBJ_PEN:
699 /* Enumerate solid pens */
700 if (!(pen = SEGPTR_NEW(LOGPEN16))) break;
701 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
703 pen->lopnStyle = PS_SOLID;
704 pen->lopnWidth.x = 1;
705 pen->lopnWidth.y = 0;
706 pen->lopnColor = solid_colors[i];
707 retval = lpEnumFunc( SEGPTR_GET(pen), lParam );
708 TRACE(gdi, "solid pen %08lx, ret=%d\n",
709 solid_colors[i], retval);
710 if (!retval) break;
712 SEGPTR_FREE(pen);
713 break;
715 case OBJ_BRUSH:
716 /* Enumerate solid brushes */
717 if (!(brush = SEGPTR_NEW(LOGBRUSH16))) break;
718 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
720 brush->lbStyle = BS_SOLID;
721 brush->lbColor = solid_colors[i];
722 brush->lbHatch = 0;
723 retval = lpEnumFunc( SEGPTR_GET(brush), lParam );
724 TRACE(gdi, "solid brush %08lx, ret=%d\n",
725 solid_colors[i], retval);
726 if (!retval) break;
729 /* Now enumerate hatched brushes */
730 if (retval) for (i = HS_HORIZONTAL; i <= HS_DIAGCROSS; i++)
732 brush->lbStyle = BS_HATCHED;
733 brush->lbColor = RGB(0,0,0);
734 brush->lbHatch = i;
735 retval = lpEnumFunc( SEGPTR_GET(brush), lParam );
736 TRACE(gdi, "hatched brush %d, ret=%d\n",
737 i, retval);
738 if (!retval) break;
740 SEGPTR_FREE(brush);
741 break;
743 default:
744 WARN(gdi, "(%d): Invalid type\n", nObjType );
745 break;
747 return retval;
751 /***********************************************************************
752 * EnumObjects32 (GDI32.89)
754 INT WINAPI EnumObjects( HDC hdc, INT nObjType,
755 GOBJENUMPROC lpEnumFunc, LPARAM lParam )
757 /* Solid colors to enumerate */
758 static const COLORREF solid_colors[] =
759 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
760 RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
761 RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
762 RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
763 RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
764 RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
765 RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
766 RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
769 INT i, retval = 0;
770 LOGPEN pen;
771 LOGBRUSH brush;
773 TRACE(gdi, "%04x %d %08lx %08lx\n",
774 hdc, nObjType, (DWORD)lpEnumFunc, lParam );
775 switch(nObjType)
777 case OBJ_PEN:
778 /* Enumerate solid pens */
779 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
781 pen.lopnStyle = PS_SOLID;
782 pen.lopnWidth.x = 1;
783 pen.lopnWidth.y = 0;
784 pen.lopnColor = solid_colors[i];
785 retval = lpEnumFunc( &pen, lParam );
786 TRACE(gdi, "solid pen %08lx, ret=%d\n",
787 solid_colors[i], retval);
788 if (!retval) break;
790 break;
792 case OBJ_BRUSH:
793 /* Enumerate solid brushes */
794 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
796 brush.lbStyle = BS_SOLID;
797 brush.lbColor = solid_colors[i];
798 brush.lbHatch = 0;
799 retval = lpEnumFunc( &brush, lParam );
800 TRACE(gdi, "solid brush %08lx, ret=%d\n",
801 solid_colors[i], retval);
802 if (!retval) break;
805 /* Now enumerate hatched brushes */
806 if (retval) for (i = HS_HORIZONTAL; i <= HS_DIAGCROSS; i++)
808 brush.lbStyle = BS_HATCHED;
809 brush.lbColor = RGB(0,0,0);
810 brush.lbHatch = i;
811 retval = lpEnumFunc( &brush, lParam );
812 TRACE(gdi, "hatched brush %d, ret=%d\n",
813 i, retval);
814 if (!retval) break;
816 break;
818 default:
819 /* FIXME: implement Win32 types */
820 WARN( gdi, "(%d): Invalid type\n", nObjType );
821 break;
823 return retval;
827 /***********************************************************************
828 * IsGDIObject (GDI.462)
830 * returns type of object if valid (W95 system programming secrets p. 264-5)
832 BOOL16 WINAPI IsGDIObject16( HGDIOBJ16 handle )
834 UINT16 magic = 0;
836 if (handle >= FIRST_STOCK_HANDLE )
838 switch (handle)
840 case STOCK_WHITE_BRUSH:
841 case STOCK_LTGRAY_BRUSH:
842 case STOCK_GRAY_BRUSH:
843 case STOCK_DKGRAY_BRUSH:
844 case STOCK_BLACK_BRUSH:
845 case STOCK_HOLLOW_BRUSH:
846 magic = BRUSH_MAGIC;
847 break;
849 case STOCK_WHITE_PEN:
850 case STOCK_BLACK_PEN:
851 case STOCK_NULL_PEN :
852 magic = PEN_MAGIC;
853 break;
855 case STOCK_OEM_FIXED_FONT:
856 case STOCK_ANSI_FIXED_FONT:
857 case STOCK_ANSI_VAR_FONT:
858 case STOCK_SYSTEM_FONT:
859 case STOCK_DEVICE_DEFAULT_FONT:
860 case STOCK_SYSTEM_FIXED_FONT:
861 case STOCK_DEFAULT_GUI_FONT:
862 magic = FONT_MAGIC;
863 break;
865 case STOCK_DEFAULT_PALETTE:
866 magic = PALETTE_MAGIC;
867 break;
870 else
872 GDIOBJHDR *object = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
873 if (object)
875 magic = object->wMagic;
876 GDI_HEAP_UNLOCK( handle );
880 if (magic >= PEN_MAGIC && magic <= METAFILE_DC_MAGIC)
881 return magic - PEN_MAGIC + 1;
882 else
883 return FALSE;
887 /***********************************************************************
888 * SetObjectOwner16 (GDI.461)
890 void WINAPI SetObjectOwner16( HGDIOBJ16 handle, HANDLE16 owner )
892 /* Nothing to do */
896 /***********************************************************************
897 * SetObjectOwner32 (GDI32.386)
899 void WINAPI SetObjectOwner( HGDIOBJ handle, HANDLE owner )
901 /* Nothing to do */
904 /***********************************************************************
905 * MakeObjectPrivate (GDI.463)
907 void WINAPI MakeObjectPrivate16( HGDIOBJ16 handle, BOOL16 private )
909 /* FIXME */
913 /***********************************************************************
914 * GdiFlush (GDI32.128)
916 BOOL WINAPI GdiFlush(void)
918 return TRUE; /* FIXME */
922 /***********************************************************************
923 * GdiGetBatchLimit (GDI32.129)
925 DWORD WINAPI GdiGetBatchLimit(void)
927 return 1; /* FIXME */
931 /***********************************************************************
932 * GdiSetBatchLimit (GDI32.139)
934 DWORD WINAPI GdiSetBatchLimit( DWORD limit )
936 return 1; /* FIXME */
940 /***********************************************************************
941 * GdiSeeGdiDo (GDI.452)
943 DWORD WINAPI GdiSeeGdiDo16( WORD wReqType, WORD wParam1, WORD wParam2,
944 WORD wParam3 )
946 switch (wReqType)
948 case 0x0001: /* LocalAlloc */
949 return LOCAL_Alloc( GDI_HeapSel, wParam1, wParam3 );
950 case 0x0002: /* LocalFree */
951 return LOCAL_Free( GDI_HeapSel, wParam1 );
952 case 0x0003: /* LocalCompact */
953 return LOCAL_Compact( GDI_HeapSel, wParam3, 0 );
954 case 0x0103: /* LocalHeap */
955 return GDI_HeapSel;
956 default:
957 WARN(gdi, "(wReqType=%04x): Unknown\n", wReqType);
958 return (DWORD)-1;
962 /***********************************************************************
963 * GdiFreeResources (GDI.609)
965 WORD WINAPI GdiFreeResources16( DWORD reserve )
967 return (WORD)( (int)LOCAL_CountFree( GDI_HeapSel ) * 100 /
968 (int)LOCAL_HeapSize( GDI_HeapSel ) );
971 /***********************************************************************
972 * MulDiv16 (GDI.128)
974 INT16 WINAPI MulDiv16( INT16 foo, INT16 bar, INT16 baz )
976 INT ret;
977 if (!baz) return -32768;
978 ret = (foo * bar) / baz;
979 if ((ret > 32767) || (ret < -32767)) return -32768;
980 return ret;
984 /***********************************************************************
985 * MulDiv32 (KERNEL32.391)
986 * RETURNS
987 * Result of multiplication and division
988 * -1: Overflow occurred or Divisor was 0
990 INT WINAPI MulDiv(
991 INT nMultiplicand,
992 INT nMultiplier,
993 INT nDivisor
995 #if (SIZEOF_LONG_LONG >= 8)
996 long long ret;
997 if (!nDivisor) return -1;
998 ret = ((long long)nMultiplicand * nMultiplier) / nDivisor;
999 if ((ret > 2147483647) || (ret < -2147483647)) return -1;
1000 return ret;
1001 #else
1002 if (!nDivisor) return -1;
1003 return (nMultiplicand * nMultiplier) / nDivisor;
1004 #endif
1006 /*******************************************************************
1007 * GetColorAdjustment [GDI32.164]
1011 BOOL WINAPI GetColorAdjustment(HDC hdc, LPCOLORADJUSTMENT lpca)
1013 FIXME(gdi, "GetColorAdjustment, stub\n");
1014 return 0;
1017 /*******************************************************************
1018 * GetMiterLimit [GDI32.201]
1022 BOOL WINAPI GetMiterLimit(HDC hdc, PFLOAT peLimit)
1024 FIXME(gdi, "GetMiterLimit, stub\n");
1025 return 0;
1028 /*******************************************************************
1029 * SetMiterLimit [GDI32.325]
1033 BOOL WINAPI SetMiterLimit(HDC hdc, FLOAT eNewLimit, PFLOAT peOldLimit)
1035 FIXME(gdi, "SetMiterLimit, stub\n");
1036 return 0;
1039 /*******************************************************************
1040 * GdiComment [GDI32.109]
1044 BOOL WINAPI GdiComment(HDC hdc, UINT cbSize, const BYTE *lpData)
1046 FIXME(gdi, "GdiComment, stub\n");
1047 return 0;
1049 /*******************************************************************
1050 * SetColorAdjustment [GDI32.309]
1054 BOOL WINAPI SetColorAdjustment(HDC hdc, const COLORADJUSTMENT* lpca)
1056 FIXME(gdi, "SetColorAdjustment, stub\n");
1057 return 0;