2 * GDI Device Context functions
4 * Copyright 1993 Alexandre Julliard
19 extern void CLIPPING_UpdateGCRegion( DC
* dc
); /* objects/clipping.c */
21 /* Default DC values */
22 static const WIN_DC_INFO DC_defaultValues
=
29 STOCK_BLACK_PEN
, /* hPen */
30 STOCK_WHITE_BRUSH
, /* hBrush */
31 STOCK_SYSTEM_FONT
, /* hFont */
35 STOCK_DEFAULT_PALETTE
, /* hPalette */
36 R2_COPYPEN
, /* ROPmode */
37 ALTERNATE
, /* polyFillMode */
38 BLACKONWHITE
, /* stretchBltMode */
39 ABSOLUTE
, /* relAbsMode */
40 OPAQUE
, /* backgroundMode */
41 RGB( 255, 255, 255 ), /* backgroundColor */
42 RGB( 0, 0, 0 ), /* textColor */
43 0, /* backgroundPixel */
47 TA_LEFT
| TA_TOP
| TA_NOUPDATECP
, /* textAlign */
49 0, /* breakTotalExtra */
54 MM_TEXT
, /* MapMode */
55 GM_COMPATIBLE
, /* GraphicsMode */
62 /* ROP code to GC function conversion */
63 const int DC_XROPfunction
[16] =
65 GXclear
, /* R2_BLACK */
66 GXnor
, /* R2_NOTMERGEPEN */
67 GXandInverted
, /* R2_MASKNOTPEN */
68 GXcopyInverted
, /* R2_NOTCOPYPEN */
69 GXandReverse
, /* R2_MASKPENNOT */
70 GXinvert
, /* R2_NOT */
71 GXxor
, /* R2_XORPEN */
72 GXnand
, /* R2_NOTMASKPEN */
73 GXand
, /* R2_MASKPEN */
74 GXequiv
, /* R2_NOTXORPEN */
76 GXorInverted
, /* R2_MERGENOTPEN */
77 GXcopy
, /* R2_COPYPEN */
78 GXorReverse
, /* R2_MERGEPENNOT */
79 GXor
, /* R2_MERGEPEN */
84 /***********************************************************************
87 * Fill the device caps structure.
89 void DC_FillDevCaps( DeviceCaps
* caps
)
91 caps
->version
= 0x300;
92 caps
->technology
= DT_RASDISPLAY
;
93 caps
->horzSize
= WidthMMOfScreen(screen
) * screenWidth
/ WidthOfScreen(screen
);
94 caps
->vertSize
= HeightMMOfScreen(screen
) * screenHeight
/ HeightOfScreen(screen
);
95 caps
->horzRes
= screenWidth
;
96 caps
->vertRes
= screenHeight
;
97 caps
->bitsPixel
= screenDepth
;
99 caps
->numBrushes
= 16+6; /* 16 solid + 6 hatched brushes */
100 caps
->numPens
= 16; /* 16 solid pens */
101 caps
->numMarkers
= 0;
103 caps
->numColors
= 100;
104 caps
->pdeviceSize
= 0;
105 caps
->curveCaps
= CC_CIRCLES
| CC_PIE
| CC_CHORD
| CC_ELLIPSES
|
106 CC_WIDE
| CC_STYLED
| CC_WIDESTYLED
|
107 CC_INTERIORS
| CC_ROUNDRECT
;
108 caps
->lineCaps
= LC_POLYLINE
| LC_MARKER
| LC_POLYMARKER
| LC_WIDE
|
109 LC_STYLED
| LC_WIDESTYLED
| LC_INTERIORS
;
110 caps
->polygonalCaps
= PC_POLYGON
| PC_RECTANGLE
| PC_WINDPOLYGON
|
111 PC_SCANLINE
| PC_WIDE
| PC_STYLED
|
112 PC_WIDESTYLED
| PC_INTERIORS
;
113 caps
->textCaps
= TC_OP_CHARACTER
| TC_OP_STROKE
| TC_CP_STROKE
|
114 TC_IA_ABLE
| TC_UA_ABLE
| TC_SO_ABLE
| TC_RA_ABLE
;
115 caps
->clipCaps
= CP_REGION
;
116 caps
->rasterCaps
= RC_BITBLT
| RC_BANDING
| RC_SCALING
| RC_BITMAP64
|
117 RC_DI_BITMAP
| RC_DIBTODEV
| RC_BIGFONT
|
118 RC_STRETCHBLT
| RC_STRETCHDIB
| RC_DEVBITS
;
120 if( !(COLOR_GetSystemPaletteFlags() & COLOR_VIRTUAL
) )
121 caps
->rasterCaps
|= RC_PALETTE
;
123 caps
->aspectX
= 36; /* ?? */
124 caps
->aspectY
= 36; /* ?? */
126 caps
->logPixelsX
= (int)(caps
->horzRes
* 25.4 / caps
->horzSize
);
127 caps
->logPixelsY
= (int)(caps
->vertRes
* 25.4 / caps
->vertSize
);
128 caps
->sizePalette
= (caps
->rasterCaps
& RC_PALETTE
)
129 ? DefaultVisual(display
,DefaultScreen(display
))->map_entries
131 caps
->numReserved
= 0;
136 /***********************************************************************
139 DC
*DC_AllocDC( const DC_FUNCTIONS
*funcs
)
144 if (!(hdc
= GDI_AllocObject( sizeof(DC
), DC_MAGIC
))) return NULL
;
145 dc
= (DC
*) GDI_HEAP_LOCK( hdc
);
162 memcpy( &dc
->w
, &DC_defaultValues
, sizeof(DC_defaultValues
) );
168 /***********************************************************************
171 DC
*DC_GetDCPtr( HDC32 hdc
)
173 GDIOBJHDR
*ptr
= (GDIOBJHDR
*)GDI_HEAP_LOCK( hdc
);
174 if (!ptr
) return NULL
;
175 if ((ptr
->wMagic
== DC_MAGIC
) || (ptr
->wMagic
== METAFILE_DC_MAGIC
))
177 GDI_HEAP_UNLOCK( hdc
);
182 /***********************************************************************
185 * Setup device-specific DC values for a newly created DC.
187 void DC_InitDC( DC
* dc
)
189 RealizeDefaultPalette( dc
->hSelf
);
190 SetTextColor32( dc
->hSelf
, dc
->w
.textColor
);
191 SetBkColor32( dc
->hSelf
, dc
->w
.backgroundColor
);
192 SelectObject32( dc
->hSelf
, dc
->w
.hPen
);
193 SelectObject32( dc
->hSelf
, dc
->w
.hBrush
);
194 SelectObject32( dc
->hSelf
, dc
->w
.hFont
);
195 CLIPPING_UpdateGCRegion( dc
);
199 /***********************************************************************
200 * DC_SetupGCForPatBlt
202 * Setup the GC for a PatBlt operation using current brush.
203 * If fMapColors is TRUE, X pixels are mapped to Windows colors.
204 * Return FALSE if brush is BS_NULL, TRUE otherwise.
206 BOOL32
DC_SetupGCForPatBlt( DC
* dc
, GC gc
, BOOL32 fMapColors
)
212 if (dc
->u
.x
.brush
.style
== BS_NULL
) return FALSE
;
213 if (dc
->u
.x
.brush
.pixel
== -1)
215 /* Special case used for monochrome pattern brushes.
216 * We need to swap foreground and background because
217 * Windows does it the wrong way...
219 val
.foreground
= dc
->w
.backgroundPixel
;
220 val
.background
= dc
->w
.textPixel
;
224 val
.foreground
= dc
->u
.x
.brush
.pixel
;
225 val
.background
= dc
->w
.backgroundPixel
;
227 if (fMapColors
&& COLOR_PixelToPalette
)
229 val
.foreground
= COLOR_PixelToPalette
[val
.foreground
];
230 val
.background
= COLOR_PixelToPalette
[val
.background
];
233 if (dc
->w
.flags
& DC_DIRTY
) CLIPPING_UpdateGCRegion(dc
);
235 val
.function
= DC_XROPfunction
[dc
->w
.ROPmode
-1];
237 ** Let's replace GXinvert by GXxor with (black xor white)
238 ** This solves the selection color and leak problems in excel
239 ** FIXME : Let's do that only if we work with X-pixels, not with Win-pixels
241 if (val
.function
== GXinvert
)
243 val
.foreground
= BlackPixelOfScreen(screen
) ^ WhitePixelOfScreen(screen
);
244 val
.function
= GXxor
;
246 val
.fill_style
= dc
->u
.x
.brush
.fillStyle
;
247 switch(val
.fill_style
)
250 case FillOpaqueStippled
:
251 if (dc
->w
.backgroundMode
==OPAQUE
) val
.fill_style
= FillOpaqueStippled
;
252 val
.stipple
= dc
->u
.x
.brush
.pixmap
;
257 if (fMapColors
&& COLOR_PixelToPalette
)
261 pixmap
= XCreatePixmap( display
, rootWindow
, 8, 8, screenDepth
);
262 image
= XGetImage( display
, dc
->u
.x
.brush
.pixmap
, 0, 0, 8, 8,
263 AllPlanes
, ZPixmap
);
264 for (y
= 0; y
< 8; y
++)
265 for (x
= 0; x
< 8; x
++)
266 XPutPixel( image
, x
, y
,
267 COLOR_PixelToPalette
[XGetPixel( image
, x
, y
)] );
268 XPutImage( display
, pixmap
, gc
, image
, 0, 0, 0, 0, 8, 8 );
269 XDestroyImage( image
);
272 else val
.tile
= dc
->u
.x
.brush
.pixmap
;
280 val
.ts_x_origin
= dc
->w
.DCOrgX
+ dc
->w
.brushOrgX
;
281 val
.ts_y_origin
= dc
->w
.DCOrgY
+ dc
->w
.brushOrgY
;
282 val
.fill_rule
= (dc
->w
.polyFillMode
==WINDING
) ? WindingRule
: EvenOddRule
;
283 XChangeGC( display
, gc
,
284 GCFunction
| GCForeground
| GCBackground
| GCFillStyle
|
285 GCFillRule
| GCTileStipXOrigin
| GCTileStipYOrigin
| mask
,
287 if (pixmap
) XFreePixmap( display
, pixmap
);
292 /***********************************************************************
295 * Setup dc->u.x.gc for drawing operations using current brush.
296 * Return FALSE if brush is BS_NULL, TRUE otherwise.
298 BOOL32
DC_SetupGCForBrush( DC
* dc
)
300 return DC_SetupGCForPatBlt( dc
, dc
->u
.x
.gc
, FALSE
);
304 /***********************************************************************
307 * Setup dc->u.x.gc for drawing operations using current pen.
308 * Return FALSE if pen is PS_NULL, TRUE otherwise.
310 BOOL32
DC_SetupGCForPen( DC
* dc
)
314 if (dc
->u
.x
.pen
.style
== PS_NULL
) return FALSE
;
316 if (dc
->w
.flags
& DC_DIRTY
) CLIPPING_UpdateGCRegion(dc
);
318 switch (dc
->w
.ROPmode
)
321 val
.foreground
= BlackPixelOfScreen( screen
);
322 val
.function
= GXcopy
;
325 val
.foreground
= WhitePixelOfScreen( screen
);
326 val
.function
= GXcopy
;
329 val
.foreground
= dc
->u
.x
.pen
.pixel
;
330 /* It is very unlikely someone wants to XOR with 0 */
331 /* This fixes the rubber-drawings in paintbrush */
332 if (val
.foreground
== 0)
333 val
.foreground
= BlackPixelOfScreen( screen
)
334 ^ WhitePixelOfScreen( screen
);
335 val
.function
= GXxor
;
338 val
.foreground
= dc
->u
.x
.pen
.pixel
;
339 val
.function
= DC_XROPfunction
[dc
->w
.ROPmode
-1];
341 val
.background
= dc
->w
.backgroundPixel
;
342 val
.fill_style
= FillSolid
;
343 if ((dc
->u
.x
.pen
.style
!=PS_SOLID
) && (dc
->u
.x
.pen
.style
!=PS_INSIDEFRAME
))
345 XSetDashes( display
, dc
->u
.x
.gc
, 0,
346 dc
->u
.x
.pen
.dashes
, dc
->u
.x
.pen
.dash_len
);
347 val
.line_style
= (dc
->w
.backgroundMode
== OPAQUE
) ?
348 LineDoubleDash
: LineOnOffDash
;
350 else val
.line_style
= LineSolid
;
351 val
.line_width
= dc
->u
.x
.pen
.width
;
352 val
.cap_style
= (val
.line_width
<= 1) ? CapNotLast
: CapRound
;
353 val
.join_style
= JoinMiter
;
354 XChangeGC( display
, dc
->u
.x
.gc
,
355 GCFunction
| GCForeground
| GCBackground
| GCLineWidth
|
356 GCLineStyle
| GCCapStyle
| GCJoinStyle
| GCFillStyle
, &val
);
361 /***********************************************************************
364 * Setup dc->u.x.gc for text drawing operations.
365 * Return FALSE if the font is null, TRUE otherwise.
367 BOOL32
DC_SetupGCForText( DC
* dc
)
369 XFontStruct
* xfs
= XFONT_GetFontStruct( dc
->u
.x
.font
);
375 if (dc
->w
.flags
& DC_DIRTY
) CLIPPING_UpdateGCRegion(dc
);
377 val
.function
= GXcopy
; /* Text is always GXcopy */
378 val
.foreground
= dc
->w
.textPixel
;
379 val
.background
= dc
->w
.backgroundPixel
;
380 val
.fill_style
= FillSolid
;
383 XChangeGC( display
, dc
->u
.x
.gc
,
384 GCFunction
| GCForeground
| GCBackground
| GCFillStyle
|
388 fprintf( stderr
, "DC_SetupGCForText: physical font failure\n" );
393 /***********************************************************************
394 * GetDCState (GDI.179)
396 HDC16 WINAPI
GetDCState( HDC16 hdc
)
401 if (!(dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
))) return 0;
402 if (!(handle
= GDI_AllocObject( sizeof(DC
), DC_MAGIC
)))
404 GDI_HEAP_UNLOCK( hdc
);
407 newdc
= (DC
*) GDI_HEAP_LOCK( handle
);
409 dprintf_dc(stddeb
, "GetDCState(%04x): returning %04x\n", hdc
, handle
);
411 memset( &newdc
->u
.x
, 0, sizeof(newdc
->u
.x
) );
412 newdc
->w
.flags
= dc
->w
.flags
| DC_SAVED
;
413 newdc
->w
.devCaps
= dc
->w
.devCaps
;
414 newdc
->w
.hPen
= dc
->w
.hPen
;
415 newdc
->w
.hBrush
= dc
->w
.hBrush
;
416 newdc
->w
.hFont
= dc
->w
.hFont
;
417 newdc
->w
.hBitmap
= dc
->w
.hBitmap
;
418 newdc
->w
.hFirstBitmap
= dc
->w
.hFirstBitmap
;
419 newdc
->w
.hDevice
= dc
->w
.hDevice
;
420 newdc
->w
.hPalette
= dc
->w
.hPalette
;
421 newdc
->w
.bitsPerPixel
= dc
->w
.bitsPerPixel
;
422 newdc
->w
.ROPmode
= dc
->w
.ROPmode
;
423 newdc
->w
.polyFillMode
= dc
->w
.polyFillMode
;
424 newdc
->w
.stretchBltMode
= dc
->w
.stretchBltMode
;
425 newdc
->w
.relAbsMode
= dc
->w
.relAbsMode
;
426 newdc
->w
.backgroundMode
= dc
->w
.backgroundMode
;
427 newdc
->w
.backgroundColor
= dc
->w
.backgroundColor
;
428 newdc
->w
.textColor
= dc
->w
.textColor
;
429 newdc
->w
.backgroundPixel
= dc
->w
.backgroundPixel
;
430 newdc
->w
.textPixel
= dc
->w
.textPixel
;
431 newdc
->w
.brushOrgX
= dc
->w
.brushOrgX
;
432 newdc
->w
.brushOrgY
= dc
->w
.brushOrgY
;
433 newdc
->w
.textAlign
= dc
->w
.textAlign
;
434 newdc
->w
.charExtra
= dc
->w
.charExtra
;
435 newdc
->w
.breakTotalExtra
= dc
->w
.breakTotalExtra
;
436 newdc
->w
.breakCount
= dc
->w
.breakCount
;
437 newdc
->w
.breakExtra
= dc
->w
.breakExtra
;
438 newdc
->w
.breakRem
= dc
->w
.breakRem
;
439 newdc
->w
.MapMode
= dc
->w
.MapMode
;
440 newdc
->w
.DCOrgX
= dc
->w
.DCOrgX
;
441 newdc
->w
.DCOrgY
= dc
->w
.DCOrgY
;
442 newdc
->w
.CursPosX
= dc
->w
.CursPosX
;
443 newdc
->w
.CursPosY
= dc
->w
.CursPosY
;
444 newdc
->wndOrgX
= dc
->wndOrgX
;
445 newdc
->wndOrgY
= dc
->wndOrgY
;
446 newdc
->wndExtX
= dc
->wndExtX
;
447 newdc
->wndExtY
= dc
->wndExtY
;
448 newdc
->vportOrgX
= dc
->vportOrgX
;
449 newdc
->vportOrgY
= dc
->vportOrgY
;
450 newdc
->vportExtX
= dc
->vportExtX
;
451 newdc
->vportExtY
= dc
->vportExtY
;
453 newdc
->hSelf
= (HDC32
)handle
;
454 newdc
->saveLevel
= 0;
456 newdc
->w
.hGCClipRgn
= 0;
457 newdc
->w
.hVisRgn
= CreateRectRgn32( 0, 0, 0, 0 );
458 CombineRgn32( newdc
->w
.hVisRgn
, dc
->w
.hVisRgn
, 0, RGN_COPY
);
461 newdc
->w
.hClipRgn
= CreateRectRgn32( 0, 0, 0, 0 );
462 CombineRgn32( newdc
->w
.hClipRgn
, dc
->w
.hClipRgn
, 0, RGN_COPY
);
465 newdc
->w
.hClipRgn
= 0;
466 GDI_HEAP_UNLOCK( handle
);
467 GDI_HEAP_UNLOCK( hdc
);
472 /***********************************************************************
473 * SetDCState (GDI.180)
475 void WINAPI
SetDCState( HDC16 hdc
, HDC16 hdcs
)
479 if (!(dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
))) return;
480 if (!(dcs
= (DC
*) GDI_GetObjPtr( hdcs
, DC_MAGIC
)))
482 GDI_HEAP_UNLOCK( hdc
);
485 if (!dcs
->w
.flags
& DC_SAVED
)
487 GDI_HEAP_UNLOCK( hdc
);
488 GDI_HEAP_UNLOCK( hdcs
);
491 dprintf_dc(stddeb
, "SetDCState: %04x %04x\n", hdc
, hdcs
);
493 dc
->w
.flags
= dcs
->w
.flags
& ~DC_SAVED
;
494 dc
->w
.devCaps
= dcs
->w
.devCaps
;
495 dc
->w
.hFirstBitmap
= dcs
->w
.hFirstBitmap
;
496 dc
->w
.hDevice
= dcs
->w
.hDevice
;
497 dc
->w
.ROPmode
= dcs
->w
.ROPmode
;
498 dc
->w
.polyFillMode
= dcs
->w
.polyFillMode
;
499 dc
->w
.stretchBltMode
= dcs
->w
.stretchBltMode
;
500 dc
->w
.relAbsMode
= dcs
->w
.relAbsMode
;
501 dc
->w
.backgroundMode
= dcs
->w
.backgroundMode
;
502 dc
->w
.backgroundColor
= dcs
->w
.backgroundColor
;
503 dc
->w
.textColor
= dcs
->w
.textColor
;
504 dc
->w
.backgroundPixel
= dcs
->w
.backgroundPixel
;
505 dc
->w
.textPixel
= dcs
->w
.textPixel
;
506 dc
->w
.brushOrgX
= dcs
->w
.brushOrgX
;
507 dc
->w
.brushOrgY
= dcs
->w
.brushOrgY
;
508 dc
->w
.textAlign
= dcs
->w
.textAlign
;
509 dc
->w
.charExtra
= dcs
->w
.charExtra
;
510 dc
->w
.breakTotalExtra
= dcs
->w
.breakTotalExtra
;
511 dc
->w
.breakCount
= dcs
->w
.breakCount
;
512 dc
->w
.breakExtra
= dcs
->w
.breakExtra
;
513 dc
->w
.breakRem
= dcs
->w
.breakRem
;
514 dc
->w
.MapMode
= dcs
->w
.MapMode
;
515 dc
->w
.DCOrgX
= dcs
->w
.DCOrgX
;
516 dc
->w
.DCOrgY
= dcs
->w
.DCOrgY
;
517 dc
->w
.CursPosX
= dcs
->w
.CursPosX
;
518 dc
->w
.CursPosY
= dcs
->w
.CursPosY
;
520 dc
->wndOrgX
= dcs
->wndOrgX
;
521 dc
->wndOrgY
= dcs
->wndOrgY
;
522 dc
->wndExtX
= dcs
->wndExtX
;
523 dc
->wndExtY
= dcs
->wndExtY
;
524 dc
->vportOrgX
= dcs
->vportOrgX
;
525 dc
->vportOrgY
= dcs
->vportOrgY
;
526 dc
->vportExtX
= dcs
->vportExtX
;
527 dc
->vportExtY
= dcs
->vportExtY
;
529 if (!(dc
->w
.flags
& DC_MEMORY
)) dc
->w
.bitsPerPixel
= dcs
->w
.bitsPerPixel
;
530 CombineRgn32( dc
->w
.hVisRgn
, dcs
->w
.hVisRgn
, 0, RGN_COPY
);
531 SelectClipRgn32( hdc
, dcs
->w
.hClipRgn
);
532 SelectObject32( hdc
, dcs
->w
.hBitmap
);
533 SelectObject32( hdc
, dcs
->w
.hBrush
);
534 SelectObject32( hdc
, dcs
->w
.hFont
);
535 SelectObject32( hdc
, dcs
->w
.hPen
);
536 GDISelectPalette( hdc
, dcs
->w
.hPalette
, FALSE
);
537 GDI_HEAP_UNLOCK( hdc
);
538 GDI_HEAP_UNLOCK( hdcs
);
542 /***********************************************************************
545 INT16 WINAPI
SaveDC16( HDC16 hdc
)
547 return (INT16
)SaveDC32( hdc
);
551 /***********************************************************************
552 * SaveDC32 (GDI32.292)
554 INT32 WINAPI
SaveDC32( HDC32 hdc
)
560 dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
563 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
565 MF_MetaParam0(dc
, META_SAVEDC
);
566 GDI_HEAP_UNLOCK( hdc
);
569 if (!(hdcs
= GetDCState( hdc
)))
571 GDI_HEAP_UNLOCK( hdc
);
574 dcs
= (DC
*) GDI_HEAP_LOCK( hdcs
);
575 dcs
->header
.hNext
= dc
->header
.hNext
;
576 dc
->header
.hNext
= hdcs
;
577 dprintf_dc(stddeb
, "SaveDC(%04x): returning %d\n", hdc
, dc
->saveLevel
+1 );
578 ret
= ++dc
->saveLevel
;
579 GDI_HEAP_UNLOCK( hdcs
);
580 GDI_HEAP_UNLOCK( hdc
);
585 /***********************************************************************
586 * RestoreDC16 (GDI.39)
588 BOOL16 WINAPI
RestoreDC16( HDC16 hdc
, INT16 level
)
590 return RestoreDC32( hdc
, level
);
594 /***********************************************************************
595 * RestoreDC32 (GDI32.290)
597 BOOL32 WINAPI
RestoreDC32( HDC32 hdc
, INT32 level
)
601 dprintf_dc(stddeb
, "RestoreDC: %04x %d\n", hdc
, level
);
602 dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
605 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
606 if (!dc
) return FALSE
;
609 GDI_HEAP_UNLOCK( hdc
);
612 MF_MetaParam1(dc
, META_RESTOREDC
, level
);
613 GDI_HEAP_UNLOCK( hdc
);
616 if (level
== -1) level
= dc
->saveLevel
;
617 if ((level
< 1) || (level
> dc
->saveLevel
))
619 GDI_HEAP_UNLOCK( hdc
);
623 while (dc
->saveLevel
>= level
)
625 HDC16 hdcs
= dc
->header
.hNext
;
626 if (!(dcs
= (DC
*) GDI_GetObjPtr( hdcs
, DC_MAGIC
)))
628 GDI_HEAP_UNLOCK( hdc
);
631 dc
->header
.hNext
= dcs
->header
.hNext
;
632 if (--dc
->saveLevel
< level
) SetDCState( hdc
, hdcs
);
635 GDI_HEAP_UNLOCK( hdc
);
640 /***********************************************************************
641 * CreateDC16 (GDI.53)
643 HDC16 WINAPI
CreateDC16( LPCSTR driver
, LPCSTR device
, LPCSTR output
,
644 const DEVMODE16
*initData
)
647 const DC_FUNCTIONS
*funcs
;
649 if (!(funcs
= DRIVER_FindDriver( driver
))) return 0;
650 if (!(dc
= DC_AllocDC( funcs
))) return 0;
653 dprintf_dc(stddeb
, "CreateDC(%s %s %s): returning %04x\n",
654 driver
, device
, output
, dc
->hSelf
);
656 if (dc
->funcs
->pCreateDC
&&
657 !dc
->funcs
->pCreateDC( dc
, driver
, device
, output
, initData
))
659 dprintf_dc( stddeb
, "CreateDC: creation aborted by device\n" );
660 GDI_HEAP_FREE( dc
->hSelf
);
665 GDI_HEAP_UNLOCK( dc
->hSelf
);
670 /***********************************************************************
671 * CreateDC32A (GDI32.)
673 HDC32 WINAPI
CreateDC32A( LPCSTR driver
, LPCSTR device
, LPCSTR output
,
674 const DEVMODE32A
*initData
)
676 return CreateDC16( driver
, device
, output
, (const DEVMODE16
*)initData
);
680 /***********************************************************************
681 * CreateDC32W (GDI32.)
683 HDC32 WINAPI
CreateDC32W( LPCWSTR driver
, LPCWSTR device
, LPCWSTR output
,
684 const DEVMODE32W
*initData
)
686 LPSTR driverA
= HEAP_strdupWtoA( GetProcessHeap(), 0, driver
);
687 LPSTR deviceA
= HEAP_strdupWtoA( GetProcessHeap(), 0, device
);
688 LPSTR outputA
= HEAP_strdupWtoA( GetProcessHeap(), 0, output
);
689 HDC32 res
= CreateDC16( driverA
, deviceA
, outputA
,
690 (const DEVMODE16
*)initData
/*FIXME*/ );
691 HeapFree( GetProcessHeap(), 0, driverA
);
692 HeapFree( GetProcessHeap(), 0, deviceA
);
693 HeapFree( GetProcessHeap(), 0, outputA
);
698 /***********************************************************************
699 * CreateIC16 (GDI.153)
701 HDC16 WINAPI
CreateIC16( LPCSTR driver
, LPCSTR device
, LPCSTR output
,
702 const DEVMODE16
* initData
)
704 /* Nothing special yet for ICs */
705 return CreateDC16( driver
, device
, output
, initData
);
709 /***********************************************************************
710 * CreateIC32A (GDI32.49)
712 HDC32 WINAPI
CreateIC32A( LPCSTR driver
, LPCSTR device
, LPCSTR output
,
713 const DEVMODE32A
* initData
)
715 /* Nothing special yet for ICs */
716 return CreateDC32A( driver
, device
, output
, initData
);
720 /***********************************************************************
721 * CreateIC32W (GDI32.50)
723 HDC32 WINAPI
CreateIC32W( LPCWSTR driver
, LPCWSTR device
, LPCWSTR output
,
724 const DEVMODE32W
* initData
)
726 /* Nothing special yet for ICs */
727 return CreateDC32W( driver
, device
, output
, initData
);
731 /***********************************************************************
732 * CreateCompatibleDC16 (GDI.52)
734 HDC16 WINAPI
CreateCompatibleDC16( HDC16 hdc
)
736 return (HDC16
)CreateCompatibleDC32( hdc
);
740 /***********************************************************************
741 * CreateCompatibleDC32 (GDI32.31)
743 HDC32 WINAPI
CreateCompatibleDC32( HDC32 hdc
)
747 const DC_FUNCTIONS
*funcs
;
749 if ((origDC
= (DC
*)GDI_GetObjPtr( hdc
, DC_MAGIC
))) funcs
= origDC
->funcs
;
750 else funcs
= DRIVER_FindDriver( "DISPLAY" );
751 if (!funcs
) return 0;
753 if (!(dc
= DC_AllocDC( funcs
))) return 0;
755 dprintf_dc(stddeb
, "CreateCompatibleDC(%04x): returning %04x\n",
758 /* Create default bitmap */
759 if (!(hbitmap
= CreateBitmap32( 1, 1, 1, 1, NULL
)))
761 GDI_HEAP_FREE( dc
->hSelf
);
764 dc
->w
.flags
= DC_MEMORY
;
765 dc
->w
.bitsPerPixel
= 1;
766 dc
->w
.hBitmap
= hbitmap
;
767 dc
->w
.hFirstBitmap
= hbitmap
;
769 if (dc
->funcs
->pCreateDC
&&
770 !dc
->funcs
->pCreateDC( dc
, NULL
, NULL
, NULL
, NULL
))
772 dprintf_dc(stddeb
, "CreateCompatibleDC: creation aborted by device\n");
773 DeleteObject32( hbitmap
);
774 GDI_HEAP_FREE( dc
->hSelf
);
779 GDI_HEAP_UNLOCK( dc
->hSelf
);
784 /***********************************************************************
785 * DeleteDC16 (GDI.68)
787 BOOL16 WINAPI
DeleteDC16( HDC16 hdc
)
789 return DeleteDC32( hdc
);
793 /***********************************************************************
794 * DeleteDC32 (GDI32.67)
796 BOOL32 WINAPI
DeleteDC32( HDC32 hdc
)
798 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
799 if (!dc
) return FALSE
;
801 dprintf_dc(stddeb
, "DeleteDC: %04x\n", hdc
);
803 while (dc
->saveLevel
)
806 HDC16 hdcs
= dc
->header
.hNext
;
807 if (!(dcs
= (DC
*) GDI_GetObjPtr( hdcs
, DC_MAGIC
))) break;
808 dc
->header
.hNext
= dcs
->header
.hNext
;
813 if (!(dc
->w
.flags
& DC_SAVED
))
815 SelectObject32( hdc
, STOCK_BLACK_PEN
);
816 SelectObject32( hdc
, STOCK_WHITE_BRUSH
);
817 SelectObject32( hdc
, STOCK_SYSTEM_FONT
);
818 if (dc
->w
.flags
& DC_MEMORY
) DeleteObject32( dc
->w
.hFirstBitmap
);
819 if (dc
->funcs
->pDeleteDC
) dc
->funcs
->pDeleteDC(dc
);
822 if (dc
->w
.hClipRgn
) DeleteObject32( dc
->w
.hClipRgn
);
823 if (dc
->w
.hVisRgn
) DeleteObject32( dc
->w
.hVisRgn
);
824 if (dc
->w
.hGCClipRgn
) DeleteObject32( dc
->w
.hGCClipRgn
);
826 return GDI_FreeObject( hdc
);
830 /***********************************************************************
831 * ResetDC16 (GDI.376)
833 HDC16 WINAPI
ResetDC16( HDC16 hdc
, const DEVMODE16
*devmode
)
835 fprintf( stderr
, "ResetDC16: empty stub!\n" );
840 /***********************************************************************
841 * ResetDC32A (GDI32.287)
843 HDC32 WINAPI
ResetDC32A( HDC32 hdc
, const DEVMODE32A
*devmode
)
845 fprintf( stderr
, "ResetDC32A: empty stub!\n" );
850 /***********************************************************************
851 * ResetDC32W (GDI32.288)
853 HDC32 WINAPI
ResetDC32W( HDC32 hdc
, const DEVMODE32W
*devmode
)
855 fprintf( stderr
, "ResetDC32A: empty stub!\n" );
860 /***********************************************************************
861 * GetDeviceCaps16 (GDI.80)
863 INT16 WINAPI
GetDeviceCaps16( HDC16 hdc
, INT16 cap
)
865 return GetDeviceCaps32( hdc
, cap
);
869 /***********************************************************************
870 * GetDeviceCaps32 (GDI32.171)
872 INT32 WINAPI
GetDeviceCaps32( HDC32 hdc
, INT32 cap
)
874 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
879 if ((cap
< 0) || (cap
> sizeof(DeviceCaps
)-sizeof(WORD
)))
881 GDI_HEAP_UNLOCK( hdc
);
885 dprintf_dc(stddeb
, "GetDeviceCaps(%04x,%d): returning %d\n",
886 hdc
, cap
, *(WORD
*)(((char *)dc
->w
.devCaps
) + cap
) );
887 ret
= *(WORD
*)(((char *)dc
->w
.devCaps
) + cap
);
888 GDI_HEAP_UNLOCK( hdc
);
893 /***********************************************************************
894 * SetBkColor16 (GDI.1)
896 COLORREF WINAPI
SetBkColor16( HDC16 hdc
, COLORREF color
)
898 return SetBkColor32( hdc
, color
);
902 /***********************************************************************
903 * SetBkColor32 (GDI32.305)
905 COLORREF WINAPI
SetBkColor32( HDC32 hdc
, COLORREF color
)
908 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
911 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
912 if (!dc
) return 0x80000000;
913 MF_MetaParam2(dc
, META_SETBKCOLOR
, HIWORD(color
), LOWORD(color
));
914 GDI_HEAP_UNLOCK( hdc
);
918 oldColor
= dc
->w
.backgroundColor
;
919 dc
->w
.backgroundColor
= color
;
920 dc
->w
.backgroundPixel
= COLOR_ToPhysical( dc
, color
);
921 GDI_HEAP_UNLOCK( hdc
);
926 /***********************************************************************
927 * SetTextColor16 (GDI.9)
929 COLORREF WINAPI
SetTextColor16( HDC16 hdc
, COLORREF color
)
931 return SetTextColor32( hdc
, color
);
935 /***********************************************************************
936 * SetTextColor32 (GDI32.338)
938 COLORREF WINAPI
SetTextColor32( HDC32 hdc
, COLORREF color
)
941 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
944 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
945 if (!dc
) return 0x80000000;
946 MF_MetaParam2(dc
, META_SETTEXTCOLOR
, HIWORD(color
), LOWORD(color
));
947 GDI_HEAP_UNLOCK( hdc
);
951 oldColor
= dc
->w
.textColor
;
952 dc
->w
.textColor
= color
;
953 dc
->w
.textPixel
= COLOR_ToPhysical( dc
, color
);
954 GDI_HEAP_UNLOCK( hdc
);
959 /***********************************************************************
960 * SetTextAlign16 (GDI.346)
962 UINT16 WINAPI
SetTextAlign16( HDC16 hdc
, UINT16 textAlign
)
964 return SetTextAlign32( hdc
, textAlign
);
968 /***********************************************************************
969 * SetTextAlign32 (GDI32.336)
971 UINT32 WINAPI
SetTextAlign32( HDC32 hdc
, UINT32 textAlign
)
974 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
977 if (!(dc
= (DC
*)GDI_GetObjPtr( hdc
, METAFILE_DC_MAGIC
))) return 0;
978 MF_MetaParam1( dc
, META_SETTEXTALIGN
, textAlign
);
979 GDI_HEAP_UNLOCK( hdc
);
982 prevAlign
= dc
->w
.textAlign
;
983 dc
->w
.textAlign
= textAlign
;
984 GDI_HEAP_UNLOCK( hdc
);
989 /***********************************************************************
990 * GetDCOrgEx (GDI32.168)
992 BOOL32 WINAPI
GetDCOrgEx( HDC32 hDC
, LPPOINT32 lpp
)
995 if (!lpp
) return FALSE
;
996 if (!(dc
= (DC
*) GDI_GetObjPtr( hDC
, DC_MAGIC
))) return FALSE
;
998 if (!(dc
->w
.flags
& DC_MEMORY
))
1001 int w
, h
, border
, depth
;
1002 /* FIXME: this is not correct for managed windows */
1003 XGetGeometry( display
, dc
->u
.x
.drawable
, &root
,
1004 &lpp
->x
, &lpp
->y
, &w
, &h
, &border
, &depth
);
1006 else lpp
->x
= lpp
->y
= 0;
1007 lpp
->x
+= dc
->w
.DCOrgX
; lpp
->y
+= dc
->w
.DCOrgY
;
1008 GDI_HEAP_UNLOCK( hDC
);
1013 /***********************************************************************
1016 DWORD WINAPI
GetDCOrg( HDC16 hdc
)
1019 if( GetDCOrgEx( hdc
, &pt
) )
1020 return MAKELONG( (WORD
)pt
.x
, (WORD
)pt
.y
);
1025 /***********************************************************************
1026 * SetDCOrg (GDI.117)
1028 DWORD WINAPI
SetDCOrg( HDC16 hdc
, INT16 x
, INT16 y
)
1031 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
1033 prevOrg
= dc
->w
.DCOrgX
| (dc
->w
.DCOrgY
<< 16);
1036 GDI_HEAP_UNLOCK( hdc
);
1041 /***********************************************************************
1042 * GetGraphicsMode (GDI32.188)
1044 INT32 WINAPI
GetGraphicsMode( HDC32 hdc
)
1046 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
1048 return dc
->w
.GraphicsMode
;
1052 /***********************************************************************
1053 * SetGraphicsMode (GDI32.317)
1055 INT32 WINAPI
SetGraphicsMode( HDC32 hdc
, INT32 mode
)
1058 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
1060 if ((mode
<= 0) || (mode
> GM_LAST
)) return 0;
1061 ret
= dc
->w
.GraphicsMode
;
1062 dc
->w
.GraphicsMode
= mode
;
1067 /***********************************************************************
1068 * GetWorldTransform (GDI32.244)
1070 BOOL32 WINAPI
GetWorldTransform( HDC32 hdc
, LPXFORM xform
)
1072 fprintf( stdnimp
, "GetWorldTransform: empty stub\n" );
1077 /***********************************************************************
1078 * SetDCHook (GDI.190)
1080 BOOL16 WINAPI
SetDCHook( HDC16 hdc
, FARPROC16 hookProc
, DWORD dwHookData
)
1082 DC
*dc
= (DC
*)GDI_GetObjPtr( hdc
, DC_MAGIC
);
1084 dprintf_dc( stddeb
, "SetDCHook: hookProc %08x, default is %08x\n",
1085 (UINT32
)hookProc
, (UINT32
)DCHook
);
1087 if (!dc
) return FALSE
;
1088 dc
->hookProc
= hookProc
;
1089 dc
->dwHookData
= dwHookData
;
1090 GDI_HEAP_UNLOCK( hdc
);
1095 /***********************************************************************
1096 * GetDCHook (GDI.191)
1098 DWORD WINAPI
GetDCHook( HDC16 hdc
, FARPROC16
*phookProc
)
1100 DC
*dc
= (DC
*)GDI_GetObjPtr( hdc
, DC_MAGIC
);
1102 *phookProc
= dc
->hookProc
;
1103 GDI_HEAP_UNLOCK( hdc
);
1104 return dc
->dwHookData
;
1108 /***********************************************************************
1109 * SetHookFlags (GDI.192)
1111 WORD WINAPI
SetHookFlags(HDC16 hDC
, WORD flags
)
1113 DC
* dc
= (DC
*)GDI_GetObjPtr( hDC
, DC_MAGIC
);
1117 WORD wRet
= dc
->w
.flags
& DC_DIRTY
;
1119 /* "Undocumented Windows" info is slightly
1123 dprintf_dc(stddeb
,"SetHookFlags: hDC %04x, flags %04x\n",hDC
,flags
);
1125 if( flags
& DCHF_INVALIDATEVISRGN
)
1126 dc
->w
.flags
|= DC_DIRTY
;
1127 else if( flags
& DCHF_VALIDATEVISRGN
|| !flags
)
1128 dc
->w
.flags
&= ~DC_DIRTY
;
1129 GDI_HEAP_UNLOCK( hDC
);