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 */
61 /* ROP code to GC function conversion */
62 const int DC_XROPfunction
[16] =
64 GXclear
, /* R2_BLACK */
65 GXnor
, /* R2_NOTMERGEPEN */
66 GXandInverted
, /* R2_MASKNOTPEN */
67 GXcopyInverted
, /* R2_NOTCOPYPEN */
68 GXandReverse
, /* R2_MASKPENNOT */
69 GXinvert
, /* R2_NOT */
70 GXxor
, /* R2_XORPEN */
71 GXnand
, /* R2_NOTMASKPEN */
72 GXand
, /* R2_MASKPEN */
73 GXequiv
, /* R2_NOTXORPEN */
75 GXorInverted
, /* R2_MERGENOTPEN */
76 GXcopy
, /* R2_COPYPEN */
77 GXorReverse
, /* R2_MERGEPENNOT */
78 GXor
, /* R2_MERGEPEN */
83 /***********************************************************************
86 * Fill the device caps structure.
88 void DC_FillDevCaps( DeviceCaps
* caps
)
90 caps
->version
= 0x300;
91 caps
->technology
= DT_RASDISPLAY
;
92 caps
->horzSize
= WidthMMOfScreen(screen
) * screenWidth
/ WidthOfScreen(screen
);
93 caps
->vertSize
= HeightMMOfScreen(screen
) * screenHeight
/ HeightOfScreen(screen
);
94 caps
->horzRes
= screenWidth
;
95 caps
->vertRes
= screenHeight
;
96 caps
->bitsPixel
= screenDepth
;
98 caps
->numBrushes
= 16+6; /* 16 solid + 6 hatched brushes */
99 caps
->numPens
= 16; /* 16 solid pens */
100 caps
->numMarkers
= 0;
102 caps
->numColors
= 100;
103 caps
->pdeviceSize
= 0;
104 caps
->curveCaps
= CC_CIRCLES
| CC_PIE
| CC_CHORD
| CC_ELLIPSES
|
105 CC_WIDE
| CC_STYLED
| CC_WIDESTYLED
|
106 CC_INTERIORS
| CC_ROUNDRECT
;
107 caps
->lineCaps
= LC_POLYLINE
| LC_MARKER
| LC_POLYMARKER
| LC_WIDE
|
108 LC_STYLED
| LC_WIDESTYLED
| LC_INTERIORS
;
109 caps
->polygonalCaps
= PC_POLYGON
| PC_RECTANGLE
| PC_WINDPOLYGON
|
110 PC_SCANLINE
| PC_WIDE
| PC_STYLED
|
111 PC_WIDESTYLED
| PC_INTERIORS
;
112 caps
->textCaps
= TC_OP_CHARACTER
| TC_OP_STROKE
| TC_CP_STROKE
|
113 TC_IA_ABLE
| TC_UA_ABLE
| TC_SO_ABLE
| TC_RA_ABLE
;
114 caps
->clipCaps
= CP_REGION
;
115 caps
->rasterCaps
= RC_BITBLT
| RC_BANDING
| RC_SCALING
| RC_BITMAP64
|
116 RC_DI_BITMAP
| RC_DIBTODEV
| RC_BIGFONT
|
117 RC_STRETCHBLT
| RC_STRETCHDIB
| RC_DEVBITS
;
119 if( !(COLOR_GetSystemPaletteFlags() & COLOR_VIRTUAL
) )
120 caps
->rasterCaps
|= RC_PALETTE
;
122 caps
->aspectX
= 36; /* ?? */
123 caps
->aspectY
= 36; /* ?? */
125 caps
->logPixelsX
= (int)(caps
->horzRes
* 25.4 / caps
->horzSize
);
126 caps
->logPixelsY
= (int)(caps
->vertRes
* 25.4 / caps
->vertSize
);
127 caps
->sizePalette
= (caps
->rasterCaps
& RC_PALETTE
)
128 ? DefaultVisual(display
,DefaultScreen(display
))->map_entries
130 caps
->numReserved
= 0;
135 /***********************************************************************
138 DC
*DC_AllocDC( const DC_FUNCTIONS
*funcs
)
143 if (!(hdc
= GDI_AllocObject( sizeof(DC
), DC_MAGIC
))) return NULL
;
144 dc
= (DC
*) GDI_HEAP_LIN_ADDR( hdc
);
161 memcpy( &dc
->w
, &DC_defaultValues
, sizeof(DC_defaultValues
) );
166 /***********************************************************************
169 DC
*DC_GetDCPtr( HDC32 hdc
)
171 GDIOBJHDR
*ptr
= (GDIOBJHDR
*)GDI_HEAP_LIN_ADDR( hdc
);
172 if (!ptr
) return NULL
;
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 SetTextColor32( dc
->hSelf
, dc
->w
.textColor
);
188 SetBkColor32( 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 switch (dc
->w
.ROPmode
)
308 val
.foreground
= BlackPixelOfScreen( screen
);
309 val
.function
= GXcopy
;
312 val
.foreground
= WhitePixelOfScreen( screen
);
313 val
.function
= GXcopy
;
316 val
.foreground
= dc
->u
.x
.pen
.pixel
;
317 /* It is very unlikely someone wants to XOR with 0 */
318 /* This fixes the rubber-drawings in paintbrush */
319 if (val
.foreground
== 0)
320 val
.foreground
= BlackPixelOfScreen( screen
)
321 ^ WhitePixelOfScreen( screen
);
322 val
.function
= GXxor
;
325 val
.foreground
= dc
->u
.x
.pen
.pixel
;
326 val
.function
= DC_XROPfunction
[dc
->w
.ROPmode
-1];
328 val
.background
= dc
->w
.backgroundPixel
;
329 val
.fill_style
= FillSolid
;
330 if ((dc
->u
.x
.pen
.style
!=PS_SOLID
) && (dc
->u
.x
.pen
.style
!=PS_INSIDEFRAME
))
332 XSetDashes( display
, dc
->u
.x
.gc
, 0,
333 dc
->u
.x
.pen
.dashes
, dc
->u
.x
.pen
.dash_len
);
334 val
.line_style
= (dc
->w
.backgroundMode
== OPAQUE
) ?
335 LineDoubleDash
: LineOnOffDash
;
337 else val
.line_style
= LineSolid
;
338 val
.line_width
= dc
->u
.x
.pen
.width
;
339 val
.cap_style
= CapRound
;
340 val
.join_style
= JoinMiter
;
341 XChangeGC( display
, dc
->u
.x
.gc
,
342 GCFunction
| GCForeground
| GCBackground
| GCLineWidth
|
343 GCLineStyle
| GCCapStyle
| GCJoinStyle
| GCFillStyle
, &val
);
348 /***********************************************************************
351 * Setup dc->u.x.gc for text drawing operations.
352 * Return FALSE if the font is null, TRUE otherwise.
354 BOOL32
DC_SetupGCForText( DC
* dc
)
356 XFontStruct
* xfs
= XFONT_GetFontStruct( dc
->u
.x
.font
);
362 if (dc
->w
.flags
& DC_DIRTY
) CLIPPING_UpdateGCRegion(dc
);
364 val
.function
= GXcopy
; /* Text is always GXcopy */
365 val
.foreground
= dc
->w
.textPixel
;
366 val
.background
= dc
->w
.backgroundPixel
;
367 val
.fill_style
= FillSolid
;
370 XChangeGC( display
, dc
->u
.x
.gc
,
371 GCFunction
| GCForeground
| GCBackground
| GCFillStyle
|
375 fprintf( stderr
, "DC_SetupGCForText: physical font failure\n" );
380 /***********************************************************************
381 * GetDCState (GDI.179)
383 HDC16
GetDCState( HDC16 hdc
)
388 if (!(dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
))) return 0;
389 if (!(handle
= GDI_AllocObject( sizeof(DC
), DC_MAGIC
))) return 0;
390 newdc
= (DC
*) GDI_HEAP_LIN_ADDR( handle
);
392 dprintf_dc(stddeb
, "GetDCState(%04x): returning %04x\n", hdc
, handle
);
394 memset( &newdc
->u
.x
, 0, sizeof(newdc
->u
.x
) );
395 newdc
->w
.flags
= dc
->w
.flags
| DC_SAVED
;
396 newdc
->w
.devCaps
= dc
->w
.devCaps
;
397 newdc
->w
.hPen
= dc
->w
.hPen
;
398 newdc
->w
.hBrush
= dc
->w
.hBrush
;
399 newdc
->w
.hFont
= dc
->w
.hFont
;
400 newdc
->w
.hBitmap
= dc
->w
.hBitmap
;
401 newdc
->w
.hFirstBitmap
= dc
->w
.hFirstBitmap
;
402 newdc
->w
.hDevice
= dc
->w
.hDevice
;
403 newdc
->w
.hPalette
= dc
->w
.hPalette
;
404 newdc
->w
.bitsPerPixel
= dc
->w
.bitsPerPixel
;
405 newdc
->w
.ROPmode
= dc
->w
.ROPmode
;
406 newdc
->w
.polyFillMode
= dc
->w
.polyFillMode
;
407 newdc
->w
.stretchBltMode
= dc
->w
.stretchBltMode
;
408 newdc
->w
.relAbsMode
= dc
->w
.relAbsMode
;
409 newdc
->w
.backgroundMode
= dc
->w
.backgroundMode
;
410 newdc
->w
.backgroundColor
= dc
->w
.backgroundColor
;
411 newdc
->w
.textColor
= dc
->w
.textColor
;
412 newdc
->w
.backgroundPixel
= dc
->w
.backgroundPixel
;
413 newdc
->w
.textPixel
= dc
->w
.textPixel
;
414 newdc
->w
.brushOrgX
= dc
->w
.brushOrgX
;
415 newdc
->w
.brushOrgY
= dc
->w
.brushOrgY
;
416 newdc
->w
.textAlign
= dc
->w
.textAlign
;
417 newdc
->w
.charExtra
= dc
->w
.charExtra
;
418 newdc
->w
.breakTotalExtra
= dc
->w
.breakTotalExtra
;
419 newdc
->w
.breakCount
= dc
->w
.breakCount
;
420 newdc
->w
.breakExtra
= dc
->w
.breakExtra
;
421 newdc
->w
.breakRem
= dc
->w
.breakRem
;
422 newdc
->w
.MapMode
= dc
->w
.MapMode
;
423 newdc
->w
.DCOrgX
= dc
->w
.DCOrgX
;
424 newdc
->w
.DCOrgY
= dc
->w
.DCOrgY
;
425 newdc
->w
.CursPosX
= dc
->w
.CursPosX
;
426 newdc
->w
.CursPosY
= dc
->w
.CursPosY
;
427 newdc
->wndOrgX
= dc
->wndOrgX
;
428 newdc
->wndOrgY
= dc
->wndOrgY
;
429 newdc
->wndExtX
= dc
->wndExtX
;
430 newdc
->wndExtY
= dc
->wndExtY
;
431 newdc
->vportOrgX
= dc
->vportOrgX
;
432 newdc
->vportOrgY
= dc
->vportOrgY
;
433 newdc
->vportExtX
= dc
->vportExtX
;
434 newdc
->vportExtY
= dc
->vportExtY
;
436 newdc
->hSelf
= (HDC32
)handle
;
437 newdc
->saveLevel
= 0;
439 newdc
->w
.hGCClipRgn
= 0;
440 newdc
->w
.hVisRgn
= CreateRectRgn32( 0, 0, 0, 0 );
441 CombineRgn32( newdc
->w
.hVisRgn
, dc
->w
.hVisRgn
, 0, RGN_COPY
);
444 newdc
->w
.hClipRgn
= CreateRectRgn32( 0, 0, 0, 0 );
445 CombineRgn32( newdc
->w
.hClipRgn
, dc
->w
.hClipRgn
, 0, RGN_COPY
);
448 newdc
->w
.hClipRgn
= 0;
453 /***********************************************************************
454 * SetDCState (GDI.180)
456 void SetDCState( HDC16 hdc
, HDC16 hdcs
)
460 if (!(dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
))) return;
461 if (!(dcs
= (DC
*) GDI_GetObjPtr( hdcs
, DC_MAGIC
))) return;
462 if (!dcs
->w
.flags
& DC_SAVED
) return;
463 dprintf_dc(stddeb
, "SetDCState: %04x %04x\n", hdc
, hdcs
);
465 dc
->w
.flags
= dcs
->w
.flags
& ~DC_SAVED
;
466 dc
->w
.devCaps
= dcs
->w
.devCaps
;
467 dc
->w
.hFirstBitmap
= dcs
->w
.hFirstBitmap
;
468 dc
->w
.hDevice
= dcs
->w
.hDevice
;
469 dc
->w
.ROPmode
= dcs
->w
.ROPmode
;
470 dc
->w
.polyFillMode
= dcs
->w
.polyFillMode
;
471 dc
->w
.stretchBltMode
= dcs
->w
.stretchBltMode
;
472 dc
->w
.relAbsMode
= dcs
->w
.relAbsMode
;
473 dc
->w
.backgroundMode
= dcs
->w
.backgroundMode
;
474 dc
->w
.backgroundColor
= dcs
->w
.backgroundColor
;
475 dc
->w
.textColor
= dcs
->w
.textColor
;
476 dc
->w
.backgroundPixel
= dcs
->w
.backgroundPixel
;
477 dc
->w
.textPixel
= dcs
->w
.textPixel
;
478 dc
->w
.brushOrgX
= dcs
->w
.brushOrgX
;
479 dc
->w
.brushOrgY
= dcs
->w
.brushOrgY
;
480 dc
->w
.textAlign
= dcs
->w
.textAlign
;
481 dc
->w
.charExtra
= dcs
->w
.charExtra
;
482 dc
->w
.breakTotalExtra
= dcs
->w
.breakTotalExtra
;
483 dc
->w
.breakCount
= dcs
->w
.breakCount
;
484 dc
->w
.breakExtra
= dcs
->w
.breakExtra
;
485 dc
->w
.breakRem
= dcs
->w
.breakRem
;
486 dc
->w
.MapMode
= dcs
->w
.MapMode
;
487 dc
->w
.DCOrgX
= dcs
->w
.DCOrgX
;
488 dc
->w
.DCOrgY
= dcs
->w
.DCOrgY
;
489 dc
->w
.CursPosX
= dcs
->w
.CursPosX
;
490 dc
->w
.CursPosY
= dcs
->w
.CursPosY
;
492 dc
->wndOrgX
= dcs
->wndOrgX
;
493 dc
->wndOrgY
= dcs
->wndOrgY
;
494 dc
->wndExtX
= dcs
->wndExtX
;
495 dc
->wndExtY
= dcs
->wndExtY
;
496 dc
->vportOrgX
= dcs
->vportOrgX
;
497 dc
->vportOrgY
= dcs
->vportOrgY
;
498 dc
->vportExtX
= dcs
->vportExtX
;
499 dc
->vportExtY
= dcs
->vportExtY
;
501 if (!(dc
->w
.flags
& DC_MEMORY
)) dc
->w
.bitsPerPixel
= dcs
->w
.bitsPerPixel
;
502 CombineRgn32( dc
->w
.hVisRgn
, dcs
->w
.hVisRgn
, 0, RGN_COPY
);
503 SelectClipRgn32( hdc
, dcs
->w
.hClipRgn
);
504 SelectObject32( hdc
, dcs
->w
.hBitmap
);
505 SelectObject32( hdc
, dcs
->w
.hBrush
);
506 SelectObject32( hdc
, dcs
->w
.hFont
);
507 SelectObject32( hdc
, dcs
->w
.hPen
);
508 GDISelectPalette( hdc
, dcs
->w
.hPalette
, FALSE
);
512 /***********************************************************************
515 INT16
SaveDC16( HDC16 hdc
)
517 return (INT16
)SaveDC32( hdc
);
521 /***********************************************************************
522 * SaveDC32 (GDI32.292)
524 INT32
SaveDC32( HDC32 hdc
)
529 dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
532 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
534 MF_MetaParam0(dc
, META_SAVEDC
);
537 if (!(hdcs
= GetDCState( hdc
))) return 0;
538 dcs
= (DC
*) GDI_HEAP_LIN_ADDR( hdcs
);
539 dcs
->header
.hNext
= dc
->header
.hNext
;
540 dc
->header
.hNext
= hdcs
;
541 dprintf_dc(stddeb
, "SaveDC(%04x): returning %d\n", hdc
, dc
->saveLevel
+1 );
542 return ++dc
->saveLevel
;
546 /***********************************************************************
547 * RestoreDC16 (GDI.39)
549 BOOL16
RestoreDC16( HDC16 hdc
, INT16 level
)
551 return RestoreDC32( hdc
, level
);
555 /***********************************************************************
556 * RestoreDC32 (GDI32.290)
558 BOOL32
RestoreDC32( HDC32 hdc
, INT32 level
)
562 dprintf_dc(stddeb
, "RestoreDC: %04x %d\n", hdc
, level
);
563 dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
566 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
567 if (!dc
) return FALSE
;
568 if (level
!= -1) return FALSE
;
569 MF_MetaParam1(dc
, META_RESTOREDC
, level
);
572 if (level
== -1) level
= dc
->saveLevel
;
573 if ((level
< 1) || (level
> dc
->saveLevel
)) return FALSE
;
575 while (dc
->saveLevel
>= level
)
577 HDC16 hdcs
= dc
->header
.hNext
;
578 if (!(dcs
= (DC
*) GDI_GetObjPtr( hdcs
, DC_MAGIC
))) return FALSE
;
579 dc
->header
.hNext
= dcs
->header
.hNext
;
580 if (--dc
->saveLevel
< level
) SetDCState( hdc
, hdcs
);
587 /***********************************************************************
588 * CreateDC16 (GDI.53)
590 HDC16
CreateDC16( LPCSTR driver
, LPCSTR device
, LPCSTR output
,
591 const DEVMODE16
*initData
)
594 const DC_FUNCTIONS
*funcs
;
596 if (!(funcs
= DRIVER_FindDriver( driver
))) return 0;
597 if (!(dc
= DC_AllocDC( funcs
))) return 0;
600 dprintf_dc(stddeb
, "CreateDC(%s %s %s): returning %04x\n",
601 driver
, device
, output
, dc
->hSelf
);
603 if (dc
->funcs
->pCreateDC
&&
604 !dc
->funcs
->pCreateDC( dc
, driver
, device
, output
, initData
))
606 dprintf_dc( stddeb
, "CreateDC: creation aborted by device\n" );
607 GDI_HEAP_FREE( dc
->hSelf
);
616 /***********************************************************************
617 * CreateDC32A (GDI32.)
619 HDC32
CreateDC32A( LPCSTR driver
, LPCSTR device
, LPCSTR output
,
620 const DEVMODE32A
*initData
)
622 return CreateDC16( driver
, device
, output
, (const DEVMODE16
*)initData
);
626 /***********************************************************************
627 * CreateDC32W (GDI32.)
629 HDC32
CreateDC32W( LPCWSTR driver
, LPCWSTR device
, LPCWSTR output
,
630 const DEVMODE32W
*initData
)
632 LPSTR driverA
= HEAP_strdupWtoA( GetProcessHeap(), 0, driver
);
633 LPSTR deviceA
= HEAP_strdupWtoA( GetProcessHeap(), 0, device
);
634 LPSTR outputA
= HEAP_strdupWtoA( GetProcessHeap(), 0, output
);
635 HDC32 res
= CreateDC16( driverA
, deviceA
, outputA
,
636 (const DEVMODE16
*)initData
/*FIXME*/ );
637 HeapFree( GetProcessHeap(), 0, driverA
);
638 HeapFree( GetProcessHeap(), 0, deviceA
);
639 HeapFree( GetProcessHeap(), 0, outputA
);
644 /***********************************************************************
645 * CreateIC16 (GDI.153)
647 HDC16
CreateIC16( LPCSTR driver
, LPCSTR device
, LPCSTR output
,
648 const DEVMODE16
* initData
)
650 /* Nothing special yet for ICs */
651 return CreateDC16( driver
, device
, output
, initData
);
655 /***********************************************************************
656 * CreateIC32A (GDI32.49)
658 HDC32
CreateIC32A( LPCSTR driver
, LPCSTR device
, LPCSTR output
,
659 const DEVMODE32A
* initData
)
661 /* Nothing special yet for ICs */
662 return CreateDC32A( driver
, device
, output
, initData
);
666 /***********************************************************************
667 * CreateIC32W (GDI32.50)
669 HDC32
CreateIC32W( LPCWSTR driver
, LPCWSTR device
, LPCWSTR output
,
670 const DEVMODE32W
* initData
)
672 /* Nothing special yet for ICs */
673 return CreateDC32W( driver
, device
, output
, initData
);
677 /***********************************************************************
678 * CreateCompatibleDC16 (GDI.52)
680 HDC16
CreateCompatibleDC16( HDC16 hdc
)
682 return (HDC16
)CreateCompatibleDC32( hdc
);
686 /***********************************************************************
687 * CreateCompatibleDC32 (GDI32.31)
689 HDC32
CreateCompatibleDC32( HDC32 hdc
)
693 const DC_FUNCTIONS
*funcs
;
695 if ((origDC
= (DC
*)GDI_GetObjPtr( hdc
, DC_MAGIC
))) funcs
= origDC
->funcs
;
696 else funcs
= DRIVER_FindDriver( "DISPLAY" );
697 if (!funcs
) return 0;
699 if (!(dc
= DC_AllocDC( funcs
))) return 0;
701 dprintf_dc(stddeb
, "CreateCompatibleDC(%04x): returning %04x\n",
704 /* Create default bitmap */
705 if (!(hbitmap
= CreateBitmap32( 1, 1, 1, 1, NULL
)))
707 GDI_HEAP_FREE( dc
->hSelf
);
710 dc
->w
.flags
= DC_MEMORY
;
711 dc
->w
.bitsPerPixel
= 1;
712 dc
->w
.hBitmap
= hbitmap
;
713 dc
->w
.hFirstBitmap
= hbitmap
;
715 if (dc
->funcs
->pCreateDC
&&
716 !dc
->funcs
->pCreateDC( dc
, NULL
, NULL
, NULL
, NULL
))
718 dprintf_dc(stddeb
, "CreateCompatibleDC: creation aborted by device\n");
719 DeleteObject32( hbitmap
);
720 GDI_HEAP_FREE( dc
->hSelf
);
729 /***********************************************************************
730 * DeleteDC16 (GDI.68)
732 BOOL16
DeleteDC16( HDC16 hdc
)
734 return DeleteDC32( hdc
);
738 /***********************************************************************
739 * DeleteDC32 (GDI32.67)
741 BOOL32
DeleteDC32( HDC32 hdc
)
743 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
744 if (!dc
) return FALSE
;
746 dprintf_dc(stddeb
, "DeleteDC: %04x\n", hdc
);
748 while (dc
->saveLevel
)
751 HDC16 hdcs
= dc
->header
.hNext
;
752 if (!(dcs
= (DC
*) GDI_GetObjPtr( hdcs
, DC_MAGIC
))) break;
753 dc
->header
.hNext
= dcs
->header
.hNext
;
758 if (!(dc
->w
.flags
& DC_SAVED
))
760 SelectObject32( hdc
, STOCK_BLACK_PEN
);
761 SelectObject32( hdc
, STOCK_WHITE_BRUSH
);
762 SelectObject32( hdc
, STOCK_SYSTEM_FONT
);
763 if (dc
->w
.flags
& DC_MEMORY
) DeleteObject32( dc
->w
.hFirstBitmap
);
764 if (dc
->funcs
->pDeleteDC
) dc
->funcs
->pDeleteDC(dc
);
767 if (dc
->w
.hClipRgn
) DeleteObject32( dc
->w
.hClipRgn
);
768 if (dc
->w
.hVisRgn
) DeleteObject32( dc
->w
.hVisRgn
);
769 if (dc
->w
.hGCClipRgn
) DeleteObject32( dc
->w
.hGCClipRgn
);
771 return GDI_FreeObject( hdc
);
775 /***********************************************************************
776 * ResetDC16 (GDI.376)
778 HDC16
ResetDC16( HDC16 hdc
, const DEVMODE16
*devmode
)
780 fprintf( stderr
, "ResetDC16: empty stub!\n" );
785 /***********************************************************************
786 * ResetDC32A (GDI32.287)
788 HDC32
ResetDC32A( HDC32 hdc
, const DEVMODE32A
*devmode
)
790 fprintf( stderr
, "ResetDC32A: empty stub!\n" );
795 /***********************************************************************
796 * ResetDC32W (GDI32.288)
798 HDC32
ResetDC32W( HDC32 hdc
, const DEVMODE32W
*devmode
)
800 fprintf( stderr
, "ResetDC32A: empty stub!\n" );
805 /***********************************************************************
806 * GetDeviceCaps16 (GDI.80)
808 INT16
GetDeviceCaps16( HDC16 hdc
, INT16 cap
)
810 return GetDeviceCaps32( hdc
, cap
);
814 /***********************************************************************
815 * GetDeviceCaps32 (GDI32.171)
817 INT32
GetDeviceCaps32( HDC32 hdc
, INT32 cap
)
819 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
822 if ((cap
< 0) || (cap
> sizeof(DeviceCaps
)-sizeof(WORD
))) return 0;
824 dprintf_dc(stddeb
, "GetDeviceCaps(%04x,%d): returning %d\n",
825 hdc
, cap
, *(WORD
*)(((char *)dc
->w
.devCaps
) + cap
) );
826 return *(WORD
*)(((char *)dc
->w
.devCaps
) + cap
);
830 /***********************************************************************
831 * SetBkColor16 (GDI.1)
833 COLORREF
SetBkColor16( HDC16 hdc
, COLORREF color
)
835 return SetBkColor32( hdc
, color
);
839 /***********************************************************************
840 * SetBkColor32 (GDI32.305)
842 COLORREF
SetBkColor32( HDC32 hdc
, COLORREF color
)
845 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
848 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
849 if (!dc
) return 0x80000000;
850 MF_MetaParam2(dc
, META_SETBKCOLOR
, HIWORD(color
), LOWORD(color
));
854 oldColor
= dc
->w
.backgroundColor
;
855 dc
->w
.backgroundColor
= color
;
856 dc
->w
.backgroundPixel
= COLOR_ToPhysical( dc
, color
);
861 /***********************************************************************
862 * SetTextColor16 (GDI.9)
864 COLORREF
SetTextColor16( HDC16 hdc
, COLORREF color
)
866 return SetTextColor32( hdc
, color
);
870 /***********************************************************************
871 * SetTextColor32 (GDI32.338)
873 COLORREF
SetTextColor32( HDC32 hdc
, COLORREF color
)
876 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
879 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
880 if (!dc
) return 0x80000000;
881 MF_MetaParam2(dc
, META_SETTEXTCOLOR
, HIWORD(color
), LOWORD(color
));
885 oldColor
= dc
->w
.textColor
;
886 dc
->w
.textColor
= color
;
887 dc
->w
.textPixel
= COLOR_ToPhysical( dc
, color
);
892 /***********************************************************************
893 * SetTextAlign16 (GDI.346)
895 UINT16
SetTextAlign16( HDC16 hdc
, UINT16 textAlign
)
897 return SetTextAlign32( hdc
, textAlign
);
901 /***********************************************************************
902 * SetTextAlign32 (GDI32.336)
904 UINT32
SetTextAlign32( HDC32 hdc
, UINT32 textAlign
)
907 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
910 if (!(dc
= (DC
*)GDI_GetObjPtr( hdc
, METAFILE_DC_MAGIC
))) return 0;
911 MF_MetaParam1( dc
, META_SETTEXTALIGN
, textAlign
);
914 prevAlign
= dc
->w
.textAlign
;
915 dc
->w
.textAlign
= textAlign
;
920 /***********************************************************************
921 * GetDCOrgEx (GDI32.168)
923 BOOL32
GetDCOrgEx( HDC32 hDC
, LPPOINT32 lpp
)
925 DC
* dc
= (DC
*) GDI_GetObjPtr( hDC
, DC_MAGIC
);
926 if (!dc
|| !lpp
) return FALSE
;
928 if (!(dc
->w
.flags
& DC_MEMORY
))
931 int w
, h
, border
, depth
;
932 /* FIXME: this is not correct for managed windows */
933 XGetGeometry( display
, dc
->u
.x
.drawable
, &root
,
934 &lpp
->x
, &lpp
->y
, &w
, &h
, &border
, &depth
);
936 else lpp
->x
= lpp
->y
= 0;
937 lpp
->x
+= dc
->w
.DCOrgX
; lpp
->y
+= dc
->w
.DCOrgY
;
942 /***********************************************************************
945 DWORD
GetDCOrg( HDC16 hdc
)
948 if( GetDCOrgEx( hdc
, &pt
) )
949 return MAKELONG( (WORD
)pt
.x
, (WORD
)pt
.y
);
954 /***********************************************************************
957 DWORD
SetDCOrg( HDC16 hdc
, INT16 x
, INT16 y
)
960 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
962 prevOrg
= dc
->w
.DCOrgX
| (dc
->w
.DCOrgY
<< 16);
969 /***********************************************************************
970 * SetDCHook (GDI.190)
972 BOOL16
SetDCHook( HDC16 hdc
, FARPROC16 hookProc
, DWORD dwHookData
)
974 DC
*dc
= (DC
*)GDI_GetObjPtr( hdc
, DC_MAGIC
);
976 dprintf_dc( stddeb
, "SetDCHook: hookProc %08x, default is %08x\n",
977 (UINT32
)hookProc
, (UINT32
)DCHook
);
979 if (!dc
) return FALSE
;
980 dc
->hookProc
= hookProc
;
981 dc
->dwHookData
= dwHookData
;
986 /***********************************************************************
987 * GetDCHook (GDI.191)
989 DWORD
GetDCHook( HDC16 hdc
, FARPROC16
*phookProc
)
991 DC
*dc
= (DC
*)GDI_GetObjPtr( hdc
, DC_MAGIC
);
993 *phookProc
= dc
->hookProc
;
994 return dc
->dwHookData
;
998 /***********************************************************************
999 * SetHookFlags (GDI.192)
1001 WORD
SetHookFlags(HDC16 hDC
, WORD flags
)
1003 DC
* dc
= (DC
*)GDI_GetObjPtr( hDC
, DC_MAGIC
);
1007 WORD wRet
= dc
->w
.flags
& DC_DIRTY
;
1009 /* "Undocumented Windows" info is slightly
1013 dprintf_dc(stddeb
,"SetHookFlags: hDC %04x, flags %04x\n",hDC
,flags
);
1015 if( flags
& DCHF_INVALIDATEVISRGN
)
1016 dc
->w
.flags
|= DC_DIRTY
;
1017 else if( flags
& DCHF_VALIDATEVISRGN
|| !flags
)
1018 dc
->w
.flags
&= ~DC_DIRTY
;