Fixed X11DRV_DIB_SetImageBits when called for RLE encoded dibs.
[wine.git] / objects / gdiobj.c
blobc48e0509807ab1040d0fd63018ccc2e045aa0317
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"
28 #include "tweak.h"
30 DEFAULT_DEBUG_CHANNEL(gdi)
32 /**********************************************************************/
34 GDI_DRIVER *GDI_Driver = NULL;
36 /***********************************************************************
37 * GDI stock objects
40 static BRUSHOBJ WhiteBrush =
42 { 0, BRUSH_MAGIC, 1 }, /* header */
43 { BS_SOLID, RGB(255,255,255), 0 } /* logbrush */
46 static BRUSHOBJ LtGrayBrush =
48 { 0, BRUSH_MAGIC, 1 }, /* header */
49 /* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
50 { BS_SOLID, RGB(192,192,192), 0 } /* logbrush */
53 static BRUSHOBJ GrayBrush =
55 { 0, BRUSH_MAGIC, 1 }, /* header */
56 /* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
57 { BS_SOLID, RGB(128,128,128), 0 } /* logbrush */
60 static BRUSHOBJ DkGrayBrush =
62 { 0, BRUSH_MAGIC, 1 }, /* header */
63 /* This is BS_HATCHED, for 1 bitperpixel. This makes the spray work in pbrush */
64 /* NB_HATCH_STYLES is an index into HatchBrushes */
65 { BS_HATCHED, RGB(0,0,0), NB_HATCH_STYLES } /* logbrush */
68 static BRUSHOBJ BlackBrush =
70 { 0, BRUSH_MAGIC, 1 }, /* header */
71 { BS_SOLID, RGB(0,0,0), 0 } /* logbrush */
74 static BRUSHOBJ NullBrush =
76 { 0, BRUSH_MAGIC, 1 }, /* header */
77 { BS_NULL, 0, 0 } /* logbrush */
80 static PENOBJ WhitePen =
82 { 0, PEN_MAGIC, 1 }, /* header */
83 { PS_SOLID, { 1, 0 }, RGB(255,255,255) } /* logpen */
86 static PENOBJ BlackPen =
88 { 0, PEN_MAGIC, 1 }, /* header */
89 { PS_SOLID, { 1, 0 }, RGB(0,0,0) } /* logpen */
92 static PENOBJ NullPen =
94 { 0, PEN_MAGIC, 1 }, /* header */
95 { PS_NULL, { 1, 0 }, 0 } /* logpen */
98 static FONTOBJ OEMFixedFont =
100 { 0, FONT_MAGIC, 1 }, /* header */
101 { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, OEM_CHARSET,
102 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" }
104 /* Filler to make the location counter dword aligned again. This is necessary
105 since (a) FONTOBJ is packed, (b) gcc places initialised variables in the code
106 segment, and (c) Solaris assembler is stupid. */
107 static UINT16 align_OEMFixedFont = 1;
109 static FONTOBJ AnsiFixedFont =
111 { 0, FONT_MAGIC, 1 }, /* header */
112 { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
113 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" }
115 static UINT16 align_AnsiFixedFont = 1;
117 static FONTOBJ AnsiVarFont =
119 { 0, FONT_MAGIC, 1 }, /* header */
120 { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
121 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "MS Sans Serif" }
123 static UINT16 align_AnsiVarFont = 1;
125 static FONTOBJ SystemFont =
127 { 0, FONT_MAGIC, 1 },
128 { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
129 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "System" }
131 static UINT16 align_SystemFont = 1;
133 static FONTOBJ DeviceDefaultFont =
135 { 0, FONT_MAGIC, 1 }, /* header */
136 { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
137 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "" }
139 static UINT16 align_DeviceDefaultFont = 1;
141 static FONTOBJ SystemFixedFont =
143 { 0, FONT_MAGIC, 1 }, /* header */
144 { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
145 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" }
147 static UINT16 align_SystemFixedFont = 1;
149 /* FIXME: Is this correct? */
150 static FONTOBJ DefaultGuiFont =
152 { 0, FONT_MAGIC, 1 }, /* header */
153 { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
154 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "MS Sans Serif" }
156 static UINT16 align_DefaultGuiFont = 1;
159 static GDIOBJHDR * StockObjects[NB_STOCK_OBJECTS] =
161 (GDIOBJHDR *) &WhiteBrush,
162 (GDIOBJHDR *) &LtGrayBrush,
163 (GDIOBJHDR *) &GrayBrush,
164 (GDIOBJHDR *) &DkGrayBrush,
165 (GDIOBJHDR *) &BlackBrush,
166 (GDIOBJHDR *) &NullBrush,
167 (GDIOBJHDR *) &WhitePen,
168 (GDIOBJHDR *) &BlackPen,
169 (GDIOBJHDR *) &NullPen,
170 NULL,
171 (GDIOBJHDR *) &OEMFixedFont,
172 (GDIOBJHDR *) &AnsiFixedFont,
173 (GDIOBJHDR *) &AnsiVarFont,
174 (GDIOBJHDR *) &SystemFont,
175 (GDIOBJHDR *) &DeviceDefaultFont,
176 NULL, /* DEFAULT_PALETTE created by PALETTE_Init */
177 (GDIOBJHDR *) &SystemFixedFont,
178 (GDIOBJHDR *) &DefaultGuiFont
181 /******************************************************************************
183 * void ReadFontInformation(
184 * char const *fontName,
185 * FONTOBJ *font,
186 * int defHeight,
187 * int defBold,
188 * int defItalic,
189 * int defUnderline,
190 * int defStrikeOut )
192 * ReadFontInformation() checks the Wine configuration file's Tweak.Fonts
193 * section for entries containing fontName.Height, fontName.Bold, etc.,
194 * where fontName is the name specified in the call (e.g., "System"). It
195 * attempts to be user friendly by accepting 'n', 'N', 'f', 'F', or '0' as
196 * the first character in the boolean attributes (bold, italic, and
197 * underline).
198 *****************************************************************************/
200 static void ReadFontInformation(
201 char const *fontName,
202 FONTOBJ *font,
203 int defHeight,
204 int defBold,
205 int defItalic,
206 int defUnderline,
207 int defStrikeOut )
209 char key[256];
211 /* In order for the stock fonts to be independent of
212 * mapping mode, the height (& width) must be 0
214 sprintf(key, "%s.Height", fontName);
215 font->logfont.lfHeight =
216 PROFILE_GetWineIniInt("Tweak.Fonts", key, defHeight);
218 sprintf(key, "%s.Bold", fontName);
219 font->logfont.lfWeight =
220 (PROFILE_GetWineIniBool("Tweak.Fonts", key, defBold)) ?
221 FW_BOLD : FW_NORMAL;
223 sprintf(key, "%s.Italic", fontName);
224 font->logfont.lfItalic =
225 PROFILE_GetWineIniBool("Tweak.Fonts", key, defItalic);
227 sprintf(key, "%s.Underline", fontName);
228 font->logfont.lfUnderline =
229 PROFILE_GetWineIniBool("Tweak.Fonts", key, defUnderline);
231 sprintf(key, "%s.StrikeOut", fontName);
232 font->logfont.lfStrikeOut =
233 PROFILE_GetWineIniBool("Tweak.Fonts", key, defStrikeOut);
235 return;
238 /***********************************************************************
239 * GDI_Init
241 * GDI initialization.
243 BOOL GDI_Init(void)
245 BOOL systemIsBold = (TWEAK_WineLook == WIN31_LOOK);
247 /* Kill some warnings. */
248 (void)align_OEMFixedFont;
249 (void)align_AnsiFixedFont;
250 (void)align_AnsiVarFont;
251 (void)align_SystemFont;
252 (void)align_DeviceDefaultFont;
253 (void)align_SystemFixedFont;
254 (void)align_DefaultGuiFont;
256 /* TWEAK: Initialize font hints */
257 ReadFontInformation("OEMFixed", &OEMFixedFont, 0, 0, 0, 0, 0);
258 ReadFontInformation("AnsiFixed", &AnsiFixedFont, 0, 0, 0, 0, 0);
259 ReadFontInformation("AnsiVar", &AnsiVarFont, 0, 0, 0, 0, 0);
260 ReadFontInformation("System", &SystemFont, 0, systemIsBold, 0, 0, 0);
261 ReadFontInformation("DeviceDefault", &DeviceDefaultFont, 0, 0, 0, 0, 0);
262 ReadFontInformation("SystemFixed", &SystemFixedFont, 0, systemIsBold, 0, 0, 0);
263 ReadFontInformation("DefaultGui", &DefaultGuiFont, 0, 0, 0, 0, 0);
265 /* Initialize drivers */
267 #ifndef X_DISPLAY_MISSING
268 GDI_Driver = &X11DRV_GDI_Driver;
269 #else /* !defined(X_DISPLAY_MISSING) */
270 GDI_Driver = &TTYDRV_GDI_Driver;
271 #endif /* !defined(X_DISPLAY_MISSING */
273 GDI_Driver->pInitialize();
275 /* Create default palette */
277 /* DR well *this* palette can't be moveable (?) */
279 HPALETTE16 hpalette = PALETTE_Init();
280 if( !hpalette )
281 return FALSE;
282 StockObjects[DEFAULT_PALETTE] = (GDIOBJHDR *)GDI_HEAP_LOCK( hpalette );
285 return TRUE;
289 /***********************************************************************
290 * GDI_AllocObject
292 HGDIOBJ16 GDI_AllocObject( WORD size, WORD magic )
294 static DWORD count = 0;
295 GDIOBJHDR * obj;
296 HGDIOBJ16 handle;
297 if ( magic == DC_MAGIC || magic == METAFILE_DC_MAGIC )
298 handle = GDI_HEAP_ALLOC( size );
299 else
300 handle = GDI_HEAP_ALLOC_MOVEABLE( size );
301 if (!handle) return 0;
302 obj = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
303 obj->hNext = 0;
304 obj->wMagic = magic;
305 obj->dwCount = ++count;
306 GDI_HEAP_UNLOCK( handle );
307 return handle;
311 /***********************************************************************
312 * GDI_FreeObject
314 BOOL GDI_FreeObject( HGDIOBJ16 handle )
316 GDIOBJHDR * object;
318 /* Can't free stock objects */
319 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
320 return TRUE;
322 object = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
323 if (!object) return FALSE;
324 object->wMagic = 0; /* Mark it as invalid */
326 /* Free object */
328 GDI_HEAP_FREE( handle );
329 return TRUE;
332 /***********************************************************************
333 * GDI_GetObjPtr
335 * Return a pointer to the GDI object associated to the handle.
336 * Return NULL if the object has the wrong magic number.
337 * Movable GDI objects are locked in memory: it is up to the caller to unlock
338 * it after the caller is done with the pointer.
340 GDIOBJHDR * GDI_GetObjPtr( HGDIOBJ16 handle, WORD magic )
342 GDIOBJHDR * ptr = NULL;
344 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
345 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
346 else
347 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
348 if (!ptr) return NULL;
349 if ((magic != MAGIC_DONTCARE) && (ptr->wMagic != magic))
351 GDI_HEAP_UNLOCK( handle );
352 return NULL;
354 return ptr;
358 /***********************************************************************
359 * DeleteObject16 (GDI.69)
361 BOOL16 WINAPI DeleteObject16( HGDIOBJ16 obj )
363 return DeleteObject( obj );
367 /***********************************************************************
368 * DeleteObject32 (GDI32.70)
370 BOOL WINAPI DeleteObject( HGDIOBJ obj )
372 /* Check if object is valid */
374 GDIOBJHDR * header;
375 if (HIWORD(obj)) return FALSE;
376 if ((obj >= FIRST_STOCK_HANDLE) && (obj <= LAST_STOCK_HANDLE))
377 return TRUE;
378 if (!(header = (GDIOBJHDR *) GDI_HEAP_LOCK( obj ))) return FALSE;
380 TRACE("%04x\n", obj );
382 /* Delete object */
384 switch(header->wMagic)
386 case PEN_MAGIC: return GDI_FreeObject( obj );
387 case BRUSH_MAGIC: return BRUSH_DeleteObject( obj, (BRUSHOBJ*)header );
388 case FONT_MAGIC: return GDI_FreeObject( obj );
389 case PALETTE_MAGIC: return PALETTE_DeleteObject(obj,(PALETTEOBJ*)header);
390 case BITMAP_MAGIC: return BITMAP_DeleteObject( obj, (BITMAPOBJ*)header);
391 case REGION_MAGIC: return REGION_DeleteObject( obj, (RGNOBJ*)header );
392 case DC_MAGIC: return DeleteDC(obj);
393 case 0 :
394 WARN("Already deleted\n");
395 break;
396 default:
397 WARN("Unknown magic number (%d)\n",header->wMagic);
399 return FALSE;
402 /***********************************************************************
403 * GetStockObject16 (GDI.87)
405 HGDIOBJ16 WINAPI GetStockObject16( INT16 obj )
407 return (HGDIOBJ16)GetStockObject( obj );
411 /***********************************************************************
412 * GetStockObject32 (GDI32.220)
414 HGDIOBJ WINAPI GetStockObject( INT obj )
416 if ((obj < 0) || (obj >= NB_STOCK_OBJECTS)) return 0;
417 if (!StockObjects[obj]) return 0;
418 TRACE("returning %d\n",
419 FIRST_STOCK_HANDLE + obj );
420 return (HGDIOBJ16)(FIRST_STOCK_HANDLE + obj);
424 /***********************************************************************
425 * GetObject16 (GDI.82)
427 INT16 WINAPI GetObject16( HANDLE16 handle, INT16 count, LPVOID buffer )
429 GDIOBJHDR * ptr = NULL;
430 INT16 result = 0;
431 TRACE("%04x %d %p\n", handle, count, buffer );
432 if (!count) return 0;
434 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
435 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
436 else
437 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
438 if (!ptr) return 0;
440 switch(ptr->wMagic)
442 case PEN_MAGIC:
443 result = PEN_GetObject16( (PENOBJ *)ptr, count, buffer );
444 break;
445 case BRUSH_MAGIC:
446 result = BRUSH_GetObject16( (BRUSHOBJ *)ptr, count, buffer );
447 break;
448 case BITMAP_MAGIC:
449 result = BITMAP_GetObject16( (BITMAPOBJ *)ptr, count, buffer );
450 break;
451 case FONT_MAGIC:
452 result = FONT_GetObject16( (FONTOBJ *)ptr, count, buffer );
453 break;
454 case PALETTE_MAGIC:
455 result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer );
456 break;
458 GDI_HEAP_UNLOCK( handle );
459 return result;
463 /***********************************************************************
464 * GetObject32A (GDI32.204)
466 INT WINAPI GetObjectA( HANDLE handle, INT count, LPVOID buffer )
468 GDIOBJHDR * ptr = NULL;
469 INT result = 0;
470 TRACE("%08x %d %p\n", handle, count, buffer );
471 if (!count) return 0;
473 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
474 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
475 else
476 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
477 if (!ptr) return 0;
479 switch(ptr->wMagic)
481 case PEN_MAGIC:
482 result = PEN_GetObject( (PENOBJ *)ptr, count, buffer );
483 break;
484 case BRUSH_MAGIC:
485 result = BRUSH_GetObject( (BRUSHOBJ *)ptr, count, buffer );
486 break;
487 case BITMAP_MAGIC:
488 result = BITMAP_GetObject( (BITMAPOBJ *)ptr, count, buffer );
489 break;
490 case FONT_MAGIC:
491 result = FONT_GetObjectA( (FONTOBJ *)ptr, count, buffer );
492 break;
493 case PALETTE_MAGIC:
494 result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer );
495 break;
496 default:
497 FIXME("Magic %04x not implemented\n",
498 ptr->wMagic );
499 break;
501 GDI_HEAP_UNLOCK( handle );
502 return result;
504 /***********************************************************************
505 * GetObject32W (GDI32.206)
507 INT WINAPI GetObjectW( HANDLE handle, INT count, LPVOID buffer )
509 GDIOBJHDR * ptr = NULL;
510 INT result = 0;
511 TRACE("%08x %d %p\n", handle, count, buffer );
512 if (!count) return 0;
514 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
515 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
516 else
517 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
518 if (!ptr) return 0;
520 switch(ptr->wMagic)
522 case PEN_MAGIC:
523 result = PEN_GetObject( (PENOBJ *)ptr, count, buffer );
524 break;
525 case BRUSH_MAGIC:
526 result = BRUSH_GetObject( (BRUSHOBJ *)ptr, count, buffer );
527 break;
528 case BITMAP_MAGIC:
529 result = BITMAP_GetObject( (BITMAPOBJ *)ptr, count, buffer );
530 break;
531 case FONT_MAGIC:
532 result = FONT_GetObjectW( (FONTOBJ *)ptr, count, buffer );
533 break;
534 case PALETTE_MAGIC:
535 result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer );
536 break;
537 default:
538 FIXME("Magic %04x not implemented\n",
539 ptr->wMagic );
540 break;
542 GDI_HEAP_UNLOCK( handle );
543 return result;
546 /***********************************************************************
547 * GetObjectType (GDI32.205)
549 DWORD WINAPI GetObjectType( HANDLE handle )
551 GDIOBJHDR * ptr = NULL;
552 INT result = 0;
553 TRACE("%08x\n", handle );
555 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
556 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
557 else
558 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
559 if (!ptr) return 0;
561 switch(ptr->wMagic)
563 case PEN_MAGIC:
564 result = OBJ_PEN;
565 break;
566 case BRUSH_MAGIC:
567 result = OBJ_BRUSH;
568 break;
569 case BITMAP_MAGIC:
570 result = OBJ_BITMAP;
571 break;
572 case FONT_MAGIC:
573 result = OBJ_FONT;
574 break;
575 case PALETTE_MAGIC:
576 result = OBJ_PAL;
577 break;
578 case REGION_MAGIC:
579 result = OBJ_REGION;
580 break;
581 case DC_MAGIC:
582 result = OBJ_DC;
583 break;
584 case META_DC_MAGIC:
585 result = OBJ_METADC;
586 break;
587 case METAFILE_MAGIC:
588 result = OBJ_METAFILE;
589 break;
590 case METAFILE_DC_MAGIC:
591 result = OBJ_METADC;
592 break;
593 case ENHMETAFILE_MAGIC:
594 result = OBJ_ENHMETAFILE;
595 break;
596 case ENHMETAFILE_DC_MAGIC:
597 result = OBJ_ENHMETADC;
598 break;
599 default:
600 FIXME("Magic %04x not implemented\n",
601 ptr->wMagic );
602 break;
604 GDI_HEAP_UNLOCK( handle );
605 return result;
608 /***********************************************************************
609 * GetCurrentObject (GDI32.166)
611 HANDLE WINAPI GetCurrentObject(HDC hdc,UINT type)
613 DC * dc = DC_GetDCPtr( hdc );
615 if (!dc)
616 return 0;
617 switch (type) {
618 case OBJ_PEN: return dc->w.hPen;
619 case OBJ_BRUSH: return dc->w.hBrush;
620 case OBJ_PAL: return dc->w.hPalette;
621 case OBJ_FONT: return dc->w.hFont;
622 case OBJ_BITMAP: return dc->w.hBitmap;
623 default:
624 /* the SDK only mentions those above */
625 WARN("(%08x,%d): unknown type.\n",hdc,type);
626 return 0;
631 /***********************************************************************
632 * SelectObject16 (GDI.45)
634 HGDIOBJ16 WINAPI SelectObject16( HDC16 hdc, HGDIOBJ16 handle )
636 return (HGDIOBJ16)SelectObject( hdc, handle );
640 /***********************************************************************
641 * SelectObject32 (GDI32.299)
643 HGDIOBJ WINAPI SelectObject( HDC hdc, HGDIOBJ handle )
645 DC * dc = DC_GetDCPtr( hdc );
646 if (!dc || !dc->funcs->pSelectObject) return 0;
647 TRACE("hdc=%04x %04x\n", hdc, handle );
648 return dc->funcs->pSelectObject( dc, handle );
652 /***********************************************************************
653 * UnrealizeObject16 (GDI.150)
655 BOOL16 WINAPI UnrealizeObject16( HGDIOBJ16 obj )
657 return UnrealizeObject( obj );
661 /***********************************************************************
662 * UnrealizeObject (GDI32.358)
664 BOOL WINAPI UnrealizeObject( HGDIOBJ obj )
666 BOOL result = TRUE;
667 /* Check if object is valid */
669 GDIOBJHDR * header = (GDIOBJHDR *) GDI_HEAP_LOCK( obj );
670 if (!header) return FALSE;
672 TRACE("%04x\n", obj );
674 /* Unrealize object */
676 switch(header->wMagic)
678 case PALETTE_MAGIC:
679 result = PALETTE_UnrealizeObject( obj, (PALETTEOBJ *)header );
680 break;
682 case BRUSH_MAGIC:
683 /* Windows resets the brush origin. We don't need to. */
684 break;
686 GDI_HEAP_UNLOCK( obj );
687 return result;
691 /***********************************************************************
692 * EnumObjects16 (GDI.71)
694 INT16 WINAPI EnumObjects16( HDC16 hdc, INT16 nObjType,
695 GOBJENUMPROC16 lpEnumFunc, LPARAM lParam )
697 /* Solid colors to enumerate */
698 static const COLORREF solid_colors[] =
699 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
700 RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
701 RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
702 RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
703 RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
704 RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
705 RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
706 RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
709 INT16 i, retval = 0;
710 LOGPEN16 *pen;
711 LOGBRUSH16 *brush = NULL;
713 TRACE("%04x %d %08lx %08lx\n",
714 hdc, nObjType, (DWORD)lpEnumFunc, lParam );
715 switch(nObjType)
717 case OBJ_PEN:
718 /* Enumerate solid pens */
719 if (!(pen = SEGPTR_NEW(LOGPEN16))) break;
720 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
722 pen->lopnStyle = PS_SOLID;
723 pen->lopnWidth.x = 1;
724 pen->lopnWidth.y = 0;
725 pen->lopnColor = solid_colors[i];
726 retval = lpEnumFunc( SEGPTR_GET(pen), lParam );
727 TRACE("solid pen %08lx, ret=%d\n",
728 solid_colors[i], retval);
729 if (!retval) break;
731 SEGPTR_FREE(pen);
732 break;
734 case OBJ_BRUSH:
735 /* Enumerate solid brushes */
736 if (!(brush = SEGPTR_NEW(LOGBRUSH16))) break;
737 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
739 brush->lbStyle = BS_SOLID;
740 brush->lbColor = solid_colors[i];
741 brush->lbHatch = 0;
742 retval = lpEnumFunc( SEGPTR_GET(brush), lParam );
743 TRACE("solid brush %08lx, ret=%d\n",
744 solid_colors[i], retval);
745 if (!retval) break;
748 /* Now enumerate hatched brushes */
749 if (retval) for (i = HS_HORIZONTAL; i <= HS_DIAGCROSS; i++)
751 brush->lbStyle = BS_HATCHED;
752 brush->lbColor = RGB(0,0,0);
753 brush->lbHatch = i;
754 retval = lpEnumFunc( SEGPTR_GET(brush), lParam );
755 TRACE("hatched brush %d, ret=%d\n",
756 i, retval);
757 if (!retval) break;
759 SEGPTR_FREE(brush);
760 break;
762 default:
763 WARN("(%d): Invalid type\n", nObjType );
764 break;
766 return retval;
770 /***********************************************************************
771 * EnumObjects32 (GDI32.89)
773 INT WINAPI EnumObjects( HDC hdc, INT nObjType,
774 GOBJENUMPROC lpEnumFunc, LPARAM lParam )
776 /* Solid colors to enumerate */
777 static const COLORREF solid_colors[] =
778 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
779 RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
780 RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
781 RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
782 RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
783 RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
784 RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
785 RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
788 INT i, retval = 0;
789 LOGPEN pen;
790 LOGBRUSH brush;
792 TRACE("%04x %d %08lx %08lx\n",
793 hdc, nObjType, (DWORD)lpEnumFunc, lParam );
794 switch(nObjType)
796 case OBJ_PEN:
797 /* Enumerate solid pens */
798 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
800 pen.lopnStyle = PS_SOLID;
801 pen.lopnWidth.x = 1;
802 pen.lopnWidth.y = 0;
803 pen.lopnColor = solid_colors[i];
804 retval = lpEnumFunc( &pen, lParam );
805 TRACE("solid pen %08lx, ret=%d\n",
806 solid_colors[i], retval);
807 if (!retval) break;
809 break;
811 case OBJ_BRUSH:
812 /* Enumerate solid brushes */
813 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
815 brush.lbStyle = BS_SOLID;
816 brush.lbColor = solid_colors[i];
817 brush.lbHatch = 0;
818 retval = lpEnumFunc( &brush, lParam );
819 TRACE("solid brush %08lx, ret=%d\n",
820 solid_colors[i], retval);
821 if (!retval) break;
824 /* Now enumerate hatched brushes */
825 if (retval) for (i = HS_HORIZONTAL; i <= HS_DIAGCROSS; i++)
827 brush.lbStyle = BS_HATCHED;
828 brush.lbColor = RGB(0,0,0);
829 brush.lbHatch = i;
830 retval = lpEnumFunc( &brush, lParam );
831 TRACE("hatched brush %d, ret=%d\n",
832 i, retval);
833 if (!retval) break;
835 break;
837 default:
838 /* FIXME: implement Win32 types */
839 WARN("(%d): Invalid type\n", nObjType );
840 break;
842 return retval;
846 /***********************************************************************
847 * IsGDIObject (GDI.462)
849 * returns type of object if valid (W95 system programming secrets p. 264-5)
851 BOOL16 WINAPI IsGDIObject16( HGDIOBJ16 handle )
853 UINT16 magic = 0;
855 if (handle >= FIRST_STOCK_HANDLE )
857 switch (handle)
859 case STOCK_WHITE_BRUSH:
860 case STOCK_LTGRAY_BRUSH:
861 case STOCK_GRAY_BRUSH:
862 case STOCK_DKGRAY_BRUSH:
863 case STOCK_BLACK_BRUSH:
864 case STOCK_HOLLOW_BRUSH:
865 magic = BRUSH_MAGIC;
866 break;
868 case STOCK_WHITE_PEN:
869 case STOCK_BLACK_PEN:
870 case STOCK_NULL_PEN :
871 magic = PEN_MAGIC;
872 break;
874 case STOCK_OEM_FIXED_FONT:
875 case STOCK_ANSI_FIXED_FONT:
876 case STOCK_ANSI_VAR_FONT:
877 case STOCK_SYSTEM_FONT:
878 case STOCK_DEVICE_DEFAULT_FONT:
879 case STOCK_SYSTEM_FIXED_FONT:
880 case STOCK_DEFAULT_GUI_FONT:
881 magic = FONT_MAGIC;
882 break;
884 case STOCK_DEFAULT_PALETTE:
885 magic = PALETTE_MAGIC;
886 break;
889 else
891 GDIOBJHDR *object = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
892 if (object)
894 magic = object->wMagic;
895 GDI_HEAP_UNLOCK( handle );
899 if (magic >= PEN_MAGIC && magic <= METAFILE_DC_MAGIC)
900 return magic - PEN_MAGIC + 1;
901 else
902 return FALSE;
906 /***********************************************************************
907 * SetObjectOwner16 (GDI.461)
909 void WINAPI SetObjectOwner16( HGDIOBJ16 handle, HANDLE16 owner )
911 /* Nothing to do */
915 /***********************************************************************
916 * SetObjectOwner32 (GDI32.386)
918 void WINAPI SetObjectOwner( HGDIOBJ handle, HANDLE owner )
920 /* Nothing to do */
923 /***********************************************************************
924 * MakeObjectPrivate (GDI.463)
926 void WINAPI MakeObjectPrivate16( HGDIOBJ16 handle, BOOL16 private )
928 /* FIXME */
932 /***********************************************************************
933 * GdiFlush (GDI32.128)
935 BOOL WINAPI GdiFlush(void)
937 return TRUE; /* FIXME */
941 /***********************************************************************
942 * GdiGetBatchLimit (GDI32.129)
944 DWORD WINAPI GdiGetBatchLimit(void)
946 return 1; /* FIXME */
950 /***********************************************************************
951 * GdiSetBatchLimit (GDI32.139)
953 DWORD WINAPI GdiSetBatchLimit( DWORD limit )
955 return 1; /* FIXME */
959 /***********************************************************************
960 * GdiSeeGdiDo (GDI.452)
962 DWORD WINAPI GdiSeeGdiDo16( WORD wReqType, WORD wParam1, WORD wParam2,
963 WORD wParam3 )
965 switch (wReqType)
967 case 0x0001: /* LocalAlloc */
968 return LOCAL_Alloc( GDI_HeapSel, wParam1, wParam3 );
969 case 0x0002: /* LocalFree */
970 return LOCAL_Free( GDI_HeapSel, wParam1 );
971 case 0x0003: /* LocalCompact */
972 return LOCAL_Compact( GDI_HeapSel, wParam3, 0 );
973 case 0x0103: /* LocalHeap */
974 return GDI_HeapSel;
975 default:
976 WARN("(wReqType=%04x): Unknown\n", wReqType);
977 return (DWORD)-1;
981 /***********************************************************************
982 * GdiSignalProc (GDI.610)
984 WORD WINAPI GdiSignalProc( UINT uCode, DWORD dwThreadOrProcessID,
985 DWORD dwFlags, HMODULE16 hModule )
987 return 0;
990 /***********************************************************************
991 * FinalGdiInit16 (GDI.405)
993 void WINAPI FinalGdiInit16( HANDLE16 unknown )
997 /***********************************************************************
998 * GdiFreeResources (GDI.609)
1000 WORD WINAPI GdiFreeResources16( DWORD reserve )
1002 return (WORD)( (int)LOCAL_CountFree( GDI_HeapSel ) * 100 /
1003 (int)LOCAL_HeapSize( GDI_HeapSel ) );
1006 /***********************************************************************
1007 * MulDiv16 (GDI.128)
1009 INT16 WINAPI MulDiv16( INT16 foo, INT16 bar, INT16 baz )
1011 INT ret;
1012 if (!baz) return -32768;
1013 ret = (foo * bar) / baz;
1014 if ((ret > 32767) || (ret < -32767)) return -32768;
1015 return ret;
1019 /***********************************************************************
1020 * MulDiv32 (KERNEL32.391)
1021 * RETURNS
1022 * Result of multiplication and division
1023 * -1: Overflow occurred or Divisor was 0
1025 INT WINAPI MulDiv(
1026 INT nMultiplicand,
1027 INT nMultiplier,
1028 INT nDivisor
1030 #if (SIZEOF_LONG_LONG >= 8)
1031 long long ret;
1033 if (!nDivisor) return -1;
1035 /* We want to deal with a positive divisor to simplify the logic. */
1036 if (nDivisor < 0)
1038 nMultiplicand = - nMultiplicand;
1039 nDivisor = -nDivisor;
1042 /* If the result is positive, we "add" to round. else, we subtract to round. */
1043 if ( ( (nMultiplicand < 0) && (nMultiplier < 0) ) ||
1044 ( (nMultiplicand >= 0) && (nMultiplier >= 0) ) )
1045 ret = (((long long)nMultiplicand * nMultiplier) + (nDivisor/2)) / nDivisor;
1046 else
1047 ret = (((long long)nMultiplicand * nMultiplier) - (nDivisor/2)) / nDivisor;
1049 if ((ret > 2147483647) || (ret < -2147483647)) return -1;
1050 return ret;
1051 #else
1052 if (!nDivisor) return -1;
1054 /* We want to deal with a positive divisor to simplify the logic. */
1055 if (nDivisor < 0)
1057 nMultiplicand = - nMultiplicand;
1058 nDivisor = -nDivisor;
1061 /* If the result is positive, we "add" to round. else, we subtract to round. */
1062 if ( ( (nMultiplicand < 0) && (nMultiplier < 0) ) ||
1063 ( (nMultiplicand >= 0) && (nMultiplier >= 0) ) )
1064 return ((nMultiplicand * nMultiplier) + (nDivisor/2)) / nDivisor;
1066 return ((nMultiplicand * nMultiplier) - (nDivisor/2)) / nDivisor;
1068 #endif
1070 /*******************************************************************
1071 * GetColorAdjustment [GDI32.164]
1075 BOOL WINAPI GetColorAdjustment(HDC hdc, LPCOLORADJUSTMENT lpca)
1077 FIXME("GetColorAdjustment, stub\n");
1078 return 0;
1081 /*******************************************************************
1082 * GetMiterLimit [GDI32.201]
1086 BOOL WINAPI GetMiterLimit(HDC hdc, PFLOAT peLimit)
1088 FIXME("GetMiterLimit, stub\n");
1089 return 0;
1092 /*******************************************************************
1093 * SetMiterLimit [GDI32.325]
1097 BOOL WINAPI SetMiterLimit(HDC hdc, FLOAT eNewLimit, PFLOAT peOldLimit)
1099 FIXME("SetMiterLimit, stub\n");
1100 return 0;
1103 /*******************************************************************
1104 * GdiComment [GDI32.109]
1108 BOOL WINAPI GdiComment(HDC hdc, UINT cbSize, const BYTE *lpData)
1110 FIXME("GdiComment, stub\n");
1111 return 0;
1113 /*******************************************************************
1114 * SetColorAdjustment [GDI32.309]
1118 BOOL WINAPI SetColorAdjustment(HDC hdc, const COLORADJUSTMENT* lpca)
1120 FIXME("SetColorAdjustment, stub\n");
1121 return 0;