2 * GDI Device Context functions
4 * Copyright 1993 Alexandre Julliard
20 static DeviceCaps
* displayDevCaps
= NULL
;
22 extern void CLIPPING_UpdateGCRegion( DC
* dc
); /* objects/clipping.c */
23 extern BOOL
DCHook( HDC
, WORD
, DWORD
, DWORD
); /* windows/dce.c */
25 /* Default DC values */
26 static const WIN_DC_INFO DC_defaultValues
=
34 STOCK_BLACK_PEN
, /* hPen */
35 STOCK_WHITE_BRUSH
, /* hBrush */
36 STOCK_SYSTEM_FONT
, /* hFont */
40 STOCK_DEFAULT_PALETTE
, /* hPalette */
41 R2_COPYPEN
, /* ROPmode */
42 ALTERNATE
, /* polyFillMode */
43 BLACKONWHITE
, /* stretchBltMode */
44 ABSOLUTE
, /* relAbsMode */
45 OPAQUE
, /* backgroundMode */
46 RGB( 255, 255, 255 ), /* backgroundColor */
47 RGB( 0, 0, 0 ), /* textColor */
48 0, /* backgroundPixel */
52 TA_LEFT
| TA_TOP
| TA_NOUPDATECP
, /* textAlign */
54 0, /* breakTotalExtra */
59 MM_TEXT
, /* MapMode */
74 /* ROP code to GC function conversion */
75 const int DC_XROPfunction
[16] =
77 GXclear
, /* R2_BLACK */
78 GXnor
, /* R2_NOTMERGEPEN */
79 GXandInverted
, /* R2_MASKNOTPEN */
80 GXcopyInverted
, /* R2_NOTCOPYPEN */
81 GXandReverse
, /* R2_MASKPENNOT */
82 GXinvert
, /* R2_NOT */
83 GXxor
, /* R2_XORPEN */
84 GXnand
, /* R2_NOTMASKPEN */
85 GXand
, /* R2_MASKPEN */
86 GXequiv
, /* R2_NOTXORPEN */
88 GXorInverted
, /* R2_MERGENOTPEN */
89 GXcopy
, /* R2_COPYPEN */
90 GXorReverse
, /* R2_MERGEPENNOT */
91 GXor
, /* R2_MERGEPEN */
96 /***********************************************************************
99 * Fill the device caps structure.
101 void DC_FillDevCaps( DeviceCaps
* caps
)
103 caps
->version
= 0x300;
104 caps
->technology
= DT_RASDISPLAY
;
105 caps
->horzSize
= WidthMMOfScreen(screen
) * screenWidth
/ WidthOfScreen(screen
);
106 caps
->vertSize
= HeightMMOfScreen(screen
) * screenHeight
/ HeightOfScreen(screen
);
107 caps
->horzRes
= screenWidth
;
108 caps
->vertRes
= screenHeight
;
109 caps
->bitsPixel
= screenDepth
;
111 caps
->numBrushes
= 16+6; /* 16 solid + 6 hatched brushes */
112 caps
->numPens
= 16; /* 16 solid pens */
113 caps
->numMarkers
= 0;
115 caps
->numColors
= 1 << caps
->bitsPixel
;
116 caps
->pdeviceSize
= 0;
117 caps
->curveCaps
= CC_CIRCLES
| CC_PIE
| CC_CHORD
| CC_ELLIPSES
|
118 CC_WIDE
| CC_STYLED
| CC_WIDESTYLED
|
119 CC_INTERIORS
| CC_ROUNDRECT
;
120 caps
->lineCaps
= LC_POLYLINE
| LC_MARKER
| LC_POLYMARKER
| LC_WIDE
|
121 LC_STYLED
| LC_WIDESTYLED
| LC_INTERIORS
;
122 caps
->polygonalCaps
= PC_POLYGON
| PC_RECTANGLE
| PC_WINDPOLYGON
|
123 PC_SCANLINE
| PC_WIDE
| PC_STYLED
|
124 PC_WIDESTYLED
| PC_INTERIORS
;
125 caps
->textCaps
= TC_OP_CHARACTER
| TC_OP_STROKE
| TC_CP_STROKE
|
126 TC_IA_ABLE
| TC_UA_ABLE
| TC_SO_ABLE
| TC_RA_ABLE
;
127 caps
->clipCaps
= CP_REGION
;
128 caps
->rasterCaps
= RC_BITBLT
| RC_BANDING
| RC_SCALING
| RC_BITMAP64
|
129 RC_DI_BITMAP
| RC_PALETTE
| RC_DIBTODEV
| RC_BIGFONT
|
130 RC_STRETCHBLT
| RC_STRETCHDIB
| RC_DEVBITS
;
131 caps
->aspectX
= 36; /* ?? */
132 caps
->aspectY
= 36; /* ?? */
134 caps
->logPixelsX
= (int)(caps
->horzRes
* 25.4 / caps
->horzSize
);
135 caps
->logPixelsY
= (int)(caps
->vertRes
* 25.4 / caps
->vertSize
);
136 caps
->sizePalette
= DefaultVisual(display
,DefaultScreen(display
))->map_entries
;
137 caps
->numReserved
= 0;
142 /***********************************************************************
145 * Setup device-specific DC values for a newly created DC.
147 void DC_InitDC( DC
* dc
)
149 RealizeDefaultPalette( dc
->hSelf
);
150 SetTextColor( dc
->hSelf
, dc
->w
.textColor
);
151 SetBkColor( dc
->hSelf
, dc
->w
.backgroundColor
);
152 SelectObject( dc
->hSelf
, dc
->w
.hPen
);
153 SelectObject( dc
->hSelf
, dc
->w
.hBrush
);
154 SelectObject( dc
->hSelf
, dc
->w
.hFont
);
155 XSetGraphicsExposures( display
, dc
->u
.x
.gc
, False
);
156 XSetSubwindowMode( display
, dc
->u
.x
.gc
, IncludeInferiors
);
157 CLIPPING_UpdateGCRegion( dc
);
161 /***********************************************************************
162 * DC_SetupGCForPatBlt
164 * Setup the GC for a PatBlt operation using current brush.
165 * If fMapColors is TRUE, X pixels are mapped to Windows colors.
166 * Return FALSE if brush is BS_NULL, TRUE otherwise.
168 BOOL
DC_SetupGCForPatBlt( DC
* dc
, GC gc
, BOOL fMapColors
)
174 if (dc
->u
.x
.brush
.style
== BS_NULL
) return FALSE
;
175 if (dc
->u
.x
.brush
.pixel
== -1)
177 /* Special case used for monochrome pattern brushes.
178 * We need to swap foreground and background because
179 * Windows does it the wrong way...
181 val
.foreground
= dc
->w
.backgroundPixel
;
182 val
.background
= dc
->w
.textPixel
;
186 val
.foreground
= dc
->u
.x
.brush
.pixel
;
187 val
.background
= dc
->w
.backgroundPixel
;
189 if (fMapColors
&& COLOR_PixelToPalette
)
191 val
.foreground
= COLOR_PixelToPalette
[val
.foreground
];
192 val
.background
= COLOR_PixelToPalette
[val
.background
];
195 if (dc
->w
.flags
& DC_DIRTY
) CLIPPING_UpdateGCRegion(dc
);
197 val
.function
= DC_XROPfunction
[dc
->w
.ROPmode
-1];
198 val
.fill_style
= dc
->u
.x
.brush
.fillStyle
;
199 switch(val
.fill_style
)
202 case FillOpaqueStippled
:
203 if (dc
->w
.backgroundMode
==OPAQUE
) val
.fill_style
= FillOpaqueStippled
;
204 val
.stipple
= dc
->u
.x
.brush
.pixmap
;
209 if (fMapColors
&& COLOR_PixelToPalette
)
213 pixmap
= XCreatePixmap( display
, rootWindow
, 8, 8, screenDepth
);
214 image
= XGetImage( display
, dc
->u
.x
.brush
.pixmap
, 0, 0, 8, 8,
215 AllPlanes
, ZPixmap
);
216 for (y
= 0; y
< 8; y
++)
217 for (x
= 0; x
< 8; x
++)
218 XPutPixel( image
, x
, y
,
219 COLOR_PixelToPalette
[XGetPixel( image
, x
, y
)] );
220 XPutImage( display
, pixmap
, gc
, image
, 0, 0, 0, 0, 8, 8 );
221 XDestroyImage( image
);
224 else val
.tile
= dc
->u
.x
.brush
.pixmap
;
232 val
.ts_x_origin
= dc
->w
.DCOrgX
+ dc
->w
.brushOrgX
;
233 val
.ts_y_origin
= dc
->w
.DCOrgY
+ dc
->w
.brushOrgY
;
234 val
.fill_rule
= (dc
->w
.polyFillMode
==WINDING
) ? WindingRule
: EvenOddRule
;
235 XChangeGC( display
, gc
,
236 GCFunction
| GCForeground
| GCBackground
| GCFillStyle
|
237 GCFillRule
| GCTileStipXOrigin
| GCTileStipYOrigin
| mask
,
239 if (pixmap
) XFreePixmap( display
, pixmap
);
244 /***********************************************************************
247 * Setup dc->u.x.gc for drawing operations using current brush.
248 * Return FALSE if brush is BS_NULL, TRUE otherwise.
250 BOOL
DC_SetupGCForBrush( DC
* dc
)
252 return DC_SetupGCForPatBlt( dc
, dc
->u
.x
.gc
, FALSE
);
256 /***********************************************************************
259 * Setup dc->u.x.gc for drawing operations using current pen.
260 * Return FALSE if pen is PS_NULL, TRUE otherwise.
262 BOOL
DC_SetupGCForPen( DC
* dc
)
266 if (dc
->u
.x
.pen
.style
== PS_NULL
) return FALSE
;
268 if (dc
->w
.flags
& DC_DIRTY
) CLIPPING_UpdateGCRegion(dc
);
270 if ((screenDepth
<= 8) && /* FIXME: Should check for palette instead */
271 ((dc
->w
.ROPmode
== R2_BLACK
) || (dc
->w
.ROPmode
== R2_WHITE
)))
273 val
.function
= GXcopy
;
274 val
.foreground
= COLOR_ToPhysical( NULL
, (dc
->w
.ROPmode
== R2_BLACK
) ?
275 RGB(0,0,0) : RGB(255,255,255) );
279 val
.function
= DC_XROPfunction
[dc
->w
.ROPmode
-1];
280 val
.foreground
= dc
->u
.x
.pen
.pixel
;
282 val
.background
= dc
->w
.backgroundPixel
;
283 val
.fill_style
= FillSolid
;
284 if ((dc
->u
.x
.pen
.style
!=PS_SOLID
) && (dc
->u
.x
.pen
.style
!=PS_INSIDEFRAME
))
286 XSetDashes( display
, dc
->u
.x
.gc
, 0,
287 dc
->u
.x
.pen
.dashes
, dc
->u
.x
.pen
.dash_len
);
288 val
.line_style
= (dc
->w
.backgroundMode
== OPAQUE
) ?
289 LineDoubleDash
: LineOnOffDash
;
291 else val
.line_style
= LineSolid
;
292 val
.line_width
= dc
->u
.x
.pen
.width
;
293 val
.cap_style
= CapRound
;
294 val
.join_style
= JoinBevel
;
295 XChangeGC( display
, dc
->u
.x
.gc
,
296 GCFunction
| GCForeground
| GCBackground
| GCLineWidth
|
297 GCLineStyle
| GCCapStyle
| GCJoinStyle
| GCFillStyle
, &val
);
302 /***********************************************************************
305 * Setup dc->u.x.gc for text drawing operations.
306 * Return FALSE if the font is null, TRUE otherwise.
308 BOOL
DC_SetupGCForText( DC
* dc
)
312 if (!dc
->u
.x
.font
.fstruct
)
314 fprintf( stderr
, "DC_SetupGCForText: fstruct is NULL. Please report this\n" );
318 if (dc
->w
.flags
& DC_DIRTY
) CLIPPING_UpdateGCRegion(dc
);
320 val
.function
= GXcopy
; /* Text is always GXcopy */
321 val
.foreground
= dc
->w
.textPixel
;
322 val
.background
= dc
->w
.backgroundPixel
;
323 val
.fill_style
= FillSolid
;
324 val
.font
= dc
->u
.x
.font
.fstruct
->fid
;
325 XChangeGC( display
, dc
->u
.x
.gc
,
326 GCFunction
| GCForeground
| GCBackground
| GCFillStyle
|
332 /***********************************************************************
335 BOOL
DC_CallHookProc(DC
* dc
, WORD code
, LPARAM lParam
)
338 FARPROC ptr
= GDI_GetDefDCHook();
340 dprintf_dc(stddeb
,"CallDCHook: code %04x\n", code
);
342 /* if 16-bit callback is, in fact, a thunk to DCHook simply call DCHook */
344 if( dc
->hookProc
&& !(dc
->w
.flags
& (DC_SAVED
| DC_MEMORY
)) )
345 bRet
= (dc
->hookProc
== ptr
) ?
346 DCHook(dc
->hSelf
, code
, dc
->dwHookData
, lParam
):
347 CallDCHookProc(dc
->hookProc
, dc
->hSelf
, code
, dc
->dwHookData
, lParam
);
352 /***********************************************************************
353 * GetDCState (GDI.179)
355 HDC
GetDCState( HDC hdc
)
360 if (!(dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
))) return 0;
361 if (!(handle
= GDI_AllocObject( sizeof(DC
), DC_MAGIC
))) return 0;
362 newdc
= (DC
*) GDI_HEAP_LIN_ADDR( handle
);
364 dprintf_dc(stddeb
, "GetDCState(%04x): returning %04x\n", hdc
, handle
);
366 memset( &newdc
->u
.x
, 0, sizeof(newdc
->u
.x
) );
367 memcpy( &newdc
->w
, &dc
->w
, sizeof(dc
->w
) );
368 memcpy( &newdc
->u
.x
.pen
, &dc
->u
.x
.pen
, sizeof(dc
->u
.x
.pen
) );
370 newdc
->hSelf
= (HDC
)handle
;
371 newdc
->saveLevel
= 0;
372 newdc
->w
.flags
|= DC_SAVED
;
374 newdc
->w
.hGCClipRgn
= 0;
375 newdc
->w
.hVisRgn
= CreateRectRgn( 0, 0, 0, 0 );
376 CombineRgn( newdc
->w
.hVisRgn
, dc
->w
.hVisRgn
, 0, RGN_COPY
);
379 newdc
->w
.hClipRgn
= CreateRectRgn( 0, 0, 0, 0 );
380 CombineRgn( newdc
->w
.hClipRgn
, dc
->w
.hClipRgn
, 0, RGN_COPY
);
382 COLOR_SetMapping( newdc
, dc
->u
.x
.pal
.hMapping
,
383 dc
->u
.x
.pal
.hRevMapping
, dc
->u
.x
.pal
.mappingSize
);
388 /***********************************************************************
389 * SetDCState (GDI.180)
391 void SetDCState( HDC hdc
, HDC hdcs
)
394 HRGN hVisRgn
, hClipRgn
, hGCClipRgn
;
398 if (!(dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
))) return;
399 if (!(dcs
= (DC
*) GDI_GetObjPtr( hdcs
, DC_MAGIC
))) return;
400 if (!dcs
->w
.flags
& DC_SAVED
) return;
401 dprintf_dc(stddeb
, "SetDCState: %04x %04x\n", hdc
, hdcs
);
403 /* Save the regions, font & brush before overwriting everything */
404 hVisRgn
= dc
->w
.hVisRgn
;
405 hClipRgn
= dc
->w
.hClipRgn
;
406 hGCClipRgn
= dc
->w
.hGCClipRgn
;
408 hbrush
= dc
->w
.hBrush
;
409 memcpy( &dc
->w
, &dcs
->w
, sizeof(dc
->w
) );
410 memcpy( &dc
->u
.x
.pen
, &dcs
->u
.x
.pen
, sizeof(dc
->u
.x
.pen
) );
411 dc
->w
.flags
&= ~DC_SAVED
;
413 /* Restore the regions */
414 dc
->w
.hVisRgn
= hVisRgn
;
415 dc
->w
.hClipRgn
= hClipRgn
;
416 dc
->w
.hGCClipRgn
= hGCClipRgn
;
418 dc
->w
.hBrush
= hbrush
;
419 CombineRgn( dc
->w
.hVisRgn
, dcs
->w
.hVisRgn
, 0, RGN_COPY
);
420 SelectClipRgn( hdc
, dcs
->w
.hClipRgn
);
422 SelectObject( hdc
, dcs
->w
.hBrush
);
423 SelectObject( hdc
, dcs
->w
.hFont
);
424 COLOR_SetMapping( dc
, dcs
->u
.x
.pal
.hMapping
,
425 dcs
->u
.x
.pal
.hRevMapping
, dcs
->u
.x
.pal
.mappingSize
);
429 /***********************************************************************
432 int SaveDC( HDC hdc
)
437 dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
440 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
442 MF_MetaParam0(dc
, META_SAVEDC
);
445 if (!(hdcs
= GetDCState( hdc
))) return 0;
446 dcs
= (DC
*) GDI_HEAP_LIN_ADDR( hdcs
);
447 dcs
->header
.hNext
= dc
->header
.hNext
;
448 dc
->header
.hNext
= hdcs
;
449 dprintf_dc(stddeb
, "SaveDC(%04x): returning %d\n", hdc
, dc
->saveLevel
+1 );
450 return ++dc
->saveLevel
;
454 /***********************************************************************
457 BOOL
RestoreDC( HDC hdc
, short level
)
461 dprintf_dc(stddeb
, "RestoreDC: %04x %d\n", hdc
, level
);
462 dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
465 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
466 if (!dc
) return FALSE
;
467 if (level
!= -1) return FALSE
;
468 MF_MetaParam1(dc
, META_RESTOREDC
, level
);
471 if (level
== -1) level
= dc
->saveLevel
;
472 if ((level
< 1) || (level
> (short)dc
->saveLevel
)) return FALSE
;
474 while ((short)dc
->saveLevel
>= level
)
476 HDC hdcs
= dc
->header
.hNext
;
477 if (!(dcs
= (DC
*) GDI_GetObjPtr( hdcs
, DC_MAGIC
))) return FALSE
;
478 dc
->header
.hNext
= dcs
->header
.hNext
;
479 if ((short)--dc
->saveLevel
< level
) SetDCState( hdc
, hdcs
);
486 /***********************************************************************
489 HDC
CreateDC( LPCSTR driver
, LPCSTR device
, LPCSTR output
, const DEVMODE
* initData
)
494 handle
= GDI_AllocObject( sizeof(DC
), DC_MAGIC
);
495 if (!handle
) return 0;
496 dc
= (DC
*) GDI_HEAP_LIN_ADDR( handle
);
498 dprintf_dc(stddeb
, "CreateDC(%s %s %s): returning %04x\n",
499 driver
, device
, output
, handle
);
503 displayDevCaps
= (DeviceCaps
*) xmalloc( sizeof(DeviceCaps
) );
504 DC_FillDevCaps( displayDevCaps
);
507 dc
->hSelf
= (HDC
)handle
;
510 dc
->hookProc
= (SEGPTR
)NULL
;
512 memcpy( &dc
->w
, &DC_defaultValues
, sizeof(DC_defaultValues
) );
513 memset( &dc
->u
.x
, 0, sizeof(dc
->u
.x
) );
515 dc
->u
.x
.drawable
= rootWindow
;
516 dc
->u
.x
.gc
= XCreateGC( display
, dc
->u
.x
.drawable
, 0, NULL
);
518 dc
->w
.devCaps
= displayDevCaps
;
519 dc
->w
.bitsPerPixel
= displayDevCaps
->bitsPixel
;
520 dc
->w
.hVisRgn
= CreateRectRgn( 0, 0, displayDevCaps
->horzRes
,
521 displayDevCaps
->vertRes
);
524 GDI_HEAP_FREE( handle
);
534 /***********************************************************************
537 HDC
CreateIC( LPCSTR driver
, LPCSTR device
, LPCSTR output
, const DEVMODE
* initData
)
539 /* Nothing special yet for ICs */
540 return CreateDC( driver
, device
, output
, initData
);
544 /***********************************************************************
545 * CreateCompatibleDC (GDI.52)
547 HDC
CreateCompatibleDC( HDC hdc
)
554 handle
= GDI_AllocObject( sizeof(DC
), DC_MAGIC
);
555 if (!handle
) return 0;
556 dc
= (DC
*) GDI_HEAP_LIN_ADDR( handle
);
558 dprintf_dc(stddeb
, "CreateCompatibleDC(%04x): returning %04x\n", hdc
, handle
);
560 /* Create default bitmap */
561 if (!(hbitmap
= CreateBitmap( 1, 1, 1, 1, NULL
)))
563 GDI_HEAP_FREE( handle
);
566 bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
);
568 dc
->hSelf
= (HDC
)handle
;
571 dc
->hookProc
= (SEGPTR
)NULL
;
573 memcpy( &dc
->w
, &DC_defaultValues
, sizeof(DC_defaultValues
) );
574 memset( &dc
->u
.x
, 0, sizeof(dc
->u
.x
) );
576 dc
->u
.x
.drawable
= bmp
->pixmap
;
577 dc
->u
.x
.gc
= XCreateGC( display
, dc
->u
.x
.drawable
, 0, NULL
);
578 dc
->w
.flags
= DC_MEMORY
;
579 dc
->w
.bitsPerPixel
= 1;
580 dc
->w
.devCaps
= displayDevCaps
;
581 dc
->w
.hBitmap
= hbitmap
;
582 dc
->w
.hFirstBitmap
= hbitmap
;
583 dc
->w
.hVisRgn
= CreateRectRgn( 0, 0, 1, 1 );
587 DeleteObject( hbitmap
);
588 GDI_HEAP_FREE( handle
);
598 /***********************************************************************
601 BOOL
DeleteDC( HDC hdc
)
603 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
604 if (!dc
) return FALSE
;
606 dprintf_dc(stddeb
, "DeleteDC: %04x\n", hdc
);
608 while (dc
->saveLevel
)
611 HDC hdcs
= dc
->header
.hNext
;
612 if (!(dcs
= (DC
*) GDI_GetObjPtr( hdcs
, DC_MAGIC
))) break;
613 dc
->header
.hNext
= dcs
->header
.hNext
;
618 if (!(dc
->w
.flags
& DC_SAVED
))
620 SelectObject( hdc
, STOCK_BLACK_PEN
);
621 SelectObject( hdc
, STOCK_WHITE_BRUSH
);
622 SelectObject( hdc
, STOCK_SYSTEM_FONT
);
623 XFreeGC( display
, dc
->u
.x
.gc
);
626 if (dc
->w
.flags
& DC_MEMORY
) DeleteObject( dc
->w
.hFirstBitmap
);
627 if (dc
->w
.hClipRgn
) DeleteObject( dc
->w
.hClipRgn
);
628 if (dc
->w
.hVisRgn
) DeleteObject( dc
->w
.hVisRgn
);
629 if (dc
->w
.hGCClipRgn
) DeleteObject( dc
->w
.hGCClipRgn
);
631 return GDI_FreeObject( hdc
);
635 /***********************************************************************
638 HDC
ResetDC( HDC hdc
, /* DEVMODE */ void *devmode
)
640 fprintf( stderr
, "ResetDC: empty stub!\n" );
645 /***********************************************************************
646 * GetDeviceCaps (GDI.80)
648 int GetDeviceCaps( HDC hdc
, WORD cap
)
650 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
653 if (cap
> sizeof(DeviceCaps
)-sizeof(WORD
)) return 0;
655 dprintf_dc(stddeb
, "GetDeviceCaps(%04x,%d): returning %d\n",
656 hdc
, cap
, *(WORD
*)(((char *)dc
->w
.devCaps
) + cap
) );
657 return *(WORD
*)(((char *)dc
->w
.devCaps
) + cap
);
661 /***********************************************************************
664 COLORREF
SetBkColor( HDC hdc
, COLORREF color
)
667 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
670 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
671 if (!dc
) return 0x80000000;
672 MF_MetaParam2(dc
, META_SETBKCOLOR
, HIWORD(color
), LOWORD(color
));
676 oldColor
= dc
->w
.backgroundColor
;
677 dc
->w
.backgroundColor
= color
;
678 dc
->w
.backgroundPixel
= COLOR_ToPhysical( dc
, color
);
683 /***********************************************************************
684 * SetTextColor (GDI.9)
686 COLORREF
SetTextColor( HDC hdc
, COLORREF color
)
689 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
692 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
693 if (!dc
) return 0x80000000;
694 MF_MetaParam2(dc
, META_SETTEXTCOLOR
, HIWORD(color
), LOWORD(color
));
698 oldColor
= dc
->w
.textColor
;
699 dc
->w
.textColor
= color
;
700 dc
->w
.textPixel
= COLOR_ToPhysical( dc
, color
);
705 /***********************************************************************
706 * SetTextAlign (GDI.346)
708 WORD
SetTextAlign( HDC hdc
, WORD textAlign
)
711 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
714 if (!(dc
= (DC
*)GDI_GetObjPtr( hdc
, METAFILE_DC_MAGIC
))) return 0;
715 MF_MetaParam1( dc
, META_SETTEXTALIGN
, textAlign
);
718 prevAlign
= dc
->w
.textAlign
;
719 dc
->w
.textAlign
= textAlign
;
724 /***********************************************************************
727 DWORD
GetDCOrg( HDC hdc
)
730 int x
, y
, w
, h
, border
, depth
;
732 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
734 if (dc
->w
.flags
& DC_MEMORY
) return 0;
735 XGetGeometry( display
, dc
->u
.x
.drawable
, &root
,
736 &x
, &y
, &w
, &h
, &border
, &depth
);
737 return MAKELONG( dc
->w
.DCOrgX
+ (WORD
)x
, dc
->w
.DCOrgY
+ (WORD
)y
);
741 /***********************************************************************
744 DWORD
SetDCOrg( HDC hdc
, short x
, short y
)
747 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
749 prevOrg
= dc
->w
.DCOrgX
| (dc
->w
.DCOrgY
<< 16);
756 /***********************************************************************
757 * SetDCHook (GDI.190)
759 BOOL
SetDCHook( HDC hDC
, FARPROC16 hookProc
, DWORD dwHookData
)
761 DC
*dc
= (DC
*)GDI_GetObjPtr( hDC
, DC_MAGIC
);
763 dprintf_dc( stddeb
, "SetDCHook: hookProc %08x, default is %08x\n",
764 (unsigned)hookProc
,(unsigned)GDI_GetDefDCHook() );
766 if (!dc
) return FALSE
;
767 dc
->hookProc
= hookProc
;
768 dc
->dwHookData
= dwHookData
;
773 /***********************************************************************
774 * GetDCHook (GDI.191)
776 DWORD
GetDCHook( HDC hDC
, FARPROC16
*phookProc
)
778 DC
*dc
= (DC
*)GDI_GetObjPtr( hDC
, DC_MAGIC
);
780 *phookProc
= dc
->hookProc
;
781 return dc
->dwHookData
;
785 /***********************************************************************
786 * SetHookFlags (GDI.192)
788 WORD
SetHookFlags(HDC hDC
, WORD flags
)
790 DC
* dc
= (DC
*)GDI_GetObjPtr( hDC
, DC_MAGIC
);
794 WORD wRet
= dc
->w
.flags
& DC_DIRTY
;
796 /* "Undocumented Windows" info is slightly
800 dprintf_dc(stddeb
,"SetHookFlags: hDC %04x, flags %04x\n",hDC
,flags
);
802 if( flags
& DCHF_INVALIDATEVISRGN
)
803 dc
->w
.flags
|= DC_DIRTY
;
804 else if( flags
& DCHF_VALIDATEVISRGN
|| !flags
)
805 dc
->w
.flags
&= ~DC_DIRTY
;