2 * GDI Device Context functions
4 * Copyright 1993 Alexandre Julliard
8 #define NO_TRANSITION_TYPES /* This file is Win32-clean */
21 extern void CLIPPING_UpdateGCRegion( DC
* dc
); /* objects/clipping.c */
23 /* Default DC values */
24 static const WIN_DC_INFO DC_defaultValues
=
31 STOCK_BLACK_PEN
, /* hPen */
32 STOCK_WHITE_BRUSH
, /* hBrush */
33 STOCK_SYSTEM_FONT
, /* hFont */
37 STOCK_DEFAULT_PALETTE
, /* hPalette */
38 R2_COPYPEN
, /* ROPmode */
39 ALTERNATE
, /* polyFillMode */
40 BLACKONWHITE
, /* stretchBltMode */
41 ABSOLUTE
, /* relAbsMode */
42 OPAQUE
, /* backgroundMode */
43 RGB( 255, 255, 255 ), /* backgroundColor */
44 RGB( 0, 0, 0 ), /* textColor */
45 0, /* backgroundPixel */
49 TA_LEFT
| TA_TOP
| TA_NOUPDATECP
, /* textAlign */
51 0, /* breakTotalExtra */
56 MM_TEXT
, /* MapMode */
63 /* ROP code to GC function conversion */
64 const int DC_XROPfunction
[16] =
66 GXclear
, /* R2_BLACK */
67 GXnor
, /* R2_NOTMERGEPEN */
68 GXandInverted
, /* R2_MASKNOTPEN */
69 GXcopyInverted
, /* R2_NOTCOPYPEN */
70 GXandReverse
, /* R2_MASKPENNOT */
71 GXinvert
, /* R2_NOT */
72 GXxor
, /* R2_XORPEN */
73 GXnand
, /* R2_NOTMASKPEN */
74 GXand
, /* R2_MASKPEN */
75 GXequiv
, /* R2_NOTXORPEN */
77 GXorInverted
, /* R2_MERGENOTPEN */
78 GXcopy
, /* R2_COPYPEN */
79 GXorReverse
, /* R2_MERGEPENNOT */
80 GXor
, /* R2_MERGEPEN */
85 /***********************************************************************
88 * Fill the device caps structure.
90 void DC_FillDevCaps( DeviceCaps
* caps
)
92 caps
->version
= 0x300;
93 caps
->technology
= DT_RASDISPLAY
;
94 caps
->horzSize
= WidthMMOfScreen(screen
) * screenWidth
/ WidthOfScreen(screen
);
95 caps
->vertSize
= HeightMMOfScreen(screen
) * screenHeight
/ HeightOfScreen(screen
);
96 caps
->horzRes
= screenWidth
;
97 caps
->vertRes
= screenHeight
;
98 caps
->bitsPixel
= screenDepth
;
100 caps
->numBrushes
= 16+6; /* 16 solid + 6 hatched brushes */
101 caps
->numPens
= 16; /* 16 solid pens */
102 caps
->numMarkers
= 0;
104 caps
->numColors
= 100;
105 caps
->pdeviceSize
= 0;
106 caps
->curveCaps
= CC_CIRCLES
| CC_PIE
| CC_CHORD
| CC_ELLIPSES
|
107 CC_WIDE
| CC_STYLED
| CC_WIDESTYLED
|
108 CC_INTERIORS
| CC_ROUNDRECT
;
109 caps
->lineCaps
= LC_POLYLINE
| LC_MARKER
| LC_POLYMARKER
| LC_WIDE
|
110 LC_STYLED
| LC_WIDESTYLED
| LC_INTERIORS
;
111 caps
->polygonalCaps
= PC_POLYGON
| PC_RECTANGLE
| PC_WINDPOLYGON
|
112 PC_SCANLINE
| PC_WIDE
| PC_STYLED
|
113 PC_WIDESTYLED
| PC_INTERIORS
;
114 caps
->textCaps
= TC_OP_CHARACTER
| TC_OP_STROKE
| TC_CP_STROKE
|
115 TC_IA_ABLE
| TC_UA_ABLE
| TC_SO_ABLE
| TC_RA_ABLE
;
116 caps
->clipCaps
= CP_REGION
;
117 caps
->rasterCaps
= RC_BITBLT
| RC_BANDING
| RC_SCALING
| RC_BITMAP64
|
118 RC_DI_BITMAP
| RC_DIBTODEV
| RC_BIGFONT
|
119 RC_STRETCHBLT
| RC_STRETCHDIB
| RC_DEVBITS
;
121 if( !(COLOR_GetSystemPaletteFlags() & COLOR_VIRTUAL
) )
122 caps
->rasterCaps
|= RC_PALETTE
;
124 caps
->aspectX
= 36; /* ?? */
125 caps
->aspectY
= 36; /* ?? */
127 caps
->logPixelsX
= (int)(caps
->horzRes
* 25.4 / caps
->horzSize
);
128 caps
->logPixelsY
= (int)(caps
->vertRes
* 25.4 / caps
->vertSize
);
129 caps
->sizePalette
= (caps
->rasterCaps
& RC_PALETTE
)
130 ? DefaultVisual(display
,DefaultScreen(display
))->map_entries
132 caps
->numReserved
= 0;
137 /***********************************************************************
140 DC
*DC_AllocDC( const DC_FUNCTIONS
*funcs
)
145 if (!(hdc
= GDI_AllocObject( sizeof(DC
), DC_MAGIC
))) return NULL
;
146 dc
= (DC
*) GDI_HEAP_LIN_ADDR( hdc
);
163 memcpy( &dc
->w
, &DC_defaultValues
, sizeof(DC_defaultValues
) );
168 /***********************************************************************
171 DC
*DC_GetDCPtr( HDC32 hdc
)
173 GDIOBJHDR
*ptr
= (GDIOBJHDR
*)GDI_HEAP_LIN_ADDR( hdc
);
174 if ((ptr
->wMagic
== DC_MAGIC
) || (ptr
->wMagic
== METAFILE_DC_MAGIC
))
180 /***********************************************************************
183 * Setup device-specific DC values for a newly created DC.
185 void DC_InitDC( DC
* dc
)
187 RealizeDefaultPalette( dc
->hSelf
);
188 SetTextColor( dc
->hSelf
, dc
->w
.textColor
);
189 SetBkColor( dc
->hSelf
, dc
->w
.backgroundColor
);
190 SelectObject32( dc
->hSelf
, dc
->w
.hPen
);
191 SelectObject32( dc
->hSelf
, dc
->w
.hBrush
);
192 SelectObject32( dc
->hSelf
, dc
->w
.hFont
);
193 CLIPPING_UpdateGCRegion( dc
);
197 /***********************************************************************
198 * DC_SetupGCForPatBlt
200 * Setup the GC for a PatBlt operation using current brush.
201 * If fMapColors is TRUE, X pixels are mapped to Windows colors.
202 * Return FALSE if brush is BS_NULL, TRUE otherwise.
204 BOOL32
DC_SetupGCForPatBlt( DC
* dc
, GC gc
, BOOL32 fMapColors
)
210 if (dc
->u
.x
.brush
.style
== BS_NULL
) return FALSE
;
211 if (dc
->u
.x
.brush
.pixel
== -1)
213 /* Special case used for monochrome pattern brushes.
214 * We need to swap foreground and background because
215 * Windows does it the wrong way...
217 val
.foreground
= dc
->w
.backgroundPixel
;
218 val
.background
= dc
->w
.textPixel
;
222 val
.foreground
= dc
->u
.x
.brush
.pixel
;
223 val
.background
= dc
->w
.backgroundPixel
;
225 if (fMapColors
&& COLOR_PixelToPalette
)
227 val
.foreground
= COLOR_PixelToPalette
[val
.foreground
];
228 val
.background
= COLOR_PixelToPalette
[val
.background
];
231 if (dc
->w
.flags
& DC_DIRTY
) CLIPPING_UpdateGCRegion(dc
);
233 val
.function
= DC_XROPfunction
[dc
->w
.ROPmode
-1];
234 val
.fill_style
= dc
->u
.x
.brush
.fillStyle
;
235 switch(val
.fill_style
)
238 case FillOpaqueStippled
:
239 if (dc
->w
.backgroundMode
==OPAQUE
) val
.fill_style
= FillOpaqueStippled
;
240 val
.stipple
= dc
->u
.x
.brush
.pixmap
;
245 if (fMapColors
&& COLOR_PixelToPalette
)
249 pixmap
= XCreatePixmap( display
, rootWindow
, 8, 8, screenDepth
);
250 image
= XGetImage( display
, dc
->u
.x
.brush
.pixmap
, 0, 0, 8, 8,
251 AllPlanes
, ZPixmap
);
252 for (y
= 0; y
< 8; y
++)
253 for (x
= 0; x
< 8; x
++)
254 XPutPixel( image
, x
, y
,
255 COLOR_PixelToPalette
[XGetPixel( image
, x
, y
)] );
256 XPutImage( display
, pixmap
, gc
, image
, 0, 0, 0, 0, 8, 8 );
257 XDestroyImage( image
);
260 else val
.tile
= dc
->u
.x
.brush
.pixmap
;
268 val
.ts_x_origin
= dc
->w
.DCOrgX
+ dc
->w
.brushOrgX
;
269 val
.ts_y_origin
= dc
->w
.DCOrgY
+ dc
->w
.brushOrgY
;
270 val
.fill_rule
= (dc
->w
.polyFillMode
==WINDING
) ? WindingRule
: EvenOddRule
;
271 XChangeGC( display
, gc
,
272 GCFunction
| GCForeground
| GCBackground
| GCFillStyle
|
273 GCFillRule
| GCTileStipXOrigin
| GCTileStipYOrigin
| mask
,
275 if (pixmap
) XFreePixmap( display
, pixmap
);
280 /***********************************************************************
283 * Setup dc->u.x.gc for drawing operations using current brush.
284 * Return FALSE if brush is BS_NULL, TRUE otherwise.
286 BOOL32
DC_SetupGCForBrush( DC
* dc
)
288 return DC_SetupGCForPatBlt( dc
, dc
->u
.x
.gc
, FALSE
);
292 /***********************************************************************
295 * Setup dc->u.x.gc for drawing operations using current pen.
296 * Return FALSE if pen is PS_NULL, TRUE otherwise.
298 BOOL32
DC_SetupGCForPen( DC
* dc
)
302 if (dc
->u
.x
.pen
.style
== PS_NULL
) return FALSE
;
304 if (dc
->w
.flags
& DC_DIRTY
) CLIPPING_UpdateGCRegion(dc
);
306 if ((screenDepth
<= 8) && /* FIXME: Should check for palette instead */
307 ((dc
->w
.ROPmode
== R2_BLACK
) || (dc
->w
.ROPmode
== R2_WHITE
)))
309 val
.function
= GXcopy
;
310 val
.foreground
= COLOR_ToPhysical( NULL
, (dc
->w
.ROPmode
== R2_BLACK
) ?
311 RGB(0,0,0) : RGB(255,255,255) );
315 val
.function
= DC_XROPfunction
[dc
->w
.ROPmode
-1];
316 val
.foreground
= dc
->u
.x
.pen
.pixel
;
318 val
.background
= dc
->w
.backgroundPixel
;
319 val
.fill_style
= FillSolid
;
320 if ((dc
->u
.x
.pen
.style
!=PS_SOLID
) && (dc
->u
.x
.pen
.style
!=PS_INSIDEFRAME
))
322 XSetDashes( display
, dc
->u
.x
.gc
, 0,
323 dc
->u
.x
.pen
.dashes
, dc
->u
.x
.pen
.dash_len
);
324 val
.line_style
= (dc
->w
.backgroundMode
== OPAQUE
) ?
325 LineDoubleDash
: LineOnOffDash
;
327 else val
.line_style
= LineSolid
;
328 val
.line_width
= dc
->u
.x
.pen
.width
;
329 val
.cap_style
= CapRound
;
330 val
.join_style
= JoinMiter
;
331 XChangeGC( display
, dc
->u
.x
.gc
,
332 GCFunction
| GCForeground
| GCBackground
| GCLineWidth
|
333 GCLineStyle
| GCCapStyle
| GCJoinStyle
| GCFillStyle
, &val
);
338 /***********************************************************************
341 * Setup dc->u.x.gc for text drawing operations.
342 * Return FALSE if the font is null, TRUE otherwise.
344 BOOL32
DC_SetupGCForText( DC
* dc
)
348 if (!dc
->u
.x
.font
.fstruct
)
350 fprintf( stderr
, "DC_SetupGCForText: fstruct is NULL. Please report this\n" );
354 if (dc
->w
.flags
& DC_DIRTY
) CLIPPING_UpdateGCRegion(dc
);
356 val
.function
= GXcopy
; /* Text is always GXcopy */
357 val
.foreground
= dc
->w
.textPixel
;
358 val
.background
= dc
->w
.backgroundPixel
;
359 val
.fill_style
= FillSolid
;
360 val
.font
= dc
->u
.x
.font
.fstruct
->fid
;
361 XChangeGC( display
, dc
->u
.x
.gc
,
362 GCFunction
| GCForeground
| GCBackground
| GCFillStyle
|
368 /***********************************************************************
369 * GetDCState (GDI.179)
371 HDC16
GetDCState( HDC16 hdc
)
376 if (!(dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
))) return 0;
377 if (!(handle
= GDI_AllocObject( sizeof(DC
), DC_MAGIC
))) return 0;
378 newdc
= (DC
*) GDI_HEAP_LIN_ADDR( handle
);
380 dprintf_dc(stddeb
, "GetDCState(%04x): returning %04x\n", hdc
, handle
);
382 memset( &newdc
->u
.x
, 0, sizeof(newdc
->u
.x
) );
383 newdc
->w
.flags
= dc
->w
.flags
| DC_SAVED
;
384 newdc
->w
.devCaps
= dc
->w
.devCaps
;
385 newdc
->w
.hPen
= dc
->w
.hPen
;
386 newdc
->w
.hBrush
= dc
->w
.hBrush
;
387 newdc
->w
.hFont
= dc
->w
.hFont
;
388 newdc
->w
.hBitmap
= dc
->w
.hBitmap
;
389 newdc
->w
.hFirstBitmap
= dc
->w
.hFirstBitmap
;
390 newdc
->w
.hDevice
= dc
->w
.hDevice
;
391 newdc
->w
.hPalette
= dc
->w
.hPalette
;
392 newdc
->w
.bitsPerPixel
= dc
->w
.bitsPerPixel
;
393 newdc
->w
.ROPmode
= dc
->w
.ROPmode
;
394 newdc
->w
.polyFillMode
= dc
->w
.polyFillMode
;
395 newdc
->w
.stretchBltMode
= dc
->w
.stretchBltMode
;
396 newdc
->w
.relAbsMode
= dc
->w
.relAbsMode
;
397 newdc
->w
.backgroundMode
= dc
->w
.backgroundMode
;
398 newdc
->w
.backgroundColor
= dc
->w
.backgroundColor
;
399 newdc
->w
.textColor
= dc
->w
.textColor
;
400 newdc
->w
.backgroundPixel
= dc
->w
.backgroundPixel
;
401 newdc
->w
.textPixel
= dc
->w
.textPixel
;
402 newdc
->w
.brushOrgX
= dc
->w
.brushOrgX
;
403 newdc
->w
.brushOrgY
= dc
->w
.brushOrgY
;
404 newdc
->w
.textAlign
= dc
->w
.textAlign
;
405 newdc
->w
.charExtra
= dc
->w
.charExtra
;
406 newdc
->w
.breakTotalExtra
= dc
->w
.breakTotalExtra
;
407 newdc
->w
.breakCount
= dc
->w
.breakCount
;
408 newdc
->w
.breakExtra
= dc
->w
.breakExtra
;
409 newdc
->w
.breakRem
= dc
->w
.breakRem
;
410 newdc
->w
.MapMode
= dc
->w
.MapMode
;
411 newdc
->w
.DCOrgX
= dc
->w
.DCOrgX
;
412 newdc
->w
.DCOrgY
= dc
->w
.DCOrgY
;
413 newdc
->w
.CursPosX
= dc
->w
.CursPosX
;
414 newdc
->w
.CursPosY
= dc
->w
.CursPosY
;
415 newdc
->wndOrgX
= dc
->wndOrgX
;
416 newdc
->wndOrgY
= dc
->wndOrgY
;
417 newdc
->wndExtX
= dc
->wndExtX
;
418 newdc
->wndExtY
= dc
->wndExtY
;
419 newdc
->vportOrgX
= dc
->vportOrgX
;
420 newdc
->vportOrgY
= dc
->vportOrgY
;
421 newdc
->vportExtX
= dc
->vportExtX
;
422 newdc
->vportExtY
= dc
->vportExtY
;
424 newdc
->hSelf
= (HDC32
)handle
;
425 newdc
->saveLevel
= 0;
427 newdc
->w
.hGCClipRgn
= 0;
428 newdc
->w
.hVisRgn
= CreateRectRgn32( 0, 0, 0, 0 );
429 CombineRgn32( newdc
->w
.hVisRgn
, dc
->w
.hVisRgn
, 0, RGN_COPY
);
432 newdc
->w
.hClipRgn
= CreateRectRgn32( 0, 0, 0, 0 );
433 CombineRgn32( newdc
->w
.hClipRgn
, dc
->w
.hClipRgn
, 0, RGN_COPY
);
439 /***********************************************************************
440 * SetDCState (GDI.180)
442 void SetDCState( HDC16 hdc
, HDC16 hdcs
)
446 if (!(dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
))) return;
447 if (!(dcs
= (DC
*) GDI_GetObjPtr( hdcs
, DC_MAGIC
))) return;
448 if (!dcs
->w
.flags
& DC_SAVED
) return;
449 dprintf_dc(stddeb
, "SetDCState: %04x %04x\n", hdc
, hdcs
);
451 dc
->w
.flags
= dcs
->w
.flags
& ~DC_SAVED
;
452 dc
->w
.devCaps
= dcs
->w
.devCaps
;
453 dc
->w
.hFirstBitmap
= dcs
->w
.hFirstBitmap
;
454 dc
->w
.hDevice
= dcs
->w
.hDevice
;
455 dc
->w
.ROPmode
= dcs
->w
.ROPmode
;
456 dc
->w
.polyFillMode
= dcs
->w
.polyFillMode
;
457 dc
->w
.stretchBltMode
= dcs
->w
.stretchBltMode
;
458 dc
->w
.relAbsMode
= dcs
->w
.relAbsMode
;
459 dc
->w
.backgroundMode
= dcs
->w
.backgroundMode
;
460 dc
->w
.backgroundColor
= dcs
->w
.backgroundColor
;
461 dc
->w
.textColor
= dcs
->w
.textColor
;
462 dc
->w
.backgroundPixel
= dcs
->w
.backgroundPixel
;
463 dc
->w
.textPixel
= dcs
->w
.textPixel
;
464 dc
->w
.brushOrgX
= dcs
->w
.brushOrgX
;
465 dc
->w
.brushOrgY
= dcs
->w
.brushOrgY
;
466 dc
->w
.textAlign
= dcs
->w
.textAlign
;
467 dc
->w
.charExtra
= dcs
->w
.charExtra
;
468 dc
->w
.breakTotalExtra
= dcs
->w
.breakTotalExtra
;
469 dc
->w
.breakCount
= dcs
->w
.breakCount
;
470 dc
->w
.breakExtra
= dcs
->w
.breakExtra
;
471 dc
->w
.breakRem
= dcs
->w
.breakRem
;
472 dc
->w
.MapMode
= dcs
->w
.MapMode
;
473 dc
->w
.DCOrgX
= dcs
->w
.DCOrgX
;
474 dc
->w
.DCOrgY
= dcs
->w
.DCOrgY
;
475 dc
->w
.CursPosX
= dcs
->w
.CursPosX
;
476 dc
->w
.CursPosY
= dcs
->w
.CursPosY
;
478 dc
->wndOrgX
= dcs
->wndOrgX
;
479 dc
->wndOrgY
= dcs
->wndOrgY
;
480 dc
->wndExtX
= dcs
->wndExtX
;
481 dc
->wndExtY
= dcs
->wndExtY
;
482 dc
->vportOrgX
= dcs
->vportOrgX
;
483 dc
->vportOrgY
= dcs
->vportOrgY
;
484 dc
->vportExtX
= dcs
->vportExtX
;
485 dc
->vportExtY
= dcs
->vportExtY
;
487 if (!(dc
->w
.flags
& DC_MEMORY
)) dc
->w
.bitsPerPixel
= dcs
->w
.bitsPerPixel
;
488 CombineRgn32( dc
->w
.hVisRgn
, dcs
->w
.hVisRgn
, 0, RGN_COPY
);
489 SelectClipRgn32( hdc
, dcs
->w
.hClipRgn
);
490 SelectObject32( hdc
, dcs
->w
.hBitmap
);
491 SelectObject32( hdc
, dcs
->w
.hBrush
);
492 SelectObject32( hdc
, dcs
->w
.hFont
);
493 SelectObject32( hdc
, dcs
->w
.hPen
);
494 GDISelectPalette( hdc
, dcs
->w
.hPalette
, FALSE
);
498 /***********************************************************************
501 INT16
SaveDC16( HDC16 hdc
)
503 return (INT16
)SaveDC32( hdc
);
507 /***********************************************************************
508 * SaveDC32 (GDI32.292)
510 INT32
SaveDC32( HDC32 hdc
)
515 dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
518 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
520 MF_MetaParam0(dc
, META_SAVEDC
);
523 if (!(hdcs
= GetDCState( hdc
))) return 0;
524 dcs
= (DC
*) GDI_HEAP_LIN_ADDR( hdcs
);
525 dcs
->header
.hNext
= dc
->header
.hNext
;
526 dc
->header
.hNext
= hdcs
;
527 dprintf_dc(stddeb
, "SaveDC(%04x): returning %d\n", hdc
, dc
->saveLevel
+1 );
528 return ++dc
->saveLevel
;
532 /***********************************************************************
533 * RestoreDC16 (GDI.39)
535 BOOL16
RestoreDC16( HDC16 hdc
, INT16 level
)
537 return RestoreDC32( hdc
, level
);
541 /***********************************************************************
542 * RestoreDC32 (GDI32.290)
544 BOOL32
RestoreDC32( HDC32 hdc
, INT32 level
)
548 dprintf_dc(stddeb
, "RestoreDC: %04x %d\n", hdc
, level
);
549 dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
552 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
553 if (!dc
) return FALSE
;
554 if (level
!= -1) return FALSE
;
555 MF_MetaParam1(dc
, META_RESTOREDC
, level
);
558 if (level
== -1) level
= dc
->saveLevel
;
559 if ((level
< 1) || (level
> dc
->saveLevel
)) return FALSE
;
561 while (dc
->saveLevel
>= level
)
563 HDC16 hdcs
= dc
->header
.hNext
;
564 if (!(dcs
= (DC
*) GDI_GetObjPtr( hdcs
, DC_MAGIC
))) return FALSE
;
565 dc
->header
.hNext
= dcs
->header
.hNext
;
566 if (--dc
->saveLevel
< level
) SetDCState( hdc
, hdcs
);
573 /***********************************************************************
574 * CreateDC16 (GDI.53)
576 HDC16
CreateDC16( LPCSTR driver
, LPCSTR device
, LPCSTR output
,
577 const DEVMODE16
*initData
)
580 const DC_FUNCTIONS
*funcs
;
582 if (!(funcs
= DRIVER_FindDriver( driver
))) return 0;
583 if (!(dc
= DC_AllocDC( funcs
))) return 0;
586 dprintf_dc(stddeb
, "CreateDC(%s %s %s): returning %04x\n",
587 driver
, device
, output
, dc
->hSelf
);
589 if (dc
->funcs
->pCreateDC
&&
590 !dc
->funcs
->pCreateDC( dc
, driver
, device
, output
, initData
))
592 dprintf_dc( stddeb
, "CreateDC: creation aborted by device\n" );
593 GDI_HEAP_FREE( dc
->hSelf
);
602 /***********************************************************************
603 * CreateDC32A (GDI32.)
605 HDC32
CreateDC32A( LPCSTR driver
, LPCSTR device
, LPCSTR output
,
606 const DEVMODE32A
*initData
)
608 return CreateDC16( driver
, device
, output
, (const DEVMODE16
*)initData
);
612 /***********************************************************************
613 * CreateDC32W (GDI32.)
615 HDC32
CreateDC32W( LPCWSTR driver
, LPCWSTR device
, LPCWSTR output
,
616 const DEVMODE32W
*initData
)
618 LPSTR driverA
= HEAP_strdupWtoA( GetProcessHeap(), 0, driver
);
619 LPSTR deviceA
= HEAP_strdupWtoA( GetProcessHeap(), 0, device
);
620 LPSTR outputA
= HEAP_strdupWtoA( GetProcessHeap(), 0, output
);
621 HDC32 res
= CreateDC16( driverA
, deviceA
, outputA
,
622 (const DEVMODE16
*)initData
/*FIXME*/ );
623 HeapFree( GetProcessHeap(), 0, driverA
);
624 HeapFree( GetProcessHeap(), 0, deviceA
);
625 HeapFree( GetProcessHeap(), 0, outputA
);
630 /***********************************************************************
631 * CreateIC16 (GDI.153)
633 HDC16
CreateIC16( LPCSTR driver
, LPCSTR device
, LPCSTR output
,
634 const DEVMODE16
* initData
)
636 /* Nothing special yet for ICs */
637 return CreateDC16( driver
, device
, output
, initData
);
641 /***********************************************************************
642 * CreateIC32A (GDI32.49)
644 HDC32
CreateIC32A( LPCSTR driver
, LPCSTR device
, LPCSTR output
,
645 const DEVMODE32A
* initData
)
647 /* Nothing special yet for ICs */
648 return CreateDC32A( driver
, device
, output
, initData
);
652 /***********************************************************************
653 * CreateIC32W (GDI32.50)
655 HDC32
CreateIC32W( LPCWSTR driver
, LPCWSTR device
, LPCWSTR output
,
656 const DEVMODE32W
* initData
)
658 /* Nothing special yet for ICs */
659 return CreateDC32W( driver
, device
, output
, initData
);
663 /***********************************************************************
664 * CreateCompatibleDC16 (GDI.52)
666 HDC16
CreateCompatibleDC16( HDC16 hdc
)
668 return (HDC16
)CreateCompatibleDC32( hdc
);
672 /***********************************************************************
673 * CreateCompatibleDC32 (GDI32.31)
675 HDC32
CreateCompatibleDC32( HDC32 hdc
)
679 const DC_FUNCTIONS
*funcs
;
681 if ((origDC
= (DC
*)GDI_GetObjPtr( hdc
, DC_MAGIC
))) funcs
= origDC
->funcs
;
682 else funcs
= DRIVER_FindDriver( "DISPLAY" );
683 if (!funcs
) return 0;
685 if (!(dc
= DC_AllocDC( funcs
))) return 0;
687 dprintf_dc(stddeb
, "CreateCompatibleDC(%04x): returning %04x\n",
690 /* Create default bitmap */
691 if (!(hbitmap
= CreateBitmap( 1, 1, 1, 1, NULL
)))
693 GDI_HEAP_FREE( dc
->hSelf
);
696 dc
->w
.flags
= DC_MEMORY
;
697 dc
->w
.bitsPerPixel
= 1;
698 dc
->w
.hBitmap
= hbitmap
;
699 dc
->w
.hFirstBitmap
= hbitmap
;
701 if (dc
->funcs
->pCreateDC
&&
702 !dc
->funcs
->pCreateDC( dc
, NULL
, NULL
, NULL
, NULL
))
704 dprintf_dc(stddeb
, "CreateCompatibleDC: creation aborted by device\n");
705 DeleteObject32( hbitmap
);
706 GDI_HEAP_FREE( dc
->hSelf
);
715 /***********************************************************************
716 * DeleteDC16 (GDI.68)
718 BOOL16
DeleteDC16( HDC16 hdc
)
720 return DeleteDC32( hdc
);
724 /***********************************************************************
725 * DeleteDC32 (GDI32.67)
727 BOOL32
DeleteDC32( HDC32 hdc
)
729 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
730 if (!dc
) return FALSE
;
732 dprintf_dc(stddeb
, "DeleteDC: %04x\n", hdc
);
734 while (dc
->saveLevel
)
737 HDC16 hdcs
= dc
->header
.hNext
;
738 if (!(dcs
= (DC
*) GDI_GetObjPtr( hdcs
, DC_MAGIC
))) break;
739 dc
->header
.hNext
= dcs
->header
.hNext
;
744 if (!(dc
->w
.flags
& DC_SAVED
))
746 SelectObject32( hdc
, STOCK_BLACK_PEN
);
747 SelectObject32( hdc
, STOCK_WHITE_BRUSH
);
748 SelectObject32( hdc
, STOCK_SYSTEM_FONT
);
749 if (dc
->w
.flags
& DC_MEMORY
) DeleteObject32( dc
->w
.hFirstBitmap
);
750 if (dc
->funcs
->pDeleteDC
) dc
->funcs
->pDeleteDC(dc
);
753 if (dc
->w
.hClipRgn
) DeleteObject32( dc
->w
.hClipRgn
);
754 if (dc
->w
.hVisRgn
) DeleteObject32( dc
->w
.hVisRgn
);
755 if (dc
->w
.hGCClipRgn
) DeleteObject32( dc
->w
.hGCClipRgn
);
757 return GDI_FreeObject( hdc
);
761 /***********************************************************************
762 * ResetDC16 (GDI.376)
764 HDC16
ResetDC16( HDC16 hdc
, const DEVMODE16
*devmode
)
766 fprintf( stderr
, "ResetDC16: empty stub!\n" );
771 /***********************************************************************
772 * ResetDC32A (GDI32.287)
774 HDC32
ResetDC32A( HDC32 hdc
, const DEVMODE32A
*devmode
)
776 fprintf( stderr
, "ResetDC32A: empty stub!\n" );
781 /***********************************************************************
782 * ResetDC32W (GDI32.288)
784 HDC32
ResetDC32W( HDC32 hdc
, const DEVMODE32W
*devmode
)
786 fprintf( stderr
, "ResetDC32A: empty stub!\n" );
791 /***********************************************************************
792 * GetDeviceCaps (GDI.80)
794 int GetDeviceCaps( HDC16 hdc
, WORD cap
)
796 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
799 if (cap
> sizeof(DeviceCaps
)-sizeof(WORD
)) return 0;
801 dprintf_dc(stddeb
, "GetDeviceCaps(%04x,%d): returning %d\n",
802 hdc
, cap
, *(WORD
*)(((char *)dc
->w
.devCaps
) + cap
) );
803 return *(WORD
*)(((char *)dc
->w
.devCaps
) + cap
);
807 /***********************************************************************
808 * SetBkColor (GDI.1) (GDI32.305)
810 COLORREF
SetBkColor( HDC32 hdc
, COLORREF color
)
813 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
816 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
817 if (!dc
) return 0x80000000;
818 MF_MetaParam2(dc
, META_SETBKCOLOR
, HIWORD(color
), LOWORD(color
));
822 oldColor
= dc
->w
.backgroundColor
;
823 dc
->w
.backgroundColor
= color
;
824 dc
->w
.backgroundPixel
= COLOR_ToPhysical( dc
, color
);
829 /***********************************************************************
830 * SetTextColor (GDI.9) (GDI32.338)
832 COLORREF
SetTextColor( HDC32 hdc
, COLORREF color
)
835 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
838 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
839 if (!dc
) return 0x80000000;
840 MF_MetaParam2(dc
, META_SETTEXTCOLOR
, HIWORD(color
), LOWORD(color
));
844 oldColor
= dc
->w
.textColor
;
845 dc
->w
.textColor
= color
;
846 dc
->w
.textPixel
= COLOR_ToPhysical( dc
, color
);
851 /***********************************************************************
852 * SetTextAlign16 (GDI.346)
854 UINT16
SetTextAlign16( HDC16 hdc
, UINT16 textAlign
)
856 return SetTextAlign32( hdc
, textAlign
);
860 /***********************************************************************
861 * SetTextAlign32 (GDI32.336)
863 UINT32
SetTextAlign32( HDC32 hdc
, UINT32 textAlign
)
866 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
869 if (!(dc
= (DC
*)GDI_GetObjPtr( hdc
, METAFILE_DC_MAGIC
))) return 0;
870 MF_MetaParam1( dc
, META_SETTEXTALIGN
, textAlign
);
873 prevAlign
= dc
->w
.textAlign
;
874 dc
->w
.textAlign
= textAlign
;
879 /***********************************************************************
880 * GetDCOrgEx (GDI32.168)
882 BOOL32
GetDCOrgEx( HDC32 hDC
, LPPOINT32 lpp
)
884 DC
* dc
= (DC
*) GDI_GetObjPtr( hDC
, DC_MAGIC
);
885 if (!dc
|| !lpp
) return FALSE
;
887 if (!(dc
->w
.flags
& DC_MEMORY
))
890 int w
, h
, border
, depth
;
891 /* FIXME: this is not correct for managed windows */
892 XGetGeometry( display
, dc
->u
.x
.drawable
, &root
,
893 &lpp
->x
, &lpp
->y
, &w
, &h
, &border
, &depth
);
895 else lpp
->x
= lpp
->y
= 0;
896 lpp
->x
+= dc
->w
.DCOrgX
; lpp
->y
+= dc
->w
.DCOrgY
;
901 /***********************************************************************
904 DWORD
GetDCOrg( HDC16 hdc
)
907 if( GetDCOrgEx( hdc
, &pt
) )
908 return MAKELONG( (WORD
)pt
.x
, (WORD
)pt
.y
);
913 /***********************************************************************
916 DWORD
SetDCOrg( HDC16 hdc
, INT16 x
, INT16 y
)
919 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
921 prevOrg
= dc
->w
.DCOrgX
| (dc
->w
.DCOrgY
<< 16);
928 /***********************************************************************
929 * SetDCHook (GDI.190)
931 BOOL16
SetDCHook( HDC16 hdc
, FARPROC16 hookProc
, DWORD dwHookData
)
933 DC
*dc
= (DC
*)GDI_GetObjPtr( hdc
, DC_MAGIC
);
935 dprintf_dc( stddeb
, "SetDCHook: hookProc %08x, default is %08x\n",
936 (UINT32
)hookProc
, (UINT32
)DCHook
);
938 if (!dc
) return FALSE
;
939 dc
->hookProc
= hookProc
;
940 dc
->dwHookData
= dwHookData
;
945 /***********************************************************************
946 * GetDCHook (GDI.191)
948 DWORD
GetDCHook( HDC16 hdc
, FARPROC16
*phookProc
)
950 DC
*dc
= (DC
*)GDI_GetObjPtr( hdc
, DC_MAGIC
);
952 *phookProc
= dc
->hookProc
;
953 return dc
->dwHookData
;
957 /***********************************************************************
958 * SetHookFlags (GDI.192)
960 WORD
SetHookFlags(HDC16 hDC
, WORD flags
)
962 DC
* dc
= (DC
*)GDI_GetObjPtr( hDC
, DC_MAGIC
);
966 WORD wRet
= dc
->w
.flags
& DC_DIRTY
;
968 /* "Undocumented Windows" info is slightly
972 dprintf_dc(stddeb
,"SetHookFlags: hDC %04x, flags %04x\n",hDC
,flags
);
974 if( flags
& DCHF_INVALIDATEVISRGN
)
975 dc
->w
.flags
|= DC_DIRTY
;
976 else if( flags
& DCHF_VALIDATEVISRGN
|| !flags
)
977 dc
->w
.flags
&= ~DC_DIRTY
;