Authors: Chris Morgan <cmorgan@wpi.edu>, James Abbatiello <abbejy@wpi.edu>
[wine/multimedia.git] / objects / gdiobj.c
blob85dc5e82d9d77c88604165d522a27d72d5758534
1 /*
2 * GDI functions
4 * Copyright 1993 Alexandre Julliard
5 */
7 #ifndef X_DISPLAY_MISSING
8 #include "x11drv.h"
9 #else /* !defined(X_DISPLAY_MISSING) */
10 #include "ttydrv.h"
11 #endif /* !defined(X_DISPLAY_MISSING */
13 #include <stdlib.h>
15 #include "bitmap.h"
16 #include "brush.h"
17 #include "dc.h"
18 #include "font.h"
19 #include "heap.h"
20 #include "options.h"
21 #include "palette.h"
22 #include "pen.h"
23 #include "region.h"
24 #include "debug.h"
25 #include "gdi.h"
27 DEFAULT_DEBUG_CHANNEL(gdi)
29 /**********************************************************************/
31 GDI_DRIVER *GDI_Driver = NULL;
33 /***********************************************************************
34 * GDI stock objects
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, { 1, 0 }, RGB(255,255,255) } /* logpen */
83 static PENOBJ BlackPen =
85 { 0, PEN_MAGIC, 1 }, /* header */
86 { PS_SOLID, { 1, 0 }, RGB(0,0,0) } /* logpen */
89 static PENOBJ NullPen =
91 { 0, PEN_MAGIC, 1 }, /* header */
92 { PS_NULL, { 1, 0 }, 0 } /* logpen */
95 static FONTOBJ OEMFixedFont =
97 { 0, FONT_MAGIC, 1 }, /* header */
98 { 12, 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 { 12, 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 { 12, 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 { 16, 0, 0, 0, FW_BOLD, 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 { 12, 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 { 12, 0, 0, 0, FW_BOLD, 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 { 9, FONT_MAGIC, 1 }, /* header */
150 { 12, 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,
167 NULL,
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 /******************************************************************************
180 * void ReadFontInformation(
181 * char const *fontName,
182 * FONTOBJ *font,
183 * int defHeight,
184 * int defBold,
185 * int defItalic,
186 * int defUnderline,
187 * int defStrikeOut )
189 * ReadFontInformation() checks the Wine configuration file's Tweak.Fonts
190 * section for entries containing fontName.Height, fontName.Bold, etc.,
191 * where fontName is the name specified in the call (e.g., "System"). It
192 * attempts to be user friendly by accepting 'n', 'N', 'f', 'F', or '0' as
193 * the first character in the boolean attributes (bold, italic, and
194 * underline).
195 *****************************************************************************/
197 static void ReadFontInformation(
198 char const *fontName,
199 FONTOBJ *font,
200 int defHeight,
201 int defBold,
202 int defItalic,
203 int defUnderline,
204 int defStrikeOut )
206 char key[256];
208 sprintf(key, "%s.Height", fontName);
209 font->logfont.lfHeight =
210 PROFILE_GetWineIniInt("Tweak.Fonts", key, defHeight);
212 sprintf(key, "%s.Bold", fontName);
213 font->logfont.lfWeight =
214 (PROFILE_GetWineIniBool("Tweak.Fonts", key, defBold)) ?
215 FW_BOLD : FW_NORMAL;
217 sprintf(key, "%s.Italic", fontName);
218 font->logfont.lfItalic =
219 PROFILE_GetWineIniBool("Tweak.Fonts", key, defItalic);
221 sprintf(key, "%s.Underline", fontName);
222 font->logfont.lfUnderline =
223 PROFILE_GetWineIniBool("Tweak.Fonts", key, defUnderline);
225 sprintf(key, "%s.StrikeOut", fontName);
226 font->logfont.lfStrikeOut =
227 PROFILE_GetWineIniBool("Tweak.Fonts", key, defStrikeOut);
229 return;
233 /***********************************************************************
234 * GDI_Init
236 * GDI initialization.
238 BOOL GDI_Init(void)
240 /* Kill some warnings. */
241 (void)align_OEMFixedFont;
242 (void)align_AnsiFixedFont;
243 (void)align_AnsiVarFont;
244 (void)align_SystemFont;
245 (void)align_DeviceDefaultFont;
246 (void)align_SystemFixedFont;
247 (void)align_DefaultGuiFont;
249 /* TWEAK: Initialize font hints */
250 ReadFontInformation("OEMFixed", &OEMFixedFont, 12, 0, 0, 0, 0);
251 ReadFontInformation("AnsiFixed", &AnsiFixedFont, 12, 0, 0, 0, 0);
252 ReadFontInformation("AnsiVar", &AnsiVarFont, 12, 0, 0, 0, 0);
253 ReadFontInformation("System", &SystemFont, 16, 1, 0, 0, 0);
254 ReadFontInformation("SystemFixed", &SystemFixedFont, 12, 1, 0, 0, 0);
256 /* Initialize drivers */
258 #ifndef X_DISPLAY_MISSING
259 GDI_Driver = &X11DRV_GDI_Driver;
260 #else /* !defined(X_DISPLAY_MISSING) */
261 GDI_Driver = &TTYDRV_GDI_Driver;
262 #endif /* !defined(X_DISPLAY_MISSING */
264 GDI_Driver->pInitialize();
266 /* Create default palette */
268 /* DR well *this* palette can't be moveable (?) */
270 HPALETTE16 hpalette = PALETTE_Init();
271 if( !hpalette )
272 return FALSE;
273 StockObjects[DEFAULT_PALETTE] = (GDIOBJHDR *)GDI_HEAP_LOCK( hpalette );
276 return TRUE;
280 /***********************************************************************
281 * GDI_AllocObject
283 HGDIOBJ16 GDI_AllocObject( WORD size, WORD magic )
285 static DWORD count = 0;
286 GDIOBJHDR * obj;
287 HGDIOBJ16 handle;
288 if ( magic == DC_MAGIC || magic == METAFILE_DC_MAGIC )
289 handle = GDI_HEAP_ALLOC( size );
290 else
291 handle = GDI_HEAP_ALLOC_MOVEABLE( size );
292 if (!handle) return 0;
293 obj = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
294 obj->hNext = 0;
295 obj->wMagic = magic;
296 obj->dwCount = ++count;
297 GDI_HEAP_UNLOCK( handle );
298 return handle;
302 /***********************************************************************
303 * GDI_FreeObject
305 BOOL GDI_FreeObject( HGDIOBJ16 handle )
307 GDIOBJHDR * object;
309 /* Can't free stock objects */
310 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
311 return TRUE;
313 object = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
314 if (!object) return FALSE;
315 object->wMagic = 0; /* Mark it as invalid */
317 /* Free object */
319 GDI_HEAP_FREE( handle );
320 return TRUE;
323 /***********************************************************************
324 * GDI_GetObjPtr
326 * Return a pointer to the GDI object associated to the handle.
327 * Return NULL if the object has the wrong magic number.
328 * Movable GDI objects are locked in memory: it is up to the caller to unlock
329 * it after the caller is done with the pointer.
331 GDIOBJHDR * GDI_GetObjPtr( HGDIOBJ16 handle, WORD magic )
333 GDIOBJHDR * ptr = NULL;
335 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
336 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
337 else
338 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
339 if (!ptr) return NULL;
340 if ((magic != MAGIC_DONTCARE) && (ptr->wMagic != magic))
342 GDI_HEAP_UNLOCK( handle );
343 return NULL;
345 return ptr;
349 /***********************************************************************
350 * DeleteObject16 (GDI.69)
352 BOOL16 WINAPI DeleteObject16( HGDIOBJ16 obj )
354 return DeleteObject( obj );
358 /***********************************************************************
359 * DeleteObject32 (GDI32.70)
361 BOOL WINAPI DeleteObject( HGDIOBJ obj )
363 /* Check if object is valid */
365 GDIOBJHDR * header;
366 if (HIWORD(obj)) return FALSE;
367 if ((obj >= FIRST_STOCK_HANDLE) && (obj <= LAST_STOCK_HANDLE))
368 return TRUE;
369 if (!(header = (GDIOBJHDR *) GDI_HEAP_LOCK( obj ))) return FALSE;
371 TRACE(gdi, "%04x\n", obj );
373 /* Delete object */
375 switch(header->wMagic)
377 case PEN_MAGIC: return GDI_FreeObject( obj );
378 case BRUSH_MAGIC: return BRUSH_DeleteObject( obj, (BRUSHOBJ*)header );
379 case FONT_MAGIC: return GDI_FreeObject( obj );
380 case PALETTE_MAGIC: return PALETTE_DeleteObject(obj,(PALETTEOBJ*)header);
381 case BITMAP_MAGIC: return BITMAP_DeleteObject( obj, (BITMAPOBJ*)header);
382 case REGION_MAGIC: return REGION_DeleteObject( obj, (RGNOBJ*)header );
383 case DC_MAGIC: return DeleteDC(obj);
384 case 0 :
385 WARN(gdi, "Already deleted\n");
386 break;
387 default:
388 WARN(gdi, "Unknown magic number (%d)\n",header->wMagic);
390 return FALSE;
393 /***********************************************************************
394 * GetStockObject16 (GDI.87)
396 HGDIOBJ16 WINAPI GetStockObject16( INT16 obj )
398 return (HGDIOBJ16)GetStockObject( obj );
402 /***********************************************************************
403 * GetStockObject32 (GDI32.220)
405 HGDIOBJ WINAPI GetStockObject( INT obj )
407 if ((obj < 0) || (obj >= NB_STOCK_OBJECTS)) return 0;
408 if (!StockObjects[obj]) return 0;
409 TRACE(gdi, "returning %d\n",
410 FIRST_STOCK_HANDLE + obj );
411 return (HGDIOBJ16)(FIRST_STOCK_HANDLE + obj);
415 /***********************************************************************
416 * GetObject16 (GDI.82)
418 INT16 WINAPI GetObject16( HANDLE16 handle, INT16 count, LPVOID buffer )
420 GDIOBJHDR * ptr = NULL;
421 INT16 result = 0;
422 TRACE(gdi, "%04x %d %p\n", handle, count, buffer );
423 if (!count) return 0;
425 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
426 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
427 else
428 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
429 if (!ptr) return 0;
431 switch(ptr->wMagic)
433 case PEN_MAGIC:
434 result = PEN_GetObject16( (PENOBJ *)ptr, count, buffer );
435 break;
436 case BRUSH_MAGIC:
437 result = BRUSH_GetObject16( (BRUSHOBJ *)ptr, count, buffer );
438 break;
439 case BITMAP_MAGIC:
440 result = BITMAP_GetObject16( (BITMAPOBJ *)ptr, count, buffer );
441 break;
442 case FONT_MAGIC:
443 result = FONT_GetObject16( (FONTOBJ *)ptr, count, buffer );
444 break;
445 case PALETTE_MAGIC:
446 result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer );
447 break;
449 GDI_HEAP_UNLOCK( handle );
450 return result;
454 /***********************************************************************
455 * GetObject32A (GDI32.204)
457 INT WINAPI GetObjectA( HANDLE handle, INT count, LPVOID buffer )
459 GDIOBJHDR * ptr = NULL;
460 INT result = 0;
461 TRACE(gdi, "%08x %d %p\n", handle, count, buffer );
462 if (!count) return 0;
464 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
465 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
466 else
467 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
468 if (!ptr) return 0;
470 switch(ptr->wMagic)
472 case PEN_MAGIC:
473 result = PEN_GetObject( (PENOBJ *)ptr, count, buffer );
474 break;
475 case BRUSH_MAGIC:
476 result = BRUSH_GetObject( (BRUSHOBJ *)ptr, count, buffer );
477 break;
478 case BITMAP_MAGIC:
479 result = BITMAP_GetObject( (BITMAPOBJ *)ptr, count, buffer );
480 break;
481 case FONT_MAGIC:
482 result = FONT_GetObjectA( (FONTOBJ *)ptr, count, buffer );
483 break;
484 case PALETTE_MAGIC:
485 result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer );
486 break;
487 default:
488 FIXME(gdi, "Magic %04x not implemented\n",
489 ptr->wMagic );
490 break;
492 GDI_HEAP_UNLOCK( handle );
493 return result;
495 /***********************************************************************
496 * GetObject32W (GDI32.206)
498 INT WINAPI GetObjectW( HANDLE handle, INT count, LPVOID buffer )
500 GDIOBJHDR * ptr = NULL;
501 INT result = 0;
502 TRACE(gdi, "%08x %d %p\n", handle, count, buffer );
503 if (!count) return 0;
505 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
506 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
507 else
508 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
509 if (!ptr) return 0;
511 switch(ptr->wMagic)
513 case PEN_MAGIC:
514 result = PEN_GetObject( (PENOBJ *)ptr, count, buffer );
515 break;
516 case BRUSH_MAGIC:
517 result = BRUSH_GetObject( (BRUSHOBJ *)ptr, count, buffer );
518 break;
519 case BITMAP_MAGIC:
520 result = BITMAP_GetObject( (BITMAPOBJ *)ptr, count, buffer );
521 break;
522 case FONT_MAGIC:
523 result = FONT_GetObjectW( (FONTOBJ *)ptr, count, buffer );
524 break;
525 case PALETTE_MAGIC:
526 result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer );
527 break;
528 default:
529 FIXME(gdi, "Magic %04x not implemented\n",
530 ptr->wMagic );
531 break;
533 GDI_HEAP_UNLOCK( handle );
534 return result;
537 /***********************************************************************
538 * GetObjectType (GDI32.205)
540 DWORD WINAPI GetObjectType( HANDLE handle )
542 GDIOBJHDR * ptr = NULL;
543 INT result = 0;
544 TRACE(gdi, "%08x\n", handle );
546 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
547 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
548 else
549 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
550 if (!ptr) return 0;
552 switch(ptr->wMagic)
554 case PEN_MAGIC:
555 result = OBJ_PEN;
556 break;
557 case BRUSH_MAGIC:
558 result = OBJ_BRUSH;
559 break;
560 case BITMAP_MAGIC:
561 result = OBJ_BITMAP;
562 break;
563 case FONT_MAGIC:
564 result = OBJ_FONT;
565 break;
566 case PALETTE_MAGIC:
567 result = OBJ_PAL;
568 break;
569 case REGION_MAGIC:
570 result = OBJ_REGION;
571 break;
572 case DC_MAGIC:
573 result = OBJ_DC;
574 break;
575 case META_DC_MAGIC:
576 result = OBJ_METADC;
577 break;
578 case METAFILE_MAGIC:
579 result = OBJ_METAFILE;
580 break;
581 case METAFILE_DC_MAGIC:
582 result = OBJ_METADC;
583 break;
585 default:
586 FIXME(gdi, "Magic %04x not implemented\n",
587 ptr->wMagic );
588 break;
590 GDI_HEAP_UNLOCK( handle );
591 return result;
594 /***********************************************************************
595 * GetCurrentObject (GDI32.166)
597 HANDLE WINAPI GetCurrentObject(HDC hdc,UINT type)
599 DC * dc = DC_GetDCPtr( hdc );
601 if (!dc)
602 return 0;
603 switch (type) {
604 case OBJ_PEN: return dc->w.hPen;
605 case OBJ_BRUSH: return dc->w.hBrush;
606 case OBJ_PAL: return dc->w.hPalette;
607 case OBJ_FONT: return dc->w.hFont;
608 case OBJ_BITMAP: return dc->w.hBitmap;
609 default:
610 /* the SDK only mentions those above */
611 WARN(gdi,"(%08x,%d): unknown type.\n",hdc,type);
612 return 0;
617 /***********************************************************************
618 * SelectObject16 (GDI.45)
620 HGDIOBJ16 WINAPI SelectObject16( HDC16 hdc, HGDIOBJ16 handle )
622 return (HGDIOBJ16)SelectObject( hdc, handle );
626 /***********************************************************************
627 * SelectObject32 (GDI32.299)
629 HGDIOBJ WINAPI SelectObject( HDC hdc, HGDIOBJ handle )
631 DC * dc = DC_GetDCPtr( hdc );
632 if (!dc || !dc->funcs->pSelectObject) return 0;
633 TRACE(gdi, "hdc=%04x %04x\n", hdc, handle );
634 return dc->funcs->pSelectObject( dc, handle );
638 /***********************************************************************
639 * UnrealizeObject16 (GDI.150)
641 BOOL16 WINAPI UnrealizeObject16( HGDIOBJ16 obj )
643 return UnrealizeObject( obj );
647 /***********************************************************************
648 * UnrealizeObject (GDI32.358)
650 BOOL WINAPI UnrealizeObject( HGDIOBJ obj )
652 BOOL result = TRUE;
653 /* Check if object is valid */
655 GDIOBJHDR * header = (GDIOBJHDR *) GDI_HEAP_LOCK( obj );
656 if (!header) return FALSE;
658 TRACE(gdi, "%04x\n", obj );
660 /* Unrealize object */
662 switch(header->wMagic)
664 case PALETTE_MAGIC:
665 result = PALETTE_UnrealizeObject( obj, (PALETTEOBJ *)header );
666 break;
668 case BRUSH_MAGIC:
669 /* Windows resets the brush origin. We don't need to. */
670 break;
672 GDI_HEAP_UNLOCK( obj );
673 return result;
677 /***********************************************************************
678 * EnumObjects16 (GDI.71)
680 INT16 WINAPI EnumObjects16( HDC16 hdc, INT16 nObjType,
681 GOBJENUMPROC16 lpEnumFunc, LPARAM lParam )
683 /* Solid colors to enumerate */
684 static const COLORREF solid_colors[] =
685 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
686 RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
687 RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
688 RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
689 RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
690 RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
691 RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
692 RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
695 INT16 i, retval = 0;
696 LOGPEN16 *pen;
697 LOGBRUSH16 *brush = NULL;
699 TRACE(gdi, "%04x %d %08lx %08lx\n",
700 hdc, nObjType, (DWORD)lpEnumFunc, lParam );
701 switch(nObjType)
703 case OBJ_PEN:
704 /* Enumerate solid pens */
705 if (!(pen = SEGPTR_NEW(LOGPEN16))) break;
706 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
708 pen->lopnStyle = PS_SOLID;
709 pen->lopnWidth.x = 1;
710 pen->lopnWidth.y = 0;
711 pen->lopnColor = solid_colors[i];
712 retval = lpEnumFunc( SEGPTR_GET(pen), lParam );
713 TRACE(gdi, "solid pen %08lx, ret=%d\n",
714 solid_colors[i], retval);
715 if (!retval) break;
717 SEGPTR_FREE(pen);
718 break;
720 case OBJ_BRUSH:
721 /* Enumerate solid brushes */
722 if (!(brush = SEGPTR_NEW(LOGBRUSH16))) break;
723 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
725 brush->lbStyle = BS_SOLID;
726 brush->lbColor = solid_colors[i];
727 brush->lbHatch = 0;
728 retval = lpEnumFunc( SEGPTR_GET(brush), lParam );
729 TRACE(gdi, "solid brush %08lx, ret=%d\n",
730 solid_colors[i], retval);
731 if (!retval) break;
734 /* Now enumerate hatched brushes */
735 if (retval) for (i = HS_HORIZONTAL; i <= HS_DIAGCROSS; i++)
737 brush->lbStyle = BS_HATCHED;
738 brush->lbColor = RGB(0,0,0);
739 brush->lbHatch = i;
740 retval = lpEnumFunc( SEGPTR_GET(brush), lParam );
741 TRACE(gdi, "hatched brush %d, ret=%d\n",
742 i, retval);
743 if (!retval) break;
745 SEGPTR_FREE(brush);
746 break;
748 default:
749 WARN(gdi, "(%d): Invalid type\n", nObjType );
750 break;
752 return retval;
756 /***********************************************************************
757 * EnumObjects32 (GDI32.89)
759 INT WINAPI EnumObjects( HDC hdc, INT nObjType,
760 GOBJENUMPROC lpEnumFunc, LPARAM lParam )
762 /* Solid colors to enumerate */
763 static const COLORREF solid_colors[] =
764 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
765 RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
766 RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
767 RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
768 RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
769 RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
770 RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
771 RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
774 INT i, retval = 0;
775 LOGPEN pen;
776 LOGBRUSH brush;
778 TRACE(gdi, "%04x %d %08lx %08lx\n",
779 hdc, nObjType, (DWORD)lpEnumFunc, lParam );
780 switch(nObjType)
782 case OBJ_PEN:
783 /* Enumerate solid pens */
784 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
786 pen.lopnStyle = PS_SOLID;
787 pen.lopnWidth.x = 1;
788 pen.lopnWidth.y = 0;
789 pen.lopnColor = solid_colors[i];
790 retval = lpEnumFunc( &pen, lParam );
791 TRACE(gdi, "solid pen %08lx, ret=%d\n",
792 solid_colors[i], retval);
793 if (!retval) break;
795 break;
797 case OBJ_BRUSH:
798 /* Enumerate solid brushes */
799 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
801 brush.lbStyle = BS_SOLID;
802 brush.lbColor = solid_colors[i];
803 brush.lbHatch = 0;
804 retval = lpEnumFunc( &brush, lParam );
805 TRACE(gdi, "solid brush %08lx, ret=%d\n",
806 solid_colors[i], retval);
807 if (!retval) break;
810 /* Now enumerate hatched brushes */
811 if (retval) for (i = HS_HORIZONTAL; i <= HS_DIAGCROSS; i++)
813 brush.lbStyle = BS_HATCHED;
814 brush.lbColor = RGB(0,0,0);
815 brush.lbHatch = i;
816 retval = lpEnumFunc( &brush, lParam );
817 TRACE(gdi, "hatched brush %d, ret=%d\n",
818 i, retval);
819 if (!retval) break;
821 break;
823 default:
824 /* FIXME: implement Win32 types */
825 WARN( gdi, "(%d): Invalid type\n", nObjType );
826 break;
828 return retval;
832 /***********************************************************************
833 * IsGDIObject (GDI.462)
835 * returns type of object if valid (W95 system programming secrets p. 264-5)
837 BOOL16 WINAPI IsGDIObject16( HGDIOBJ16 handle )
839 UINT16 magic = 0;
841 if (handle >= FIRST_STOCK_HANDLE )
843 switch (handle)
845 case STOCK_WHITE_BRUSH:
846 case STOCK_LTGRAY_BRUSH:
847 case STOCK_GRAY_BRUSH:
848 case STOCK_DKGRAY_BRUSH:
849 case STOCK_BLACK_BRUSH:
850 case STOCK_HOLLOW_BRUSH:
851 magic = BRUSH_MAGIC;
852 break;
854 case STOCK_WHITE_PEN:
855 case STOCK_BLACK_PEN:
856 case STOCK_NULL_PEN :
857 magic = PEN_MAGIC;
858 break;
860 case STOCK_OEM_FIXED_FONT:
861 case STOCK_ANSI_FIXED_FONT:
862 case STOCK_ANSI_VAR_FONT:
863 case STOCK_SYSTEM_FONT:
864 case STOCK_DEVICE_DEFAULT_FONT:
865 case STOCK_SYSTEM_FIXED_FONT:
866 case STOCK_DEFAULT_GUI_FONT:
867 magic = FONT_MAGIC;
868 break;
870 case STOCK_DEFAULT_PALETTE:
871 magic = PALETTE_MAGIC;
872 break;
875 else
877 GDIOBJHDR *object = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
878 if (object)
880 magic = object->wMagic;
881 GDI_HEAP_UNLOCK( handle );
885 if (magic >= PEN_MAGIC && magic <= METAFILE_DC_MAGIC)
886 return magic - PEN_MAGIC + 1;
887 else
888 return FALSE;
892 /***********************************************************************
893 * SetObjectOwner16 (GDI.461)
895 void WINAPI SetObjectOwner16( HGDIOBJ16 handle, HANDLE16 owner )
897 /* Nothing to do */
901 /***********************************************************************
902 * SetObjectOwner32 (GDI32.386)
904 void WINAPI SetObjectOwner( HGDIOBJ handle, HANDLE owner )
906 /* Nothing to do */
909 /***********************************************************************
910 * MakeObjectPrivate (GDI.463)
912 void WINAPI MakeObjectPrivate16( HGDIOBJ16 handle, BOOL16 private )
914 /* FIXME */
918 /***********************************************************************
919 * GdiFlush (GDI32.128)
921 BOOL WINAPI GdiFlush(void)
923 return TRUE; /* FIXME */
927 /***********************************************************************
928 * GdiGetBatchLimit (GDI32.129)
930 DWORD WINAPI GdiGetBatchLimit(void)
932 return 1; /* FIXME */
936 /***********************************************************************
937 * GdiSetBatchLimit (GDI32.139)
939 DWORD WINAPI GdiSetBatchLimit( DWORD limit )
941 return 1; /* FIXME */
945 /***********************************************************************
946 * GdiSeeGdiDo (GDI.452)
948 DWORD WINAPI GdiSeeGdiDo16( WORD wReqType, WORD wParam1, WORD wParam2,
949 WORD wParam3 )
951 switch (wReqType)
953 case 0x0001: /* LocalAlloc */
954 return LOCAL_Alloc( GDI_HeapSel, wParam1, wParam3 );
955 case 0x0002: /* LocalFree */
956 return LOCAL_Free( GDI_HeapSel, wParam1 );
957 case 0x0003: /* LocalCompact */
958 return LOCAL_Compact( GDI_HeapSel, wParam3, 0 );
959 case 0x0103: /* LocalHeap */
960 return GDI_HeapSel;
961 default:
962 WARN(gdi, "(wReqType=%04x): Unknown\n", wReqType);
963 return (DWORD)-1;
967 /***********************************************************************
968 * GdiSignalProc (GDI.610)
970 WORD WINAPI GdiSignalProc( UINT uCode, DWORD dwThreadOrProcessID,
971 DWORD dwFlags, HMODULE16 hModule )
973 return 0;
977 /***********************************************************************
978 * GdiFreeResources (GDI.609)
980 WORD WINAPI GdiFreeResources16( DWORD reserve )
982 return (WORD)( (int)LOCAL_CountFree( GDI_HeapSel ) * 100 /
983 (int)LOCAL_HeapSize( GDI_HeapSel ) );
986 /***********************************************************************
987 * MulDiv16 (GDI.128)
989 INT16 WINAPI MulDiv16( INT16 foo, INT16 bar, INT16 baz )
991 INT ret;
992 if (!baz) return -32768;
993 ret = (foo * bar) / baz;
994 if ((ret > 32767) || (ret < -32767)) return -32768;
995 return ret;
999 /***********************************************************************
1000 * MulDiv32 (KERNEL32.391)
1001 * RETURNS
1002 * Result of multiplication and division
1003 * -1: Overflow occurred or Divisor was 0
1005 INT WINAPI MulDiv(
1006 INT nMultiplicand,
1007 INT nMultiplier,
1008 INT nDivisor
1010 #if (SIZEOF_LONG_LONG >= 8)
1011 long long ret;
1012 if (!nDivisor) return -1;
1013 ret = ((long long)nMultiplicand * nMultiplier) / nDivisor;
1014 if ((ret > 2147483647) || (ret < -2147483647)) return -1;
1015 return ret;
1016 #else
1017 if (!nDivisor) return -1;
1018 return (nMultiplicand * nMultiplier) / nDivisor;
1019 #endif
1021 /*******************************************************************
1022 * GetColorAdjustment [GDI32.164]
1026 BOOL WINAPI GetColorAdjustment(HDC hdc, LPCOLORADJUSTMENT lpca)
1028 FIXME(gdi, "GetColorAdjustment, stub\n");
1029 return 0;
1032 /*******************************************************************
1033 * GetMiterLimit [GDI32.201]
1037 BOOL WINAPI GetMiterLimit(HDC hdc, PFLOAT peLimit)
1039 FIXME(gdi, "GetMiterLimit, stub\n");
1040 return 0;
1043 /*******************************************************************
1044 * SetMiterLimit [GDI32.325]
1048 BOOL WINAPI SetMiterLimit(HDC hdc, FLOAT eNewLimit, PFLOAT peOldLimit)
1050 FIXME(gdi, "SetMiterLimit, stub\n");
1051 return 0;
1054 /*******************************************************************
1055 * GdiComment [GDI32.109]
1059 BOOL WINAPI GdiComment(HDC hdc, UINT cbSize, const BYTE *lpData)
1061 FIXME(gdi, "GdiComment, stub\n");
1062 return 0;
1064 /*******************************************************************
1065 * SetColorAdjustment [GDI32.309]
1069 BOOL WINAPI SetColorAdjustment(HDC hdc, const COLORADJUSTMENT* lpca)
1071 FIXME(gdi, "SetColorAdjustment, stub\n");
1072 return 0;