Changed ressource dir structures.
[wine/dcerpc.git] / objects / gdiobj.c
blob0ab9f855919f0471d2c5f8bc6b68fe944daf1a89
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 /**********************************************************************/
29 GDI_DRIVER *GDI_Driver = NULL;
31 /***********************************************************************
32 * GDI stock objects
35 static BRUSHOBJ WhiteBrush =
37 { 0, BRUSH_MAGIC, 1 }, /* header */
38 { BS_SOLID, RGB(255,255,255), 0 } /* logbrush */
41 static BRUSHOBJ LtGrayBrush =
43 { 0, BRUSH_MAGIC, 1 }, /* header */
44 /* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
45 { BS_SOLID, RGB(192,192,192), 0 } /* logbrush */
48 static BRUSHOBJ GrayBrush =
50 { 0, BRUSH_MAGIC, 1 }, /* header */
51 /* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
52 { BS_SOLID, RGB(128,128,128), 0 } /* logbrush */
55 static BRUSHOBJ DkGrayBrush =
57 { 0, BRUSH_MAGIC, 1 }, /* header */
58 /* This is BS_HATCHED, for 1 bitperpixel. This makes the spray work in pbrush */
59 /* NB_HATCH_STYLES is an index into HatchBrushes */
60 { BS_HATCHED, RGB(0,0,0), NB_HATCH_STYLES } /* logbrush */
63 static BRUSHOBJ BlackBrush =
65 { 0, BRUSH_MAGIC, 1 }, /* header */
66 { BS_SOLID, RGB(0,0,0), 0 } /* logbrush */
69 static BRUSHOBJ NullBrush =
71 { 0, BRUSH_MAGIC, 1 }, /* header */
72 { BS_NULL, 0, 0 } /* logbrush */
75 static PENOBJ WhitePen =
77 { 0, PEN_MAGIC, 1 }, /* header */
78 { PS_SOLID, { 1, 0 }, RGB(255,255,255) } /* logpen */
81 static PENOBJ BlackPen =
83 { 0, PEN_MAGIC, 1 }, /* header */
84 { PS_SOLID, { 1, 0 }, RGB(0,0,0) } /* logpen */
87 static PENOBJ NullPen =
89 { 0, PEN_MAGIC, 1 }, /* header */
90 { PS_NULL, { 1, 0 }, 0 } /* logpen */
93 static FONTOBJ OEMFixedFont =
95 { 0, FONT_MAGIC, 1 }, /* header */
96 { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, OEM_CHARSET,
97 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" }
99 /* Filler to make the location counter dword aligned again. This is necessary
100 since (a) FONTOBJ is packed, (b) gcc places initialised variables in the code
101 segment, and (c) Solaris assembler is stupid. */
102 static UINT16 align_OEMFixedFont = 1;
104 static FONTOBJ AnsiFixedFont =
106 { 0, FONT_MAGIC, 1 }, /* header */
107 { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
108 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" }
110 static UINT16 align_AnsiFixedFont = 1;
112 static FONTOBJ AnsiVarFont =
114 { 0, FONT_MAGIC, 1 }, /* header */
115 { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
116 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "MS Sans Serif" }
118 static UINT16 align_AnsiVarFont = 1;
120 static FONTOBJ SystemFont =
122 { 0, FONT_MAGIC, 1 },
123 { 16, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, ANSI_CHARSET,
124 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "System" }
126 static UINT16 align_SystemFont = 1;
128 static FONTOBJ DeviceDefaultFont =
130 { 0, FONT_MAGIC, 1 }, /* header */
131 { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
132 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "" }
134 static UINT16 align_DeviceDefaultFont = 1;
136 static FONTOBJ SystemFixedFont =
138 { 0, FONT_MAGIC, 1 }, /* header */
139 { 12, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, ANSI_CHARSET,
140 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" }
142 static UINT16 align_SystemFixedFont = 1;
144 /* FIXME: Is this correct? */
145 static FONTOBJ DefaultGuiFont =
147 { 9, FONT_MAGIC, 1 }, /* header */
148 { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
149 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "MS Sans Serif" }
151 static UINT16 align_DefaultGuiFont = 1;
154 static GDIOBJHDR * StockObjects[NB_STOCK_OBJECTS] =
156 (GDIOBJHDR *) &WhiteBrush,
157 (GDIOBJHDR *) &LtGrayBrush,
158 (GDIOBJHDR *) &GrayBrush,
159 (GDIOBJHDR *) &DkGrayBrush,
160 (GDIOBJHDR *) &BlackBrush,
161 (GDIOBJHDR *) &NullBrush,
162 (GDIOBJHDR *) &WhitePen,
163 (GDIOBJHDR *) &BlackPen,
164 (GDIOBJHDR *) &NullPen,
165 NULL,
166 (GDIOBJHDR *) &OEMFixedFont,
167 (GDIOBJHDR *) &AnsiFixedFont,
168 (GDIOBJHDR *) &AnsiVarFont,
169 (GDIOBJHDR *) &SystemFont,
170 (GDIOBJHDR *) &DeviceDefaultFont,
171 NULL, /* DEFAULT_PALETTE created by PALETTE_Init */
172 (GDIOBJHDR *) &SystemFixedFont,
173 (GDIOBJHDR *) &DefaultGuiFont
176 /******************************************************************************
178 * void ReadFontInformation(
179 * char const *fontName,
180 * FONTOBJ *font,
181 * int defHeight,
182 * int defBold,
183 * int defItalic,
184 * int defUnderline,
185 * int defStrikeOut )
187 * ReadFontInformation() checks the Wine configuration file's Tweak.Fonts
188 * section for entries containing fontName.Height, fontName.Bold, etc.,
189 * where fontName is the name specified in the call (e.g., "System"). It
190 * attempts to be user friendly by accepting 'n', 'N', 'f', 'F', or '0' as
191 * the first character in the boolean attributes (bold, italic, and
192 * underline).
193 *****************************************************************************/
195 static void ReadFontInformation(
196 char const *fontName,
197 FONTOBJ *font,
198 int defHeight,
199 int defBold,
200 int defItalic,
201 int defUnderline,
202 int defStrikeOut )
204 char key[256];
206 sprintf(key, "%s.Height", fontName);
207 font->logfont.lfHeight =
208 PROFILE_GetWineIniInt("Tweak.Fonts", key, defHeight);
210 sprintf(key, "%s.Bold", fontName);
211 font->logfont.lfWeight =
212 (PROFILE_GetWineIniBool("Tweak.Fonts", key, defBold)) ?
213 FW_BOLD : FW_NORMAL;
215 sprintf(key, "%s.Italic", fontName);
216 font->logfont.lfItalic =
217 PROFILE_GetWineIniBool("Tweak.Fonts", key, defItalic);
219 sprintf(key, "%s.Underline", fontName);
220 font->logfont.lfUnderline =
221 PROFILE_GetWineIniBool("Tweak.Fonts", key, defUnderline);
223 sprintf(key, "%s.StrikeOut", fontName);
224 font->logfont.lfStrikeOut =
225 PROFILE_GetWineIniBool("Tweak.Fonts", key, defStrikeOut);
227 return;
231 /***********************************************************************
232 * GDI_Init
234 * GDI initialization.
236 BOOL GDI_Init(void)
238 /* Kill some warnings. */
239 (void)align_OEMFixedFont;
240 (void)align_AnsiFixedFont;
241 (void)align_AnsiVarFont;
242 (void)align_SystemFont;
243 (void)align_DeviceDefaultFont;
244 (void)align_SystemFixedFont;
245 (void)align_DefaultGuiFont;
247 /* TWEAK: Initialize font hints */
248 ReadFontInformation("OEMFixed", &OEMFixedFont, 12, 0, 0, 0, 0);
249 ReadFontInformation("AnsiFixed", &AnsiFixedFont, 12, 0, 0, 0, 0);
250 ReadFontInformation("AnsiVar", &AnsiVarFont, 12, 0, 0, 0, 0);
251 ReadFontInformation("System", &SystemFont, 16, 1, 0, 0, 0);
252 ReadFontInformation("SystemFixed", &SystemFixedFont, 12, 1, 0, 0, 0);
254 /* Initialize drivers */
256 #ifndef X_DISPLAY_MISSING
257 GDI_Driver = &X11DRV_GDI_Driver;
258 #else /* !defined(X_DISPLAY_MISSING) */
259 GDI_Driver = &TTYDRV_GDI_Driver;
260 #endif /* !defined(X_DISPLAY_MISSING */
262 GDI_Driver->pInitialize();
264 /* Create default palette */
266 /* DR well *this* palette can't be moveable (?) */
268 HPALETTE16 hpalette = PALETTE_Init();
269 if( !hpalette )
270 return FALSE;
271 StockObjects[DEFAULT_PALETTE] = (GDIOBJHDR *)GDI_HEAP_LOCK( hpalette );
274 return TRUE;
278 /***********************************************************************
279 * GDI_AllocObject
281 HGDIOBJ16 GDI_AllocObject( WORD size, WORD magic )
283 static DWORD count = 0;
284 GDIOBJHDR * obj;
285 HGDIOBJ16 handle;
286 if ( magic == DC_MAGIC || magic == METAFILE_DC_MAGIC )
287 handle = GDI_HEAP_ALLOC( size );
288 else
289 handle = GDI_HEAP_ALLOC_MOVEABLE( size );
290 if (!handle) return 0;
291 obj = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
292 obj->hNext = 0;
293 obj->wMagic = magic;
294 obj->dwCount = ++count;
295 GDI_HEAP_UNLOCK( handle );
296 return handle;
300 /***********************************************************************
301 * GDI_FreeObject
303 BOOL GDI_FreeObject( HGDIOBJ16 handle )
305 GDIOBJHDR * object;
307 /* Can't free stock objects */
308 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
309 return TRUE;
311 object = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
312 if (!object) return FALSE;
313 object->wMagic = 0; /* Mark it as invalid */
315 /* Free object */
317 GDI_HEAP_FREE( handle );
318 return TRUE;
321 /***********************************************************************
322 * GDI_GetObjPtr
324 * Return a pointer to the GDI object associated to the handle.
325 * Return NULL if the object has the wrong magic number.
326 * Movable GDI objects are locked in memory: it is up to the caller to unlock
327 * it after the caller is done with the pointer.
329 GDIOBJHDR * GDI_GetObjPtr( HGDIOBJ16 handle, WORD magic )
331 GDIOBJHDR * ptr = NULL;
333 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
334 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
335 else
336 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
337 if (!ptr) return NULL;
338 if ((magic != MAGIC_DONTCARE) && (ptr->wMagic != magic))
340 GDI_HEAP_UNLOCK( handle );
341 return NULL;
343 return ptr;
347 /***********************************************************************
348 * DeleteObject16 (GDI.69)
350 BOOL16 WINAPI DeleteObject16( HGDIOBJ16 obj )
352 return DeleteObject( obj );
356 /***********************************************************************
357 * DeleteObject32 (GDI32.70)
359 BOOL WINAPI DeleteObject( HGDIOBJ obj )
361 /* Check if object is valid */
363 GDIOBJHDR * header;
364 if (HIWORD(obj)) return FALSE;
365 if ((obj >= FIRST_STOCK_HANDLE) && (obj <= LAST_STOCK_HANDLE))
366 return TRUE;
367 if (!(header = (GDIOBJHDR *) GDI_HEAP_LOCK( obj ))) return FALSE;
369 TRACE(gdi, "%04x\n", obj );
371 /* Delete object */
373 switch(header->wMagic)
375 case PEN_MAGIC: return GDI_FreeObject( obj );
376 case BRUSH_MAGIC: return BRUSH_DeleteObject( obj, (BRUSHOBJ*)header );
377 case FONT_MAGIC: return GDI_FreeObject( obj );
378 case PALETTE_MAGIC: return PALETTE_DeleteObject(obj,(PALETTEOBJ*)header);
379 case BITMAP_MAGIC: return BITMAP_DeleteObject( obj, (BITMAPOBJ*)header);
380 case REGION_MAGIC: return REGION_DeleteObject( obj, (RGNOBJ*)header );
381 case DC_MAGIC: return DeleteDC(obj);
382 case 0 :
383 WARN(gdi, "Already deleted\n");
384 break;
385 default:
386 WARN(gdi, "Unknown magic number (%d)\n",header->wMagic);
388 return FALSE;
391 /***********************************************************************
392 * GetStockObject16 (GDI.87)
394 HGDIOBJ16 WINAPI GetStockObject16( INT16 obj )
396 return (HGDIOBJ16)GetStockObject( obj );
400 /***********************************************************************
401 * GetStockObject32 (GDI32.220)
403 HGDIOBJ WINAPI GetStockObject( INT obj )
405 if ((obj < 0) || (obj >= NB_STOCK_OBJECTS)) return 0;
406 if (!StockObjects[obj]) return 0;
407 TRACE(gdi, "returning %d\n",
408 FIRST_STOCK_HANDLE + obj );
409 return (HGDIOBJ16)(FIRST_STOCK_HANDLE + obj);
413 /***********************************************************************
414 * GetObject16 (GDI.82)
416 INT16 WINAPI GetObject16( HANDLE16 handle, INT16 count, LPVOID buffer )
418 GDIOBJHDR * ptr = NULL;
419 INT16 result = 0;
420 TRACE(gdi, "%04x %d %p\n", handle, count, buffer );
421 if (!count) return 0;
423 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
424 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
425 else
426 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
427 if (!ptr) return 0;
429 switch(ptr->wMagic)
431 case PEN_MAGIC:
432 result = PEN_GetObject16( (PENOBJ *)ptr, count, buffer );
433 break;
434 case BRUSH_MAGIC:
435 result = BRUSH_GetObject16( (BRUSHOBJ *)ptr, count, buffer );
436 break;
437 case BITMAP_MAGIC:
438 result = BITMAP_GetObject16( (BITMAPOBJ *)ptr, count, buffer );
439 break;
440 case FONT_MAGIC:
441 result = FONT_GetObject16( (FONTOBJ *)ptr, count, buffer );
442 break;
443 case PALETTE_MAGIC:
444 result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer );
445 break;
447 GDI_HEAP_UNLOCK( handle );
448 return result;
452 /***********************************************************************
453 * GetObject32A (GDI32.204)
455 INT WINAPI GetObjectA( HANDLE handle, INT count, LPVOID buffer )
457 GDIOBJHDR * ptr = NULL;
458 INT result = 0;
459 TRACE(gdi, "%08x %d %p\n", handle, count, buffer );
460 if (!count) return 0;
462 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
463 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
464 else
465 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
466 if (!ptr) return 0;
468 switch(ptr->wMagic)
470 case PEN_MAGIC:
471 result = PEN_GetObject( (PENOBJ *)ptr, count, buffer );
472 break;
473 case BRUSH_MAGIC:
474 result = BRUSH_GetObject( (BRUSHOBJ *)ptr, count, buffer );
475 break;
476 case BITMAP_MAGIC:
477 result = BITMAP_GetObject( (BITMAPOBJ *)ptr, count, buffer );
478 break;
479 case FONT_MAGIC:
480 result = FONT_GetObjectA( (FONTOBJ *)ptr, count, buffer );
481 break;
482 case PALETTE_MAGIC:
483 result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer );
484 break;
485 default:
486 FIXME(gdi, "Magic %04x not implemented\n",
487 ptr->wMagic );
488 break;
490 GDI_HEAP_UNLOCK( handle );
491 return result;
493 /***********************************************************************
494 * GetObject32W (GDI32.206)
496 INT WINAPI GetObjectW( HANDLE handle, INT count, LPVOID buffer )
498 GDIOBJHDR * ptr = NULL;
499 INT result = 0;
500 TRACE(gdi, "%08x %d %p\n", handle, count, buffer );
501 if (!count) return 0;
503 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
504 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
505 else
506 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
507 if (!ptr) return 0;
509 switch(ptr->wMagic)
511 case PEN_MAGIC:
512 result = PEN_GetObject( (PENOBJ *)ptr, count, buffer );
513 break;
514 case BRUSH_MAGIC:
515 result = BRUSH_GetObject( (BRUSHOBJ *)ptr, count, buffer );
516 break;
517 case BITMAP_MAGIC:
518 result = BITMAP_GetObject( (BITMAPOBJ *)ptr, count, buffer );
519 break;
520 case FONT_MAGIC:
521 result = FONT_GetObjectW( (FONTOBJ *)ptr, count, buffer );
522 break;
523 case PALETTE_MAGIC:
524 result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer );
525 break;
526 default:
527 FIXME(gdi, "Magic %04x not implemented\n",
528 ptr->wMagic );
529 break;
531 GDI_HEAP_UNLOCK( handle );
532 return result;
535 /***********************************************************************
536 * GetObjectType (GDI32.205)
538 DWORD WINAPI GetObjectType( HANDLE handle )
540 GDIOBJHDR * ptr = NULL;
541 INT result = 0;
542 TRACE(gdi, "%08x\n", handle );
544 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
545 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
546 else
547 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
548 if (!ptr) return 0;
550 switch(ptr->wMagic)
552 case PEN_MAGIC:
553 result = OBJ_PEN;
554 break;
555 case BRUSH_MAGIC:
556 result = OBJ_BRUSH;
557 break;
558 case BITMAP_MAGIC:
559 result = OBJ_BITMAP;
560 break;
561 case FONT_MAGIC:
562 result = OBJ_FONT;
563 break;
564 case PALETTE_MAGIC:
565 result = OBJ_PAL;
566 break;
567 case REGION_MAGIC:
568 result = OBJ_REGION;
569 break;
570 case DC_MAGIC:
571 result = OBJ_DC;
572 break;
573 case META_DC_MAGIC:
574 result = OBJ_METADC;
575 break;
576 case METAFILE_MAGIC:
577 result = OBJ_METAFILE;
578 break;
579 case METAFILE_DC_MAGIC:
580 result = OBJ_METADC;
581 break;
583 default:
584 FIXME(gdi, "Magic %04x not implemented\n",
585 ptr->wMagic );
586 break;
588 GDI_HEAP_UNLOCK( handle );
589 return result;
592 /***********************************************************************
593 * GetCurrentObject (GDI32.166)
595 HANDLE WINAPI GetCurrentObject(HDC hdc,UINT type)
597 DC * dc = DC_GetDCPtr( hdc );
599 if (!dc)
600 return 0;
601 switch (type) {
602 case OBJ_PEN: return dc->w.hPen;
603 case OBJ_BRUSH: return dc->w.hBrush;
604 case OBJ_PAL: return dc->w.hPalette;
605 case OBJ_FONT: return dc->w.hFont;
606 case OBJ_BITMAP: return dc->w.hBitmap;
607 default:
608 /* the SDK only mentions those above */
609 WARN(gdi,"(%08x,%d): unknown type.\n",hdc,type);
610 return 0;
615 /***********************************************************************
616 * SelectObject16 (GDI.45)
618 HGDIOBJ16 WINAPI SelectObject16( HDC16 hdc, HGDIOBJ16 handle )
620 return (HGDIOBJ16)SelectObject( hdc, handle );
624 /***********************************************************************
625 * SelectObject32 (GDI32.299)
627 HGDIOBJ WINAPI SelectObject( HDC hdc, HGDIOBJ handle )
629 DC * dc = DC_GetDCPtr( hdc );
630 if (!dc || !dc->funcs->pSelectObject) return 0;
631 TRACE(gdi, "hdc=%04x %04x\n", hdc, handle );
632 return dc->funcs->pSelectObject( dc, handle );
636 /***********************************************************************
637 * UnrealizeObject16 (GDI.150)
639 BOOL16 WINAPI UnrealizeObject16( HGDIOBJ16 obj )
641 return UnrealizeObject( obj );
645 /***********************************************************************
646 * UnrealizeObject (GDI32.358)
648 BOOL WINAPI UnrealizeObject( HGDIOBJ obj )
650 BOOL result = TRUE;
651 /* Check if object is valid */
653 GDIOBJHDR * header = (GDIOBJHDR *) GDI_HEAP_LOCK( obj );
654 if (!header) return FALSE;
656 TRACE(gdi, "%04x\n", obj );
658 /* Unrealize object */
660 switch(header->wMagic)
662 case PALETTE_MAGIC:
663 result = PALETTE_UnrealizeObject( obj, (PALETTEOBJ *)header );
664 break;
666 case BRUSH_MAGIC:
667 /* Windows resets the brush origin. We don't need to. */
668 break;
670 GDI_HEAP_UNLOCK( obj );
671 return result;
675 /***********************************************************************
676 * EnumObjects16 (GDI.71)
678 INT16 WINAPI EnumObjects16( HDC16 hdc, INT16 nObjType,
679 GOBJENUMPROC16 lpEnumFunc, LPARAM lParam )
681 /* Solid colors to enumerate */
682 static const COLORREF solid_colors[] =
683 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
684 RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
685 RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
686 RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
687 RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
688 RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
689 RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
690 RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
693 INT16 i, retval = 0;
694 LOGPEN16 *pen;
695 LOGBRUSH16 *brush = NULL;
697 TRACE(gdi, "%04x %d %08lx %08lx\n",
698 hdc, nObjType, (DWORD)lpEnumFunc, lParam );
699 switch(nObjType)
701 case OBJ_PEN:
702 /* Enumerate solid pens */
703 if (!(pen = SEGPTR_NEW(LOGPEN16))) break;
704 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
706 pen->lopnStyle = PS_SOLID;
707 pen->lopnWidth.x = 1;
708 pen->lopnWidth.y = 0;
709 pen->lopnColor = solid_colors[i];
710 retval = lpEnumFunc( SEGPTR_GET(pen), lParam );
711 TRACE(gdi, "solid pen %08lx, ret=%d\n",
712 solid_colors[i], retval);
713 if (!retval) break;
715 SEGPTR_FREE(pen);
716 break;
718 case OBJ_BRUSH:
719 /* Enumerate solid brushes */
720 if (!(brush = SEGPTR_NEW(LOGBRUSH16))) break;
721 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
723 brush->lbStyle = BS_SOLID;
724 brush->lbColor = solid_colors[i];
725 brush->lbHatch = 0;
726 retval = lpEnumFunc( SEGPTR_GET(brush), lParam );
727 TRACE(gdi, "solid brush %08lx, ret=%d\n",
728 solid_colors[i], retval);
729 if (!retval) break;
732 /* Now enumerate hatched brushes */
733 if (retval) for (i = HS_HORIZONTAL; i <= HS_DIAGCROSS; i++)
735 brush->lbStyle = BS_HATCHED;
736 brush->lbColor = RGB(0,0,0);
737 brush->lbHatch = i;
738 retval = lpEnumFunc( SEGPTR_GET(brush), lParam );
739 TRACE(gdi, "hatched brush %d, ret=%d\n",
740 i, retval);
741 if (!retval) break;
743 SEGPTR_FREE(brush);
744 break;
746 default:
747 WARN(gdi, "(%d): Invalid type\n", nObjType );
748 break;
750 return retval;
754 /***********************************************************************
755 * EnumObjects32 (GDI32.89)
757 INT WINAPI EnumObjects( HDC hdc, INT nObjType,
758 GOBJENUMPROC lpEnumFunc, LPARAM lParam )
760 /* Solid colors to enumerate */
761 static const COLORREF solid_colors[] =
762 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
763 RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
764 RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
765 RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
766 RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
767 RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
768 RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
769 RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
772 INT i, retval = 0;
773 LOGPEN pen;
774 LOGBRUSH brush;
776 TRACE(gdi, "%04x %d %08lx %08lx\n",
777 hdc, nObjType, (DWORD)lpEnumFunc, lParam );
778 switch(nObjType)
780 case OBJ_PEN:
781 /* Enumerate solid pens */
782 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
784 pen.lopnStyle = PS_SOLID;
785 pen.lopnWidth.x = 1;
786 pen.lopnWidth.y = 0;
787 pen.lopnColor = solid_colors[i];
788 retval = lpEnumFunc( &pen, lParam );
789 TRACE(gdi, "solid pen %08lx, ret=%d\n",
790 solid_colors[i], retval);
791 if (!retval) break;
793 break;
795 case OBJ_BRUSH:
796 /* Enumerate solid brushes */
797 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
799 brush.lbStyle = BS_SOLID;
800 brush.lbColor = solid_colors[i];
801 brush.lbHatch = 0;
802 retval = lpEnumFunc( &brush, lParam );
803 TRACE(gdi, "solid brush %08lx, ret=%d\n",
804 solid_colors[i], retval);
805 if (!retval) break;
808 /* Now enumerate hatched brushes */
809 if (retval) for (i = HS_HORIZONTAL; i <= HS_DIAGCROSS; i++)
811 brush.lbStyle = BS_HATCHED;
812 brush.lbColor = RGB(0,0,0);
813 brush.lbHatch = i;
814 retval = lpEnumFunc( &brush, lParam );
815 TRACE(gdi, "hatched brush %d, ret=%d\n",
816 i, retval);
817 if (!retval) break;
819 break;
821 default:
822 /* FIXME: implement Win32 types */
823 WARN( gdi, "(%d): Invalid type\n", nObjType );
824 break;
826 return retval;
830 /***********************************************************************
831 * IsGDIObject (GDI.462)
833 * returns type of object if valid (W95 system programming secrets p. 264-5)
835 BOOL16 WINAPI IsGDIObject16( HGDIOBJ16 handle )
837 UINT16 magic = 0;
839 if (handle >= FIRST_STOCK_HANDLE )
841 switch (handle)
843 case STOCK_WHITE_BRUSH:
844 case STOCK_LTGRAY_BRUSH:
845 case STOCK_GRAY_BRUSH:
846 case STOCK_DKGRAY_BRUSH:
847 case STOCK_BLACK_BRUSH:
848 case STOCK_HOLLOW_BRUSH:
849 magic = BRUSH_MAGIC;
850 break;
852 case STOCK_WHITE_PEN:
853 case STOCK_BLACK_PEN:
854 case STOCK_NULL_PEN :
855 magic = PEN_MAGIC;
856 break;
858 case STOCK_OEM_FIXED_FONT:
859 case STOCK_ANSI_FIXED_FONT:
860 case STOCK_ANSI_VAR_FONT:
861 case STOCK_SYSTEM_FONT:
862 case STOCK_DEVICE_DEFAULT_FONT:
863 case STOCK_SYSTEM_FIXED_FONT:
864 case STOCK_DEFAULT_GUI_FONT:
865 magic = FONT_MAGIC;
866 break;
868 case STOCK_DEFAULT_PALETTE:
869 magic = PALETTE_MAGIC;
870 break;
873 else
875 GDIOBJHDR *object = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
876 if (object)
878 magic = object->wMagic;
879 GDI_HEAP_UNLOCK( handle );
883 if (magic >= PEN_MAGIC && magic <= METAFILE_DC_MAGIC)
884 return magic - PEN_MAGIC + 1;
885 else
886 return FALSE;
890 /***********************************************************************
891 * SetObjectOwner16 (GDI.461)
893 void WINAPI SetObjectOwner16( HGDIOBJ16 handle, HANDLE16 owner )
895 /* Nothing to do */
899 /***********************************************************************
900 * SetObjectOwner32 (GDI32.386)
902 void WINAPI SetObjectOwner( HGDIOBJ handle, HANDLE owner )
904 /* Nothing to do */
907 /***********************************************************************
908 * MakeObjectPrivate (GDI.463)
910 void WINAPI MakeObjectPrivate16( HGDIOBJ16 handle, BOOL16 private )
912 /* FIXME */
916 /***********************************************************************
917 * GdiFlush (GDI32.128)
919 BOOL WINAPI GdiFlush(void)
921 return TRUE; /* FIXME */
925 /***********************************************************************
926 * GdiGetBatchLimit (GDI32.129)
928 DWORD WINAPI GdiGetBatchLimit(void)
930 return 1; /* FIXME */
934 /***********************************************************************
935 * GdiSetBatchLimit (GDI32.139)
937 DWORD WINAPI GdiSetBatchLimit( DWORD limit )
939 return 1; /* FIXME */
943 /***********************************************************************
944 * GdiSeeGdiDo (GDI.452)
946 DWORD WINAPI GdiSeeGdiDo16( WORD wReqType, WORD wParam1, WORD wParam2,
947 WORD wParam3 )
949 switch (wReqType)
951 case 0x0001: /* LocalAlloc */
952 return LOCAL_Alloc( GDI_HeapSel, wParam1, wParam3 );
953 case 0x0002: /* LocalFree */
954 return LOCAL_Free( GDI_HeapSel, wParam1 );
955 case 0x0003: /* LocalCompact */
956 return LOCAL_Compact( GDI_HeapSel, wParam3, 0 );
957 case 0x0103: /* LocalHeap */
958 return GDI_HeapSel;
959 default:
960 WARN(gdi, "(wReqType=%04x): Unknown\n", wReqType);
961 return (DWORD)-1;
965 /***********************************************************************
966 * GdiSignalProc (GDI.610)
968 WORD WINAPI GdiSignalProc( UINT uCode, DWORD dwThreadOrProcessID,
969 DWORD dwFlags, HMODULE16 hModule )
971 return 0;
975 /***********************************************************************
976 * GdiFreeResources (GDI.609)
978 WORD WINAPI GdiFreeResources16( DWORD reserve )
980 return (WORD)( (int)LOCAL_CountFree( GDI_HeapSel ) * 100 /
981 (int)LOCAL_HeapSize( GDI_HeapSel ) );
984 /***********************************************************************
985 * MulDiv16 (GDI.128)
987 INT16 WINAPI MulDiv16( INT16 foo, INT16 bar, INT16 baz )
989 INT ret;
990 if (!baz) return -32768;
991 ret = (foo * bar) / baz;
992 if ((ret > 32767) || (ret < -32767)) return -32768;
993 return ret;
997 /***********************************************************************
998 * MulDiv32 (KERNEL32.391)
999 * RETURNS
1000 * Result of multiplication and division
1001 * -1: Overflow occurred or Divisor was 0
1003 INT WINAPI MulDiv(
1004 INT nMultiplicand,
1005 INT nMultiplier,
1006 INT nDivisor
1008 #if (SIZEOF_LONG_LONG >= 8)
1009 long long ret;
1010 if (!nDivisor) return -1;
1011 ret = ((long long)nMultiplicand * nMultiplier) / nDivisor;
1012 if ((ret > 2147483647) || (ret < -2147483647)) return -1;
1013 return ret;
1014 #else
1015 if (!nDivisor) return -1;
1016 return (nMultiplicand * nMultiplier) / nDivisor;
1017 #endif
1019 /*******************************************************************
1020 * GetColorAdjustment [GDI32.164]
1024 BOOL WINAPI GetColorAdjustment(HDC hdc, LPCOLORADJUSTMENT lpca)
1026 FIXME(gdi, "GetColorAdjustment, stub\n");
1027 return 0;
1030 /*******************************************************************
1031 * GetMiterLimit [GDI32.201]
1035 BOOL WINAPI GetMiterLimit(HDC hdc, PFLOAT peLimit)
1037 FIXME(gdi, "GetMiterLimit, stub\n");
1038 return 0;
1041 /*******************************************************************
1042 * SetMiterLimit [GDI32.325]
1046 BOOL WINAPI SetMiterLimit(HDC hdc, FLOAT eNewLimit, PFLOAT peOldLimit)
1048 FIXME(gdi, "SetMiterLimit, stub\n");
1049 return 0;
1052 /*******************************************************************
1053 * GdiComment [GDI32.109]
1057 BOOL WINAPI GdiComment(HDC hdc, UINT cbSize, const BYTE *lpData)
1059 FIXME(gdi, "GdiComment, stub\n");
1060 return 0;
1062 /*******************************************************************
1063 * SetColorAdjustment [GDI32.309]
1067 BOOL WINAPI SetColorAdjustment(HDC hdc, const COLORADJUSTMENT* lpca)
1069 FIXME(gdi, "SetColorAdjustment, stub\n");
1070 return 0;