Separated stuff for shv background contextmenu to separate file.
[wine.git] / objects / gdiobj.c
blobee50d78ef39f306189a4f9dec4d415abc0b0f83b
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>
17 #include "bitmap.h"
18 #include "brush.h"
19 #include "dc.h"
20 #include "font.h"
21 #include "heap.h"
22 #include "options.h"
23 #include "palette.h"
24 #include "pen.h"
25 #include "region.h"
26 #include "debugtools.h"
27 #include "gdi.h"
29 DEFAULT_DEBUG_CHANNEL(gdi)
31 /**********************************************************************/
33 GDI_DRIVER *GDI_Driver = NULL;
35 /***********************************************************************
36 * GDI stock objects
39 static BRUSHOBJ WhiteBrush =
41 { 0, BRUSH_MAGIC, 1 }, /* header */
42 { BS_SOLID, RGB(255,255,255), 0 } /* logbrush */
45 static BRUSHOBJ LtGrayBrush =
47 { 0, BRUSH_MAGIC, 1 }, /* header */
48 /* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
49 { BS_SOLID, RGB(192,192,192), 0 } /* logbrush */
52 static BRUSHOBJ GrayBrush =
54 { 0, BRUSH_MAGIC, 1 }, /* header */
55 /* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
56 { BS_SOLID, RGB(128,128,128), 0 } /* logbrush */
59 static BRUSHOBJ DkGrayBrush =
61 { 0, BRUSH_MAGIC, 1 }, /* header */
62 /* This is BS_HATCHED, for 1 bitperpixel. This makes the spray work in pbrush */
63 /* NB_HATCH_STYLES is an index into HatchBrushes */
64 { BS_HATCHED, RGB(0,0,0), NB_HATCH_STYLES } /* logbrush */
67 static BRUSHOBJ BlackBrush =
69 { 0, BRUSH_MAGIC, 1 }, /* header */
70 { BS_SOLID, RGB(0,0,0), 0 } /* logbrush */
73 static BRUSHOBJ NullBrush =
75 { 0, BRUSH_MAGIC, 1 }, /* header */
76 { BS_NULL, 0, 0 } /* logbrush */
79 static PENOBJ WhitePen =
81 { 0, PEN_MAGIC, 1 }, /* header */
82 { PS_SOLID, { 1, 0 }, RGB(255,255,255) } /* logpen */
85 static PENOBJ BlackPen =
87 { 0, PEN_MAGIC, 1 }, /* header */
88 { PS_SOLID, { 1, 0 }, RGB(0,0,0) } /* logpen */
91 static PENOBJ NullPen =
93 { 0, PEN_MAGIC, 1 }, /* header */
94 { PS_NULL, { 1, 0 }, 0 } /* logpen */
97 static FONTOBJ OEMFixedFont =
99 { 0, FONT_MAGIC, 1 }, /* header */
100 { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, OEM_CHARSET,
101 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" }
103 /* Filler to make the location counter dword aligned again. This is necessary
104 since (a) FONTOBJ is packed, (b) gcc places initialised variables in the code
105 segment, and (c) Solaris assembler is stupid. */
106 static UINT16 align_OEMFixedFont = 1;
108 static FONTOBJ AnsiFixedFont =
110 { 0, FONT_MAGIC, 1 }, /* header */
111 { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
112 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" }
114 static UINT16 align_AnsiFixedFont = 1;
116 static FONTOBJ AnsiVarFont =
118 { 0, FONT_MAGIC, 1 }, /* header */
119 { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
120 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "MS Sans Serif" }
122 static UINT16 align_AnsiVarFont = 1;
124 static FONTOBJ SystemFont =
126 { 0, FONT_MAGIC, 1 },
127 { 16, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, ANSI_CHARSET,
128 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "System" }
130 static UINT16 align_SystemFont = 1;
132 static FONTOBJ DeviceDefaultFont =
134 { 0, FONT_MAGIC, 1 }, /* header */
135 { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
136 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "" }
138 static UINT16 align_DeviceDefaultFont = 1;
140 static FONTOBJ SystemFixedFont =
142 { 0, FONT_MAGIC, 1 }, /* header */
143 { 12, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, ANSI_CHARSET,
144 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" }
146 static UINT16 align_SystemFixedFont = 1;
148 /* FIXME: Is this correct? */
149 static FONTOBJ DefaultGuiFont =
151 { 9, FONT_MAGIC, 1 }, /* header */
152 { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
153 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "MS Sans Serif" }
155 static UINT16 align_DefaultGuiFont = 1;
158 static GDIOBJHDR * StockObjects[NB_STOCK_OBJECTS] =
160 (GDIOBJHDR *) &WhiteBrush,
161 (GDIOBJHDR *) &LtGrayBrush,
162 (GDIOBJHDR *) &GrayBrush,
163 (GDIOBJHDR *) &DkGrayBrush,
164 (GDIOBJHDR *) &BlackBrush,
165 (GDIOBJHDR *) &NullBrush,
166 (GDIOBJHDR *) &WhitePen,
167 (GDIOBJHDR *) &BlackPen,
168 (GDIOBJHDR *) &NullPen,
169 NULL,
170 (GDIOBJHDR *) &OEMFixedFont,
171 (GDIOBJHDR *) &AnsiFixedFont,
172 (GDIOBJHDR *) &AnsiVarFont,
173 (GDIOBJHDR *) &SystemFont,
174 (GDIOBJHDR *) &DeviceDefaultFont,
175 NULL, /* DEFAULT_PALETTE created by PALETTE_Init */
176 (GDIOBJHDR *) &SystemFixedFont,
177 (GDIOBJHDR *) &DefaultGuiFont
180 /******************************************************************************
182 * void ReadFontInformation(
183 * char const *fontName,
184 * FONTOBJ *font,
185 * int defHeight,
186 * int defBold,
187 * int defItalic,
188 * int defUnderline,
189 * int defStrikeOut )
191 * ReadFontInformation() checks the Wine configuration file's Tweak.Fonts
192 * section for entries containing fontName.Height, fontName.Bold, etc.,
193 * where fontName is the name specified in the call (e.g., "System"). It
194 * attempts to be user friendly by accepting 'n', 'N', 'f', 'F', or '0' as
195 * the first character in the boolean attributes (bold, italic, and
196 * underline).
197 *****************************************************************************/
199 static void ReadFontInformation(
200 char const *fontName,
201 FONTOBJ *font,
202 int defHeight,
203 int defBold,
204 int defItalic,
205 int defUnderline,
206 int defStrikeOut )
208 char key[256];
210 sprintf(key, "%s.Height", fontName);
211 font->logfont.lfHeight =
212 PROFILE_GetWineIniInt("Tweak.Fonts", key, defHeight);
214 sprintf(key, "%s.Bold", fontName);
215 font->logfont.lfWeight =
216 (PROFILE_GetWineIniBool("Tweak.Fonts", key, defBold)) ?
217 FW_BOLD : FW_NORMAL;
219 sprintf(key, "%s.Italic", fontName);
220 font->logfont.lfItalic =
221 PROFILE_GetWineIniBool("Tweak.Fonts", key, defItalic);
223 sprintf(key, "%s.Underline", fontName);
224 font->logfont.lfUnderline =
225 PROFILE_GetWineIniBool("Tweak.Fonts", key, defUnderline);
227 sprintf(key, "%s.StrikeOut", fontName);
228 font->logfont.lfStrikeOut =
229 PROFILE_GetWineIniBool("Tweak.Fonts", key, defStrikeOut);
231 return;
235 /***********************************************************************
236 * GDI_Init
238 * GDI initialization.
240 BOOL GDI_Init(void)
242 /* Kill some warnings. */
243 (void)align_OEMFixedFont;
244 (void)align_AnsiFixedFont;
245 (void)align_AnsiVarFont;
246 (void)align_SystemFont;
247 (void)align_DeviceDefaultFont;
248 (void)align_SystemFixedFont;
249 (void)align_DefaultGuiFont;
251 /* TWEAK: Initialize font hints */
252 ReadFontInformation("OEMFixed", &OEMFixedFont, 12, 0, 0, 0, 0);
253 ReadFontInformation("AnsiFixed", &AnsiFixedFont, 12, 0, 0, 0, 0);
254 ReadFontInformation("AnsiVar", &AnsiVarFont, 12, 0, 0, 0, 0);
255 ReadFontInformation("System", &SystemFont, 16, 1, 0, 0, 0);
256 ReadFontInformation("SystemFixed", &SystemFixedFont, 12, 1, 0, 0, 0);
258 /* Initialize drivers */
260 #ifndef X_DISPLAY_MISSING
261 GDI_Driver = &X11DRV_GDI_Driver;
262 #else /* !defined(X_DISPLAY_MISSING) */
263 GDI_Driver = &TTYDRV_GDI_Driver;
264 #endif /* !defined(X_DISPLAY_MISSING */
266 GDI_Driver->pInitialize();
268 /* Create default palette */
270 /* DR well *this* palette can't be moveable (?) */
272 HPALETTE16 hpalette = PALETTE_Init();
273 if( !hpalette )
274 return FALSE;
275 StockObjects[DEFAULT_PALETTE] = (GDIOBJHDR *)GDI_HEAP_LOCK( hpalette );
278 return TRUE;
282 /***********************************************************************
283 * GDI_AllocObject
285 HGDIOBJ16 GDI_AllocObject( WORD size, WORD magic )
287 static DWORD count = 0;
288 GDIOBJHDR * obj;
289 HGDIOBJ16 handle;
290 if ( magic == DC_MAGIC || magic == METAFILE_DC_MAGIC )
291 handle = GDI_HEAP_ALLOC( size );
292 else
293 handle = GDI_HEAP_ALLOC_MOVEABLE( size );
294 if (!handle) return 0;
295 obj = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
296 obj->hNext = 0;
297 obj->wMagic = magic;
298 obj->dwCount = ++count;
299 GDI_HEAP_UNLOCK( handle );
300 return handle;
304 /***********************************************************************
305 * GDI_FreeObject
307 BOOL GDI_FreeObject( HGDIOBJ16 handle )
309 GDIOBJHDR * object;
311 /* Can't free stock objects */
312 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
313 return TRUE;
315 object = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
316 if (!object) return FALSE;
317 object->wMagic = 0; /* Mark it as invalid */
319 /* Free object */
321 GDI_HEAP_FREE( handle );
322 return TRUE;
325 /***********************************************************************
326 * GDI_GetObjPtr
328 * Return a pointer to the GDI object associated to the handle.
329 * Return NULL if the object has the wrong magic number.
330 * Movable GDI objects are locked in memory: it is up to the caller to unlock
331 * it after the caller is done with the pointer.
333 GDIOBJHDR * GDI_GetObjPtr( HGDIOBJ16 handle, WORD magic )
335 GDIOBJHDR * ptr = NULL;
337 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
338 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
339 else
340 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
341 if (!ptr) return NULL;
342 if ((magic != MAGIC_DONTCARE) && (ptr->wMagic != magic))
344 GDI_HEAP_UNLOCK( handle );
345 return NULL;
347 return ptr;
351 /***********************************************************************
352 * DeleteObject16 (GDI.69)
354 BOOL16 WINAPI DeleteObject16( HGDIOBJ16 obj )
356 return DeleteObject( obj );
360 /***********************************************************************
361 * DeleteObject32 (GDI32.70)
363 BOOL WINAPI DeleteObject( HGDIOBJ obj )
365 /* Check if object is valid */
367 GDIOBJHDR * header;
368 if (HIWORD(obj)) return FALSE;
369 if ((obj >= FIRST_STOCK_HANDLE) && (obj <= LAST_STOCK_HANDLE))
370 return TRUE;
371 if (!(header = (GDIOBJHDR *) GDI_HEAP_LOCK( obj ))) return FALSE;
373 TRACE("%04x\n", obj );
375 /* Delete object */
377 switch(header->wMagic)
379 case PEN_MAGIC: return GDI_FreeObject( obj );
380 case BRUSH_MAGIC: return BRUSH_DeleteObject( obj, (BRUSHOBJ*)header );
381 case FONT_MAGIC: return GDI_FreeObject( obj );
382 case PALETTE_MAGIC: return PALETTE_DeleteObject(obj,(PALETTEOBJ*)header);
383 case BITMAP_MAGIC: return BITMAP_DeleteObject( obj, (BITMAPOBJ*)header);
384 case REGION_MAGIC: return REGION_DeleteObject( obj, (RGNOBJ*)header );
385 case DC_MAGIC: return DeleteDC(obj);
386 case 0 :
387 WARN("Already deleted\n");
388 break;
389 default:
390 WARN("Unknown magic number (%d)\n",header->wMagic);
392 return FALSE;
395 /***********************************************************************
396 * GetStockObject16 (GDI.87)
398 HGDIOBJ16 WINAPI GetStockObject16( INT16 obj )
400 return (HGDIOBJ16)GetStockObject( obj );
404 /***********************************************************************
405 * GetStockObject32 (GDI32.220)
407 HGDIOBJ WINAPI GetStockObject( INT obj )
409 if ((obj < 0) || (obj >= NB_STOCK_OBJECTS)) return 0;
410 if (!StockObjects[obj]) return 0;
411 TRACE("returning %d\n",
412 FIRST_STOCK_HANDLE + obj );
413 return (HGDIOBJ16)(FIRST_STOCK_HANDLE + obj);
417 /***********************************************************************
418 * GetObject16 (GDI.82)
420 INT16 WINAPI GetObject16( HANDLE16 handle, INT16 count, LPVOID buffer )
422 GDIOBJHDR * ptr = NULL;
423 INT16 result = 0;
424 TRACE("%04x %d %p\n", handle, count, buffer );
425 if (!count) return 0;
427 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
428 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
429 else
430 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
431 if (!ptr) return 0;
433 switch(ptr->wMagic)
435 case PEN_MAGIC:
436 result = PEN_GetObject16( (PENOBJ *)ptr, count, buffer );
437 break;
438 case BRUSH_MAGIC:
439 result = BRUSH_GetObject16( (BRUSHOBJ *)ptr, count, buffer );
440 break;
441 case BITMAP_MAGIC:
442 result = BITMAP_GetObject16( (BITMAPOBJ *)ptr, count, buffer );
443 break;
444 case FONT_MAGIC:
445 result = FONT_GetObject16( (FONTOBJ *)ptr, count, buffer );
446 break;
447 case PALETTE_MAGIC:
448 result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer );
449 break;
451 GDI_HEAP_UNLOCK( handle );
452 return result;
456 /***********************************************************************
457 * GetObject32A (GDI32.204)
459 INT WINAPI GetObjectA( HANDLE handle, INT count, LPVOID buffer )
461 GDIOBJHDR * ptr = NULL;
462 INT result = 0;
463 TRACE("%08x %d %p\n", handle, count, buffer );
464 if (!count) return 0;
466 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
467 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
468 else
469 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
470 if (!ptr) return 0;
472 switch(ptr->wMagic)
474 case PEN_MAGIC:
475 result = PEN_GetObject( (PENOBJ *)ptr, count, buffer );
476 break;
477 case BRUSH_MAGIC:
478 result = BRUSH_GetObject( (BRUSHOBJ *)ptr, count, buffer );
479 break;
480 case BITMAP_MAGIC:
481 result = BITMAP_GetObject( (BITMAPOBJ *)ptr, count, buffer );
482 break;
483 case FONT_MAGIC:
484 result = FONT_GetObjectA( (FONTOBJ *)ptr, count, buffer );
485 break;
486 case PALETTE_MAGIC:
487 result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer );
488 break;
489 default:
490 FIXME("Magic %04x not implemented\n",
491 ptr->wMagic );
492 break;
494 GDI_HEAP_UNLOCK( handle );
495 return result;
497 /***********************************************************************
498 * GetObject32W (GDI32.206)
500 INT WINAPI GetObjectW( HANDLE handle, INT count, LPVOID buffer )
502 GDIOBJHDR * ptr = NULL;
503 INT result = 0;
504 TRACE("%08x %d %p\n", handle, count, buffer );
505 if (!count) return 0;
507 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
508 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
509 else
510 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
511 if (!ptr) return 0;
513 switch(ptr->wMagic)
515 case PEN_MAGIC:
516 result = PEN_GetObject( (PENOBJ *)ptr, count, buffer );
517 break;
518 case BRUSH_MAGIC:
519 result = BRUSH_GetObject( (BRUSHOBJ *)ptr, count, buffer );
520 break;
521 case BITMAP_MAGIC:
522 result = BITMAP_GetObject( (BITMAPOBJ *)ptr, count, buffer );
523 break;
524 case FONT_MAGIC:
525 result = FONT_GetObjectW( (FONTOBJ *)ptr, count, buffer );
526 break;
527 case PALETTE_MAGIC:
528 result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer );
529 break;
530 default:
531 FIXME("Magic %04x not implemented\n",
532 ptr->wMagic );
533 break;
535 GDI_HEAP_UNLOCK( handle );
536 return result;
539 /***********************************************************************
540 * GetObjectType (GDI32.205)
542 DWORD WINAPI GetObjectType( HANDLE handle )
544 GDIOBJHDR * ptr = NULL;
545 INT result = 0;
546 TRACE("%08x\n", handle );
548 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
549 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
550 else
551 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
552 if (!ptr) return 0;
554 switch(ptr->wMagic)
556 case PEN_MAGIC:
557 result = OBJ_PEN;
558 break;
559 case BRUSH_MAGIC:
560 result = OBJ_BRUSH;
561 break;
562 case BITMAP_MAGIC:
563 result = OBJ_BITMAP;
564 break;
565 case FONT_MAGIC:
566 result = OBJ_FONT;
567 break;
568 case PALETTE_MAGIC:
569 result = OBJ_PAL;
570 break;
571 case REGION_MAGIC:
572 result = OBJ_REGION;
573 break;
574 case DC_MAGIC:
575 result = OBJ_DC;
576 break;
577 case META_DC_MAGIC:
578 result = OBJ_METADC;
579 break;
580 case METAFILE_MAGIC:
581 result = OBJ_METAFILE;
582 break;
583 case METAFILE_DC_MAGIC:
584 result = OBJ_METADC;
585 break;
586 case ENHMETAFILE_MAGIC:
587 result = OBJ_ENHMETAFILE;
588 break;
589 case ENHMETAFILE_DC_MAGIC:
590 result = OBJ_ENHMETADC;
591 break;
592 default:
593 FIXME("Magic %04x not implemented\n",
594 ptr->wMagic );
595 break;
597 GDI_HEAP_UNLOCK( handle );
598 return result;
601 /***********************************************************************
602 * GetCurrentObject (GDI32.166)
604 HANDLE WINAPI GetCurrentObject(HDC hdc,UINT type)
606 DC * dc = DC_GetDCPtr( hdc );
608 if (!dc)
609 return 0;
610 switch (type) {
611 case OBJ_PEN: return dc->w.hPen;
612 case OBJ_BRUSH: return dc->w.hBrush;
613 case OBJ_PAL: return dc->w.hPalette;
614 case OBJ_FONT: return dc->w.hFont;
615 case OBJ_BITMAP: return dc->w.hBitmap;
616 default:
617 /* the SDK only mentions those above */
618 WARN("(%08x,%d): unknown type.\n",hdc,type);
619 return 0;
624 /***********************************************************************
625 * SelectObject16 (GDI.45)
627 HGDIOBJ16 WINAPI SelectObject16( HDC16 hdc, HGDIOBJ16 handle )
629 return (HGDIOBJ16)SelectObject( hdc, handle );
633 /***********************************************************************
634 * SelectObject32 (GDI32.299)
636 HGDIOBJ WINAPI SelectObject( HDC hdc, HGDIOBJ handle )
638 DC * dc = DC_GetDCPtr( hdc );
639 if (!dc || !dc->funcs->pSelectObject) return 0;
640 TRACE("hdc=%04x %04x\n", hdc, handle );
641 return dc->funcs->pSelectObject( dc, handle );
645 /***********************************************************************
646 * UnrealizeObject16 (GDI.150)
648 BOOL16 WINAPI UnrealizeObject16( HGDIOBJ16 obj )
650 return UnrealizeObject( obj );
654 /***********************************************************************
655 * UnrealizeObject (GDI32.358)
657 BOOL WINAPI UnrealizeObject( HGDIOBJ obj )
659 BOOL result = TRUE;
660 /* Check if object is valid */
662 GDIOBJHDR * header = (GDIOBJHDR *) GDI_HEAP_LOCK( obj );
663 if (!header) return FALSE;
665 TRACE("%04x\n", obj );
667 /* Unrealize object */
669 switch(header->wMagic)
671 case PALETTE_MAGIC:
672 result = PALETTE_UnrealizeObject( obj, (PALETTEOBJ *)header );
673 break;
675 case BRUSH_MAGIC:
676 /* Windows resets the brush origin. We don't need to. */
677 break;
679 GDI_HEAP_UNLOCK( obj );
680 return result;
684 /***********************************************************************
685 * EnumObjects16 (GDI.71)
687 INT16 WINAPI EnumObjects16( HDC16 hdc, INT16 nObjType,
688 GOBJENUMPROC16 lpEnumFunc, LPARAM lParam )
690 /* Solid colors to enumerate */
691 static const COLORREF solid_colors[] =
692 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
693 RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
694 RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
695 RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
696 RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
697 RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
698 RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
699 RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
702 INT16 i, retval = 0;
703 LOGPEN16 *pen;
704 LOGBRUSH16 *brush = NULL;
706 TRACE("%04x %d %08lx %08lx\n",
707 hdc, nObjType, (DWORD)lpEnumFunc, lParam );
708 switch(nObjType)
710 case OBJ_PEN:
711 /* Enumerate solid pens */
712 if (!(pen = SEGPTR_NEW(LOGPEN16))) break;
713 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
715 pen->lopnStyle = PS_SOLID;
716 pen->lopnWidth.x = 1;
717 pen->lopnWidth.y = 0;
718 pen->lopnColor = solid_colors[i];
719 retval = lpEnumFunc( SEGPTR_GET(pen), lParam );
720 TRACE("solid pen %08lx, ret=%d\n",
721 solid_colors[i], retval);
722 if (!retval) break;
724 SEGPTR_FREE(pen);
725 break;
727 case OBJ_BRUSH:
728 /* Enumerate solid brushes */
729 if (!(brush = SEGPTR_NEW(LOGBRUSH16))) break;
730 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
732 brush->lbStyle = BS_SOLID;
733 brush->lbColor = solid_colors[i];
734 brush->lbHatch = 0;
735 retval = lpEnumFunc( SEGPTR_GET(brush), lParam );
736 TRACE("solid brush %08lx, ret=%d\n",
737 solid_colors[i], retval);
738 if (!retval) break;
741 /* Now enumerate hatched brushes */
742 if (retval) for (i = HS_HORIZONTAL; i <= HS_DIAGCROSS; i++)
744 brush->lbStyle = BS_HATCHED;
745 brush->lbColor = RGB(0,0,0);
746 brush->lbHatch = i;
747 retval = lpEnumFunc( SEGPTR_GET(brush), lParam );
748 TRACE("hatched brush %d, ret=%d\n",
749 i, retval);
750 if (!retval) break;
752 SEGPTR_FREE(brush);
753 break;
755 default:
756 WARN("(%d): Invalid type\n", nObjType );
757 break;
759 return retval;
763 /***********************************************************************
764 * EnumObjects32 (GDI32.89)
766 INT WINAPI EnumObjects( HDC hdc, INT nObjType,
767 GOBJENUMPROC lpEnumFunc, LPARAM lParam )
769 /* Solid colors to enumerate */
770 static const COLORREF solid_colors[] =
771 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
772 RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
773 RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
774 RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
775 RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
776 RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
777 RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
778 RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
781 INT i, retval = 0;
782 LOGPEN pen;
783 LOGBRUSH brush;
785 TRACE("%04x %d %08lx %08lx\n",
786 hdc, nObjType, (DWORD)lpEnumFunc, lParam );
787 switch(nObjType)
789 case OBJ_PEN:
790 /* Enumerate solid pens */
791 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
793 pen.lopnStyle = PS_SOLID;
794 pen.lopnWidth.x = 1;
795 pen.lopnWidth.y = 0;
796 pen.lopnColor = solid_colors[i];
797 retval = lpEnumFunc( &pen, lParam );
798 TRACE("solid pen %08lx, ret=%d\n",
799 solid_colors[i], retval);
800 if (!retval) break;
802 break;
804 case OBJ_BRUSH:
805 /* Enumerate solid brushes */
806 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
808 brush.lbStyle = BS_SOLID;
809 brush.lbColor = solid_colors[i];
810 brush.lbHatch = 0;
811 retval = lpEnumFunc( &brush, lParam );
812 TRACE("solid brush %08lx, ret=%d\n",
813 solid_colors[i], retval);
814 if (!retval) break;
817 /* Now enumerate hatched brushes */
818 if (retval) for (i = HS_HORIZONTAL; i <= HS_DIAGCROSS; i++)
820 brush.lbStyle = BS_HATCHED;
821 brush.lbColor = RGB(0,0,0);
822 brush.lbHatch = i;
823 retval = lpEnumFunc( &brush, lParam );
824 TRACE("hatched brush %d, ret=%d\n",
825 i, retval);
826 if (!retval) break;
828 break;
830 default:
831 /* FIXME: implement Win32 types */
832 WARN("(%d): Invalid type\n", nObjType );
833 break;
835 return retval;
839 /***********************************************************************
840 * IsGDIObject (GDI.462)
842 * returns type of object if valid (W95 system programming secrets p. 264-5)
844 BOOL16 WINAPI IsGDIObject16( HGDIOBJ16 handle )
846 UINT16 magic = 0;
848 if (handle >= FIRST_STOCK_HANDLE )
850 switch (handle)
852 case STOCK_WHITE_BRUSH:
853 case STOCK_LTGRAY_BRUSH:
854 case STOCK_GRAY_BRUSH:
855 case STOCK_DKGRAY_BRUSH:
856 case STOCK_BLACK_BRUSH:
857 case STOCK_HOLLOW_BRUSH:
858 magic = BRUSH_MAGIC;
859 break;
861 case STOCK_WHITE_PEN:
862 case STOCK_BLACK_PEN:
863 case STOCK_NULL_PEN :
864 magic = PEN_MAGIC;
865 break;
867 case STOCK_OEM_FIXED_FONT:
868 case STOCK_ANSI_FIXED_FONT:
869 case STOCK_ANSI_VAR_FONT:
870 case STOCK_SYSTEM_FONT:
871 case STOCK_DEVICE_DEFAULT_FONT:
872 case STOCK_SYSTEM_FIXED_FONT:
873 case STOCK_DEFAULT_GUI_FONT:
874 magic = FONT_MAGIC;
875 break;
877 case STOCK_DEFAULT_PALETTE:
878 magic = PALETTE_MAGIC;
879 break;
882 else
884 GDIOBJHDR *object = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
885 if (object)
887 magic = object->wMagic;
888 GDI_HEAP_UNLOCK( handle );
892 if (magic >= PEN_MAGIC && magic <= METAFILE_DC_MAGIC)
893 return magic - PEN_MAGIC + 1;
894 else
895 return FALSE;
899 /***********************************************************************
900 * SetObjectOwner16 (GDI.461)
902 void WINAPI SetObjectOwner16( HGDIOBJ16 handle, HANDLE16 owner )
904 /* Nothing to do */
908 /***********************************************************************
909 * SetObjectOwner32 (GDI32.386)
911 void WINAPI SetObjectOwner( HGDIOBJ handle, HANDLE owner )
913 /* Nothing to do */
916 /***********************************************************************
917 * MakeObjectPrivate (GDI.463)
919 void WINAPI MakeObjectPrivate16( HGDIOBJ16 handle, BOOL16 private )
921 /* FIXME */
925 /***********************************************************************
926 * GdiFlush (GDI32.128)
928 BOOL WINAPI GdiFlush(void)
930 return TRUE; /* FIXME */
934 /***********************************************************************
935 * GdiGetBatchLimit (GDI32.129)
937 DWORD WINAPI GdiGetBatchLimit(void)
939 return 1; /* FIXME */
943 /***********************************************************************
944 * GdiSetBatchLimit (GDI32.139)
946 DWORD WINAPI GdiSetBatchLimit( DWORD limit )
948 return 1; /* FIXME */
952 /***********************************************************************
953 * GdiSeeGdiDo (GDI.452)
955 DWORD WINAPI GdiSeeGdiDo16( WORD wReqType, WORD wParam1, WORD wParam2,
956 WORD wParam3 )
958 switch (wReqType)
960 case 0x0001: /* LocalAlloc */
961 return LOCAL_Alloc( GDI_HeapSel, wParam1, wParam3 );
962 case 0x0002: /* LocalFree */
963 return LOCAL_Free( GDI_HeapSel, wParam1 );
964 case 0x0003: /* LocalCompact */
965 return LOCAL_Compact( GDI_HeapSel, wParam3, 0 );
966 case 0x0103: /* LocalHeap */
967 return GDI_HeapSel;
968 default:
969 WARN("(wReqType=%04x): Unknown\n", wReqType);
970 return (DWORD)-1;
974 /***********************************************************************
975 * GdiSignalProc (GDI.610)
977 WORD WINAPI GdiSignalProc( UINT uCode, DWORD dwThreadOrProcessID,
978 DWORD dwFlags, HMODULE16 hModule )
980 return 0;
984 /***********************************************************************
985 * GdiFreeResources (GDI.609)
987 WORD WINAPI GdiFreeResources16( DWORD reserve )
989 return (WORD)( (int)LOCAL_CountFree( GDI_HeapSel ) * 100 /
990 (int)LOCAL_HeapSize( GDI_HeapSel ) );
993 /***********************************************************************
994 * MulDiv16 (GDI.128)
996 INT16 WINAPI MulDiv16( INT16 foo, INT16 bar, INT16 baz )
998 INT ret;
999 if (!baz) return -32768;
1000 ret = (foo * bar) / baz;
1001 if ((ret > 32767) || (ret < -32767)) return -32768;
1002 return ret;
1006 /***********************************************************************
1007 * MulDiv32 (KERNEL32.391)
1008 * RETURNS
1009 * Result of multiplication and division
1010 * -1: Overflow occurred or Divisor was 0
1012 INT WINAPI MulDiv(
1013 INT nMultiplicand,
1014 INT nMultiplier,
1015 INT nDivisor
1017 #if (SIZEOF_LONG_LONG >= 8)
1018 long long ret;
1019 if (!nDivisor) return -1;
1020 ret = (((long long)nMultiplicand * nMultiplier) + (nDivisor/2)) / nDivisor;
1021 if ((ret > 2147483647) || (ret < -2147483647)) return -1;
1022 return ret;
1023 #else
1024 if (!nDivisor) return -1;
1025 return ((nMultiplicand * nMultiplier) + (nDivisor/2)) / nDivisor;
1026 #endif
1028 /*******************************************************************
1029 * GetColorAdjustment [GDI32.164]
1033 BOOL WINAPI GetColorAdjustment(HDC hdc, LPCOLORADJUSTMENT lpca)
1035 FIXME("GetColorAdjustment, stub\n");
1036 return 0;
1039 /*******************************************************************
1040 * GetMiterLimit [GDI32.201]
1044 BOOL WINAPI GetMiterLimit(HDC hdc, PFLOAT peLimit)
1046 FIXME("GetMiterLimit, stub\n");
1047 return 0;
1050 /*******************************************************************
1051 * SetMiterLimit [GDI32.325]
1055 BOOL WINAPI SetMiterLimit(HDC hdc, FLOAT eNewLimit, PFLOAT peOldLimit)
1057 FIXME("SetMiterLimit, stub\n");
1058 return 0;
1061 /*******************************************************************
1062 * GdiComment [GDI32.109]
1066 BOOL WINAPI GdiComment(HDC hdc, UINT cbSize, const BYTE *lpData)
1068 FIXME("GdiComment, stub\n");
1069 return 0;
1071 /*******************************************************************
1072 * SetColorAdjustment [GDI32.309]
1076 BOOL WINAPI SetColorAdjustment(HDC hdc, const COLORADJUSTMENT* lpca)
1078 FIXME("SetColorAdjustment, stub\n");
1079 return 0;