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_LOCK( hdc
);
161 memcpy( &dc
->w
, &DC_defaultValues
, sizeof(DC_defaultValues
) );
167 /***********************************************************************
170 DC
*DC_GetDCPtr( HDC32 hdc
)
172 GDIOBJHDR
*ptr
= (GDIOBJHDR
*)GDI_HEAP_LOCK( hdc
);
173 if (!ptr
) return NULL
;
174 if ((ptr
->wMagic
== DC_MAGIC
) || (ptr
->wMagic
== METAFILE_DC_MAGIC
))
176 GDI_HEAP_UNLOCK( hdc
);
181 /***********************************************************************
184 * Setup device-specific DC values for a newly created DC.
186 void DC_InitDC( DC
* dc
)
188 RealizeDefaultPalette( dc
->hSelf
);
189 SetTextColor32( dc
->hSelf
, dc
->w
.textColor
);
190 SetBkColor32( dc
->hSelf
, dc
->w
.backgroundColor
);
191 SelectObject32( dc
->hSelf
, dc
->w
.hPen
);
192 SelectObject32( dc
->hSelf
, dc
->w
.hBrush
);
193 SelectObject32( dc
->hSelf
, dc
->w
.hFont
);
194 CLIPPING_UpdateGCRegion( dc
);
198 /***********************************************************************
199 * DC_SetupGCForPatBlt
201 * Setup the GC for a PatBlt operation using current brush.
202 * If fMapColors is TRUE, X pixels are mapped to Windows colors.
203 * Return FALSE if brush is BS_NULL, TRUE otherwise.
205 BOOL32
DC_SetupGCForPatBlt( DC
* dc
, GC gc
, BOOL32 fMapColors
)
211 if (dc
->u
.x
.brush
.style
== BS_NULL
) return FALSE
;
212 if (dc
->u
.x
.brush
.pixel
== -1)
214 /* Special case used for monochrome pattern brushes.
215 * We need to swap foreground and background because
216 * Windows does it the wrong way...
218 val
.foreground
= dc
->w
.backgroundPixel
;
219 val
.background
= dc
->w
.textPixel
;
223 val
.foreground
= dc
->u
.x
.brush
.pixel
;
224 val
.background
= dc
->w
.backgroundPixel
;
226 if (fMapColors
&& COLOR_PixelToPalette
)
228 val
.foreground
= COLOR_PixelToPalette
[val
.foreground
];
229 val
.background
= COLOR_PixelToPalette
[val
.background
];
232 if (dc
->w
.flags
& DC_DIRTY
) CLIPPING_UpdateGCRegion(dc
);
234 val
.function
= DC_XROPfunction
[dc
->w
.ROPmode
-1];
235 val
.fill_style
= dc
->u
.x
.brush
.fillStyle
;
236 switch(val
.fill_style
)
239 case FillOpaqueStippled
:
240 if (dc
->w
.backgroundMode
==OPAQUE
) val
.fill_style
= FillOpaqueStippled
;
241 val
.stipple
= dc
->u
.x
.brush
.pixmap
;
246 if (fMapColors
&& COLOR_PixelToPalette
)
250 pixmap
= XCreatePixmap( display
, rootWindow
, 8, 8, screenDepth
);
251 image
= XGetImage( display
, dc
->u
.x
.brush
.pixmap
, 0, 0, 8, 8,
252 AllPlanes
, ZPixmap
);
253 for (y
= 0; y
< 8; y
++)
254 for (x
= 0; x
< 8; x
++)
255 XPutPixel( image
, x
, y
,
256 COLOR_PixelToPalette
[XGetPixel( image
, x
, y
)] );
257 XPutImage( display
, pixmap
, gc
, image
, 0, 0, 0, 0, 8, 8 );
258 XDestroyImage( image
);
261 else val
.tile
= dc
->u
.x
.brush
.pixmap
;
269 val
.ts_x_origin
= dc
->w
.DCOrgX
+ dc
->w
.brushOrgX
;
270 val
.ts_y_origin
= dc
->w
.DCOrgY
+ dc
->w
.brushOrgY
;
271 val
.fill_rule
= (dc
->w
.polyFillMode
==WINDING
) ? WindingRule
: EvenOddRule
;
272 XChangeGC( display
, gc
,
273 GCFunction
| GCForeground
| GCBackground
| GCFillStyle
|
274 GCFillRule
| GCTileStipXOrigin
| GCTileStipYOrigin
| mask
,
276 if (pixmap
) XFreePixmap( display
, pixmap
);
281 /***********************************************************************
284 * Setup dc->u.x.gc for drawing operations using current brush.
285 * Return FALSE if brush is BS_NULL, TRUE otherwise.
287 BOOL32
DC_SetupGCForBrush( DC
* dc
)
289 return DC_SetupGCForPatBlt( dc
, dc
->u
.x
.gc
, FALSE
);
293 /***********************************************************************
296 * Setup dc->u.x.gc for drawing operations using current pen.
297 * Return FALSE if pen is PS_NULL, TRUE otherwise.
299 BOOL32
DC_SetupGCForPen( DC
* dc
)
303 if (dc
->u
.x
.pen
.style
== PS_NULL
) return FALSE
;
305 if (dc
->w
.flags
& DC_DIRTY
) CLIPPING_UpdateGCRegion(dc
);
307 switch (dc
->w
.ROPmode
)
310 val
.foreground
= BlackPixelOfScreen( screen
);
311 val
.function
= GXcopy
;
314 val
.foreground
= WhitePixelOfScreen( screen
);
315 val
.function
= GXcopy
;
318 val
.foreground
= dc
->u
.x
.pen
.pixel
;
319 /* It is very unlikely someone wants to XOR with 0 */
320 /* This fixes the rubber-drawings in paintbrush */
321 if (val
.foreground
== 0)
322 val
.foreground
= BlackPixelOfScreen( screen
)
323 ^ WhitePixelOfScreen( screen
);
324 val
.function
= GXxor
;
327 val
.foreground
= dc
->u
.x
.pen
.pixel
;
328 val
.function
= DC_XROPfunction
[dc
->w
.ROPmode
-1];
330 val
.background
= dc
->w
.backgroundPixel
;
331 val
.fill_style
= FillSolid
;
332 if ((dc
->u
.x
.pen
.style
!=PS_SOLID
) && (dc
->u
.x
.pen
.style
!=PS_INSIDEFRAME
))
334 XSetDashes( display
, dc
->u
.x
.gc
, 0,
335 dc
->u
.x
.pen
.dashes
, dc
->u
.x
.pen
.dash_len
);
336 val
.line_style
= (dc
->w
.backgroundMode
== OPAQUE
) ?
337 LineDoubleDash
: LineOnOffDash
;
339 else val
.line_style
= LineSolid
;
340 val
.line_width
= dc
->u
.x
.pen
.width
;
341 val
.cap_style
= CapRound
;
342 val
.join_style
= JoinMiter
;
343 XChangeGC( display
, dc
->u
.x
.gc
,
344 GCFunction
| GCForeground
| GCBackground
| GCLineWidth
|
345 GCLineStyle
| GCCapStyle
| GCJoinStyle
| GCFillStyle
, &val
);
350 /***********************************************************************
353 * Setup dc->u.x.gc for text drawing operations.
354 * Return FALSE if the font is null, TRUE otherwise.
356 BOOL32
DC_SetupGCForText( DC
* dc
)
358 XFontStruct
* xfs
= XFONT_GetFontStruct( dc
->u
.x
.font
);
364 if (dc
->w
.flags
& DC_DIRTY
) CLIPPING_UpdateGCRegion(dc
);
366 val
.function
= GXcopy
; /* Text is always GXcopy */
367 val
.foreground
= dc
->w
.textPixel
;
368 val
.background
= dc
->w
.backgroundPixel
;
369 val
.fill_style
= FillSolid
;
372 XChangeGC( display
, dc
->u
.x
.gc
,
373 GCFunction
| GCForeground
| GCBackground
| GCFillStyle
|
377 fprintf( stderr
, "DC_SetupGCForText: physical font failure\n" );
382 /***********************************************************************
383 * GetDCState (GDI.179)
385 HDC16 WINAPI
GetDCState( HDC16 hdc
)
390 if (!(dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
))) return 0;
391 if (!(handle
= GDI_AllocObject( sizeof(DC
), DC_MAGIC
)))
393 GDI_HEAP_UNLOCK( hdc
);
396 newdc
= (DC
*) GDI_HEAP_LOCK( handle
);
398 dprintf_dc(stddeb
, "GetDCState(%04x): returning %04x\n", hdc
, handle
);
400 memset( &newdc
->u
.x
, 0, sizeof(newdc
->u
.x
) );
401 newdc
->w
.flags
= dc
->w
.flags
| DC_SAVED
;
402 newdc
->w
.devCaps
= dc
->w
.devCaps
;
403 newdc
->w
.hPen
= dc
->w
.hPen
;
404 newdc
->w
.hBrush
= dc
->w
.hBrush
;
405 newdc
->w
.hFont
= dc
->w
.hFont
;
406 newdc
->w
.hBitmap
= dc
->w
.hBitmap
;
407 newdc
->w
.hFirstBitmap
= dc
->w
.hFirstBitmap
;
408 newdc
->w
.hDevice
= dc
->w
.hDevice
;
409 newdc
->w
.hPalette
= dc
->w
.hPalette
;
410 newdc
->w
.bitsPerPixel
= dc
->w
.bitsPerPixel
;
411 newdc
->w
.ROPmode
= dc
->w
.ROPmode
;
412 newdc
->w
.polyFillMode
= dc
->w
.polyFillMode
;
413 newdc
->w
.stretchBltMode
= dc
->w
.stretchBltMode
;
414 newdc
->w
.relAbsMode
= dc
->w
.relAbsMode
;
415 newdc
->w
.backgroundMode
= dc
->w
.backgroundMode
;
416 newdc
->w
.backgroundColor
= dc
->w
.backgroundColor
;
417 newdc
->w
.textColor
= dc
->w
.textColor
;
418 newdc
->w
.backgroundPixel
= dc
->w
.backgroundPixel
;
419 newdc
->w
.textPixel
= dc
->w
.textPixel
;
420 newdc
->w
.brushOrgX
= dc
->w
.brushOrgX
;
421 newdc
->w
.brushOrgY
= dc
->w
.brushOrgY
;
422 newdc
->w
.textAlign
= dc
->w
.textAlign
;
423 newdc
->w
.charExtra
= dc
->w
.charExtra
;
424 newdc
->w
.breakTotalExtra
= dc
->w
.breakTotalExtra
;
425 newdc
->w
.breakCount
= dc
->w
.breakCount
;
426 newdc
->w
.breakExtra
= dc
->w
.breakExtra
;
427 newdc
->w
.breakRem
= dc
->w
.breakRem
;
428 newdc
->w
.MapMode
= dc
->w
.MapMode
;
429 newdc
->w
.DCOrgX
= dc
->w
.DCOrgX
;
430 newdc
->w
.DCOrgY
= dc
->w
.DCOrgY
;
431 newdc
->w
.CursPosX
= dc
->w
.CursPosX
;
432 newdc
->w
.CursPosY
= dc
->w
.CursPosY
;
433 newdc
->wndOrgX
= dc
->wndOrgX
;
434 newdc
->wndOrgY
= dc
->wndOrgY
;
435 newdc
->wndExtX
= dc
->wndExtX
;
436 newdc
->wndExtY
= dc
->wndExtY
;
437 newdc
->vportOrgX
= dc
->vportOrgX
;
438 newdc
->vportOrgY
= dc
->vportOrgY
;
439 newdc
->vportExtX
= dc
->vportExtX
;
440 newdc
->vportExtY
= dc
->vportExtY
;
442 newdc
->hSelf
= (HDC32
)handle
;
443 newdc
->saveLevel
= 0;
445 newdc
->w
.hGCClipRgn
= 0;
446 newdc
->w
.hVisRgn
= CreateRectRgn32( 0, 0, 0, 0 );
447 CombineRgn32( newdc
->w
.hVisRgn
, dc
->w
.hVisRgn
, 0, RGN_COPY
);
450 newdc
->w
.hClipRgn
= CreateRectRgn32( 0, 0, 0, 0 );
451 CombineRgn32( newdc
->w
.hClipRgn
, dc
->w
.hClipRgn
, 0, RGN_COPY
);
454 newdc
->w
.hClipRgn
= 0;
455 GDI_HEAP_UNLOCK( handle
);
456 GDI_HEAP_UNLOCK( hdc
);
461 /***********************************************************************
462 * SetDCState (GDI.180)
464 void WINAPI
SetDCState( HDC16 hdc
, HDC16 hdcs
)
468 if (!(dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
))) return;
469 if (!(dcs
= (DC
*) GDI_GetObjPtr( hdcs
, DC_MAGIC
)))
471 GDI_HEAP_UNLOCK( hdc
);
474 if (!dcs
->w
.flags
& DC_SAVED
)
476 GDI_HEAP_UNLOCK( hdc
);
477 GDI_HEAP_UNLOCK( hdcs
);
480 dprintf_dc(stddeb
, "SetDCState: %04x %04x\n", hdc
, hdcs
);
482 dc
->w
.flags
= dcs
->w
.flags
& ~DC_SAVED
;
483 dc
->w
.devCaps
= dcs
->w
.devCaps
;
484 dc
->w
.hFirstBitmap
= dcs
->w
.hFirstBitmap
;
485 dc
->w
.hDevice
= dcs
->w
.hDevice
;
486 dc
->w
.ROPmode
= dcs
->w
.ROPmode
;
487 dc
->w
.polyFillMode
= dcs
->w
.polyFillMode
;
488 dc
->w
.stretchBltMode
= dcs
->w
.stretchBltMode
;
489 dc
->w
.relAbsMode
= dcs
->w
.relAbsMode
;
490 dc
->w
.backgroundMode
= dcs
->w
.backgroundMode
;
491 dc
->w
.backgroundColor
= dcs
->w
.backgroundColor
;
492 dc
->w
.textColor
= dcs
->w
.textColor
;
493 dc
->w
.backgroundPixel
= dcs
->w
.backgroundPixel
;
494 dc
->w
.textPixel
= dcs
->w
.textPixel
;
495 dc
->w
.brushOrgX
= dcs
->w
.brushOrgX
;
496 dc
->w
.brushOrgY
= dcs
->w
.brushOrgY
;
497 dc
->w
.textAlign
= dcs
->w
.textAlign
;
498 dc
->w
.charExtra
= dcs
->w
.charExtra
;
499 dc
->w
.breakTotalExtra
= dcs
->w
.breakTotalExtra
;
500 dc
->w
.breakCount
= dcs
->w
.breakCount
;
501 dc
->w
.breakExtra
= dcs
->w
.breakExtra
;
502 dc
->w
.breakRem
= dcs
->w
.breakRem
;
503 dc
->w
.MapMode
= dcs
->w
.MapMode
;
504 dc
->w
.DCOrgX
= dcs
->w
.DCOrgX
;
505 dc
->w
.DCOrgY
= dcs
->w
.DCOrgY
;
506 dc
->w
.CursPosX
= dcs
->w
.CursPosX
;
507 dc
->w
.CursPosY
= dcs
->w
.CursPosY
;
509 dc
->wndOrgX
= dcs
->wndOrgX
;
510 dc
->wndOrgY
= dcs
->wndOrgY
;
511 dc
->wndExtX
= dcs
->wndExtX
;
512 dc
->wndExtY
= dcs
->wndExtY
;
513 dc
->vportOrgX
= dcs
->vportOrgX
;
514 dc
->vportOrgY
= dcs
->vportOrgY
;
515 dc
->vportExtX
= dcs
->vportExtX
;
516 dc
->vportExtY
= dcs
->vportExtY
;
518 if (!(dc
->w
.flags
& DC_MEMORY
)) dc
->w
.bitsPerPixel
= dcs
->w
.bitsPerPixel
;
519 CombineRgn32( dc
->w
.hVisRgn
, dcs
->w
.hVisRgn
, 0, RGN_COPY
);
520 SelectClipRgn32( hdc
, dcs
->w
.hClipRgn
);
521 SelectObject32( hdc
, dcs
->w
.hBitmap
);
522 SelectObject32( hdc
, dcs
->w
.hBrush
);
523 SelectObject32( hdc
, dcs
->w
.hFont
);
524 SelectObject32( hdc
, dcs
->w
.hPen
);
525 GDISelectPalette( hdc
, dcs
->w
.hPalette
, FALSE
);
526 GDI_HEAP_UNLOCK( hdc
);
527 GDI_HEAP_UNLOCK( hdcs
);
531 /***********************************************************************
534 INT16 WINAPI
SaveDC16( HDC16 hdc
)
536 return (INT16
)SaveDC32( hdc
);
540 /***********************************************************************
541 * SaveDC32 (GDI32.292)
543 INT32 WINAPI
SaveDC32( HDC32 hdc
)
549 dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
552 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
554 MF_MetaParam0(dc
, META_SAVEDC
);
555 GDI_HEAP_UNLOCK( hdc
);
558 if (!(hdcs
= GetDCState( hdc
)))
560 GDI_HEAP_UNLOCK( hdc
);
563 dcs
= (DC
*) GDI_HEAP_LOCK( hdcs
);
564 dcs
->header
.hNext
= dc
->header
.hNext
;
565 dc
->header
.hNext
= hdcs
;
566 dprintf_dc(stddeb
, "SaveDC(%04x): returning %d\n", hdc
, dc
->saveLevel
+1 );
567 ret
= ++dc
->saveLevel
;
568 GDI_HEAP_UNLOCK( hdcs
);
569 GDI_HEAP_UNLOCK( hdc
);
574 /***********************************************************************
575 * RestoreDC16 (GDI.39)
577 BOOL16 WINAPI
RestoreDC16( HDC16 hdc
, INT16 level
)
579 return RestoreDC32( hdc
, level
);
583 /***********************************************************************
584 * RestoreDC32 (GDI32.290)
586 BOOL32 WINAPI
RestoreDC32( HDC32 hdc
, INT32 level
)
590 dprintf_dc(stddeb
, "RestoreDC: %04x %d\n", hdc
, level
);
591 dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
594 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
595 if (!dc
) return FALSE
;
598 GDI_HEAP_UNLOCK( hdc
);
601 MF_MetaParam1(dc
, META_RESTOREDC
, level
);
602 GDI_HEAP_UNLOCK( hdc
);
605 if (level
== -1) level
= dc
->saveLevel
;
606 if ((level
< 1) || (level
> dc
->saveLevel
))
608 GDI_HEAP_UNLOCK( hdc
);
612 while (dc
->saveLevel
>= level
)
614 HDC16 hdcs
= dc
->header
.hNext
;
615 if (!(dcs
= (DC
*) GDI_GetObjPtr( hdcs
, DC_MAGIC
)))
617 GDI_HEAP_UNLOCK( hdc
);
620 dc
->header
.hNext
= dcs
->header
.hNext
;
621 if (--dc
->saveLevel
< level
) SetDCState( hdc
, hdcs
);
624 GDI_HEAP_UNLOCK( hdc
);
629 /***********************************************************************
630 * CreateDC16 (GDI.53)
632 HDC16 WINAPI
CreateDC16( LPCSTR driver
, LPCSTR device
, LPCSTR output
,
633 const DEVMODE16
*initData
)
636 const DC_FUNCTIONS
*funcs
;
638 if (!(funcs
= DRIVER_FindDriver( driver
))) return 0;
639 if (!(dc
= DC_AllocDC( funcs
))) return 0;
642 dprintf_dc(stddeb
, "CreateDC(%s %s %s): returning %04x\n",
643 driver
, device
, output
, dc
->hSelf
);
645 if (dc
->funcs
->pCreateDC
&&
646 !dc
->funcs
->pCreateDC( dc
, driver
, device
, output
, initData
))
648 dprintf_dc( stddeb
, "CreateDC: creation aborted by device\n" );
649 GDI_HEAP_FREE( dc
->hSelf
);
654 GDI_HEAP_UNLOCK( dc
->hSelf
);
659 /***********************************************************************
660 * CreateDC32A (GDI32.)
662 HDC32 WINAPI
CreateDC32A( LPCSTR driver
, LPCSTR device
, LPCSTR output
,
663 const DEVMODE32A
*initData
)
665 return CreateDC16( driver
, device
, output
, (const DEVMODE16
*)initData
);
669 /***********************************************************************
670 * CreateDC32W (GDI32.)
672 HDC32 WINAPI
CreateDC32W( LPCWSTR driver
, LPCWSTR device
, LPCWSTR output
,
673 const DEVMODE32W
*initData
)
675 LPSTR driverA
= HEAP_strdupWtoA( GetProcessHeap(), 0, driver
);
676 LPSTR deviceA
= HEAP_strdupWtoA( GetProcessHeap(), 0, device
);
677 LPSTR outputA
= HEAP_strdupWtoA( GetProcessHeap(), 0, output
);
678 HDC32 res
= CreateDC16( driverA
, deviceA
, outputA
,
679 (const DEVMODE16
*)initData
/*FIXME*/ );
680 HeapFree( GetProcessHeap(), 0, driverA
);
681 HeapFree( GetProcessHeap(), 0, deviceA
);
682 HeapFree( GetProcessHeap(), 0, outputA
);
687 /***********************************************************************
688 * CreateIC16 (GDI.153)
690 HDC16 WINAPI
CreateIC16( LPCSTR driver
, LPCSTR device
, LPCSTR output
,
691 const DEVMODE16
* initData
)
693 /* Nothing special yet for ICs */
694 return CreateDC16( driver
, device
, output
, initData
);
698 /***********************************************************************
699 * CreateIC32A (GDI32.49)
701 HDC32 WINAPI
CreateIC32A( LPCSTR driver
, LPCSTR device
, LPCSTR output
,
702 const DEVMODE32A
* initData
)
704 /* Nothing special yet for ICs */
705 return CreateDC32A( driver
, device
, output
, initData
);
709 /***********************************************************************
710 * CreateIC32W (GDI32.50)
712 HDC32 WINAPI
CreateIC32W( LPCWSTR driver
, LPCWSTR device
, LPCWSTR output
,
713 const DEVMODE32W
* initData
)
715 /* Nothing special yet for ICs */
716 return CreateDC32W( driver
, device
, output
, initData
);
720 /***********************************************************************
721 * CreateCompatibleDC16 (GDI.52)
723 HDC16 WINAPI
CreateCompatibleDC16( HDC16 hdc
)
725 return (HDC16
)CreateCompatibleDC32( hdc
);
729 /***********************************************************************
730 * CreateCompatibleDC32 (GDI32.31)
732 HDC32 WINAPI
CreateCompatibleDC32( HDC32 hdc
)
736 const DC_FUNCTIONS
*funcs
;
738 if ((origDC
= (DC
*)GDI_GetObjPtr( hdc
, DC_MAGIC
))) funcs
= origDC
->funcs
;
739 else funcs
= DRIVER_FindDriver( "DISPLAY" );
740 if (!funcs
) return 0;
742 if (!(dc
= DC_AllocDC( funcs
))) return 0;
744 dprintf_dc(stddeb
, "CreateCompatibleDC(%04x): returning %04x\n",
747 /* Create default bitmap */
748 if (!(hbitmap
= CreateBitmap32( 1, 1, 1, 1, NULL
)))
750 GDI_HEAP_FREE( dc
->hSelf
);
753 dc
->w
.flags
= DC_MEMORY
;
754 dc
->w
.bitsPerPixel
= 1;
755 dc
->w
.hBitmap
= hbitmap
;
756 dc
->w
.hFirstBitmap
= hbitmap
;
758 if (dc
->funcs
->pCreateDC
&&
759 !dc
->funcs
->pCreateDC( dc
, NULL
, NULL
, NULL
, NULL
))
761 dprintf_dc(stddeb
, "CreateCompatibleDC: creation aborted by device\n");
762 DeleteObject32( hbitmap
);
763 GDI_HEAP_FREE( dc
->hSelf
);
768 GDI_HEAP_UNLOCK( dc
->hSelf
);
773 /***********************************************************************
774 * DeleteDC16 (GDI.68)
776 BOOL16 WINAPI
DeleteDC16( HDC16 hdc
)
778 return DeleteDC32( hdc
);
782 /***********************************************************************
783 * DeleteDC32 (GDI32.67)
785 BOOL32 WINAPI
DeleteDC32( HDC32 hdc
)
787 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
788 if (!dc
) return FALSE
;
790 dprintf_dc(stddeb
, "DeleteDC: %04x\n", hdc
);
792 while (dc
->saveLevel
)
795 HDC16 hdcs
= dc
->header
.hNext
;
796 if (!(dcs
= (DC
*) GDI_GetObjPtr( hdcs
, DC_MAGIC
))) break;
797 dc
->header
.hNext
= dcs
->header
.hNext
;
802 if (!(dc
->w
.flags
& DC_SAVED
))
804 SelectObject32( hdc
, STOCK_BLACK_PEN
);
805 SelectObject32( hdc
, STOCK_WHITE_BRUSH
);
806 SelectObject32( hdc
, STOCK_SYSTEM_FONT
);
807 if (dc
->w
.flags
& DC_MEMORY
) DeleteObject32( dc
->w
.hFirstBitmap
);
808 if (dc
->funcs
->pDeleteDC
) dc
->funcs
->pDeleteDC(dc
);
811 if (dc
->w
.hClipRgn
) DeleteObject32( dc
->w
.hClipRgn
);
812 if (dc
->w
.hVisRgn
) DeleteObject32( dc
->w
.hVisRgn
);
813 if (dc
->w
.hGCClipRgn
) DeleteObject32( dc
->w
.hGCClipRgn
);
815 return GDI_FreeObject( hdc
);
819 /***********************************************************************
820 * ResetDC16 (GDI.376)
822 HDC16 WINAPI
ResetDC16( HDC16 hdc
, const DEVMODE16
*devmode
)
824 fprintf( stderr
, "ResetDC16: empty stub!\n" );
829 /***********************************************************************
830 * ResetDC32A (GDI32.287)
832 HDC32 WINAPI
ResetDC32A( HDC32 hdc
, const DEVMODE32A
*devmode
)
834 fprintf( stderr
, "ResetDC32A: empty stub!\n" );
839 /***********************************************************************
840 * ResetDC32W (GDI32.288)
842 HDC32 WINAPI
ResetDC32W( HDC32 hdc
, const DEVMODE32W
*devmode
)
844 fprintf( stderr
, "ResetDC32A: empty stub!\n" );
849 /***********************************************************************
850 * GetDeviceCaps16 (GDI.80)
852 INT16 WINAPI
GetDeviceCaps16( HDC16 hdc
, INT16 cap
)
854 return GetDeviceCaps32( hdc
, cap
);
858 /***********************************************************************
859 * GetDeviceCaps32 (GDI32.171)
861 INT32 WINAPI
GetDeviceCaps32( HDC32 hdc
, INT32 cap
)
863 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
868 if ((cap
< 0) || (cap
> sizeof(DeviceCaps
)-sizeof(WORD
)))
870 GDI_HEAP_UNLOCK( hdc
);
874 dprintf_dc(stddeb
, "GetDeviceCaps(%04x,%d): returning %d\n",
875 hdc
, cap
, *(WORD
*)(((char *)dc
->w
.devCaps
) + cap
) );
876 ret
= *(WORD
*)(((char *)dc
->w
.devCaps
) + cap
);
877 GDI_HEAP_UNLOCK( hdc
);
882 /***********************************************************************
883 * SetBkColor16 (GDI.1)
885 COLORREF WINAPI
SetBkColor16( HDC16 hdc
, COLORREF color
)
887 return SetBkColor32( hdc
, color
);
891 /***********************************************************************
892 * SetBkColor32 (GDI32.305)
894 COLORREF WINAPI
SetBkColor32( HDC32 hdc
, COLORREF color
)
897 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
900 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
901 if (!dc
) return 0x80000000;
902 MF_MetaParam2(dc
, META_SETBKCOLOR
, HIWORD(color
), LOWORD(color
));
903 GDI_HEAP_UNLOCK( hdc
);
907 oldColor
= dc
->w
.backgroundColor
;
908 dc
->w
.backgroundColor
= color
;
909 dc
->w
.backgroundPixel
= COLOR_ToPhysical( dc
, color
);
910 GDI_HEAP_UNLOCK( hdc
);
915 /***********************************************************************
916 * SetTextColor16 (GDI.9)
918 COLORREF WINAPI
SetTextColor16( HDC16 hdc
, COLORREF color
)
920 return SetTextColor32( hdc
, color
);
924 /***********************************************************************
925 * SetTextColor32 (GDI32.338)
927 COLORREF WINAPI
SetTextColor32( HDC32 hdc
, COLORREF color
)
930 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
933 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
934 if (!dc
) return 0x80000000;
935 MF_MetaParam2(dc
, META_SETTEXTCOLOR
, HIWORD(color
), LOWORD(color
));
936 GDI_HEAP_UNLOCK( hdc
);
940 oldColor
= dc
->w
.textColor
;
941 dc
->w
.textColor
= color
;
942 dc
->w
.textPixel
= COLOR_ToPhysical( dc
, color
);
943 GDI_HEAP_UNLOCK( hdc
);
948 /***********************************************************************
949 * SetTextAlign16 (GDI.346)
951 UINT16 WINAPI
SetTextAlign16( HDC16 hdc
, UINT16 textAlign
)
953 return SetTextAlign32( hdc
, textAlign
);
957 /***********************************************************************
958 * SetTextAlign32 (GDI32.336)
960 UINT32 WINAPI
SetTextAlign32( HDC32 hdc
, UINT32 textAlign
)
963 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
966 if (!(dc
= (DC
*)GDI_GetObjPtr( hdc
, METAFILE_DC_MAGIC
))) return 0;
967 MF_MetaParam1( dc
, META_SETTEXTALIGN
, textAlign
);
968 GDI_HEAP_UNLOCK( hdc
);
971 prevAlign
= dc
->w
.textAlign
;
972 dc
->w
.textAlign
= textAlign
;
973 GDI_HEAP_UNLOCK( hdc
);
978 /***********************************************************************
979 * GetDCOrgEx (GDI32.168)
981 BOOL32 WINAPI
GetDCOrgEx( HDC32 hDC
, LPPOINT32 lpp
)
984 if (!lpp
) return FALSE
;
985 if (!(dc
= (DC
*) GDI_GetObjPtr( hDC
, DC_MAGIC
))) return FALSE
;
987 if (!(dc
->w
.flags
& DC_MEMORY
))
990 int w
, h
, border
, depth
;
991 /* FIXME: this is not correct for managed windows */
992 XGetGeometry( display
, dc
->u
.x
.drawable
, &root
,
993 &lpp
->x
, &lpp
->y
, &w
, &h
, &border
, &depth
);
995 else lpp
->x
= lpp
->y
= 0;
996 lpp
->x
+= dc
->w
.DCOrgX
; lpp
->y
+= dc
->w
.DCOrgY
;
997 GDI_HEAP_UNLOCK( hDC
);
1002 /***********************************************************************
1005 DWORD WINAPI
GetDCOrg( HDC16 hdc
)
1008 if( GetDCOrgEx( hdc
, &pt
) )
1009 return MAKELONG( (WORD
)pt
.x
, (WORD
)pt
.y
);
1014 /***********************************************************************
1015 * SetDCOrg (GDI.117)
1017 DWORD WINAPI
SetDCOrg( HDC16 hdc
, INT16 x
, INT16 y
)
1020 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
1022 prevOrg
= dc
->w
.DCOrgX
| (dc
->w
.DCOrgY
<< 16);
1025 GDI_HEAP_UNLOCK( hdc
);
1030 /***********************************************************************
1031 * SetDCHook (GDI.190)
1033 BOOL16 WINAPI
SetDCHook( HDC16 hdc
, FARPROC16 hookProc
, DWORD dwHookData
)
1035 DC
*dc
= (DC
*)GDI_GetObjPtr( hdc
, DC_MAGIC
);
1037 dprintf_dc( stddeb
, "SetDCHook: hookProc %08x, default is %08x\n",
1038 (UINT32
)hookProc
, (UINT32
)DCHook
);
1040 if (!dc
) return FALSE
;
1041 dc
->hookProc
= hookProc
;
1042 dc
->dwHookData
= dwHookData
;
1043 GDI_HEAP_UNLOCK( hdc
);
1048 /***********************************************************************
1049 * GetDCHook (GDI.191)
1051 DWORD WINAPI
GetDCHook( HDC16 hdc
, FARPROC16
*phookProc
)
1053 DC
*dc
= (DC
*)GDI_GetObjPtr( hdc
, DC_MAGIC
);
1055 *phookProc
= dc
->hookProc
;
1056 GDI_HEAP_UNLOCK( hdc
);
1057 return dc
->dwHookData
;
1061 /***********************************************************************
1062 * SetHookFlags (GDI.192)
1064 WORD WINAPI
SetHookFlags(HDC16 hDC
, WORD flags
)
1066 DC
* dc
= (DC
*)GDI_GetObjPtr( hDC
, DC_MAGIC
);
1070 WORD wRet
= dc
->w
.flags
& DC_DIRTY
;
1072 /* "Undocumented Windows" info is slightly
1076 dprintf_dc(stddeb
,"SetHookFlags: hDC %04x, flags %04x\n",hDC
,flags
);
1078 if( flags
& DCHF_INVALIDATEVISRGN
)
1079 dc
->w
.flags
|= DC_DIRTY
;
1080 else if( flags
& DCHF_VALIDATEVISRGN
|| !flags
)
1081 dc
->w
.flags
&= ~DC_DIRTY
;
1082 GDI_HEAP_UNLOCK( hDC
);