Added implementations for InterlockedExchangeAdd() and
[wine/multimedia.git] / objects / gdiobj.c
bloba81408caf8fd311f10459b9c36c7d555820689c8
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 if( ! X11DRV_Init() )
248 return FALSE;
250 /* Create default palette */
252 /* DR well *this* palette can't be moveable (?) */
254 HPALETTE16 hpalette = PALETTE_Init();
255 if( !hpalette )
256 return FALSE;
257 StockObjects[DEFAULT_PALETTE] = (GDIOBJHDR *)GDI_HEAP_LOCK( hpalette );
260 return TRUE;
264 /***********************************************************************
265 * GDI_AllocObject
267 HGDIOBJ16 GDI_AllocObject( WORD size, WORD magic )
269 static DWORD count = 0;
270 GDIOBJHDR * obj;
271 HGDIOBJ16 handle;
272 if ( magic == DC_MAGIC || magic == METAFILE_DC_MAGIC )
273 handle = GDI_HEAP_ALLOC( size );
274 else
275 handle = GDI_HEAP_ALLOC_MOVEABLE( size );
276 if (!handle) return 0;
277 obj = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
278 obj->hNext = 0;
279 obj->wMagic = magic;
280 obj->dwCount = ++count;
281 GDI_HEAP_UNLOCK( handle );
282 return handle;
286 /***********************************************************************
287 * GDI_FreeObject
289 BOOL32 GDI_FreeObject( HGDIOBJ16 handle )
291 GDIOBJHDR * object;
293 /* Can't free stock objects */
294 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
295 return TRUE;
297 object = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
298 if (!object) return FALSE;
299 object->wMagic = 0; /* Mark it as invalid */
301 /* Free object */
303 GDI_HEAP_FREE( handle );
304 return TRUE;
307 /***********************************************************************
308 * GDI_GetObjPtr
310 * Return a pointer to the GDI object associated to the handle.
311 * Return NULL if the object has the wrong magic number.
312 * Movable GDI objects are locked in memory: it is up to the caller to unlock
313 * it after the caller is done with the pointer.
315 GDIOBJHDR * GDI_GetObjPtr( HGDIOBJ16 handle, WORD magic )
317 GDIOBJHDR * ptr = NULL;
319 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
320 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
321 else
322 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
323 if (!ptr) return NULL;
324 if ((magic != MAGIC_DONTCARE) && (ptr->wMagic != magic))
326 GDI_HEAP_UNLOCK( handle );
327 return NULL;
329 return ptr;
333 /***********************************************************************
334 * DeleteObject16 (GDI.69)
336 BOOL16 WINAPI DeleteObject16( HGDIOBJ16 obj )
338 return DeleteObject32( obj );
342 /***********************************************************************
343 * DeleteObject32 (GDI32.70)
345 BOOL32 WINAPI DeleteObject32( HGDIOBJ32 obj )
347 /* Check if object is valid */
349 GDIOBJHDR * header;
350 if (HIWORD(obj)) return FALSE;
351 if ((obj >= FIRST_STOCK_HANDLE) && (obj <= LAST_STOCK_HANDLE))
352 return TRUE;
353 if (!(header = (GDIOBJHDR *) GDI_HEAP_LOCK( obj ))) return FALSE;
355 TRACE(gdi, "%04x\n", obj );
357 /* Delete object */
359 switch(header->wMagic)
361 case PEN_MAGIC: return GDI_FreeObject( obj );
362 case BRUSH_MAGIC: return BRUSH_DeleteObject( obj, (BRUSHOBJ*)header );
363 case FONT_MAGIC: return GDI_FreeObject( obj );
364 case PALETTE_MAGIC: return PALETTE_DeleteObject(obj,(PALETTEOBJ*)header);
365 case BITMAP_MAGIC: return BITMAP_DeleteObject( obj, (BITMAPOBJ*)header);
366 case REGION_MAGIC: return REGION_DeleteObject( obj, (RGNOBJ*)header );
367 case DC_MAGIC: return DeleteDC32(obj);
368 case 0 :
369 WARN(gdi, "Already deleted\n");
370 break;
371 default:
372 WARN(gdi, "Unknown magic number (%d)\n",header->wMagic);
374 return FALSE;
377 /***********************************************************************
378 * GetStockObject16 (GDI.87)
380 HGDIOBJ16 WINAPI GetStockObject16( INT16 obj )
382 return (HGDIOBJ16)GetStockObject32( obj );
386 /***********************************************************************
387 * GetStockObject32 (GDI32.220)
389 HGDIOBJ32 WINAPI GetStockObject32( INT32 obj )
391 if ((obj < 0) || (obj >= NB_STOCK_OBJECTS)) return 0;
392 if (!StockObjects[obj]) return 0;
393 TRACE(gdi, "returning %d\n",
394 FIRST_STOCK_HANDLE + obj );
395 return (HGDIOBJ16)(FIRST_STOCK_HANDLE + obj);
399 /***********************************************************************
400 * GetObject16 (GDI.82)
402 INT16 WINAPI GetObject16( HANDLE16 handle, INT16 count, LPVOID buffer )
404 GDIOBJHDR * ptr = NULL;
405 INT16 result = 0;
406 TRACE(gdi, "%04x %d %p\n", handle, count, buffer );
407 if (!count) return 0;
409 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
410 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
411 else
412 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
413 if (!ptr) return 0;
415 switch(ptr->wMagic)
417 case PEN_MAGIC:
418 result = PEN_GetObject16( (PENOBJ *)ptr, count, buffer );
419 break;
420 case BRUSH_MAGIC:
421 result = BRUSH_GetObject16( (BRUSHOBJ *)ptr, count, buffer );
422 break;
423 case BITMAP_MAGIC:
424 result = BITMAP_GetObject16( (BITMAPOBJ *)ptr, count, buffer );
425 break;
426 case FONT_MAGIC:
427 result = FONT_GetObject16( (FONTOBJ *)ptr, count, buffer );
428 break;
429 case PALETTE_MAGIC:
430 result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer );
431 break;
433 GDI_HEAP_UNLOCK( handle );
434 return result;
438 /***********************************************************************
439 * GetObject32A (GDI32.204)
441 INT32 WINAPI GetObject32A( HANDLE32 handle, INT32 count, LPVOID buffer )
443 GDIOBJHDR * ptr = NULL;
444 INT32 result = 0;
445 TRACE(gdi, "%08x %d %p\n", handle, count, buffer );
446 if (!count) return 0;
448 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
449 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
450 else
451 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
452 if (!ptr) return 0;
454 switch(ptr->wMagic)
456 case PEN_MAGIC:
457 result = PEN_GetObject32( (PENOBJ *)ptr, count, buffer );
458 break;
459 case BRUSH_MAGIC:
460 result = BRUSH_GetObject32( (BRUSHOBJ *)ptr, count, buffer );
461 break;
462 case BITMAP_MAGIC:
463 result = BITMAP_GetObject32( (BITMAPOBJ *)ptr, count, buffer );
464 break;
465 case FONT_MAGIC:
466 result = FONT_GetObject32A( (FONTOBJ *)ptr, count, buffer );
467 break;
468 case PALETTE_MAGIC:
469 result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer );
470 break;
471 default:
472 FIXME(gdi, "Magic %04x not implemented\n",
473 ptr->wMagic );
474 break;
476 GDI_HEAP_UNLOCK( handle );
477 return result;
479 /***********************************************************************
480 * GetObject32W (GDI32.206)
482 INT32 WINAPI GetObject32W( HANDLE32 handle, INT32 count, LPVOID buffer )
484 GDIOBJHDR * ptr = NULL;
485 INT32 result = 0;
486 TRACE(gdi, "%08x %d %p\n", handle, count, buffer );
487 if (!count) return 0;
489 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
490 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
491 else
492 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
493 if (!ptr) return 0;
495 switch(ptr->wMagic)
497 case PEN_MAGIC:
498 result = PEN_GetObject32( (PENOBJ *)ptr, count, buffer );
499 break;
500 case BRUSH_MAGIC:
501 result = BRUSH_GetObject32( (BRUSHOBJ *)ptr, count, buffer );
502 break;
503 case BITMAP_MAGIC:
504 result = BITMAP_GetObject32( (BITMAPOBJ *)ptr, count, buffer );
505 break;
506 case FONT_MAGIC:
507 result = FONT_GetObject32W( (FONTOBJ *)ptr, count, buffer );
508 break;
509 case PALETTE_MAGIC:
510 result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer );
511 break;
512 default:
513 FIXME(gdi, "Magic %04x not implemented\n",
514 ptr->wMagic );
515 break;
517 GDI_HEAP_UNLOCK( handle );
518 return result;
521 /***********************************************************************
522 * GetObjectType (GDI32.205)
524 DWORD WINAPI GetObjectType( HANDLE32 handle )
526 GDIOBJHDR * ptr = NULL;
527 INT32 result = 0;
528 TRACE(gdi, "%08x\n", handle );
530 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
531 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
532 else
533 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
534 if (!ptr) return 0;
536 switch(ptr->wMagic)
538 case PEN_MAGIC:
539 result = OBJ_PEN;
540 break;
541 case BRUSH_MAGIC:
542 result = OBJ_BRUSH;
543 break;
544 case BITMAP_MAGIC:
545 result = OBJ_BITMAP;
546 break;
547 case FONT_MAGIC:
548 result = OBJ_FONT;
549 break;
550 case PALETTE_MAGIC:
551 result = OBJ_PAL;
552 break;
553 case REGION_MAGIC:
554 result = OBJ_REGION;
555 break;
556 case DC_MAGIC:
557 result = OBJ_DC;
558 break;
559 case META_DC_MAGIC:
560 result = OBJ_METADC;
561 break;
562 case METAFILE_MAGIC:
563 result = OBJ_METAFILE;
564 break;
565 case METAFILE_DC_MAGIC:
566 result = OBJ_METADC;
567 break;
569 default:
570 FIXME(gdi, "Magic %04x not implemented\n",
571 ptr->wMagic );
572 break;
574 GDI_HEAP_UNLOCK( handle );
575 return result;
578 /***********************************************************************
579 * GetCurrentObject (GDI32.166)
581 HANDLE32 WINAPI GetCurrentObject(HDC32 hdc,UINT32 type)
583 DC * dc = DC_GetDCPtr( hdc );
585 if (!dc)
586 return 0;
587 switch (type) {
588 case OBJ_PEN: return dc->w.hPen;
589 case OBJ_BRUSH: return dc->w.hBrush;
590 case OBJ_PAL: return dc->w.hPalette;
591 case OBJ_FONT: return dc->w.hFont;
592 case OBJ_BITMAP: return dc->w.hBitmap;
593 default:
594 /* the SDK only mentions those above */
595 WARN(gdi,"(%08x,%d): unknown type.\n",hdc,type);
596 return 0;
601 /***********************************************************************
602 * SelectObject16 (GDI.45)
604 HGDIOBJ16 WINAPI SelectObject16( HDC16 hdc, HGDIOBJ16 handle )
606 return (HGDIOBJ16)SelectObject32( hdc, handle );
610 /***********************************************************************
611 * SelectObject32 (GDI32.299)
613 HGDIOBJ32 WINAPI SelectObject32( HDC32 hdc, HGDIOBJ32 handle )
615 DC * dc = DC_GetDCPtr( hdc );
616 if (!dc || !dc->funcs->pSelectObject) return 0;
617 TRACE(gdi, "hdc=%04x %04x\n", hdc, handle );
618 return dc->funcs->pSelectObject( dc, handle );
622 /***********************************************************************
623 * UnrealizeObject16 (GDI.150)
625 BOOL16 WINAPI UnrealizeObject16( HGDIOBJ16 obj )
627 return UnrealizeObject32( obj );
631 /***********************************************************************
632 * UnrealizeObject (GDI32.358)
634 BOOL32 WINAPI UnrealizeObject32( HGDIOBJ32 obj )
636 BOOL32 result = TRUE;
637 /* Check if object is valid */
639 GDIOBJHDR * header = (GDIOBJHDR *) GDI_HEAP_LOCK( obj );
640 if (!header) return FALSE;
642 TRACE(gdi, "%04x\n", obj );
644 /* Unrealize object */
646 switch(header->wMagic)
648 case PALETTE_MAGIC:
649 result = PALETTE_UnrealizeObject( obj, (PALETTEOBJ *)header );
650 break;
652 case BRUSH_MAGIC:
653 /* Windows resets the brush origin. We don't need to. */
654 break;
656 GDI_HEAP_UNLOCK( obj );
657 return result;
661 /***********************************************************************
662 * EnumObjects16 (GDI.71)
664 INT16 WINAPI EnumObjects16( HDC16 hdc, INT16 nObjType,
665 GOBJENUMPROC16 lpEnumFunc, LPARAM lParam )
667 /* Solid colors to enumerate */
668 static const COLORREF solid_colors[] =
669 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
670 RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
671 RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
672 RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
673 RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
674 RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
675 RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
676 RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
679 INT16 i, retval = 0;
680 LOGPEN16 *pen;
681 LOGBRUSH16 *brush = NULL;
683 TRACE(gdi, "%04x %d %08lx %08lx\n",
684 hdc, nObjType, (DWORD)lpEnumFunc, lParam );
685 switch(nObjType)
687 case OBJ_PEN:
688 /* Enumerate solid pens */
689 if (!(pen = SEGPTR_NEW(LOGPEN16))) break;
690 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
692 pen->lopnStyle = PS_SOLID;
693 pen->lopnWidth.x = 1;
694 pen->lopnWidth.y = 0;
695 pen->lopnColor = solid_colors[i];
696 retval = lpEnumFunc( SEGPTR_GET(pen), lParam );
697 TRACE(gdi, "solid pen %08lx, ret=%d\n",
698 solid_colors[i], retval);
699 if (!retval) break;
701 SEGPTR_FREE(pen);
702 break;
704 case OBJ_BRUSH:
705 /* Enumerate solid brushes */
706 if (!(brush = SEGPTR_NEW(LOGBRUSH16))) break;
707 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
709 brush->lbStyle = BS_SOLID;
710 brush->lbColor = solid_colors[i];
711 brush->lbHatch = 0;
712 retval = lpEnumFunc( SEGPTR_GET(brush), lParam );
713 TRACE(gdi, "solid brush %08lx, ret=%d\n",
714 solid_colors[i], retval);
715 if (!retval) break;
718 /* Now enumerate hatched brushes */
719 if (retval) for (i = HS_HORIZONTAL; i <= HS_DIAGCROSS; i++)
721 brush->lbStyle = BS_HATCHED;
722 brush->lbColor = RGB(0,0,0);
723 brush->lbHatch = i;
724 retval = lpEnumFunc( SEGPTR_GET(brush), lParam );
725 TRACE(gdi, "hatched brush %d, ret=%d\n",
726 i, retval);
727 if (!retval) break;
729 SEGPTR_FREE(brush);
730 break;
732 default:
733 WARN(gdi, "(%d): Invalid type\n", nObjType );
734 break;
736 return retval;
740 /***********************************************************************
741 * EnumObjects32 (GDI32.89)
743 INT32 WINAPI EnumObjects32( HDC32 hdc, INT32 nObjType,
744 GOBJENUMPROC32 lpEnumFunc, LPARAM lParam )
746 /* Solid colors to enumerate */
747 static const COLORREF solid_colors[] =
748 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
749 RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
750 RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
751 RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
752 RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
753 RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
754 RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
755 RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
758 INT32 i, retval = 0;
759 LOGPEN32 pen;
760 LOGBRUSH32 brush;
762 TRACE(gdi, "%04x %d %08lx %08lx\n",
763 hdc, nObjType, (DWORD)lpEnumFunc, lParam );
764 switch(nObjType)
766 case OBJ_PEN:
767 /* Enumerate solid pens */
768 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
770 pen.lopnStyle = PS_SOLID;
771 pen.lopnWidth.x = 1;
772 pen.lopnWidth.y = 0;
773 pen.lopnColor = solid_colors[i];
774 retval = lpEnumFunc( &pen, lParam );
775 TRACE(gdi, "solid pen %08lx, ret=%d\n",
776 solid_colors[i], retval);
777 if (!retval) break;
779 break;
781 case OBJ_BRUSH:
782 /* Enumerate solid brushes */
783 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
785 brush.lbStyle = BS_SOLID;
786 brush.lbColor = solid_colors[i];
787 brush.lbHatch = 0;
788 retval = lpEnumFunc( &brush, lParam );
789 TRACE(gdi, "solid brush %08lx, ret=%d\n",
790 solid_colors[i], retval);
791 if (!retval) break;
794 /* Now enumerate hatched brushes */
795 if (retval) for (i = HS_HORIZONTAL; i <= HS_DIAGCROSS; i++)
797 brush.lbStyle = BS_HATCHED;
798 brush.lbColor = RGB(0,0,0);
799 brush.lbHatch = i;
800 retval = lpEnumFunc( &brush, lParam );
801 TRACE(gdi, "hatched brush %d, ret=%d\n",
802 i, retval);
803 if (!retval) break;
805 break;
807 default:
808 /* FIXME: implement Win32 types */
809 WARN( gdi, "(%d): Invalid type\n", nObjType );
810 break;
812 return retval;
816 /***********************************************************************
817 * IsGDIObject (GDI.462)
819 * returns type of object if valid (W95 system programming secrets p. 264-5)
821 BOOL16 WINAPI IsGDIObject( HGDIOBJ16 handle )
823 UINT16 magic = 0;
825 if (handle >= FIRST_STOCK_HANDLE )
827 switch (handle)
829 case STOCK_WHITE_BRUSH:
830 case STOCK_LTGRAY_BRUSH:
831 case STOCK_GRAY_BRUSH:
832 case STOCK_DKGRAY_BRUSH:
833 case STOCK_BLACK_BRUSH:
834 case STOCK_HOLLOW_BRUSH:
835 magic = BRUSH_MAGIC;
836 break;
838 case STOCK_WHITE_PEN:
839 case STOCK_BLACK_PEN:
840 case STOCK_NULL_PEN :
841 magic = PEN_MAGIC;
842 break;
844 case STOCK_OEM_FIXED_FONT:
845 case STOCK_ANSI_FIXED_FONT:
846 case STOCK_ANSI_VAR_FONT:
847 case STOCK_SYSTEM_FONT:
848 case STOCK_DEVICE_DEFAULT_FONT:
849 case STOCK_SYSTEM_FIXED_FONT:
850 case STOCK_DEFAULT_GUI_FONT:
851 magic = FONT_MAGIC;
852 break;
854 case STOCK_DEFAULT_PALETTE:
855 magic = PALETTE_MAGIC;
856 break;
859 else
861 GDIOBJHDR *object = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
862 if (object)
864 magic = object->wMagic;
865 GDI_HEAP_UNLOCK( handle );
869 if (magic >= PEN_MAGIC && magic <= METAFILE_DC_MAGIC)
870 return magic - PEN_MAGIC + 1;
871 else
872 return FALSE;
876 /***********************************************************************
877 * SetObjectOwner16 (GDI.461)
879 void WINAPI SetObjectOwner16( HGDIOBJ16 handle, HANDLE16 owner )
881 /* Nothing to do */
885 /***********************************************************************
886 * SetObjectOwner32 (GDI32.386)
888 void WINAPI SetObjectOwner32( HGDIOBJ32 handle, HANDLE32 owner )
890 /* Nothing to do */
893 /***********************************************************************
894 * MakeObjectPrivate (GDI.463)
896 void WINAPI MakeObjectPrivate( HGDIOBJ16 handle, BOOL16 private )
898 /* FIXME */
902 /***********************************************************************
903 * GdiFlush (GDI32.128)
905 BOOL32 WINAPI GdiFlush(void)
907 return TRUE; /* FIXME */
911 /***********************************************************************
912 * GdiGetBatchLimit (GDI32.129)
914 DWORD WINAPI GdiGetBatchLimit(void)
916 return 1; /* FIXME */
920 /***********************************************************************
921 * GdiSetBatchLimit (GDI32.139)
923 DWORD WINAPI GdiSetBatchLimit( DWORD limit )
925 return 1; /* FIXME */
929 /***********************************************************************
930 * GdiSeeGdiDo (GDI.452)
932 DWORD WINAPI GdiSeeGdiDo( WORD wReqType, WORD wParam1, WORD wParam2,
933 WORD wParam3 )
935 switch (wReqType)
937 case 0x0001: /* LocalAlloc */
938 return LOCAL_Alloc( GDI_HeapSel, wParam1, wParam3 );
939 case 0x0002: /* LocalFree */
940 return LOCAL_Free( GDI_HeapSel, wParam1 );
941 case 0x0003: /* LocalCompact */
942 return LOCAL_Compact( GDI_HeapSel, wParam3, 0 );
943 case 0x0103: /* LocalHeap */
944 return GDI_HeapSel;
945 default:
946 WARN(gdi, "(wReqType=%04x): Unknown\n", wReqType);
947 return (DWORD)-1;
951 /***********************************************************************
952 * MulDiv16 (GDI.128)
954 INT16 WINAPI MulDiv16( INT16 foo, INT16 bar, INT16 baz )
956 INT32 ret;
957 if (!baz) return -32768;
958 ret = (foo * bar) / baz;
959 if ((ret > 32767) || (ret < -32767)) return -32768;
960 return ret;
964 /***********************************************************************
965 * MulDiv32 (KERNEL32.391)
966 * RETURNS
967 * Result of multiplication and division
968 * -1: Overflow occurred or Divisor was 0
970 INT32 WINAPI MulDiv32(
971 INT32 nMultiplicand,
972 INT32 nMultiplier,
973 INT32 nDivisor
975 #if (SIZEOF_LONG_LONG >= 8)
976 long long ret;
977 if (!nDivisor) return -1;
978 ret = ((long long)nMultiplicand * nMultiplier) / nDivisor;
979 if ((ret > 2147483647) || (ret < -2147483647)) return -1;
980 return ret;
981 #else
982 if (!nDivisor) return -1;
983 return (nMultiplicand * nMultiplier) / nDivisor;
984 #endif