2 * GDI Device Context functions
4 * Copyright 1993 Alexandre Julliard
20 extern void CLIPPING_UpdateGCRegion( DC
* dc
); /* objects/clipping.c */
22 /* Default DC values */
23 static const WIN_DC_INFO DC_defaultValues
=
30 STOCK_BLACK_PEN
, /* hPen */
31 STOCK_WHITE_BRUSH
, /* hBrush */
32 STOCK_SYSTEM_FONT
, /* hFont */
36 STOCK_DEFAULT_PALETTE
, /* hPalette */
37 R2_COPYPEN
, /* ROPmode */
38 ALTERNATE
, /* polyFillMode */
39 BLACKONWHITE
, /* stretchBltMode */
40 ABSOLUTE
, /* relAbsMode */
41 OPAQUE
, /* backgroundMode */
42 RGB( 255, 255, 255 ), /* backgroundColor */
43 RGB( 0, 0, 0 ), /* textColor */
44 0, /* backgroundPixel */
48 TA_LEFT
| TA_TOP
| TA_NOUPDATECP
, /* textAlign */
50 0, /* breakTotalExtra */
55 MM_TEXT
, /* MapMode */
70 /* ROP code to GC function conversion */
71 const int DC_XROPfunction
[16] =
73 GXclear
, /* R2_BLACK */
74 GXnor
, /* R2_NOTMERGEPEN */
75 GXandInverted
, /* R2_MASKNOTPEN */
76 GXcopyInverted
, /* R2_NOTCOPYPEN */
77 GXandReverse
, /* R2_MASKPENNOT */
78 GXinvert
, /* R2_NOT */
79 GXxor
, /* R2_XORPEN */
80 GXnand
, /* R2_NOTMASKPEN */
81 GXand
, /* R2_MASKPEN */
82 GXequiv
, /* R2_NOTXORPEN */
84 GXorInverted
, /* R2_MERGENOTPEN */
85 GXcopy
, /* R2_COPYPEN */
86 GXorReverse
, /* R2_MERGEPENNOT */
87 GXor
, /* R2_MERGEPEN */
92 /***********************************************************************
95 * Fill the device caps structure.
97 void DC_FillDevCaps( DeviceCaps
* caps
)
99 caps
->version
= 0x300;
100 caps
->technology
= DT_RASDISPLAY
;
101 caps
->horzSize
= WidthMMOfScreen(screen
) * screenWidth
/ WidthOfScreen(screen
);
102 caps
->vertSize
= HeightMMOfScreen(screen
) * screenHeight
/ HeightOfScreen(screen
);
103 caps
->horzRes
= screenWidth
;
104 caps
->vertRes
= screenHeight
;
105 caps
->bitsPixel
= screenDepth
;
107 caps
->numBrushes
= 16+6; /* 16 solid + 6 hatched brushes */
108 caps
->numPens
= 16; /* 16 solid pens */
109 caps
->numMarkers
= 0;
111 caps
->numColors
= 100;
112 caps
->pdeviceSize
= 0;
113 caps
->curveCaps
= CC_CIRCLES
| CC_PIE
| CC_CHORD
| CC_ELLIPSES
|
114 CC_WIDE
| CC_STYLED
| CC_WIDESTYLED
|
115 CC_INTERIORS
| CC_ROUNDRECT
;
116 caps
->lineCaps
= LC_POLYLINE
| LC_MARKER
| LC_POLYMARKER
| LC_WIDE
|
117 LC_STYLED
| LC_WIDESTYLED
| LC_INTERIORS
;
118 caps
->polygonalCaps
= PC_POLYGON
| PC_RECTANGLE
| PC_WINDPOLYGON
|
119 PC_SCANLINE
| PC_WIDE
| PC_STYLED
|
120 PC_WIDESTYLED
| PC_INTERIORS
;
121 caps
->textCaps
= TC_OP_CHARACTER
| TC_OP_STROKE
| TC_CP_STROKE
|
122 TC_IA_ABLE
| TC_UA_ABLE
| TC_SO_ABLE
| TC_RA_ABLE
;
123 caps
->clipCaps
= CP_REGION
;
124 caps
->rasterCaps
= RC_BITBLT
| RC_BANDING
| RC_SCALING
| RC_BITMAP64
|
125 RC_DI_BITMAP
| RC_DIBTODEV
| RC_BIGFONT
|
126 RC_STRETCHBLT
| RC_STRETCHDIB
| RC_DEVBITS
;
128 if( !(COLOR_GetSystemPaletteFlags() & COLOR_VIRTUAL
) )
129 caps
->rasterCaps
|= RC_PALETTE
;
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
= (caps
->rasterCaps
& RC_PALETTE
)
137 ? DefaultVisual(display
,DefaultScreen(display
))->map_entries
139 caps
->numReserved
= 0;
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_LIN_ADDR( hdc
);
162 memcpy( &dc
->w
, &DC_defaultValues
, sizeof(DC_defaultValues
) );
167 /***********************************************************************
170 DC
*DC_GetDCPtr( HDC32 hdc
)
172 GDIOBJHDR
*ptr
= (GDIOBJHDR
*)GDI_HEAP_LIN_ADDR( hdc
);
173 if ((ptr
->wMagic
== DC_MAGIC
) || (ptr
->wMagic
== METAFILE_DC_MAGIC
))
179 /***********************************************************************
182 * Setup device-specific DC values for a newly created DC.
184 void DC_InitDC( DC
* dc
)
186 RealizeDefaultPalette( dc
->hSelf
);
187 SetTextColor( dc
->hSelf
, dc
->w
.textColor
);
188 SetBkColor( dc
->hSelf
, dc
->w
.backgroundColor
);
189 SelectObject32( dc
->hSelf
, dc
->w
.hPen
);
190 SelectObject32( dc
->hSelf
, dc
->w
.hBrush
);
191 SelectObject32( dc
->hSelf
, dc
->w
.hFont
);
192 CLIPPING_UpdateGCRegion( dc
);
196 /***********************************************************************
197 * DC_SetupGCForPatBlt
199 * Setup the GC for a PatBlt operation using current brush.
200 * If fMapColors is TRUE, X pixels are mapped to Windows colors.
201 * Return FALSE if brush is BS_NULL, TRUE otherwise.
203 BOOL32
DC_SetupGCForPatBlt( DC
* dc
, GC gc
, BOOL32 fMapColors
)
209 if (dc
->u
.x
.brush
.style
== BS_NULL
) return FALSE
;
210 if (dc
->u
.x
.brush
.pixel
== -1)
212 /* Special case used for monochrome pattern brushes.
213 * We need to swap foreground and background because
214 * Windows does it the wrong way...
216 val
.foreground
= dc
->w
.backgroundPixel
;
217 val
.background
= dc
->w
.textPixel
;
221 val
.foreground
= dc
->u
.x
.brush
.pixel
;
222 val
.background
= dc
->w
.backgroundPixel
;
224 if (fMapColors
&& COLOR_PixelToPalette
)
226 val
.foreground
= COLOR_PixelToPalette
[val
.foreground
];
227 val
.background
= COLOR_PixelToPalette
[val
.background
];
230 if (dc
->w
.flags
& DC_DIRTY
) CLIPPING_UpdateGCRegion(dc
);
232 val
.function
= DC_XROPfunction
[dc
->w
.ROPmode
-1];
233 val
.fill_style
= dc
->u
.x
.brush
.fillStyle
;
234 switch(val
.fill_style
)
237 case FillOpaqueStippled
:
238 if (dc
->w
.backgroundMode
==OPAQUE
) val
.fill_style
= FillOpaqueStippled
;
239 val
.stipple
= dc
->u
.x
.brush
.pixmap
;
244 if (fMapColors
&& COLOR_PixelToPalette
)
248 pixmap
= XCreatePixmap( display
, rootWindow
, 8, 8, screenDepth
);
249 image
= XGetImage( display
, dc
->u
.x
.brush
.pixmap
, 0, 0, 8, 8,
250 AllPlanes
, ZPixmap
);
251 for (y
= 0; y
< 8; y
++)
252 for (x
= 0; x
< 8; x
++)
253 XPutPixel( image
, x
, y
,
254 COLOR_PixelToPalette
[XGetPixel( image
, x
, y
)] );
255 XPutImage( display
, pixmap
, gc
, image
, 0, 0, 0, 0, 8, 8 );
256 XDestroyImage( image
);
259 else val
.tile
= dc
->u
.x
.brush
.pixmap
;
267 val
.ts_x_origin
= dc
->w
.DCOrgX
+ dc
->w
.brushOrgX
;
268 val
.ts_y_origin
= dc
->w
.DCOrgY
+ dc
->w
.brushOrgY
;
269 val
.fill_rule
= (dc
->w
.polyFillMode
==WINDING
) ? WindingRule
: EvenOddRule
;
270 XChangeGC( display
, gc
,
271 GCFunction
| GCForeground
| GCBackground
| GCFillStyle
|
272 GCFillRule
| GCTileStipXOrigin
| GCTileStipYOrigin
| mask
,
274 if (pixmap
) XFreePixmap( display
, pixmap
);
279 /***********************************************************************
282 * Setup dc->u.x.gc for drawing operations using current brush.
283 * Return FALSE if brush is BS_NULL, TRUE otherwise.
285 BOOL32
DC_SetupGCForBrush( DC
* dc
)
287 return DC_SetupGCForPatBlt( dc
, dc
->u
.x
.gc
, FALSE
);
291 /***********************************************************************
294 * Setup dc->u.x.gc for drawing operations using current pen.
295 * Return FALSE if pen is PS_NULL, TRUE otherwise.
297 BOOL32
DC_SetupGCForPen( DC
* dc
)
301 if (dc
->u
.x
.pen
.style
== PS_NULL
) return FALSE
;
303 if (dc
->w
.flags
& DC_DIRTY
) CLIPPING_UpdateGCRegion(dc
);
305 if ((screenDepth
<= 8) && /* FIXME: Should check for palette instead */
306 ((dc
->w
.ROPmode
== R2_BLACK
) || (dc
->w
.ROPmode
== R2_WHITE
)))
308 val
.function
= GXcopy
;
309 val
.foreground
= COLOR_ToPhysical( NULL
, (dc
->w
.ROPmode
== R2_BLACK
) ?
310 RGB(0,0,0) : RGB(255,255,255) );
314 val
.function
= DC_XROPfunction
[dc
->w
.ROPmode
-1];
315 val
.foreground
= dc
->u
.x
.pen
.pixel
;
317 val
.background
= dc
->w
.backgroundPixel
;
318 val
.fill_style
= FillSolid
;
319 if ((dc
->u
.x
.pen
.style
!=PS_SOLID
) && (dc
->u
.x
.pen
.style
!=PS_INSIDEFRAME
))
321 XSetDashes( display
, dc
->u
.x
.gc
, 0,
322 dc
->u
.x
.pen
.dashes
, dc
->u
.x
.pen
.dash_len
);
323 val
.line_style
= (dc
->w
.backgroundMode
== OPAQUE
) ?
324 LineDoubleDash
: LineOnOffDash
;
326 else val
.line_style
= LineSolid
;
327 val
.line_width
= dc
->u
.x
.pen
.width
;
328 val
.cap_style
= CapRound
;
329 val
.join_style
= JoinMiter
;
330 XChangeGC( display
, dc
->u
.x
.gc
,
331 GCFunction
| GCForeground
| GCBackground
| GCLineWidth
|
332 GCLineStyle
| GCCapStyle
| GCJoinStyle
| GCFillStyle
, &val
);
337 /***********************************************************************
340 * Setup dc->u.x.gc for text drawing operations.
341 * Return FALSE if the font is null, TRUE otherwise.
343 BOOL32
DC_SetupGCForText( DC
* dc
)
347 if (!dc
->u
.x
.font
.fstruct
)
349 fprintf( stderr
, "DC_SetupGCForText: fstruct is NULL. Please report this\n" );
353 if (dc
->w
.flags
& DC_DIRTY
) CLIPPING_UpdateGCRegion(dc
);
355 val
.function
= GXcopy
; /* Text is always GXcopy */
356 val
.foreground
= dc
->w
.textPixel
;
357 val
.background
= dc
->w
.backgroundPixel
;
358 val
.fill_style
= FillSolid
;
359 val
.font
= dc
->u
.x
.font
.fstruct
->fid
;
360 XChangeGC( display
, dc
->u
.x
.gc
,
361 GCFunction
| GCForeground
| GCBackground
| GCFillStyle
|
367 /***********************************************************************
368 * GetDCState (GDI.179)
370 HDC16
GetDCState( HDC16 hdc
)
375 if (!(dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
))) return 0;
376 if (!(handle
= GDI_AllocObject( sizeof(DC
), DC_MAGIC
))) return 0;
377 newdc
= (DC
*) GDI_HEAP_LIN_ADDR( handle
);
379 dprintf_dc(stddeb
, "GetDCState(%04x): returning %04x\n", hdc
, handle
);
381 memset( &newdc
->u
.x
, 0, sizeof(newdc
->u
.x
) );
382 memcpy( &newdc
->w
, &dc
->w
, sizeof(dc
->w
) );
384 newdc
->hSelf
= (HDC32
)handle
;
385 newdc
->saveLevel
= 0;
386 newdc
->w
.flags
|= DC_SAVED
;
388 newdc
->w
.hGCClipRgn
= 0;
389 newdc
->w
.hVisRgn
= CreateRectRgn32( 0, 0, 0, 0 );
390 CombineRgn32( newdc
->w
.hVisRgn
, dc
->w
.hVisRgn
, 0, RGN_COPY
);
393 newdc
->w
.hClipRgn
= CreateRectRgn32( 0, 0, 0, 0 );
394 CombineRgn32( newdc
->w
.hClipRgn
, dc
->w
.hClipRgn
, 0, RGN_COPY
);
400 /***********************************************************************
401 * SetDCState (GDI.180)
403 void SetDCState( HDC16 hdc
, HDC16 hdcs
)
407 if (!(dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
))) return;
408 if (!(dcs
= (DC
*) GDI_GetObjPtr( hdcs
, DC_MAGIC
))) return;
409 if (!dcs
->w
.flags
& DC_SAVED
) return;
410 dprintf_dc(stddeb
, "SetDCState: %04x %04x\n", hdc
, hdcs
);
412 dc
->w
.flags
= dcs
->w
.flags
& ~DC_SAVED
;
413 dc
->w
.devCaps
= dcs
->w
.devCaps
;
414 dc
->w
.hFirstBitmap
= dcs
->w
.hFirstBitmap
;
415 dc
->w
.hDevice
= dcs
->w
.hDevice
;
416 dc
->w
.ROPmode
= dcs
->w
.ROPmode
;
417 dc
->w
.polyFillMode
= dcs
->w
.polyFillMode
;
418 dc
->w
.stretchBltMode
= dcs
->w
.stretchBltMode
;
419 dc
->w
.relAbsMode
= dcs
->w
.relAbsMode
;
420 dc
->w
.backgroundMode
= dcs
->w
.backgroundMode
;
421 dc
->w
.backgroundColor
= dcs
->w
.backgroundColor
;
422 dc
->w
.textColor
= dcs
->w
.textColor
;
423 dc
->w
.backgroundPixel
= dcs
->w
.backgroundPixel
;
424 dc
->w
.textPixel
= dcs
->w
.textPixel
;
425 dc
->w
.brushOrgX
= dcs
->w
.brushOrgX
;
426 dc
->w
.brushOrgY
= dcs
->w
.brushOrgY
;
427 dc
->w
.textAlign
= dcs
->w
.textAlign
;
428 dc
->w
.charExtra
= dcs
->w
.charExtra
;
429 dc
->w
.breakTotalExtra
= dcs
->w
.breakTotalExtra
;
430 dc
->w
.breakCount
= dcs
->w
.breakCount
;
431 dc
->w
.breakExtra
= dcs
->w
.breakExtra
;
432 dc
->w
.breakRem
= dcs
->w
.breakRem
;
433 dc
->w
.MapMode
= dcs
->w
.MapMode
;
434 dc
->w
.DCOrgX
= dcs
->w
.DCOrgX
;
435 dc
->w
.DCOrgY
= dcs
->w
.DCOrgY
;
436 dc
->w
.CursPosX
= dcs
->w
.CursPosX
;
437 dc
->w
.CursPosY
= dcs
->w
.CursPosY
;
438 dc
->w
.WndOrgX
= dcs
->w
.WndOrgX
;
439 dc
->w
.WndOrgY
= dcs
->w
.WndOrgY
;
440 dc
->w
.WndExtX
= dcs
->w
.WndExtX
;
441 dc
->w
.WndExtY
= dcs
->w
.WndExtY
;
442 dc
->w
.VportOrgX
= dcs
->w
.VportOrgX
;
443 dc
->w
.VportOrgY
= dcs
->w
.VportOrgY
;
444 dc
->w
.VportExtX
= dcs
->w
.VportExtX
;
445 dc
->w
.VportExtY
= dcs
->w
.VportExtY
;
447 if (!(dc
->w
.flags
& DC_MEMORY
)) dc
->w
.bitsPerPixel
= dcs
->w
.bitsPerPixel
;
448 CombineRgn32( dc
->w
.hVisRgn
, dcs
->w
.hVisRgn
, 0, RGN_COPY
);
449 SelectClipRgn32( hdc
, dcs
->w
.hClipRgn
);
450 SelectObject32( hdc
, dcs
->w
.hBitmap
);
451 SelectObject32( hdc
, dcs
->w
.hBrush
);
452 SelectObject32( hdc
, dcs
->w
.hFont
);
453 SelectObject32( hdc
, dcs
->w
.hPen
);
454 GDISelectPalette( hdc
, dcs
->w
.hPalette
, FALSE
);
458 /***********************************************************************
461 int SaveDC( HDC16 hdc
)
466 dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
469 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
471 MF_MetaParam0(dc
, META_SAVEDC
);
474 if (!(hdcs
= GetDCState( hdc
))) return 0;
475 dcs
= (DC
*) GDI_HEAP_LIN_ADDR( hdcs
);
476 dcs
->header
.hNext
= dc
->header
.hNext
;
477 dc
->header
.hNext
= hdcs
;
478 dprintf_dc(stddeb
, "SaveDC(%04x): returning %d\n", hdc
, dc
->saveLevel
+1 );
479 return ++dc
->saveLevel
;
483 /***********************************************************************
486 BOOL
RestoreDC( HDC16 hdc
, short level
)
490 dprintf_dc(stddeb
, "RestoreDC: %04x %d\n", hdc
, level
);
491 dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
494 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
495 if (!dc
) return FALSE
;
496 if (level
!= -1) return FALSE
;
497 MF_MetaParam1(dc
, META_RESTOREDC
, level
);
500 if (level
== -1) level
= dc
->saveLevel
;
501 if ((level
< 1) || (level
> (short)dc
->saveLevel
)) return FALSE
;
503 while ((short)dc
->saveLevel
>= level
)
505 HDC16 hdcs
= dc
->header
.hNext
;
506 if (!(dcs
= (DC
*) GDI_GetObjPtr( hdcs
, DC_MAGIC
))) return FALSE
;
507 dc
->header
.hNext
= dcs
->header
.hNext
;
508 if ((short)--dc
->saveLevel
< level
) SetDCState( hdc
, hdcs
);
515 /***********************************************************************
516 * CreateDC16 (GDI.53)
518 HDC16
CreateDC16( LPCSTR driver
, LPCSTR device
, LPCSTR output
,
519 const DEVMODE16
*initData
)
522 const DC_FUNCTIONS
*funcs
;
524 if (!(funcs
= DRIVER_FindDriver( driver
))) return 0;
525 if (!(dc
= DC_AllocDC( funcs
))) return 0;
528 dprintf_dc(stddeb
, "CreateDC(%s %s %s): returning %04x\n",
529 driver
, device
, output
, dc
->hSelf
);
531 if (dc
->funcs
->pCreateDC
&&
532 !dc
->funcs
->pCreateDC( dc
, driver
, device
, output
, initData
))
534 dprintf_dc( stddeb
, "CreateDC: creation aborted by device\n" );
535 GDI_HEAP_FREE( dc
->hSelf
);
544 /***********************************************************************
545 * CreateDC32A (GDI32.)
547 HDC32
CreateDC32A( LPCSTR driver
, LPCSTR device
, LPCSTR output
,
548 const DEVMODE32A
*initData
)
550 return CreateDC16( driver
, device
, output
, (const DEVMODE16
*)initData
);
554 /***********************************************************************
555 * CreateDC32W (GDI32.)
557 HDC32
CreateDC32W( LPCWSTR driver
, LPCWSTR device
, LPCWSTR output
,
558 const DEVMODE32W
*initData
)
560 LPSTR driverA
= driver
?STRING32_DupUniToAnsi(driver
):NULL
;
561 LPSTR deviceA
= device
?STRING32_DupUniToAnsi(device
):NULL
;
562 LPSTR outputA
= output
?STRING32_DupUniToAnsi(output
):NULL
;
565 res
= CreateDC16( driverA
, deviceA
, outputA
, (const DEVMODE16
*)initData
);
566 if (driverA
) free(driverA
);
567 if (deviceA
) free(deviceA
);
568 if (outputA
) free(outputA
);
573 /***********************************************************************
576 HDC16
CreateIC( LPCSTR driver
, LPCSTR device
, LPCSTR output
,
577 const DEVMODE16
* initData
)
579 /* Nothing special yet for ICs */
580 return CreateDC16( driver
, device
, output
, initData
);
584 /***********************************************************************
585 * CreateCompatibleDC (GDI.52)
587 HDC16
CreateCompatibleDC( HDC16 hdc
)
591 const DC_FUNCTIONS
*funcs
;
593 if ((origDC
= (DC
*)GDI_GetObjPtr( hdc
, DC_MAGIC
))) funcs
= origDC
->funcs
;
594 else funcs
= DRIVER_FindDriver( "DISPLAY" );
595 if (!funcs
) return 0;
597 if (!(dc
= DC_AllocDC( funcs
))) return 0;
599 dprintf_dc(stddeb
, "CreateCompatibleDC(%04x): returning %04x\n",
602 /* Create default bitmap */
603 if (!(hbitmap
= CreateBitmap( 1, 1, 1, 1, NULL
)))
605 GDI_HEAP_FREE( dc
->hSelf
);
608 dc
->w
.flags
= DC_MEMORY
;
609 dc
->w
.bitsPerPixel
= 1;
610 dc
->w
.hBitmap
= hbitmap
;
611 dc
->w
.hFirstBitmap
= hbitmap
;
613 if (dc
->funcs
->pCreateDC
&&
614 !dc
->funcs
->pCreateDC( dc
, NULL
, NULL
, NULL
, NULL
))
616 dprintf_dc( stddeb
, "CreateDC: creation aborted by device\n" );
617 DeleteObject32( hbitmap
);
618 GDI_HEAP_FREE( dc
->hSelf
);
627 /***********************************************************************
630 BOOL
DeleteDC( HDC16 hdc
)
632 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
633 if (!dc
) return FALSE
;
635 dprintf_dc(stddeb
, "DeleteDC: %04x\n", hdc
);
637 while (dc
->saveLevel
)
640 HDC16 hdcs
= dc
->header
.hNext
;
641 if (!(dcs
= (DC
*) GDI_GetObjPtr( hdcs
, DC_MAGIC
))) break;
642 dc
->header
.hNext
= dcs
->header
.hNext
;
647 if (!(dc
->w
.flags
& DC_SAVED
))
649 SelectObject32( hdc
, STOCK_BLACK_PEN
);
650 SelectObject32( hdc
, STOCK_WHITE_BRUSH
);
651 SelectObject32( hdc
, STOCK_SYSTEM_FONT
);
652 if (dc
->w
.flags
& DC_MEMORY
) DeleteObject32( dc
->w
.hFirstBitmap
);
653 if (dc
->funcs
->pDeleteDC
) dc
->funcs
->pDeleteDC(dc
);
656 if (dc
->w
.hClipRgn
) DeleteObject32( dc
->w
.hClipRgn
);
657 if (dc
->w
.hVisRgn
) DeleteObject32( dc
->w
.hVisRgn
);
658 if (dc
->w
.hGCClipRgn
) DeleteObject32( dc
->w
.hGCClipRgn
);
660 return GDI_FreeObject( hdc
);
664 /***********************************************************************
667 HDC16
ResetDC( HDC16 hdc
, /* DEVMODE */ void *devmode
)
669 fprintf( stderr
, "ResetDC: empty stub!\n" );
674 /***********************************************************************
675 * GetDeviceCaps (GDI.80)
677 int GetDeviceCaps( HDC16 hdc
, WORD cap
)
679 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
682 if (cap
> sizeof(DeviceCaps
)-sizeof(WORD
)) return 0;
684 dprintf_dc(stddeb
, "GetDeviceCaps(%04x,%d): returning %d\n",
685 hdc
, cap
, *(WORD
*)(((char *)dc
->w
.devCaps
) + cap
) );
686 return *(WORD
*)(((char *)dc
->w
.devCaps
) + cap
);
690 /***********************************************************************
691 * SetBkColor (GDI.1) (GDI32.305)
693 COLORREF
SetBkColor( HDC32 hdc
, COLORREF color
)
696 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
699 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
700 if (!dc
) return 0x80000000;
701 MF_MetaParam2(dc
, META_SETBKCOLOR
, HIWORD(color
), LOWORD(color
));
705 oldColor
= dc
->w
.backgroundColor
;
706 dc
->w
.backgroundColor
= color
;
707 dc
->w
.backgroundPixel
= COLOR_ToPhysical( dc
, color
);
712 /***********************************************************************
713 * SetTextColor (GDI.9) (GDI32.338)
715 COLORREF
SetTextColor( HDC32 hdc
, COLORREF color
)
718 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
721 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
722 if (!dc
) return 0x80000000;
723 MF_MetaParam2(dc
, META_SETTEXTCOLOR
, HIWORD(color
), LOWORD(color
));
727 oldColor
= dc
->w
.textColor
;
728 dc
->w
.textColor
= color
;
729 dc
->w
.textPixel
= COLOR_ToPhysical( dc
, color
);
734 /***********************************************************************
735 * SetTextAlign (GDI.346)
737 WORD
SetTextAlign( HDC16 hdc
, WORD textAlign
)
740 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
743 if (!(dc
= (DC
*)GDI_GetObjPtr( hdc
, METAFILE_DC_MAGIC
))) return 0;
744 MF_MetaParam1( dc
, META_SETTEXTALIGN
, textAlign
);
747 prevAlign
= dc
->w
.textAlign
;
748 dc
->w
.textAlign
= textAlign
;
753 /***********************************************************************
754 * GetDCOrgEx (GDI32.168)
756 BOOL32
GetDCOrgEx(HDC32 hDC
, LPPOINT32 lpp
)
758 DC
* dc
= (DC
*) GDI_GetObjPtr( hDC
, DC_MAGIC
);
759 if (!dc
|| !lpp
) return FALSE
;
761 if (!(dc
->w
.flags
& DC_MEMORY
))
764 int w
, h
, border
, depth
;
766 XGetGeometry( display
, dc
->u
.x
.drawable
, &root
,
767 &lpp
->x
, &lpp
->y
, &w
, &h
, &border
, &depth
);
769 else lpp
->x
= lpp
->y
= 0;
770 lpp
->x
+= dc
->w
.DCOrgX
; lpp
->y
+= dc
->w
.DCOrgY
;
775 /***********************************************************************
778 DWORD
GetDCOrg( HDC16 hdc
)
781 if( GetDCOrgEx( hdc
, &pt
) )
782 return MAKELONG( (WORD
)pt
.x
, (WORD
)pt
.y
);
787 /***********************************************************************
790 DWORD
SetDCOrg( HDC16 hdc
, short x
, short y
)
793 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
795 prevOrg
= dc
->w
.DCOrgX
| (dc
->w
.DCOrgY
<< 16);
802 /***********************************************************************
803 * SetDCHook (GDI.190)
805 BOOL16
SetDCHook( HDC16 hdc
, FARPROC16 hookProc
, DWORD dwHookData
)
807 DC
*dc
= (DC
*)GDI_GetObjPtr( hdc
, DC_MAGIC
);
809 dprintf_dc( stddeb
, "SetDCHook: hookProc %08x, default is %08x\n",
810 (UINT32
)hookProc
, (UINT32
)DCHook
);
812 if (!dc
) return FALSE
;
813 dc
->hookProc
= hookProc
;
814 dc
->dwHookData
= dwHookData
;
819 /***********************************************************************
820 * GetDCHook (GDI.191)
822 DWORD
GetDCHook( HDC16 hdc
, FARPROC16
*phookProc
)
824 DC
*dc
= (DC
*)GDI_GetObjPtr( hdc
, DC_MAGIC
);
826 *phookProc
= dc
->hookProc
;
827 return dc
->dwHookData
;
831 /***********************************************************************
832 * SetHookFlags (GDI.192)
834 WORD
SetHookFlags(HDC16 hDC
, WORD flags
)
836 DC
* dc
= (DC
*)GDI_GetObjPtr( hDC
, DC_MAGIC
);
840 WORD wRet
= dc
->w
.flags
& DC_DIRTY
;
842 /* "Undocumented Windows" info is slightly
846 dprintf_dc(stddeb
,"SetHookFlags: hDC %04x, flags %04x\n",hDC
,flags
);
848 if( flags
& DCHF_INVALIDATEVISRGN
)
849 dc
->w
.flags
|= DC_DIRTY
;
850 else if( flags
& DCHF_VALIDATEVISRGN
|| !flags
)
851 dc
->w
.flags
&= ~DC_DIRTY
;