4 * Copyright 1993 Alexandre Julliard
24 /* Object types for EnumObjects() */
28 /***********************************************************************
32 static BRUSHOBJ WhiteBrush =
34 { 0, BRUSH_MAGIC, 1 }, /* header */
35 { BS_SOLID, RGB(255,255,255), 0 } /* logbrush */
38 static BRUSHOBJ LtGrayBrush =
40 { 0, BRUSH_MAGIC, 1 }, /* header */
41 /* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
42 { BS_SOLID, RGB(192,192,192), 0 } /* logbrush */
45 static BRUSHOBJ GrayBrush =
47 { 0, BRUSH_MAGIC, 1 }, /* header */
48 /* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
49 { BS_SOLID, RGB(128,128,128), 0 } /* logbrush */
52 static BRUSHOBJ DkGrayBrush =
54 { 0, BRUSH_MAGIC, 1 }, /* header */
55 /* This is BS_HATCHED, for 1 bitperpixel. This makes the spray work in pbrush */
56 /* NB_HATCH_STYLES is an index into HatchBrushes */
57 { BS_HATCHED, RGB(0,0,0), NB_HATCH_STYLES } /* logbrush */
60 static BRUSHOBJ BlackBrush =
62 { 0, BRUSH_MAGIC, 1 }, /* header */
63 { BS_SOLID, RGB(0,0,0), 0 } /* logbrush */
66 static BRUSHOBJ NullBrush =
68 { 0, BRUSH_MAGIC, 1 }, /* header */
69 { BS_NULL, 0, 0 } /* logbrush */
72 static PENOBJ WhitePen =
74 { 0, PEN_MAGIC, 1 }, /* header */
75 { PS_SOLID, { 1, 0 }, RGB(255,255,255) } /* logpen */
78 static PENOBJ BlackPen =
80 { 0, PEN_MAGIC, 1 }, /* header */
81 { PS_SOLID, { 1, 0 }, RGB(0,0,0) } /* logpen */
84 static PENOBJ NullPen =
86 { 0, PEN_MAGIC, 1 }, /* header */
87 { PS_NULL, { 1, 0 }, 0 } /* logpen */
90 static FONTOBJ OEMFixedFont =
92 { 0, FONT_MAGIC, 1 }, /* header */
93 { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, OEM_CHARSET,
94 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" }
97 static FONTOBJ AnsiFixedFont =
99 { 0, FONT_MAGIC, 1 }, /* header */
100 { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
101 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" }
104 static FONTOBJ AnsiVarFont =
106 { 0, FONT_MAGIC, 1 }, /* header */
107 { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
108 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "MS Sans Serif" }
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" }
118 static FONTOBJ DeviceDefaultFont =
120 { 0, FONT_MAGIC, 1 }, /* header */
121 { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
122 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "" }
125 static FONTOBJ SystemFixedFont =
127 { 0, FONT_MAGIC, 1 }, /* header */
128 { 12, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, ANSI_CHARSET,
129 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" }
133 static GDIOBJHDR * StockObjects[NB_STOCK_OBJECTS] =
135 (GDIOBJHDR *) &WhiteBrush,
136 (GDIOBJHDR *) &LtGrayBrush,
137 (GDIOBJHDR *) &GrayBrush,
138 (GDIOBJHDR *) &DkGrayBrush,
139 (GDIOBJHDR *) &BlackBrush,
140 (GDIOBJHDR *) &NullBrush,
141 (GDIOBJHDR *) &WhitePen,
142 (GDIOBJHDR *) &BlackPen,
143 (GDIOBJHDR *) &NullPen,
145 (GDIOBJHDR *) &OEMFixedFont,
146 (GDIOBJHDR *) &AnsiFixedFont,
147 (GDIOBJHDR *) &AnsiVarFont,
148 (GDIOBJHDR *) &SystemFont,
149 (GDIOBJHDR *) &DeviceDefaultFont,
150 NULL, /* DEFAULT_PALETTE created by PALETTE_Init */
151 (GDIOBJHDR *) &SystemFixedFont
154 /******************************************************************************
156 * void ReadFontInformation(
157 * char const *fontName,
165 * ReadFontInformation() checks the Wine configuration file's Tweak.Fonts
166 * section for entries containing fontName.Height, fontName.Bold, etc.,
167 * where fontName is the name specified in the call (e.g., "System"). It
168 * attempts to be user friendly by accepting 'n', 'N', 'f', 'F', or '0' as
169 * the first character in the boolean attributes (bold, italic, and
171 *****************************************************************************/
173 static void ReadFontInformation(
174 char const *fontName,
184 sprintf(key, "%s.Height", fontName);
185 font->logfont.lfHeight =
186 PROFILE_GetWineIniInt("Tweak.Fonts", key, defHeight);
188 sprintf(key, "%s.Bold", fontName);
189 font->logfont.lfWeight =
190 (PROFILE_GetWineIniBool("Tweak.Fonts", key, defBold)) ?
193 sprintf(key, "%s.Italic", fontName);
194 font->logfont.lfItalic =
195 PROFILE_GetWineIniBool("Tweak.Fonts", key, defItalic);
197 sprintf(key, "%s.Underline", fontName);
198 font->logfont.lfUnderline =
199 PROFILE_GetWineIniBool("Tweak.Fonts", key, defUnderline);
201 sprintf(key, "%s.StrikeOut", fontName);
202 font->logfont.lfStrikeOut =
203 PROFILE_GetWineIniBool("Tweak.Fonts", key, defStrikeOut);
209 /***********************************************************************
212 * GDI initialization.
214 BOOL32 GDI_Init(void)
216 extern BOOL32 X11DRV_Init(void);
217 extern BOOL32 DIB_Init(void);
219 /* TWEAK: Initialize font hints */
220 ReadFontInformation("OEMFixed", &OEMFixedFont, 12, 0, 0, 0, 0);
221 ReadFontInformation("AnsiFixed", &AnsiFixedFont, 12, 0, 0, 0, 0);
222 ReadFontInformation("AnsiVar", &AnsiVarFont, 12, 0, 0, 0, 0);
223 ReadFontInformation("System", &SystemFont, 16, 1, 0, 0, 0);
224 ReadFontInformation("SystemFixed", &SystemFixedFont, 12, 1, 0, 0, 0);
226 /* Initialize drivers */
228 DIB_Init(); /* always before X11DRV_Init() */
232 /* Create default palette */
234 HPALETTE16 hpalette = PALETTE_Init();
238 StockObjects[DEFAULT_PALETTE] = (GDIOBJHDR *)GDI_HEAP_LIN_ADDR( hpalette );
246 /***********************************************************************
249 HGDIOBJ16 GDI_AllocObject( WORD size, WORD magic )
251 static DWORD count = 0;
253 HGDIOBJ16 handle = GDI_HEAP_ALLOC( size );
254 if (!handle) return 0;
255 obj = (GDIOBJHDR *) GDI_HEAP_LIN_ADDR( handle );
258 obj->dwCount = ++count;
263 /***********************************************************************
266 BOOL32 GDI_FreeObject( HGDIOBJ16 handle )
270 /* Can't free stock objects */
271 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
274 object = (GDIOBJHDR *) GDI_HEAP_LIN_ADDR( handle );
275 if (!object) return FALSE;
276 object->wMagic = 0; /* Mark it as invalid */
280 GDI_HEAP_FREE( handle );
284 /***********************************************************************
287 * Return a pointer to the GDI object associated to the handle.
288 * Return NULL if the object has the wrong magic number.
290 GDIOBJHDR * GDI_GetObjPtr( HGDIOBJ16 handle, WORD magic )
292 GDIOBJHDR * ptr = NULL;
294 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
295 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
297 ptr = (GDIOBJHDR *) GDI_HEAP_LIN_ADDR( handle );
298 if (!ptr) return NULL;
299 if ((magic != MAGIC_DONTCARE) && (ptr->wMagic != magic)) return NULL;
304 /***********************************************************************
305 * DeleteObject16 (GDI.69)
307 BOOL16 DeleteObject16( HGDIOBJ16 obj )
309 return DeleteObject32( obj );
313 /***********************************************************************
314 * DeleteObject32 (GDI32.70)
316 BOOL32 DeleteObject32( HGDIOBJ32 obj )
318 /* Check if object is valid */
320 GDIOBJHDR * header = (GDIOBJHDR *) GDI_HEAP_LIN_ADDR( obj );
321 if (!header || HIWORD(obj)) return FALSE;
323 dprintf_gdi(stddeb, "DeleteObject: %04x\n", obj );
327 switch(header->wMagic)
329 case PEN_MAGIC: return GDI_FreeObject( obj );
330 case BRUSH_MAGIC: return BRUSH_DeleteObject( obj, (BRUSHOBJ*)header );
331 case FONT_MAGIC: return GDI_FreeObject( obj );
332 case PALETTE_MAGIC: return PALETTE_DeleteObject(obj,(PALETTEOBJ*)header);
333 case BITMAP_MAGIC: return BITMAP_DeleteObject( obj, (BITMAPOBJ*)header);
334 case REGION_MAGIC: return REGION_DeleteObject( obj, (RGNOBJ*)header );
340 /***********************************************************************
341 * GetStockObject16 (GDI.87)
343 HGDIOBJ16 GetStockObject16( INT16 obj )
345 return (HGDIOBJ16)GetStockObject32( obj );
349 /***********************************************************************
350 * GetStockObject32 (GDI32.220)
352 HGDIOBJ32 GetStockObject32( INT32 obj )
354 if ((obj < 0) || (obj >= NB_STOCK_OBJECTS)) return 0;
355 if (!StockObjects[obj]) return 0;
356 dprintf_gdi(stddeb, "GetStockObject: returning %d\n",
357 FIRST_STOCK_HANDLE + obj );
358 return (HGDIOBJ16)(FIRST_STOCK_HANDLE + obj);
362 /***********************************************************************
363 * GetObject16 (GDI.82)
365 INT16 GetObject16( HANDLE16 handle, INT16 count, LPVOID buffer )
367 GDIOBJHDR * ptr = NULL;
368 dprintf_gdi(stddeb, "GetObject16: %04x %d %p\n", handle, count, buffer );
369 if (!count) return 0;
371 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
372 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
374 ptr = (GDIOBJHDR *) GDI_HEAP_LIN_ADDR( handle );
380 return PEN_GetObject16( (PENOBJ *)ptr, count, buffer );
382 return BRUSH_GetObject16( (BRUSHOBJ *)ptr, count, buffer );
384 return BITMAP_GetObject16( (BITMAPOBJ *)ptr, count, buffer );
386 return FONT_GetObject16( (FONTOBJ *)ptr, count, buffer );
388 return PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer );
394 /***********************************************************************
395 * GetObject32A (GDI32.204)
397 INT32 GetObject32A( HANDLE32 handle, INT32 count, LPVOID buffer )
399 GDIOBJHDR * ptr = NULL;
400 dprintf_gdi(stddeb, "GetObject32A: %08x %d %p\n", handle, count, buffer );
401 if (!count) return 0;
403 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
404 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
406 ptr = (GDIOBJHDR *) GDI_HEAP_LIN_ADDR( handle );
412 return PEN_GetObject32( (PENOBJ *)ptr, count, buffer );
414 return BRUSH_GetObject32( (BRUSHOBJ *)ptr, count, buffer );
416 return BITMAP_GetObject32( (BITMAPOBJ *)ptr, count, buffer );
418 return FONT_GetObject32A( (FONTOBJ *)ptr, count, buffer );
420 fprintf( stderr, "GetObject32: magic %04x not implemented\n",
428 /***********************************************************************
429 * GetObject32W (GDI32.206)
431 INT32 GetObject32W( HANDLE32 handle, INT32 count, LPVOID buffer )
433 return GetObject32A( handle, count, buffer );
437 /***********************************************************************
438 * SelectObject16 (GDI.45)
440 HGDIOBJ16 SelectObject16( HDC16 hdc, HGDIOBJ16 handle )
442 return (HGDIOBJ16)SelectObject32( hdc, handle );
446 /***********************************************************************
447 * SelectObject32 (GDI32.299)
449 HGDIOBJ32 SelectObject32( HDC32 hdc, HGDIOBJ32 handle )
451 DC * dc = DC_GetDCPtr( hdc );
452 if (!dc || !dc->funcs->pSelectObject) return 0;
453 dprintf_gdi(stddeb, "SelectObject: hdc=%04x %04x\n", hdc, handle );
454 return dc->funcs->pSelectObject( dc, handle );
458 /***********************************************************************
459 * UnrealizeObject16 (GDI.150)
461 BOOL16 UnrealizeObject16( HGDIOBJ16 obj )
463 return UnrealizeObject32( obj );
467 /***********************************************************************
468 * UnrealizeObject (GDI32.358)
470 BOOL32 UnrealizeObject32( HGDIOBJ32 obj )
472 /* Check if object is valid */
474 GDIOBJHDR * header = (GDIOBJHDR *) GDI_HEAP_LIN_ADDR( obj );
475 if (!header) return FALSE;
477 dprintf_gdi( stddeb, "UnrealizeObject: %04x\n", obj );
479 /* Unrealize object */
481 switch(header->wMagic)
484 return PALETTE_UnrealizeObject( obj, (PALETTEOBJ *)header );
487 /* Windows resets the brush origin. We don't need to. */
494 /***********************************************************************
495 * EnumObjects16 (GDI.71)
497 INT16 EnumObjects16( HDC16 hdc, INT16 nObjType, GOBJENUMPROC16 lpEnumFunc,
500 /* Solid colors to enumerate */
501 static const COLORREF solid_colors[] =
502 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
503 RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
504 RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
505 RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
506 RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
507 RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
508 RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
509 RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
514 LOGBRUSH16 *brush = NULL;
516 dprintf_gdi( stddeb, "EnumObjects16: %04x %d %08lx %08lx\n",
517 hdc, nObjType, (DWORD)lpEnumFunc, lParam );
521 /* Enumerate solid pens */
522 if (!(pen = SEGPTR_NEW(LOGPEN16))) break;
523 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
525 pen->lopnStyle = PS_SOLID;
526 pen->lopnWidth.x = 1;
527 pen->lopnWidth.y = 0;
528 pen->lopnColor = solid_colors[i];
529 retval = lpEnumFunc( SEGPTR_GET(pen), lParam );
530 dprintf_gdi( stddeb, "EnumObjects16: solid pen %08lx, ret=%d\n",
531 solid_colors[i], retval);
538 /* Enumerate solid brushes */
539 if (!(brush = SEGPTR_NEW(LOGBRUSH16))) break;
540 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
542 brush->lbStyle = BS_SOLID;
543 brush->lbColor = solid_colors[i];
545 retval = lpEnumFunc( SEGPTR_GET(brush), lParam );
546 dprintf_gdi( stddeb, "EnumObjects16: solid brush %08lx, ret=%d\n",
547 solid_colors[i], retval);
551 /* Now enumerate hatched brushes */
552 if (retval) for (i = HS_HORIZONTAL; i <= HS_DIAGCROSS; i++)
554 brush->lbStyle = BS_HATCHED;
555 brush->lbColor = RGB(0,0,0);
557 retval = lpEnumFunc( SEGPTR_GET(brush), lParam );
558 dprintf_gdi( stddeb, "EnumObjects16: hatched brush %d, ret=%d\n",
566 fprintf( stderr, "EnumObjects16: invalid type %d\n", nObjType );
573 /***********************************************************************
574 * EnumObjects32 (GDI32.89)
576 INT32 EnumObjects32( HDC32 hdc, INT32 nObjType, GOBJENUMPROC32 lpEnumFunc,
579 /* Solid colors to enumerate */
580 static const COLORREF solid_colors[] =
581 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
582 RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
583 RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
584 RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
585 RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
586 RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
587 RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
588 RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
595 dprintf_gdi( stddeb, "EnumObjects32: %04x %d %08lx %08lx\n",
596 hdc, nObjType, (DWORD)lpEnumFunc, lParam );
600 /* Enumerate solid pens */
601 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
603 pen.lopnStyle = PS_SOLID;
606 pen.lopnColor = solid_colors[i];
607 retval = lpEnumFunc( &pen, lParam );
608 dprintf_gdi( stddeb, "EnumObjects32: solid pen %08lx, ret=%d\n",
609 solid_colors[i], retval);
615 /* Enumerate solid brushes */
616 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
618 brush.lbStyle = BS_SOLID;
619 brush.lbColor = solid_colors[i];
621 retval = lpEnumFunc( &brush, lParam );
622 dprintf_gdi( stddeb, "EnumObjects32: solid brush %08lx, ret=%d\n",
623 solid_colors[i], retval);
627 /* Now enumerate hatched brushes */
628 if (retval) for (i = HS_HORIZONTAL; i <= HS_DIAGCROSS; i++)
630 brush.lbStyle = BS_HATCHED;
631 brush.lbColor = RGB(0,0,0);
633 retval = lpEnumFunc( &brush, lParam );
634 dprintf_gdi( stddeb, "EnumObjects32: hatched brush %d, ret=%d\n",
641 /* FIXME: implement Win32 types */
642 fprintf( stderr, "EnumObjects32: invalid type %d\n", nObjType );
649 /***********************************************************************
650 * IsGDIObject (GDI.462)
652 BOOL16 IsGDIObject( HGDIOBJ16 handle )
654 GDIOBJHDR *object = (GDIOBJHDR *) GDI_HEAP_LIN_ADDR( handle );
656 return (object->wMagic>=PEN_MAGIC && object->wMagic<= METAFILE_DC_MAGIC);
661 /***********************************************************************
664 INT16 MulDiv16( INT16 foo, INT16 bar, INT16 baz )
667 if (!baz) return -32768;
668 ret = (foo * bar) / baz;
669 if ((ret > 32767) || (ret < -32767)) return -32768;
674 /***********************************************************************
675 * MulDiv32 (KERNEL32.391)
677 INT32 MulDiv32( INT32 foo, INT32 bar, INT32 baz )
682 ret = ((long long)foo * bar) / baz;
683 if ((ret > 2147483647) || (ret < -2147483647)) return -1;
687 return (foo * bar) / baz;