Added FIXME message in PostMessage32x if parameters are truncated
[wine/multimedia.git] / objects / gdiobj.c
blob88242e4ab2961917d9ac7ba3390e5589dc9f0213
1 /*
2 * GDI functions
4 * Copyright 1993 Alexandre Julliard
5 */
7 #include <stdlib.h>
8 #include "color.h"
9 #include "bitmap.h"
10 #include "brush.h"
11 #include "dc.h"
12 #include "font.h"
13 #include "heap.h"
14 #include "options.h"
15 #include "palette.h"
16 #include "pen.h"
17 #include "region.h"
18 #include "debug.h"
19 #include "gdi.h"
22 /***********************************************************************
23 * GDI stock objects
26 static BRUSHOBJ WhiteBrush =
28 { 0, BRUSH_MAGIC, 1 }, /* header */
29 { BS_SOLID, RGB(255,255,255), 0 } /* logbrush */
32 static BRUSHOBJ LtGrayBrush =
34 { 0, BRUSH_MAGIC, 1 }, /* header */
35 /* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
36 { BS_SOLID, RGB(192,192,192), 0 } /* logbrush */
39 static BRUSHOBJ GrayBrush =
41 { 0, BRUSH_MAGIC, 1 }, /* header */
42 /* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
43 { BS_SOLID, RGB(128,128,128), 0 } /* logbrush */
46 static BRUSHOBJ DkGrayBrush =
48 { 0, BRUSH_MAGIC, 1 }, /* header */
49 /* This is BS_HATCHED, for 1 bitperpixel. This makes the spray work in pbrush */
50 /* NB_HATCH_STYLES is an index into HatchBrushes */
51 { BS_HATCHED, RGB(0,0,0), NB_HATCH_STYLES } /* logbrush */
54 static BRUSHOBJ BlackBrush =
56 { 0, BRUSH_MAGIC, 1 }, /* header */
57 { BS_SOLID, RGB(0,0,0), 0 } /* logbrush */
60 static BRUSHOBJ NullBrush =
62 { 0, BRUSH_MAGIC, 1 }, /* header */
63 { BS_NULL, 0, 0 } /* logbrush */
66 static PENOBJ WhitePen =
68 { 0, PEN_MAGIC, 1 }, /* header */
69 { PS_SOLID, { 1, 0 }, RGB(255,255,255) } /* logpen */
72 static PENOBJ BlackPen =
74 { 0, PEN_MAGIC, 1 }, /* header */
75 { PS_SOLID, { 1, 0 }, RGB(0,0,0) } /* logpen */
78 static PENOBJ NullPen =
80 { 0, PEN_MAGIC, 1 }, /* header */
81 { PS_NULL, { 1, 0 }, 0 } /* logpen */
84 static FONTOBJ OEMFixedFont =
86 { 0, FONT_MAGIC, 1 }, /* header */
87 { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, OEM_CHARSET,
88 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" }
90 /* Filler to make the location counter dword aligned again. This is necessary
91 since (a) FONTOBJ is packed, (b) gcc places initialised variables in the code
92 segment, and (c) Solaris assembler is stupid. */
93 static UINT16 align_OEMFixedFont = 1;
95 static FONTOBJ AnsiFixedFont =
97 { 0, FONT_MAGIC, 1 }, /* header */
98 { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
99 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" }
101 static UINT16 align_AnsiFixedFont = 1;
103 static FONTOBJ AnsiVarFont =
105 { 0, FONT_MAGIC, 1 }, /* header */
106 { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
107 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "MS Sans Serif" }
109 static UINT16 align_AnsiVarFont = 1;
111 static FONTOBJ SystemFont =
113 { 0, FONT_MAGIC, 1 },
114 { 16, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, ANSI_CHARSET,
115 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "System" }
117 static UINT16 align_SystemFont = 1;
119 static FONTOBJ DeviceDefaultFont =
121 { 0, FONT_MAGIC, 1 }, /* header */
122 { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
123 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "" }
125 static UINT16 align_DeviceDefaultFont = 1;
127 static FONTOBJ SystemFixedFont =
129 { 0, FONT_MAGIC, 1 }, /* header */
130 { 12, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, ANSI_CHARSET,
131 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" }
133 static UINT16 align_SystemFixedFont = 1;
135 /* FIXME: Is this correct? */
136 static FONTOBJ DefaultGuiFont =
138 { 9, FONT_MAGIC, 1 }, /* header */
139 { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
140 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "MS Sans Serif" }
142 static UINT16 align_DefaultGuiFont = 1;
145 static GDIOBJHDR * StockObjects[NB_STOCK_OBJECTS] =
147 (GDIOBJHDR *) &WhiteBrush,
148 (GDIOBJHDR *) &LtGrayBrush,
149 (GDIOBJHDR *) &GrayBrush,
150 (GDIOBJHDR *) &DkGrayBrush,
151 (GDIOBJHDR *) &BlackBrush,
152 (GDIOBJHDR *) &NullBrush,
153 (GDIOBJHDR *) &WhitePen,
154 (GDIOBJHDR *) &BlackPen,
155 (GDIOBJHDR *) &NullPen,
156 NULL,
157 (GDIOBJHDR *) &OEMFixedFont,
158 (GDIOBJHDR *) &AnsiFixedFont,
159 (GDIOBJHDR *) &AnsiVarFont,
160 (GDIOBJHDR *) &SystemFont,
161 (GDIOBJHDR *) &DeviceDefaultFont,
162 NULL, /* DEFAULT_PALETTE created by PALETTE_Init */
163 (GDIOBJHDR *) &SystemFixedFont,
164 (GDIOBJHDR *) &DefaultGuiFont
167 /******************************************************************************
169 * void ReadFontInformation(
170 * char const *fontName,
171 * FONTOBJ *font,
172 * int defHeight,
173 * int defBold,
174 * int defItalic,
175 * int defUnderline,
176 * int defStrikeOut )
178 * ReadFontInformation() checks the Wine configuration file's Tweak.Fonts
179 * section for entries containing fontName.Height, fontName.Bold, etc.,
180 * where fontName is the name specified in the call (e.g., "System"). It
181 * attempts to be user friendly by accepting 'n', 'N', 'f', 'F', or '0' as
182 * the first character in the boolean attributes (bold, italic, and
183 * underline).
184 *****************************************************************************/
186 static void ReadFontInformation(
187 char const *fontName,
188 FONTOBJ *font,
189 int defHeight,
190 int defBold,
191 int defItalic,
192 int defUnderline,
193 int defStrikeOut )
195 char key[256];
197 sprintf(key, "%s.Height", fontName);
198 font->logfont.lfHeight =
199 PROFILE_GetWineIniInt("Tweak.Fonts", key, defHeight);
201 sprintf(key, "%s.Bold", fontName);
202 font->logfont.lfWeight =
203 (PROFILE_GetWineIniBool("Tweak.Fonts", key, defBold)) ?
204 FW_BOLD : FW_NORMAL;
206 sprintf(key, "%s.Italic", fontName);
207 font->logfont.lfItalic =
208 PROFILE_GetWineIniBool("Tweak.Fonts", key, defItalic);
210 sprintf(key, "%s.Underline", fontName);
211 font->logfont.lfUnderline =
212 PROFILE_GetWineIniBool("Tweak.Fonts", key, defUnderline);
214 sprintf(key, "%s.StrikeOut", fontName);
215 font->logfont.lfStrikeOut =
216 PROFILE_GetWineIniBool("Tweak.Fonts", key, defStrikeOut);
218 return;
222 /***********************************************************************
223 * GDI_Init
225 * GDI initialization.
227 BOOL32 GDI_Init(void)
229 /* Kill some warnings. */
230 (void)align_OEMFixedFont;
231 (void)align_AnsiFixedFont;
232 (void)align_AnsiVarFont;
233 (void)align_SystemFont;
234 (void)align_DeviceDefaultFont;
235 (void)align_SystemFixedFont;
236 (void)align_DefaultGuiFont;
238 /* TWEAK: Initialize font hints */
239 ReadFontInformation("OEMFixed", &OEMFixedFont, 12, 0, 0, 0, 0);
240 ReadFontInformation("AnsiFixed", &AnsiFixedFont, 12, 0, 0, 0, 0);
241 ReadFontInformation("AnsiVar", &AnsiVarFont, 12, 0, 0, 0, 0);
242 ReadFontInformation("System", &SystemFont, 16, 1, 0, 0, 0);
243 ReadFontInformation("SystemFixed", &SystemFixedFont, 12, 1, 0, 0, 0);
245 /* Initialize drivers */
247 DIB_Init(); /* always before X11DRV_Init() */
249 if( ! X11DRV_Init() )
250 return FALSE;
252 /* Create default palette */
254 /* DR well *this* palette can't be moveable (?) */
256 HPALETTE16 hpalette = PALETTE_Init();
257 if( !hpalette )
258 return FALSE;
259 StockObjects[DEFAULT_PALETTE] = (GDIOBJHDR *)GDI_HEAP_LOCK( hpalette );
262 return TRUE;
266 /***********************************************************************
267 * GDI_AllocObject
269 HGDIOBJ16 GDI_AllocObject( WORD size, WORD magic )
271 static DWORD count = 0;
272 GDIOBJHDR * obj;
273 HGDIOBJ16 handle;
274 if ( magic == DC_MAGIC || magic == METAFILE_DC_MAGIC )
275 handle = GDI_HEAP_ALLOC( size );
276 else
277 handle = GDI_HEAP_ALLOC_MOVEABLE( size );
278 if (!handle) return 0;
279 obj = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
280 obj->hNext = 0;
281 obj->wMagic = magic;
282 obj->dwCount = ++count;
283 GDI_HEAP_UNLOCK( handle );
284 return handle;
288 /***********************************************************************
289 * GDI_FreeObject
291 BOOL32 GDI_FreeObject( HGDIOBJ16 handle )
293 GDIOBJHDR * object;
295 /* Can't free stock objects */
296 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
297 return TRUE;
299 object = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
300 if (!object) return FALSE;
301 object->wMagic = 0; /* Mark it as invalid */
303 /* Free object */
305 GDI_HEAP_FREE( handle );
306 return TRUE;
309 /***********************************************************************
310 * GDI_GetObjPtr
312 * Return a pointer to the GDI object associated to the handle.
313 * Return NULL if the object has the wrong magic number.
314 * Movable GDI objects are locked in memory: it is up to the caller to unlock
315 * it after the caller is done with the pointer.
317 GDIOBJHDR * GDI_GetObjPtr( HGDIOBJ16 handle, WORD magic )
319 GDIOBJHDR * ptr = NULL;
321 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
322 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
323 else
324 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
325 if (!ptr) return NULL;
326 if ((magic != MAGIC_DONTCARE) && (ptr->wMagic != magic))
328 GDI_HEAP_UNLOCK( handle );
329 return NULL;
331 return ptr;
335 /***********************************************************************
336 * DeleteObject16 (GDI.69)
338 BOOL16 WINAPI DeleteObject16( HGDIOBJ16 obj )
340 return DeleteObject32( obj );
344 /***********************************************************************
345 * DeleteObject32 (GDI32.70)
347 BOOL32 WINAPI DeleteObject32( HGDIOBJ32 obj )
349 /* Check if object is valid */
351 GDIOBJHDR * header;
352 if (HIWORD(obj)) return FALSE;
353 if ((obj >= FIRST_STOCK_HANDLE) && (obj <= LAST_STOCK_HANDLE))
354 return TRUE;
355 if (!(header = (GDIOBJHDR *) GDI_HEAP_LOCK( obj ))) return FALSE;
357 TRACE(gdi, "%04x\n", obj );
359 /* Delete object */
361 switch(header->wMagic)
363 case PEN_MAGIC: return GDI_FreeObject( obj );
364 case BRUSH_MAGIC: return BRUSH_DeleteObject( obj, (BRUSHOBJ*)header );
365 case FONT_MAGIC: return GDI_FreeObject( obj );
366 case PALETTE_MAGIC: return PALETTE_DeleteObject(obj,(PALETTEOBJ*)header);
367 case BITMAP_MAGIC: return BITMAP_DeleteObject( obj, (BITMAPOBJ*)header);
368 case REGION_MAGIC: return REGION_DeleteObject( obj, (RGNOBJ*)header );
369 case DC_MAGIC: return DeleteDC32(obj);
370 case 0 :
371 WARN(gdi, "Already deleted\n");
372 break;
373 default:
374 WARN(gdi, "Unknown magic number (%d)\n",header->wMagic);
376 return FALSE;
379 /***********************************************************************
380 * GetStockObject16 (GDI.87)
382 HGDIOBJ16 WINAPI GetStockObject16( INT16 obj )
384 return (HGDIOBJ16)GetStockObject32( obj );
388 /***********************************************************************
389 * GetStockObject32 (GDI32.220)
391 HGDIOBJ32 WINAPI GetStockObject32( INT32 obj )
393 if ((obj < 0) || (obj >= NB_STOCK_OBJECTS)) return 0;
394 if (!StockObjects[obj]) return 0;
395 TRACE(gdi, "returning %d\n",
396 FIRST_STOCK_HANDLE + obj );
397 return (HGDIOBJ16)(FIRST_STOCK_HANDLE + obj);
401 /***********************************************************************
402 * GetObject16 (GDI.82)
404 INT16 WINAPI GetObject16( HANDLE16 handle, INT16 count, LPVOID buffer )
406 GDIOBJHDR * ptr = NULL;
407 INT16 result = 0;
408 TRACE(gdi, "%04x %d %p\n", handle, count, buffer );
409 if (!count) return 0;
411 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
412 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
413 else
414 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
415 if (!ptr) return 0;
417 switch(ptr->wMagic)
419 case PEN_MAGIC:
420 result = PEN_GetObject16( (PENOBJ *)ptr, count, buffer );
421 break;
422 case BRUSH_MAGIC:
423 result = BRUSH_GetObject16( (BRUSHOBJ *)ptr, count, buffer );
424 break;
425 case BITMAP_MAGIC:
426 result = BITMAP_GetObject16( (BITMAPOBJ *)ptr, count, buffer );
427 break;
428 case FONT_MAGIC:
429 result = FONT_GetObject16( (FONTOBJ *)ptr, count, buffer );
430 break;
431 case PALETTE_MAGIC:
432 result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer );
433 break;
435 GDI_HEAP_UNLOCK( handle );
436 return result;
440 /***********************************************************************
441 * GetObject32A (GDI32.204)
443 INT32 WINAPI GetObject32A( HANDLE32 handle, INT32 count, LPVOID buffer )
445 GDIOBJHDR * ptr = NULL;
446 INT32 result = 0;
447 TRACE(gdi, "%08x %d %p\n", handle, count, buffer );
448 if (!count) return 0;
450 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
451 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
452 else
453 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
454 if (!ptr) return 0;
456 switch(ptr->wMagic)
458 case PEN_MAGIC:
459 result = PEN_GetObject32( (PENOBJ *)ptr, count, buffer );
460 break;
461 case BRUSH_MAGIC:
462 result = BRUSH_GetObject32( (BRUSHOBJ *)ptr, count, buffer );
463 break;
464 case BITMAP_MAGIC:
465 result = BITMAP_GetObject32( (BITMAPOBJ *)ptr, count, buffer );
466 break;
467 case FONT_MAGIC:
468 result = FONT_GetObject32A( (FONTOBJ *)ptr, count, buffer );
469 break;
470 case PALETTE_MAGIC:
471 result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer );
472 break;
473 default:
474 FIXME(gdi, "Magic %04x not implemented\n",
475 ptr->wMagic );
476 break;
478 GDI_HEAP_UNLOCK( handle );
479 return result;
481 /***********************************************************************
482 * GetObject32W (GDI32.206)
484 INT32 WINAPI GetObject32W( HANDLE32 handle, INT32 count, LPVOID buffer )
486 GDIOBJHDR * ptr = NULL;
487 INT32 result = 0;
488 TRACE(gdi, "%08x %d %p\n", handle, count, buffer );
489 if (!count) return 0;
491 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
492 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
493 else
494 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
495 if (!ptr) return 0;
497 switch(ptr->wMagic)
499 case PEN_MAGIC:
500 result = PEN_GetObject32( (PENOBJ *)ptr, count, buffer );
501 break;
502 case BRUSH_MAGIC:
503 result = BRUSH_GetObject32( (BRUSHOBJ *)ptr, count, buffer );
504 break;
505 case BITMAP_MAGIC:
506 result = BITMAP_GetObject32( (BITMAPOBJ *)ptr, count, buffer );
507 break;
508 case FONT_MAGIC:
509 result = FONT_GetObject32W( (FONTOBJ *)ptr, count, buffer );
510 break;
511 case PALETTE_MAGIC:
512 result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer );
513 break;
514 default:
515 FIXME(gdi, "Magic %04x not implemented\n",
516 ptr->wMagic );
517 break;
519 GDI_HEAP_UNLOCK( handle );
520 return result;
523 /***********************************************************************
524 * GetObjectType (GDI32.205)
526 DWORD WINAPI GetObjectType( HANDLE32 handle )
528 GDIOBJHDR * ptr = NULL;
529 INT32 result = 0;
530 TRACE(gdi, "%08x\n", handle );
532 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
533 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
534 else
535 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
536 if (!ptr) return 0;
538 switch(ptr->wMagic)
540 case PEN_MAGIC:
541 result = OBJ_PEN;
542 break;
543 case BRUSH_MAGIC:
544 result = OBJ_BRUSH;
545 break;
546 case BITMAP_MAGIC:
547 result = OBJ_BITMAP;
548 break;
549 case FONT_MAGIC:
550 result = OBJ_FONT;
551 break;
552 case PALETTE_MAGIC:
553 result = OBJ_PAL;
554 break;
555 case REGION_MAGIC:
556 result = OBJ_REGION;
557 break;
558 case DC_MAGIC:
559 result = OBJ_DC;
560 break;
561 case META_DC_MAGIC:
562 result = OBJ_METADC;
563 break;
564 case METAFILE_MAGIC:
565 result = OBJ_METAFILE;
566 break;
567 case METAFILE_DC_MAGIC:
568 result = OBJ_METADC;
569 break;
571 default:
572 FIXME(gdi, "Magic %04x not implemented\n",
573 ptr->wMagic );
574 break;
576 GDI_HEAP_UNLOCK( handle );
577 return result;
580 /***********************************************************************
581 * GetCurrentObject (GDI32.166)
583 HANDLE32 WINAPI GetCurrentObject(HDC32 hdc,UINT32 type)
585 DC * dc = DC_GetDCPtr( hdc );
587 if (!dc)
588 return 0;
589 switch (type) {
590 case OBJ_PEN: return dc->w.hPen;
591 case OBJ_BRUSH: return dc->w.hBrush;
592 case OBJ_PAL: return dc->w.hPalette;
593 case OBJ_FONT: return dc->w.hFont;
594 case OBJ_BITMAP: return dc->w.hBitmap;
595 default:
596 /* the SDK only mentions those above */
597 WARN(gdi,"(%08x,%d): unknown type.\n",hdc,type);
598 return 0;
603 /***********************************************************************
604 * SelectObject16 (GDI.45)
606 HGDIOBJ16 WINAPI SelectObject16( HDC16 hdc, HGDIOBJ16 handle )
608 return (HGDIOBJ16)SelectObject32( hdc, handle );
612 /***********************************************************************
613 * SelectObject32 (GDI32.299)
615 HGDIOBJ32 WINAPI SelectObject32( HDC32 hdc, HGDIOBJ32 handle )
617 DC * dc = DC_GetDCPtr( hdc );
618 if (!dc || !dc->funcs->pSelectObject) return 0;
619 TRACE(gdi, "hdc=%04x %04x\n", hdc, handle );
620 return dc->funcs->pSelectObject( dc, handle );
624 /***********************************************************************
625 * UnrealizeObject16 (GDI.150)
627 BOOL16 WINAPI UnrealizeObject16( HGDIOBJ16 obj )
629 return UnrealizeObject32( obj );
633 /***********************************************************************
634 * UnrealizeObject (GDI32.358)
636 BOOL32 WINAPI UnrealizeObject32( HGDIOBJ32 obj )
638 BOOL32 result = TRUE;
639 /* Check if object is valid */
641 GDIOBJHDR * header = (GDIOBJHDR *) GDI_HEAP_LOCK( obj );
642 if (!header) return FALSE;
644 TRACE(gdi, "%04x\n", obj );
646 /* Unrealize object */
648 switch(header->wMagic)
650 case PALETTE_MAGIC:
651 result = PALETTE_UnrealizeObject( obj, (PALETTEOBJ *)header );
652 break;
654 case BRUSH_MAGIC:
655 /* Windows resets the brush origin. We don't need to. */
656 break;
658 GDI_HEAP_UNLOCK( obj );
659 return result;
663 /***********************************************************************
664 * EnumObjects16 (GDI.71)
666 INT16 WINAPI EnumObjects16( HDC16 hdc, INT16 nObjType,
667 GOBJENUMPROC16 lpEnumFunc, LPARAM lParam )
669 /* Solid colors to enumerate */
670 static const COLORREF solid_colors[] =
671 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
672 RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
673 RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
674 RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
675 RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
676 RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
677 RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
678 RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
681 INT16 i, retval = 0;
682 LOGPEN16 *pen;
683 LOGBRUSH16 *brush = NULL;
685 TRACE(gdi, "%04x %d %08lx %08lx\n",
686 hdc, nObjType, (DWORD)lpEnumFunc, lParam );
687 switch(nObjType)
689 case OBJ_PEN:
690 /* Enumerate solid pens */
691 if (!(pen = SEGPTR_NEW(LOGPEN16))) break;
692 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
694 pen->lopnStyle = PS_SOLID;
695 pen->lopnWidth.x = 1;
696 pen->lopnWidth.y = 0;
697 pen->lopnColor = solid_colors[i];
698 retval = lpEnumFunc( SEGPTR_GET(pen), lParam );
699 TRACE(gdi, "solid pen %08lx, ret=%d\n",
700 solid_colors[i], retval);
701 if (!retval) break;
703 SEGPTR_FREE(pen);
704 break;
706 case OBJ_BRUSH:
707 /* Enumerate solid brushes */
708 if (!(brush = SEGPTR_NEW(LOGBRUSH16))) break;
709 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
711 brush->lbStyle = BS_SOLID;
712 brush->lbColor = solid_colors[i];
713 brush->lbHatch = 0;
714 retval = lpEnumFunc( SEGPTR_GET(brush), lParam );
715 TRACE(gdi, "solid brush %08lx, ret=%d\n",
716 solid_colors[i], retval);
717 if (!retval) break;
720 /* Now enumerate hatched brushes */
721 if (retval) for (i = HS_HORIZONTAL; i <= HS_DIAGCROSS; i++)
723 brush->lbStyle = BS_HATCHED;
724 brush->lbColor = RGB(0,0,0);
725 brush->lbHatch = i;
726 retval = lpEnumFunc( SEGPTR_GET(brush), lParam );
727 TRACE(gdi, "hatched brush %d, ret=%d\n",
728 i, retval);
729 if (!retval) break;
731 SEGPTR_FREE(brush);
732 break;
734 default:
735 WARN(gdi, "(%d): Invalid type\n", nObjType );
736 break;
738 return retval;
742 /***********************************************************************
743 * EnumObjects32 (GDI32.89)
745 INT32 WINAPI EnumObjects32( HDC32 hdc, INT32 nObjType,
746 GOBJENUMPROC32 lpEnumFunc, LPARAM lParam )
748 /* Solid colors to enumerate */
749 static const COLORREF solid_colors[] =
750 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
751 RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
752 RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
753 RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
754 RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
755 RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
756 RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
757 RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
760 INT32 i, retval = 0;
761 LOGPEN32 pen;
762 LOGBRUSH32 brush;
764 TRACE(gdi, "%04x %d %08lx %08lx\n",
765 hdc, nObjType, (DWORD)lpEnumFunc, lParam );
766 switch(nObjType)
768 case OBJ_PEN:
769 /* Enumerate solid pens */
770 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
772 pen.lopnStyle = PS_SOLID;
773 pen.lopnWidth.x = 1;
774 pen.lopnWidth.y = 0;
775 pen.lopnColor = solid_colors[i];
776 retval = lpEnumFunc( &pen, lParam );
777 TRACE(gdi, "solid pen %08lx, ret=%d\n",
778 solid_colors[i], retval);
779 if (!retval) break;
781 break;
783 case OBJ_BRUSH:
784 /* Enumerate solid brushes */
785 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
787 brush.lbStyle = BS_SOLID;
788 brush.lbColor = solid_colors[i];
789 brush.lbHatch = 0;
790 retval = lpEnumFunc( &brush, lParam );
791 TRACE(gdi, "solid brush %08lx, ret=%d\n",
792 solid_colors[i], retval);
793 if (!retval) break;
796 /* Now enumerate hatched brushes */
797 if (retval) for (i = HS_HORIZONTAL; i <= HS_DIAGCROSS; i++)
799 brush.lbStyle = BS_HATCHED;
800 brush.lbColor = RGB(0,0,0);
801 brush.lbHatch = i;
802 retval = lpEnumFunc( &brush, lParam );
803 TRACE(gdi, "hatched brush %d, ret=%d\n",
804 i, retval);
805 if (!retval) break;
807 break;
809 default:
810 /* FIXME: implement Win32 types */
811 WARN( gdi, "(%d): Invalid type\n", nObjType );
812 break;
814 return retval;
818 /***********************************************************************
819 * IsGDIObject (GDI.462)
821 * returns type of object if valid (W95 system programming secrets p. 264-5)
823 BOOL16 WINAPI IsGDIObject( HGDIOBJ16 handle )
825 UINT16 magic = 0;
827 if (handle >= FIRST_STOCK_HANDLE )
829 switch (handle)
831 case STOCK_WHITE_BRUSH:
832 case STOCK_LTGRAY_BRUSH:
833 case STOCK_GRAY_BRUSH:
834 case STOCK_DKGRAY_BRUSH:
835 case STOCK_BLACK_BRUSH:
836 case STOCK_HOLLOW_BRUSH:
837 magic = BRUSH_MAGIC;
838 break;
840 case STOCK_WHITE_PEN:
841 case STOCK_BLACK_PEN:
842 case STOCK_NULL_PEN :
843 magic = PEN_MAGIC;
844 break;
846 case STOCK_OEM_FIXED_FONT:
847 case STOCK_ANSI_FIXED_FONT:
848 case STOCK_ANSI_VAR_FONT:
849 case STOCK_SYSTEM_FONT:
850 case STOCK_DEVICE_DEFAULT_FONT:
851 case STOCK_SYSTEM_FIXED_FONT:
852 case STOCK_DEFAULT_GUI_FONT:
853 magic = FONT_MAGIC;
854 break;
856 case STOCK_DEFAULT_PALETTE:
857 magic = PALETTE_MAGIC;
858 break;
861 else
863 GDIOBJHDR *object = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
864 if (object)
866 magic = object->wMagic;
867 GDI_HEAP_UNLOCK( handle );
871 if (magic >= PEN_MAGIC && magic <= METAFILE_DC_MAGIC)
872 return magic - PEN_MAGIC + 1;
873 else
874 return FALSE;
878 /***********************************************************************
879 * SetObjectOwner16 (GDI.461)
881 void WINAPI SetObjectOwner16( HGDIOBJ16 handle, HANDLE16 owner )
883 /* Nothing to do */
887 /***********************************************************************
888 * SetObjectOwner32 (GDI32.386)
890 void WINAPI SetObjectOwner32( HGDIOBJ32 handle, HANDLE32 owner )
892 /* Nothing to do */
895 /***********************************************************************
896 * MakeObjectPrivate (GDI.463)
898 void WINAPI MakeObjectPrivate( HGDIOBJ16 handle, BOOL16 private )
900 /* FIXME */
904 /***********************************************************************
905 * GdiFlush (GDI32.128)
907 BOOL32 WINAPI GdiFlush(void)
909 return TRUE; /* FIXME */
913 /***********************************************************************
914 * GdiGetBatchLimit (GDI32.129)
916 DWORD WINAPI GdiGetBatchLimit(void)
918 return 1; /* FIXME */
922 /***********************************************************************
923 * GdiSetBatchLimit (GDI32.139)
925 DWORD WINAPI GdiSetBatchLimit( DWORD limit )
927 return 1; /* FIXME */
931 /***********************************************************************
932 * GdiSeeGdiDo (GDI.452)
934 DWORD WINAPI GdiSeeGdiDo( WORD wReqType, WORD wParam1, WORD wParam2,
935 WORD wParam3 )
937 switch (wReqType)
939 case 0x0001: /* LocalAlloc */
940 return LOCAL_Alloc( GDI_HeapSel, wParam1, wParam3 );
941 case 0x0002: /* LocalFree */
942 return LOCAL_Free( GDI_HeapSel, wParam1 );
943 case 0x0003: /* LocalCompact */
944 return LOCAL_Compact( GDI_HeapSel, wParam3, 0 );
945 case 0x0103: /* LocalHeap */
946 return GDI_HeapSel;
947 default:
948 WARN(gdi, "(wReqType=%04x): Unknown\n", wReqType);
949 return (DWORD)-1;
953 /***********************************************************************
954 * MulDiv16 (GDI.128)
956 INT16 WINAPI MulDiv16( INT16 foo, INT16 bar, INT16 baz )
958 INT32 ret;
959 if (!baz) return -32768;
960 ret = (foo * bar) / baz;
961 if ((ret > 32767) || (ret < -32767)) return -32768;
962 return ret;
966 /***********************************************************************
967 * MulDiv32 (KERNEL32.391)
968 * RETURNS
969 * Result of multiplication and division
970 * -1: Overflow occurred or Divisor was 0
972 INT32 WINAPI MulDiv32(
973 INT32 nMultiplicand,
974 INT32 nMultiplier,
975 INT32 nDivisor
977 #if (SIZEOF_LONG_LONG >= 8)
978 long long ret;
979 if (!nDivisor) return -1;
980 ret = ((long long)nMultiplicand * nMultiplier) / nDivisor;
981 if ((ret > 2147483647) || (ret < -2147483647)) return -1;
982 return ret;
983 #else
984 if (!nDivisor) return -1;
985 return (nMultiplicand * nMultiplier) / nDivisor;
986 #endif