2 * GDI Device Context functions
4 * Copyright 1993 Alexandre Julliard
7 static char Copyright
[] = "Copyright Alexandre Julliard, 1993";
13 extern HBITMAP BITMAP_hbitmapMemDC
;
15 static DeviceCaps
* displayDevCaps
= NULL
;
17 extern const WIN_DC_INFO DCVAL_defaultValues
;
19 extern void CLIPPING_SetDeviceClipping( DC
* dc
); /* in objects/clipping.c */
22 /* ROP code to GC function conversion */
23 const int DC_XROPfunction
[16] =
25 GXclear
, /* R2_BLACK */
26 GXnor
, /* R2_NOTMERGEPEN */
27 GXandInverted
, /* R2_MASKNOTPEN */
28 GXcopyInverted
, /* R2_NOTCOPYPEN */
29 GXandReverse
, /* R2_MASKPENNOT */
30 GXinvert
, /* R2_NOT */
31 GXxor
, /* R2_XORPEN */
32 GXnand
, /* R2_NOTMASKPEN */
33 GXand
, /* R2_MASKPEN */
34 GXequiv
, /* R2_NOTXORPEN */
36 GXorInverted
, /* R2_MERGENOTPEN */
37 GXcopy
, /* R2_COPYPEN */
38 GXorReverse
, /* R2_MERGEPENNOT */
39 GXor
, /* R2_MERGEPEN */
44 /***********************************************************************
47 * Fill the device caps structure.
49 void DC_FillDevCaps( DeviceCaps
* caps
)
51 caps
->version
= 0x300;
52 caps
->technology
= DT_RASDISPLAY
;
53 caps
->horzSize
= WidthMMOfScreen( XT_screen
);
54 caps
->vertSize
= HeightMMOfScreen( XT_screen
);
55 caps
->horzRes
= WidthOfScreen( XT_screen
);
56 caps
->vertRes
= HeightOfScreen( XT_screen
);
57 caps
->bitsPixel
= DefaultDepthOfScreen( XT_screen
);
63 caps
->numColors
= 1 << caps
->bitsPixel
;
64 caps
->pdeviceSize
= 0;
65 caps
->curveCaps
= CC_CIRCLES
| CC_PIE
| CC_CHORD
| CC_ELLIPSES
|
66 CC_WIDE
| CC_STYLED
| CC_WIDESTYLED
|
67 CC_INTERIORS
| CC_ROUNDRECT
;
68 caps
->lineCaps
= LC_POLYLINE
| LC_MARKER
| LC_POLYMARKER
| LC_WIDE
|
69 LC_STYLED
| LC_WIDESTYLED
| LC_INTERIORS
;
70 caps
->polygonalCaps
= PC_POLYGON
| PC_RECTANGLE
| PC_WINDPOLYGON
|
71 PC_SCANLINE
| PC_WIDE
| PC_STYLED
|
72 PC_WIDESTYLED
| PC_INTERIORS
;
73 caps
->textCaps
= TC_OP_CHARACTER
| TC_OP_STROKE
| TC_CP_STROKE
|
74 TC_IA_ABLE
| TC_UA_ABLE
| TC_SO_ABLE
| TC_RA_ABLE
;
75 caps
->clipCaps
= CP_REGION
;
76 caps
->rasterCaps
= RC_BITBLT
| RC_BANDING
| RC_SCALING
| RC_BITMAP64
|
77 RC_DI_BITMAP
| RC_PALETTE
| RC_DIBTODEV
| RC_BIGFONT
|
78 RC_STRETCHBLT
| RC_STRETCHDIB
| RC_DEVBITS
;
79 caps
->aspectX
= 36; /* ?? */
80 caps
->aspectY
= 36; /* ?? */
82 caps
->logPixelsX
= (int)(caps
->horzRes
* 25.4 / caps
->horzSize
);
83 caps
->logPixelsY
= (int)(caps
->vertRes
* 25.4 / caps
->vertSize
);
84 caps
->sizePalette
= DefaultVisual( XT_display
, DefaultScreen(XT_display
) )->map_entries
;
85 caps
->numReserved
= 0;
90 /***********************************************************************
93 * Set device-specific info from device-independent info.
95 void DC_SetDeviceInfo( HDC hdc
, DC
* dc
)
97 SetTextColor( hdc
, dc
->w
.textColor
);
98 SetBkColor( hdc
, dc
->w
.backgroundColor
);
99 SetROP2( hdc
, dc
->w
.ROPmode
);
100 SelectObject( hdc
, dc
->w
.hPen
);
101 SelectObject( hdc
, dc
->w
.hBrush
);
102 SelectObject( hdc
, dc
->w
.hFont
);
104 XSetGraphicsExposures( XT_display
, dc
->u
.x
.gc
, False
);
105 CLIPPING_SetDeviceClipping( dc
);
109 /***********************************************************************
112 * Setup dc->u.x.gc for drawing operations using current brush.
113 * Return 0 if brush is BS_NULL, 1 otherwise.
115 int DC_SetupGCForBrush( DC
* dc
)
117 if (dc
->u
.x
.brush
.style
== BS_NULL
) return 0;
118 if (dc
->u
.x
.brush
.pixel
== -1)
120 /* Special case used for monochrome pattern brushes.
121 * We need to swap foreground and background because
122 * Windows does it the wrong way...
124 XSetForeground( XT_display
, dc
->u
.x
.gc
, dc
->w
.backgroundPixel
);
125 XSetBackground( XT_display
, dc
->u
.x
.gc
, dc
->w
.textPixel
);
129 XSetForeground( XT_display
, dc
->u
.x
.gc
, dc
->u
.x
.brush
.pixel
);
130 XSetBackground( XT_display
, dc
->u
.x
.gc
, dc
->w
.backgroundPixel
);
133 if (dc
->u
.x
.brush
.fillStyle
!= FillStippled
)
134 XSetFillStyle( XT_display
, dc
->u
.x
.gc
, dc
->u
.x
.brush
.fillStyle
);
136 XSetFillStyle( XT_display
, dc
->u
.x
.gc
,
137 (dc
->w
.backgroundMode
== OPAQUE
) ?
138 FillOpaqueStippled
: FillStippled
);
139 XSetTSOrigin( XT_display
, dc
->u
.x
.gc
, dc
->w
.DCOrgX
+ dc
->w
.brushOrgX
,
140 dc
->w
.DCOrgY
+ dc
->w
.brushOrgY
);
141 XSetFunction( XT_display
, dc
->u
.x
.gc
, DC_XROPfunction
[dc
->w
.ROPmode
-1] );
142 XSetFillRule( XT_display
, dc
->u
.x
.gc
,
143 (dc
->w
.polyFillMode
== WINDING
) ? WindingRule
: EvenOddRule
);
148 /***********************************************************************
151 * Setup dc->u.x.gc for drawing operations using current pen.
152 * Return 0 if pen is PS_NULL, 1 otherwise.
154 int DC_SetupGCForPen( DC
* dc
)
156 if (dc
->u
.x
.pen
.style
== PS_NULL
) return 0;
157 XSetForeground( XT_display
, dc
->u
.x
.gc
, dc
->u
.x
.pen
.pixel
);
158 XSetBackground( XT_display
, dc
->u
.x
.gc
, dc
->w
.backgroundPixel
);
159 XSetFillStyle( XT_display
, dc
->u
.x
.gc
, FillSolid
);
160 if ((dc
->u
.x
.pen
.style
== PS_SOLID
) ||
161 (dc
->u
.x
.pen
.style
== PS_INSIDEFRAME
))
163 XSetLineAttributes( XT_display
, dc
->u
.x
.gc
, dc
->u
.x
.pen
.width
,
164 LineSolid
, CapRound
, JoinBevel
);
168 XSetLineAttributes( XT_display
, dc
->u
.x
.gc
, dc
->u
.x
.pen
.width
,
169 (dc
->w
.backgroundMode
== OPAQUE
) ? LineDoubleDash
: LineOnOffDash
,
170 CapRound
, JoinBevel
);
172 XSetFunction( XT_display
, dc
->u
.x
.gc
, DC_XROPfunction
[dc
->w
.ROPmode
-1] );
177 /***********************************************************************
180 * Setup dc->u.x.gc for text drawing operations.
181 * Return 0 if the font is null, 1 otherwise.
183 int DC_SetupGCForText( DC
* dc
)
185 XSetForeground( XT_display
, dc
->u
.x
.gc
, dc
->w
.textPixel
);
186 XSetBackground( XT_display
, dc
->u
.x
.gc
, dc
->w
.backgroundPixel
);
187 XSetFillStyle( XT_display
, dc
->u
.x
.gc
, FillSolid
);
188 XSetFunction( XT_display
, dc
->u
.x
.gc
, DC_XROPfunction
[dc
->w
.ROPmode
-1] );
189 if (!dc
->u
.x
.font
.fstruct
) return 0;
190 XSetFont( XT_display
, dc
->u
.x
.gc
, dc
->u
.x
.font
.fstruct
->fid
);
195 /***********************************************************************
196 * GetDCState (GDI.179)
198 HDC
GetDCState( HDC hdc
)
203 if (!(dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
))) return 0;
204 if (!(handle
= GDI_AllocObject( sizeof(DC
), DC_MAGIC
))) return 0;
205 newdc
= (DC
*) GDI_HEAP_ADDR( handle
);
208 printf( "GetDCState(%d): returning %d\n", hdc
, handle
);
211 memcpy( &newdc
->w
, &dc
->w
, sizeof(dc
->w
) );
212 newdc
->saveLevel
= 0;
213 newdc
->w
.flags
|= DC_SAVED
;
217 newdc
->w
.hClipRgn
= CreateRectRgn( 0, 0, 0, 0 );
218 CombineRgn( newdc
->w
.hClipRgn
, dc
->w
.hClipRgn
, 0, RGN_COPY
);
222 newdc
->w
.hVisRgn
= CreateRectRgn( 0, 0, 0, 0 );
223 CombineRgn( newdc
->w
.hVisRgn
, dc
->w
.hVisRgn
, 0, RGN_COPY
);
225 newdc
->w
.hGCClipRgn
= 0;
230 /***********************************************************************
231 * SetDCState (GDI.180)
233 void SetDCState( HDC hdc
, HDC hdcs
)
237 if (!(dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
))) return;
238 if (!(dcs
= (DC
*) GDI_GetObjPtr( hdcs
, DC_MAGIC
))) return;
239 if (!dcs
->w
.flags
& DC_SAVED
) return;
241 printf( "SetDCState: %d %d\n", hdc
, hdcs
);
243 if (dc
->w
.hClipRgn
) DeleteObject( dc
->w
.hClipRgn
);
244 if (dc
->w
.hVisRgn
) DeleteObject( dc
->w
.hVisRgn
);
245 if (dc
->w
.hGCClipRgn
) DeleteObject( dc
->w
.hGCClipRgn
);
246 memcpy( &dc
->w
, &dcs
->w
, sizeof(dc
->w
) );
247 dc
->w
.hClipRgn
= dc
->w
.hVisRgn
= dc
->w
.hGCClipRgn
= 0;
248 dc
->w
.flags
&= ~DC_SAVED
;
249 DC_SetDeviceInfo( hdc
, dc
);
250 SelectClipRgn( hdc
, dcs
->w
.hClipRgn
);
251 SelectVisRgn( hdc
, dcs
->w
.hVisRgn
);
255 /***********************************************************************
258 int SaveDC( HDC hdc
)
263 if (!(dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
))) return 0;
264 if (!(hdcs
= GetDCState( hdc
))) return 0;
265 dcs
= (DC
*) GDI_HEAP_ADDR( hdcs
);
266 dcs
->header
.hNext
= dc
->header
.hNext
;
267 dc
->header
.hNext
= hdcs
;
269 printf( "SaveDC(%d): returning %d\n", hdc
, dc
->saveLevel
+1 );
271 return ++dc
->saveLevel
;
275 /***********************************************************************
278 BOOL
RestoreDC( HDC hdc
, short level
)
283 printf( "RestoreDC: %d %d\n", hdc
, level
);
285 if (!(dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
))) return FALSE
;
286 if (level
== -1) level
= dc
->saveLevel
;
287 if ((level
< 1) || (level
> dc
->saveLevel
)) return FALSE
;
289 while (dc
->saveLevel
>= level
)
291 HDC hdcs
= dc
->header
.hNext
;
292 if (!(dcs
= (DC
*) GDI_GetObjPtr( hdcs
, DC_MAGIC
))) return FALSE
;
293 dc
->header
.hNext
= dcs
->header
.hNext
;
294 if (--dc
->saveLevel
< level
) SetDCState( hdc
, hdcs
);
301 /***********************************************************************
304 HDC
CreateDC( LPSTR driver
, LPSTR device
, LPSTR output
, LPSTR initData
)
309 handle
= GDI_AllocObject( sizeof(DC
), DC_MAGIC
);
310 if (!handle
) return 0;
311 dc
= (DC
*) GDI_HEAP_ADDR( handle
);
314 printf( "CreateDC(%s %s %s): returning %d\n", driver
, device
, output
, handle
);
319 displayDevCaps
= (DeviceCaps
*) malloc( sizeof(DeviceCaps
) );
320 DC_FillDevCaps( displayDevCaps
);
324 memcpy( &dc
->w
, &DCVAL_defaultValues
, sizeof(DCVAL_defaultValues
) );
325 memset( &dc
->u
.x
, 0, sizeof(dc
->u
.x
) );
327 dc
->u
.x
.drawable
= DefaultRootWindow( XT_display
);
328 dc
->u
.x
.gc
= XCreateGC( XT_display
, dc
->u
.x
.drawable
, 0, NULL
);
330 dc
->w
.devCaps
= displayDevCaps
;
331 dc
->w
.planes
= displayDevCaps
->planes
;
332 dc
->w
.bitsPerPixel
= displayDevCaps
->bitsPixel
;
333 dc
->w
.DCSizeX
= displayDevCaps
->horzRes
;
334 dc
->w
.DCSizeY
= displayDevCaps
->vertRes
;
336 DC_SetDeviceInfo( handle
, dc
);
342 /***********************************************************************
343 * CreateCompatibleDC (GDI.52)
345 HDC
CreateCompatibleDC( HDC hdc
)
350 handle
= GDI_AllocObject( sizeof(DC
), DC_MAGIC
);
351 if (!handle
) return 0;
352 dc
= (DC
*) GDI_HEAP_ADDR( handle
);
355 printf( "CreateCompatibleDC(%d): returning %d\n", hdc
, handle
);
359 memcpy( &dc
->w
, &DCVAL_defaultValues
, sizeof(DCVAL_defaultValues
) );
360 memset( &dc
->u
.x
, 0, sizeof(dc
->u
.x
) );
362 dc
->u
.x
.drawable
= XCreatePixmap( XT_display
,
363 DefaultRootWindow( XT_display
),
365 dc
->u
.x
.gc
= XCreateGC( XT_display
, dc
->u
.x
.drawable
, 0, NULL
);
366 dc
->w
.flags
= DC_MEMORY
;
368 dc
->w
.bitsPerPixel
= 1;
369 dc
->w
.devCaps
= displayDevCaps
;
373 SelectObject( handle
, BITMAP_hbitmapMemDC
);
374 DC_SetDeviceInfo( handle
, dc
);
380 /***********************************************************************
383 BOOL
DeleteDC( HDC hdc
)
385 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
386 if (!dc
) return FALSE
;
389 printf( "DeleteDC: %d\n", hdc
);
392 while (dc
->saveLevel
)
395 HDC hdcs
= dc
->header
.hNext
;
396 if (!(dcs
= (DC
*) GDI_GetObjPtr( hdcs
, DC_MAGIC
))) break;
397 dc
->header
.hNext
= dcs
->header
.hNext
;
402 if (!(dc
->w
.flags
& DC_SAVED
))
404 SelectObject( hdc
, STOCK_BLACK_PEN
);
405 SelectObject( hdc
, STOCK_WHITE_BRUSH
);
406 SelectObject( hdc
, STOCK_SYSTEM_FONT
);
408 XFreeGC( XT_display
, dc
->u
.x
.gc
);
409 if (dc
->w
.flags
& DC_MEMORY
) BITMAP_UnselectBitmap( dc
);
412 if (dc
->w
.hClipRgn
) DeleteObject( dc
->w
.hClipRgn
);
413 if (dc
->w
.hVisRgn
) DeleteObject( dc
->w
.hVisRgn
);
414 if (dc
->w
.hGCClipRgn
) DeleteObject( dc
->w
.hGCClipRgn
);
416 return GDI_FreeObject( hdc
);
420 /***********************************************************************
421 * GetDeviceCaps (GDI.80)
423 int GetDeviceCaps( HDC hdc
, WORD cap
)
425 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
428 if (cap
> sizeof(DeviceCaps
)-sizeof(WORD
)) return 0;
431 printf( "GetDeviceCaps(%d,%d): returning %d\n",
432 hdc
, cap
, *(WORD
*)(((char *)dc
->w
.devCaps
) + cap
) );
434 return *(WORD
*)(((char *)dc
->w
.devCaps
) + cap
);
438 /***********************************************************************
441 COLORREF
SetBkColor( HDC hdc
, COLORREF color
)
444 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
445 if (!dc
) return 0x80000000;
447 oldColor
= dc
->w
.backgroundColor
;
448 dc
->w
.backgroundColor
= color
;
449 dc
->w
.backgroundPixel
= GetNearestPaletteIndex( dc
->w
.hPalette
, color
);
450 XSetBackground( XT_display
, dc
->u
.x
.gc
, dc
->w
.backgroundPixel
);
455 /***********************************************************************
456 * SetTextColor (GDI.9)
458 COLORREF
SetTextColor( HDC hdc
, COLORREF color
)
461 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
462 if (!dc
) return 0x80000000;
464 oldColor
= dc
->w
.textColor
;
465 dc
->w
.textColor
= color
;
466 dc
->w
.textPixel
= GetNearestPaletteIndex( dc
->w
.hPalette
, color
);
467 XSetForeground( XT_display
, dc
->u
.x
.gc
, dc
->w
.textPixel
);
472 /***********************************************************************
475 DWORD
SetDCOrg( HDC hdc
, short x
, short y
)
478 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
480 prevOrg
= dc
->w
.DCOrgX
| (dc
->w
.DCOrgY
<< 16);