2 * GDI Device Context functions
4 * Copyright 1993 Alexandre Julliard
19 extern void CLIPPING_UpdateGCRegion( DC * dc ); /* objects/clipping.c */
22 /* ROP code to GC function conversion */
23 const int DC_XROPfunction[16] =
25 GXclear, /* R2_BLACK */
26 GXnor, /* R2_NOTMERGEPEN */
27 GXandInverted, /* R2_MASKNOTPEN */
28 GXcopyInverted, /* R2_NOTCOPYPEN */
29 GXandReverse, /* R2_MASKPENNOT */
30 GXinvert, /* R2_NOT */
31 GXxor, /* R2_XORPEN */
32 GXnand, /* R2_NOTMASKPEN */
33 GXand, /* R2_MASKPEN */
34 GXequiv, /* R2_NOTXORPEN */
36 GXorInverted, /* R2_MERGENOTPEN */
37 GXcopy, /* R2_COPYPEN */
38 GXorReverse, /* R2_MERGEPENNOT */
39 GXor, /* R2_MERGEPEN */
44 /***********************************************************************
47 * Fill the device caps structure.
49 void DC_FillDevCaps( DeviceCaps * caps )
51 caps->version = 0x300;
52 caps->technology = DT_RASDISPLAY;
53 caps->horzSize = WidthMMOfScreen(screen) * screenWidth / WidthOfScreen(screen);
54 caps->vertSize = HeightMMOfScreen(screen) * screenHeight / HeightOfScreen(screen);
55 caps->horzRes = screenWidth;
56 caps->vertRes = screenHeight;
57 caps->bitsPixel = screenDepth;
59 caps->numBrushes = 16+6; /* 16 solid + 6 hatched brushes */
60 caps->numPens = 16; /* 16 solid pens */
63 caps->numColors = 100;
64 caps->pdeviceSize = 0;
65 caps->curveCaps = CC_CIRCLES | CC_PIE | CC_CHORD | CC_ELLIPSES |
66 CC_WIDE | CC_STYLED | CC_WIDESTYLED |
67 CC_INTERIORS | CC_ROUNDRECT;
68 caps->lineCaps = LC_POLYLINE | LC_MARKER | LC_POLYMARKER | LC_WIDE |
69 LC_STYLED | LC_WIDESTYLED | LC_INTERIORS;
70 caps->polygonalCaps = PC_POLYGON | PC_RECTANGLE | PC_WINDPOLYGON |
71 PC_SCANLINE | PC_WIDE | PC_STYLED |
72 PC_WIDESTYLED | PC_INTERIORS;
73 caps->textCaps = TC_OP_CHARACTER | TC_OP_STROKE | TC_CP_STROKE |
74 TC_IA_ABLE | TC_UA_ABLE | TC_SO_ABLE | TC_RA_ABLE;
75 caps->clipCaps = CP_REGION;
76 caps->rasterCaps = RC_BITBLT | RC_BANDING | RC_SCALING | RC_BITMAP64 |
77 RC_DI_BITMAP | RC_DIBTODEV | RC_BIGFONT|
78 RC_STRETCHBLT | RC_STRETCHDIB | RC_DEVBITS;
80 if( !(COLOR_GetSystemPaletteFlags() & COLOR_VIRTUAL) )
81 caps->rasterCaps |= RC_PALETTE;
83 caps->aspectX = 36; /* ?? */
84 caps->aspectY = 36; /* ?? */
86 caps->logPixelsX = (int)(caps->horzRes * 25.4 / caps->horzSize);
87 caps->logPixelsY = (int)(caps->vertRes * 25.4 / caps->vertSize);
88 caps->sizePalette = (caps->rasterCaps & RC_PALETTE)
89 ? DefaultVisual(display,DefaultScreen(display))->map_entries
91 caps->numReserved = 0;
96 /***********************************************************************
99 * Fill the WIN_DC_INFO structure.
101 static void DC_Init_DC_INFO( WIN_DC_INFO *win_dc_info )
103 win_dc_info->flags = 0;
104 win_dc_info->devCaps = NULL;
105 win_dc_info->hClipRgn = 0;
106 win_dc_info->hVisRgn = 0;
107 win_dc_info->hGCClipRgn = 0;
108 win_dc_info->hPen = STOCK_BLACK_PEN;
109 win_dc_info->hBrush = STOCK_WHITE_BRUSH;
110 win_dc_info->hFont = STOCK_SYSTEM_FONT;
111 win_dc_info->hBitmap = 0;
112 win_dc_info->hFirstBitmap = 0;
113 win_dc_info->hDevice = 0;
114 win_dc_info->hPalette = STOCK_DEFAULT_PALETTE;
115 win_dc_info->ROPmode = R2_COPYPEN;
116 win_dc_info->polyFillMode = ALTERNATE;
117 win_dc_info->stretchBltMode = BLACKONWHITE;
118 win_dc_info->relAbsMode = ABSOLUTE;
119 win_dc_info->backgroundMode = OPAQUE;
120 win_dc_info->backgroundColor = RGB( 255, 255, 255 );
121 win_dc_info->textColor = RGB( 0, 0, 0 );
122 win_dc_info->backgroundPixel = 0;
123 win_dc_info->textPixel = 0;
124 win_dc_info->brushOrgX = 0;
125 win_dc_info->brushOrgY = 0;
126 win_dc_info->textAlign = TA_LEFT | TA_TOP | TA_NOUPDATECP;
127 win_dc_info->charExtra = 0;
128 win_dc_info->breakTotalExtra = 0;
129 win_dc_info->breakCount = 0;
130 win_dc_info->breakExtra = 0;
131 win_dc_info->breakRem = 0;
132 win_dc_info->bitsPerPixel = 1;
133 win_dc_info->MapMode = MM_TEXT;
134 win_dc_info->GraphicsMode = GM_COMPATIBLE;
135 win_dc_info->DCOrgX = 0;
136 win_dc_info->DCOrgY = 0;
137 win_dc_info->CursPosX = 0;
138 win_dc_info->CursPosY = 0;
140 PATH_InitGdiPath(&win_dc_info->path);
144 /***********************************************************************
147 DC *DC_AllocDC( const DC_FUNCTIONS *funcs )
152 if (!(hdc = GDI_AllocObject( sizeof(DC), DC_MAGIC ))) return NULL;
153 dc = (DC *) GDI_HEAP_LOCK( hdc );
170 DC_Init_DC_INFO( &dc->w );
177 /***********************************************************************
180 DC *DC_GetDCPtr( HDC32 hdc )
182 GDIOBJHDR *ptr = (GDIOBJHDR *)GDI_HEAP_LOCK( hdc );
183 if (!ptr) return NULL;
184 if ((ptr->wMagic == DC_MAGIC) || (ptr->wMagic == METAFILE_DC_MAGIC))
186 GDI_HEAP_UNLOCK( hdc );
191 /***********************************************************************
194 * Setup device-specific DC values for a newly created DC.
196 void DC_InitDC( DC* dc )
198 RealizeDefaultPalette( dc->hSelf );
199 SetTextColor32( dc->hSelf, dc->w.textColor );
200 SetBkColor32( dc->hSelf, dc->w.backgroundColor );
201 SelectObject32( dc->hSelf, dc->w.hPen );
202 SelectObject32( dc->hSelf, dc->w.hBrush );
203 SelectObject32( dc->hSelf, dc->w.hFont );
204 CLIPPING_UpdateGCRegion( dc );
208 /***********************************************************************
209 * DC_SetupGCForPatBlt
211 * Setup the GC for a PatBlt operation using current brush.
212 * If fMapColors is TRUE, X pixels are mapped to Windows colors.
213 * Return FALSE if brush is BS_NULL, TRUE otherwise.
215 BOOL32 DC_SetupGCForPatBlt( DC * dc, GC gc, BOOL32 fMapColors )
221 if (dc->u.x.brush.style == BS_NULL) return FALSE;
222 if (dc->u.x.brush.pixel == -1)
224 /* Special case used for monochrome pattern brushes.
225 * We need to swap foreground and background because
226 * Windows does it the wrong way...
228 val.foreground = dc->w.backgroundPixel;
229 val.background = dc->w.textPixel;
233 val.foreground = dc->u.x.brush.pixel;
234 val.background = dc->w.backgroundPixel;
236 if (fMapColors && COLOR_PixelToPalette)
238 val.foreground = COLOR_PixelToPalette[val.foreground];
239 val.background = COLOR_PixelToPalette[val.background];
242 if (dc->w.flags & DC_DIRTY) CLIPPING_UpdateGCRegion(dc);
244 val.function = DC_XROPfunction[dc->w.ROPmode-1];
246 ** Let's replace GXinvert by GXxor with (black xor white)
247 ** This solves the selection color and leak problems in excel
248 ** FIXME : Let's do that only if we work with X-pixels, not with Win-pixels
250 if (val.function == GXinvert)
252 val.foreground = BlackPixelOfScreen(screen) ^ WhitePixelOfScreen(screen);
253 val.function = GXxor;
255 val.fill_style = dc->u.x.brush.fillStyle;
256 switch(val.fill_style)
259 case FillOpaqueStippled:
260 if (dc->w.backgroundMode==OPAQUE) val.fill_style = FillOpaqueStippled;
261 val.stipple = dc->u.x.brush.pixmap;
266 if (fMapColors && COLOR_PixelToPalette)
270 pixmap = XCreatePixmap( display, rootWindow, 8, 8, screenDepth );
271 image = XGetImage( display, dc->u.x.brush.pixmap, 0, 0, 8, 8,
272 AllPlanes, ZPixmap );
273 for (y = 0; y < 8; y++)
274 for (x = 0; x < 8; x++)
275 XPutPixel( image, x, y,
276 COLOR_PixelToPalette[XGetPixel( image, x, y)] );
277 XPutImage( display, pixmap, gc, image, 0, 0, 0, 0, 8, 8 );
278 XDestroyImage( image );
281 else val.tile = dc->u.x.brush.pixmap;
289 val.ts_x_origin = dc->w.DCOrgX + dc->w.brushOrgX;
290 val.ts_y_origin = dc->w.DCOrgY + dc->w.brushOrgY;
291 val.fill_rule = (dc->w.polyFillMode==WINDING) ? WindingRule : EvenOddRule;
292 XChangeGC( display, gc,
293 GCFunction | GCForeground | GCBackground | GCFillStyle |
294 GCFillRule | GCTileStipXOrigin | GCTileStipYOrigin | mask,
296 if (pixmap) XFreePixmap( display, pixmap );
301 /***********************************************************************
304 * Setup dc->u.x.gc for drawing operations using current brush.
305 * Return FALSE if brush is BS_NULL, TRUE otherwise.
307 BOOL32 DC_SetupGCForBrush( DC * dc )
309 return DC_SetupGCForPatBlt( dc, dc->u.x.gc, FALSE );
313 /***********************************************************************
316 * Setup dc->u.x.gc for drawing operations using current pen.
317 * Return FALSE if pen is PS_NULL, TRUE otherwise.
319 BOOL32 DC_SetupGCForPen( DC * dc )
323 if (dc->u.x.pen.style == PS_NULL) return FALSE;
325 if (dc->w.flags & DC_DIRTY) CLIPPING_UpdateGCRegion(dc);
327 switch (dc->w.ROPmode)
330 val.foreground = BlackPixelOfScreen( screen );
331 val.function = GXcopy;
334 val.foreground = WhitePixelOfScreen( screen );
335 val.function = GXcopy;
338 val.foreground = dc->u.x.pen.pixel;
339 /* It is very unlikely someone wants to XOR with 0 */
340 /* This fixes the rubber-drawings in paintbrush */
341 if (val.foreground == 0)
342 val.foreground = BlackPixelOfScreen( screen )
343 ^ WhitePixelOfScreen( screen );
344 val.function = GXxor;
347 val.foreground = dc->u.x.pen.pixel;
348 val.function = DC_XROPfunction[dc->w.ROPmode-1];
350 val.background = dc->w.backgroundPixel;
351 val.fill_style = FillSolid;
352 if ((dc->u.x.pen.style!=PS_SOLID) && (dc->u.x.pen.style!=PS_INSIDEFRAME))
354 XSetDashes( display, dc->u.x.gc, 0,
355 dc->u.x.pen.dashes, dc->u.x.pen.dash_len );
356 val.line_style = (dc->w.backgroundMode == OPAQUE) ?
357 LineDoubleDash : LineOnOffDash;
359 else val.line_style = LineSolid;
360 val.line_width = dc->u.x.pen.width;
361 if (val.line_width <= 1) {
362 val.cap_style = CapNotLast;
364 switch (dc->u.x.pen.endcap)
366 case PS_ENDCAP_SQUARE:
367 val.cap_style = CapProjecting;
370 val.cap_style = CapButt;
372 case PS_ENDCAP_ROUND:
374 val.cap_style = CapRound;
377 switch (dc->u.x.pen.linejoin)
380 val.join_style = JoinBevel;
382 val.join_style = JoinMiter;
385 val.join_style = JoinRound;
387 XChangeGC( display, dc->u.x.gc,
388 GCFunction | GCForeground | GCBackground | GCLineWidth |
389 GCLineStyle | GCCapStyle | GCJoinStyle | GCFillStyle, &val );
394 /***********************************************************************
397 * Setup dc->u.x.gc for text drawing operations.
398 * Return FALSE if the font is null, TRUE otherwise.
400 BOOL32 DC_SetupGCForText( DC * dc )
402 XFontStruct* xfs = XFONT_GetFontStruct( dc->u.x.font );
408 if (dc->w.flags & DC_DIRTY) CLIPPING_UpdateGCRegion(dc);
410 val.function = GXcopy; /* Text is always GXcopy */
411 val.foreground = dc->w.textPixel;
412 val.background = dc->w.backgroundPixel;
413 val.fill_style = FillSolid;
416 XChangeGC( display, dc->u.x.gc,
417 GCFunction | GCForeground | GCBackground | GCFillStyle |
421 fprintf( stderr, "DC_SetupGCForText: physical font failure\n" );
426 /***********************************************************************
427 * GetDCState (GDI.179)
429 HDC16 WINAPI GetDCState( HDC16 hdc )
434 if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
435 if (!(handle = GDI_AllocObject( sizeof(DC), DC_MAGIC )))
437 GDI_HEAP_UNLOCK( hdc );
440 newdc = (DC *) GDI_HEAP_LOCK( handle );
442 dprintf_dc(stddeb, "GetDCState(%04x): returning %04x\n", hdc, handle );
444 memset( &newdc->u.x, 0, sizeof(newdc->u.x) );
445 newdc->w.flags = dc->w.flags | DC_SAVED;
446 newdc->w.devCaps = dc->w.devCaps;
447 newdc->w.hPen = dc->w.hPen;
448 newdc->w.hBrush = dc->w.hBrush;
449 newdc->w.hFont = dc->w.hFont;
450 newdc->w.hBitmap = dc->w.hBitmap;
451 newdc->w.hFirstBitmap = dc->w.hFirstBitmap;
452 newdc->w.hDevice = dc->w.hDevice;
453 newdc->w.hPalette = dc->w.hPalette;
454 newdc->w.bitsPerPixel = dc->w.bitsPerPixel;
455 newdc->w.ROPmode = dc->w.ROPmode;
456 newdc->w.polyFillMode = dc->w.polyFillMode;
457 newdc->w.stretchBltMode = dc->w.stretchBltMode;
458 newdc->w.relAbsMode = dc->w.relAbsMode;
459 newdc->w.backgroundMode = dc->w.backgroundMode;
460 newdc->w.backgroundColor = dc->w.backgroundColor;
461 newdc->w.textColor = dc->w.textColor;
462 newdc->w.backgroundPixel = dc->w.backgroundPixel;
463 newdc->w.textPixel = dc->w.textPixel;
464 newdc->w.brushOrgX = dc->w.brushOrgX;
465 newdc->w.brushOrgY = dc->w.brushOrgY;
466 newdc->w.textAlign = dc->w.textAlign;
467 newdc->w.charExtra = dc->w.charExtra;
468 newdc->w.breakTotalExtra = dc->w.breakTotalExtra;
469 newdc->w.breakCount = dc->w.breakCount;
470 newdc->w.breakExtra = dc->w.breakExtra;
471 newdc->w.breakRem = dc->w.breakRem;
472 newdc->w.MapMode = dc->w.MapMode;
473 newdc->w.DCOrgX = dc->w.DCOrgX;
474 newdc->w.DCOrgY = dc->w.DCOrgY;
475 newdc->w.CursPosX = dc->w.CursPosX;
476 newdc->w.CursPosY = dc->w.CursPosY;
477 newdc->wndOrgX = dc->wndOrgX;
478 newdc->wndOrgY = dc->wndOrgY;
479 newdc->wndExtX = dc->wndExtX;
480 newdc->wndExtY = dc->wndExtY;
481 newdc->vportOrgX = dc->vportOrgX;
482 newdc->vportOrgY = dc->vportOrgY;
483 newdc->vportExtX = dc->vportExtX;
484 newdc->vportExtY = dc->vportExtY;
486 newdc->hSelf = (HDC32)handle;
487 newdc->saveLevel = 0;
489 PATH_InitGdiPath( &newdc->w.path );
491 /* Get/SetDCState() don't change hVisRgn field ("Undoc. Windows" p.559). */
493 newdc->w.hGCClipRgn = newdc->w.hVisRgn = 0;
496 newdc->w.hClipRgn = CreateRectRgn32( 0, 0, 0, 0 );
497 CombineRgn32( newdc->w.hClipRgn, dc->w.hClipRgn, 0, RGN_COPY );
500 newdc->w.hClipRgn = 0;
501 GDI_HEAP_UNLOCK( handle );
502 GDI_HEAP_UNLOCK( hdc );
507 /***********************************************************************
508 * SetDCState (GDI.180)
510 void WINAPI SetDCState( HDC16 hdc, HDC16 hdcs )
514 if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return;
515 if (!(dcs = (DC *) GDI_GetObjPtr( hdcs, DC_MAGIC )))
517 GDI_HEAP_UNLOCK( hdc );
520 if (!dcs->w.flags & DC_SAVED)
522 GDI_HEAP_UNLOCK( hdc );
523 GDI_HEAP_UNLOCK( hdcs );
526 dprintf_dc(stddeb, "SetDCState: %04x %04x\n", hdc, hdcs );
528 dc->w.flags = dcs->w.flags & ~DC_SAVED;
529 dc->w.devCaps = dcs->w.devCaps;
530 dc->w.hFirstBitmap = dcs->w.hFirstBitmap;
531 dc->w.hDevice = dcs->w.hDevice;
532 dc->w.ROPmode = dcs->w.ROPmode;
533 dc->w.polyFillMode = dcs->w.polyFillMode;
534 dc->w.stretchBltMode = dcs->w.stretchBltMode;
535 dc->w.relAbsMode = dcs->w.relAbsMode;
536 dc->w.backgroundMode = dcs->w.backgroundMode;
537 dc->w.backgroundColor = dcs->w.backgroundColor;
538 dc->w.textColor = dcs->w.textColor;
539 dc->w.backgroundPixel = dcs->w.backgroundPixel;
540 dc->w.textPixel = dcs->w.textPixel;
541 dc->w.brushOrgX = dcs->w.brushOrgX;
542 dc->w.brushOrgY = dcs->w.brushOrgY;
543 dc->w.textAlign = dcs->w.textAlign;
544 dc->w.charExtra = dcs->w.charExtra;
545 dc->w.breakTotalExtra = dcs->w.breakTotalExtra;
546 dc->w.breakCount = dcs->w.breakCount;
547 dc->w.breakExtra = dcs->w.breakExtra;
548 dc->w.breakRem = dcs->w.breakRem;
549 dc->w.MapMode = dcs->w.MapMode;
550 dc->w.DCOrgX = dcs->w.DCOrgX;
551 dc->w.DCOrgY = dcs->w.DCOrgY;
552 dc->w.CursPosX = dcs->w.CursPosX;
553 dc->w.CursPosY = dcs->w.CursPosY;
555 dc->wndOrgX = dcs->wndOrgX;
556 dc->wndOrgY = dcs->wndOrgY;
557 dc->wndExtX = dcs->wndExtX;
558 dc->wndExtY = dcs->wndExtY;
559 dc->vportOrgX = dcs->vportOrgX;
560 dc->vportOrgY = dcs->vportOrgY;
561 dc->vportExtX = dcs->vportExtX;
562 dc->vportExtY = dcs->vportExtY;
564 if (!(dc->w.flags & DC_MEMORY)) dc->w.bitsPerPixel = dcs->w.bitsPerPixel;
565 SelectClipRgn32( hdc, dcs->w.hClipRgn );
567 SelectObject32( hdc, dcs->w.hBitmap );
568 SelectObject32( hdc, dcs->w.hBrush );
569 SelectObject32( hdc, dcs->w.hFont );
570 SelectObject32( hdc, dcs->w.hPen );
571 GDISelectPalette( hdc, dcs->w.hPalette, FALSE );
572 GDI_HEAP_UNLOCK( hdc );
573 GDI_HEAP_UNLOCK( hdcs );
577 /***********************************************************************
580 INT16 WINAPI SaveDC16( HDC16 hdc )
582 return (INT16)SaveDC32( hdc );
586 /***********************************************************************
587 * SaveDC32 (GDI32.292)
589 INT32 WINAPI SaveDC32( HDC32 hdc )
595 dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
598 dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
600 MF_MetaParam0(dc, META_SAVEDC);
601 GDI_HEAP_UNLOCK( hdc );
604 if (!(hdcs = GetDCState( hdc )))
606 GDI_HEAP_UNLOCK( hdc );
609 dcs = (DC *) GDI_HEAP_LOCK( hdcs );
611 /* Copy path. The reason why path saving / restoring is in SaveDC/
612 * RestoreDC and not in GetDCState/SetDCState is that the ...DCState
613 * functions are only in Win16 (which doesn't have paths) and that
614 * SetDCState doesn't allow us to signal an error (which can happen
615 * when copying paths).
617 if (!PATH_AssignGdiPath( &dcs->w.path, &dc->w.path ))
619 GDI_HEAP_UNLOCK( hdc );
620 GDI_HEAP_UNLOCK( hdcs );
625 dcs->header.hNext = dc->header.hNext;
626 dc->header.hNext = hdcs;
627 dprintf_dc(stddeb, "SaveDC(%04x): returning %d\n", hdc, dc->saveLevel+1 );
628 ret = ++dc->saveLevel;
629 GDI_HEAP_UNLOCK( hdcs );
630 GDI_HEAP_UNLOCK( hdc );
635 /***********************************************************************
636 * RestoreDC16 (GDI.39)
638 BOOL16 WINAPI RestoreDC16( HDC16 hdc, INT16 level )
640 return RestoreDC32( hdc, level );
644 /***********************************************************************
645 * RestoreDC32 (GDI32.290)
647 BOOL32 WINAPI RestoreDC32( HDC32 hdc, INT32 level )
652 dprintf_dc(stddeb, "RestoreDC: %04x %d\n", hdc, level );
653 dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
656 dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
657 if (!dc) return FALSE;
660 GDI_HEAP_UNLOCK( hdc );
663 MF_MetaParam1(dc, META_RESTOREDC, level);
664 GDI_HEAP_UNLOCK( hdc );
667 if (level == -1) level = dc->saveLevel;
668 if ((level < 1) || (level > dc->saveLevel))
670 GDI_HEAP_UNLOCK( hdc );
675 while (dc->saveLevel >= level)
677 HDC16 hdcs = dc->header.hNext;
678 if (!(dcs = (DC *) GDI_GetObjPtr( hdcs, DC_MAGIC )))
680 GDI_HEAP_UNLOCK( hdc );
683 dc->header.hNext = dcs->header.hNext;
684 if (--dc->saveLevel < level)
686 SetDCState( hdc, hdcs );
687 if (!PATH_AssignGdiPath( &dc->w.path, &dcs->w.path ))
688 /* FIXME: This might not be quite right, since we're
689 * returning FALSE but still destroying the saved DC state */
694 GDI_HEAP_UNLOCK( hdc );
699 /***********************************************************************
700 * CreateDC16 (GDI.53)
702 HDC16 WINAPI CreateDC16( LPCSTR driver, LPCSTR device, LPCSTR output,
703 const DEVMODE16 *initData )
706 const DC_FUNCTIONS *funcs;
708 if (!(funcs = DRIVER_FindDriver( driver ))) return 0;
709 if (!(dc = DC_AllocDC( funcs ))) return 0;
712 dprintf_dc(stddeb, "CreateDC(%s %s %s): returning %04x\n",
713 driver, device, output, dc->hSelf );
715 if (dc->funcs->pCreateDC &&
716 !dc->funcs->pCreateDC( dc, driver, device, output, initData ))
718 dprintf_dc( stddeb, "CreateDC: creation aborted by device\n" );
719 GDI_HEAP_FREE( dc->hSelf );
724 GDI_HEAP_UNLOCK( dc->hSelf );
729 /***********************************************************************
730 * CreateDC32A (GDI32.)
732 HDC32 WINAPI CreateDC32A( LPCSTR driver, LPCSTR device, LPCSTR output,
733 const DEVMODE32A *initData )
735 return CreateDC16( driver, device, output, (const DEVMODE16 *)initData );
739 /***********************************************************************
740 * CreateDC32W (GDI32.)
742 HDC32 WINAPI CreateDC32W( LPCWSTR driver, LPCWSTR device, LPCWSTR output,
743 const DEVMODE32W *initData )
745 LPSTR driverA = HEAP_strdupWtoA( GetProcessHeap(), 0, driver );
746 LPSTR deviceA = HEAP_strdupWtoA( GetProcessHeap(), 0, device );
747 LPSTR outputA = HEAP_strdupWtoA( GetProcessHeap(), 0, output );
748 HDC32 res = CreateDC16( driverA, deviceA, outputA,
749 (const DEVMODE16 *)initData /*FIXME*/ );
750 HeapFree( GetProcessHeap(), 0, driverA );
751 HeapFree( GetProcessHeap(), 0, deviceA );
752 HeapFree( GetProcessHeap(), 0, outputA );
757 /***********************************************************************
758 * CreateIC16 (GDI.153)
760 HDC16 WINAPI CreateIC16( LPCSTR driver, LPCSTR device, LPCSTR output,
761 const DEVMODE16* initData )
763 /* Nothing special yet for ICs */
764 return CreateDC16( driver, device, output, initData );
768 /***********************************************************************
769 * CreateIC32A (GDI32.49)
771 HDC32 WINAPI CreateIC32A( LPCSTR driver, LPCSTR device, LPCSTR output,
772 const DEVMODE32A* initData )
774 /* Nothing special yet for ICs */
775 return CreateDC32A( driver, device, output, initData );
779 /***********************************************************************
780 * CreateIC32W (GDI32.50)
782 HDC32 WINAPI CreateIC32W( LPCWSTR driver, LPCWSTR device, LPCWSTR output,
783 const DEVMODE32W* initData )
785 /* Nothing special yet for ICs */
786 return CreateDC32W( driver, device, output, initData );
790 /***********************************************************************
791 * CreateCompatibleDC16 (GDI.52)
793 HDC16 WINAPI CreateCompatibleDC16( HDC16 hdc )
795 return (HDC16)CreateCompatibleDC32( hdc );
799 /***********************************************************************
800 * CreateCompatibleDC32 (GDI32.31)
802 HDC32 WINAPI CreateCompatibleDC32( HDC32 hdc )
806 const DC_FUNCTIONS *funcs;
808 if ((origDC = (DC *)GDI_GetObjPtr( hdc, DC_MAGIC ))) funcs = origDC->funcs;
809 else funcs = DRIVER_FindDriver( "DISPLAY" );
810 if (!funcs) return 0;
812 if (!(dc = DC_AllocDC( funcs ))) return 0;
814 dprintf_dc(stddeb, "CreateCompatibleDC(%04x): returning %04x\n",
817 /* Create default bitmap */
818 if (!(hbitmap = CreateBitmap32( 1, 1, 1, 1, NULL )))
820 GDI_HEAP_FREE( dc->hSelf );
823 dc->w.flags = DC_MEMORY;
824 dc->w.bitsPerPixel = 1;
825 dc->w.hBitmap = hbitmap;
826 dc->w.hFirstBitmap = hbitmap;
828 if (dc->funcs->pCreateDC &&
829 !dc->funcs->pCreateDC( dc, NULL, NULL, NULL, NULL ))
831 dprintf_dc(stddeb, "CreateCompatibleDC: creation aborted by device\n");
832 DeleteObject32( hbitmap );
833 GDI_HEAP_FREE( dc->hSelf );
838 GDI_HEAP_UNLOCK( dc->hSelf );
843 /***********************************************************************
844 * DeleteDC16 (GDI.68)
846 BOOL16 WINAPI DeleteDC16( HDC16 hdc )
848 return DeleteDC32( hdc );
852 /***********************************************************************
853 * DeleteDC32 (GDI32.67)
855 BOOL32 WINAPI DeleteDC32( HDC32 hdc )
857 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
858 if (!dc) return FALSE;
860 dprintf_dc(stddeb, "DeleteDC: %04x\n", hdc );
862 while (dc->saveLevel)
865 HDC16 hdcs = dc->header.hNext;
866 if (!(dcs = (DC *) GDI_GetObjPtr( hdcs, DC_MAGIC ))) break;
867 dc->header.hNext = dcs->header.hNext;
872 if (!(dc->w.flags & DC_SAVED))
874 SelectObject32( hdc, STOCK_BLACK_PEN );
875 SelectObject32( hdc, STOCK_WHITE_BRUSH );
876 SelectObject32( hdc, STOCK_SYSTEM_FONT );
877 if (dc->w.flags & DC_MEMORY) DeleteObject32( dc->w.hFirstBitmap );
878 if (dc->funcs->pDeleteDC) dc->funcs->pDeleteDC(dc);
881 if (dc->w.hClipRgn) DeleteObject32( dc->w.hClipRgn );
882 if (dc->w.hVisRgn) DeleteObject32( dc->w.hVisRgn );
883 if (dc->w.hGCClipRgn) DeleteObject32( dc->w.hGCClipRgn );
885 PATH_DestroyGdiPath(&dc->w.path);
887 return GDI_FreeObject( hdc );
891 /***********************************************************************
892 * ResetDC16 (GDI.376)
894 HDC16 WINAPI ResetDC16( HDC16 hdc, const DEVMODE16 *devmode )
896 fprintf( stderr, "ResetDC16: empty stub!\n" );
901 /***********************************************************************
902 * ResetDC32A (GDI32.287)
904 HDC32 WINAPI ResetDC32A( HDC32 hdc, const DEVMODE32A *devmode )
906 fprintf( stderr, "ResetDC32A: empty stub!\n" );
911 /***********************************************************************
912 * ResetDC32W (GDI32.288)
914 HDC32 WINAPI ResetDC32W( HDC32 hdc, const DEVMODE32W *devmode )
916 fprintf( stderr, "ResetDC32A: empty stub!\n" );
921 /***********************************************************************
922 * GetDeviceCaps16 (GDI.80)
924 INT16 WINAPI GetDeviceCaps16( HDC16 hdc, INT16 cap )
926 return GetDeviceCaps32( hdc, cap );
930 /***********************************************************************
931 * GetDeviceCaps32 (GDI32.171)
933 INT32 WINAPI GetDeviceCaps32( HDC32 hdc, INT32 cap )
935 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
940 if ((cap < 0) || (cap > sizeof(DeviceCaps)-sizeof(WORD)))
942 GDI_HEAP_UNLOCK( hdc );
946 dprintf_dc(stddeb, "GetDeviceCaps(%04x,%d): returning %d\n",
947 hdc, cap, *(WORD *)(((char *)dc->w.devCaps) + cap) );
948 ret = *(WORD *)(((char *)dc->w.devCaps) + cap);
949 GDI_HEAP_UNLOCK( hdc );
954 /***********************************************************************
955 * SetBkColor16 (GDI.1)
957 COLORREF WINAPI SetBkColor16( HDC16 hdc, COLORREF color )
959 return SetBkColor32( hdc, color );
963 /***********************************************************************
964 * SetBkColor32 (GDI32.305)
966 COLORREF WINAPI SetBkColor32( HDC32 hdc, COLORREF color )
969 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
972 dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
973 if (!dc) return 0x80000000;
974 MF_MetaParam2(dc, META_SETBKCOLOR, HIWORD(color), LOWORD(color));
975 GDI_HEAP_UNLOCK( hdc );
979 oldColor = dc->w.backgroundColor;
980 dc->w.backgroundColor = color;
981 dc->w.backgroundPixel = COLOR_ToPhysical( dc, color );
982 GDI_HEAP_UNLOCK( hdc );
987 /***********************************************************************
988 * SetTextColor16 (GDI.9)
990 COLORREF WINAPI SetTextColor16( HDC16 hdc, COLORREF color )
992 return SetTextColor32( hdc, color );
996 /***********************************************************************
997 * SetTextColor32 (GDI32.338)
999 COLORREF WINAPI SetTextColor32( HDC32 hdc, COLORREF color )
1002 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
1005 dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
1006 if (!dc) return 0x80000000;
1007 MF_MetaParam2(dc, META_SETTEXTCOLOR, HIWORD(color), LOWORD(color));
1008 GDI_HEAP_UNLOCK( hdc );
1012 oldColor = dc->w.textColor;
1013 dc->w.textColor = color;
1014 dc->w.textPixel = COLOR_ToPhysical( dc, color );
1015 GDI_HEAP_UNLOCK( hdc );
1020 /***********************************************************************
1021 * SetTextAlign16 (GDI.346)
1023 UINT16 WINAPI SetTextAlign16( HDC16 hdc, UINT16 textAlign )
1025 return SetTextAlign32( hdc, textAlign );
1029 /***********************************************************************
1030 * SetTextAlign32 (GDI32.336)
1032 UINT32 WINAPI SetTextAlign32( HDC32 hdc, UINT32 textAlign )
1035 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
1038 if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC ))) return 0;
1039 MF_MetaParam1( dc, META_SETTEXTALIGN, textAlign );
1040 GDI_HEAP_UNLOCK( hdc );
1043 prevAlign = dc->w.textAlign;
1044 dc->w.textAlign = textAlign;
1045 GDI_HEAP_UNLOCK( hdc );
1050 /***********************************************************************
1051 * GetDCOrgEx (GDI32.168)
1053 BOOL32 WINAPI GetDCOrgEx( HDC32 hDC, LPPOINT32 lpp )
1056 if (!lpp) return FALSE;
1057 if (!(dc = (DC *) GDI_GetObjPtr( hDC, DC_MAGIC ))) return FALSE;
1059 if (!(dc->w.flags & DC_MEMORY))
1062 int w, h, border, depth;
1063 /* FIXME: this is not correct for managed windows */
1064 XGetGeometry( display, dc->u.x.drawable, &root,
1065 &lpp->x, &lpp->y, &w, &h, &border, &depth );
1067 else lpp->x = lpp->y = 0;
1068 lpp->x += dc->w.DCOrgX; lpp->y += dc->w.DCOrgY;
1069 GDI_HEAP_UNLOCK( hDC );
1074 /***********************************************************************
1077 DWORD WINAPI GetDCOrg( HDC16 hdc )
1080 if( GetDCOrgEx( hdc, &pt) )
1081 return MAKELONG( (WORD)pt.x, (WORD)pt.y );
1086 /***********************************************************************
1087 * SetDCOrg (GDI.117)
1089 DWORD WINAPI SetDCOrg( HDC16 hdc, INT16 x, INT16 y )
1092 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
1094 prevOrg = dc->w.DCOrgX | (dc->w.DCOrgY << 16);
1097 GDI_HEAP_UNLOCK( hdc );
1102 /***********************************************************************
1103 * GetGraphicsMode (GDI32.188)
1105 INT32 WINAPI GetGraphicsMode( HDC32 hdc )
1107 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
1109 return dc->w.GraphicsMode;
1113 /***********************************************************************
1114 * SetGraphicsMode (GDI32.317)
1116 INT32 WINAPI SetGraphicsMode( HDC32 hdc, INT32 mode )
1119 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
1121 if ((mode <= 0) || (mode > GM_LAST)) return 0;
1122 ret = dc->w.GraphicsMode;
1123 dc->w.GraphicsMode = mode;
1128 /***********************************************************************
1129 * GetWorldTransform (GDI32.244)
1131 BOOL32 WINAPI GetWorldTransform( HDC32 hdc, LPXFORM xform )
1133 fprintf( stdnimp, "GetWorldTransform: empty stub\n" );
1138 /***********************************************************************
1139 * SetDCHook (GDI.190)
1141 BOOL16 WINAPI SetDCHook( HDC16 hdc, FARPROC16 hookProc, DWORD dwHookData )
1143 DC *dc = (DC *)GDI_GetObjPtr( hdc, DC_MAGIC );
1145 dprintf_dc( stddeb, "SetDCHook: hookProc %08x, default is %08x\n",
1146 (UINT32)hookProc, (UINT32)DCHook );
1148 if (!dc) return FALSE;
1149 dc->hookProc = hookProc;
1150 dc->dwHookData = dwHookData;
1151 GDI_HEAP_UNLOCK( hdc );
1156 /***********************************************************************
1157 * GetDCHook (GDI.191)
1159 DWORD WINAPI GetDCHook( HDC16 hdc, FARPROC16 *phookProc )
1161 DC *dc = (DC *)GDI_GetObjPtr( hdc, DC_MAGIC );
1163 *phookProc = dc->hookProc;
1164 GDI_HEAP_UNLOCK( hdc );
1165 return dc->dwHookData;
1169 /***********************************************************************
1170 * SetHookFlags (GDI.192)
1172 WORD WINAPI SetHookFlags(HDC16 hDC, WORD flags)
1174 DC* dc = (DC*)GDI_GetObjPtr( hDC, DC_MAGIC );
1178 WORD wRet = dc->w.flags & DC_DIRTY;
1180 /* "Undocumented Windows" info is slightly confusing.
1183 dprintf_dc(stddeb,"SetHookFlags: hDC %04x, flags %04x\n",hDC,flags);
1185 if( flags & DCHF_INVALIDATEVISRGN )
1186 dc->w.flags |= DC_DIRTY;
1187 else if( flags & DCHF_VALIDATEVISRGN || !flags )
1188 dc->w.flags &= ~DC_DIRTY;
1189 GDI_HEAP_UNLOCK( hDC );