2 * GDI Device Context functions
4 * Copyright 1993 Alexandre Julliard
7 static char Copyright
[] = "Copyright Alexandre Julliard, 1993";
14 static DeviceCaps
* displayDevCaps
= NULL
;
16 extern const WIN_DC_INFO DCVAL_defaultValues
;
18 extern void CLIPPING_SetDeviceClipping( DC
* dc
); /* objects/clipping.c */
19 extern WORD
COLOR_ToPhysical( DC
*dc
, COLORREF color
);/* objects/color.c */
20 extern void COLOR_SetMapping( DC
*dc
, HANDLE
, WORD
); /* objects/color.c */
23 /* ROP code to GC function conversion */
24 const int DC_XROPfunction
[16] =
26 GXclear
, /* R2_BLACK */
27 GXnor
, /* R2_NOTMERGEPEN */
28 GXandInverted
, /* R2_MASKNOTPEN */
29 GXcopyInverted
, /* R2_NOTCOPYPEN */
30 GXandReverse
, /* R2_MASKPENNOT */
31 GXinvert
, /* R2_NOT */
32 GXxor
, /* R2_XORPEN */
33 GXnand
, /* R2_NOTMASKPEN */
34 GXand
, /* R2_MASKPEN */
35 GXequiv
, /* R2_NOTXORPEN */
37 GXorInverted
, /* R2_MERGENOTPEN */
38 GXcopy
, /* R2_COPYPEN */
39 GXorReverse
, /* R2_MERGEPENNOT */
40 GXor
, /* R2_MERGEPEN */
45 /***********************************************************************
48 * Fill the device caps structure.
50 void DC_FillDevCaps( DeviceCaps
* caps
)
52 caps
->version
= 0x300;
53 caps
->technology
= DT_RASDISPLAY
;
54 caps
->horzSize
= WidthMMOfScreen(screen
) * screenWidth
/ WidthOfScreen(screen
);
55 caps
->vertSize
= HeightMMOfScreen(screen
) * screenHeight
/ HeightOfScreen(screen
);
56 caps
->horzRes
= screenWidth
;
57 caps
->vertRes
= screenHeight
;
58 caps
->bitsPixel
= screenDepth
;
64 caps
->numColors
= 1 << caps
->bitsPixel
;
65 caps
->pdeviceSize
= 0;
66 caps
->curveCaps
= CC_CIRCLES
| CC_PIE
| CC_CHORD
| CC_ELLIPSES
|
67 CC_WIDE
| CC_STYLED
| CC_WIDESTYLED
|
68 CC_INTERIORS
| CC_ROUNDRECT
;
69 caps
->lineCaps
= LC_POLYLINE
| LC_MARKER
| LC_POLYMARKER
| LC_WIDE
|
70 LC_STYLED
| LC_WIDESTYLED
| LC_INTERIORS
;
71 caps
->polygonalCaps
= PC_POLYGON
| PC_RECTANGLE
| PC_WINDPOLYGON
|
72 PC_SCANLINE
| PC_WIDE
| PC_STYLED
|
73 PC_WIDESTYLED
| PC_INTERIORS
;
74 caps
->textCaps
= TC_OP_CHARACTER
| TC_OP_STROKE
| TC_CP_STROKE
|
75 TC_IA_ABLE
| TC_UA_ABLE
| TC_SO_ABLE
| TC_RA_ABLE
;
76 caps
->clipCaps
= CP_REGION
;
77 caps
->rasterCaps
= RC_BITBLT
| RC_BANDING
| RC_SCALING
| RC_BITMAP64
|
78 RC_DI_BITMAP
| RC_PALETTE
| RC_DIBTODEV
| RC_BIGFONT
|
79 RC_STRETCHBLT
| RC_STRETCHDIB
| RC_DEVBITS
;
80 caps
->aspectX
= 36; /* ?? */
81 caps
->aspectY
= 36; /* ?? */
83 caps
->logPixelsX
= (int)(caps
->horzRes
* 25.4 / caps
->horzSize
);
84 caps
->logPixelsY
= (int)(caps
->vertRes
* 25.4 / caps
->vertSize
);
85 caps
->sizePalette
= DefaultVisual(display
,DefaultScreen(display
))->map_entries
;
86 caps
->numReserved
= 0;
91 /***********************************************************************
94 * Setup device-specific DC values for a newly created DC.
96 static void DC_InitDC( HDC hdc
)
98 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
99 RealizeDefaultPalette( hdc
);
100 SetTextColor( hdc
, dc
->w
.textColor
);
101 SetBkColor( hdc
, dc
->w
.backgroundColor
);
102 SelectObject( hdc
, dc
->w
.hPen
);
103 SelectObject( hdc
, dc
->w
.hBrush
);
104 SelectObject( hdc
, dc
->w
.hFont
);
105 XSetGraphicsExposures( XT_display
, dc
->u
.x
.gc
, False
);
106 CLIPPING_SetDeviceClipping( dc
);
110 /***********************************************************************
113 * Setup dc->u.x.gc for drawing operations using current brush.
114 * Return 0 if brush is BS_NULL, 1 otherwise.
116 int DC_SetupGCForBrush( DC
* dc
)
119 unsigned long mask
= 0;
121 if (dc
->u
.x
.brush
.style
== BS_NULL
) return 0;
122 if (dc
->u
.x
.brush
.pixel
== -1)
124 /* Special case used for monochrome pattern brushes.
125 * We need to swap foreground and background because
126 * Windows does it the wrong way...
128 val
.foreground
= dc
->w
.backgroundPixel
;
129 val
.background
= dc
->w
.textPixel
;
133 val
.foreground
= dc
->u
.x
.brush
.pixel
;
134 val
.background
= dc
->w
.backgroundPixel
;
136 val
.function
= DC_XROPfunction
[dc
->w
.ROPmode
-1];
137 val
.fill_style
= dc
->u
.x
.brush
.fillStyle
;
138 if (val
.fill_style
== FillStippled
)
140 if (dc
->w
.backgroundMode
==OPAQUE
) val
.fill_style
= FillOpaqueStippled
;
141 val
.stipple
= dc
->u
.x
.brush
.pixmap
;
144 else if (val
.fill_style
== FillTiled
)
146 val
.tile
= dc
->u
.x
.brush
.pixmap
;
149 val
.ts_x_origin
= dc
->w
.DCOrgX
+ dc
->w
.brushOrgX
;
150 val
.ts_y_origin
= dc
->w
.DCOrgY
+ dc
->w
.brushOrgY
;
151 val
.fill_rule
= (dc
->w
.polyFillMode
==WINDING
) ? WindingRule
: EvenOddRule
;
152 XChangeGC( display
, dc
->u
.x
.gc
,
153 GCFunction
| GCForeground
| GCBackground
| GCFillStyle
|
154 GCFillRule
| GCTileStipXOrigin
| GCTileStipYOrigin
| mask
,
160 /***********************************************************************
163 * Setup dc->u.x.gc for drawing operations using current pen.
164 * Return 0 if pen is PS_NULL, 1 otherwise.
166 int DC_SetupGCForPen( DC
* dc
)
170 if (dc
->u
.x
.pen
.style
== PS_NULL
) return 0;
171 val
.function
= DC_XROPfunction
[dc
->w
.ROPmode
-1];
172 val
.foreground
= dc
->u
.x
.pen
.pixel
;
173 val
.background
= dc
->w
.backgroundPixel
;
174 val
.fill_style
= FillSolid
;
175 if ((dc
->u
.x
.pen
.style
!=PS_SOLID
) && (dc
->u
.x
.pen
.style
!=PS_INSIDEFRAME
))
177 XSetDashes( display
, dc
->u
.x
.gc
, 0,
178 dc
->u
.x
.pen
.dashes
, dc
->u
.x
.pen
.dash_len
);
179 val
.line_style
= (dc
->w
.backgroundMode
== OPAQUE
) ?
180 LineDoubleDash
: LineOnOffDash
;
182 else val
.line_style
= LineSolid
;
183 val
.line_width
= dc
->u
.x
.pen
.width
;
184 val
.cap_style
= CapRound
;
185 val
.join_style
= JoinBevel
;
186 XChangeGC( display
, dc
->u
.x
.gc
,
187 GCFunction
| GCForeground
| GCBackground
| GCLineWidth
|
188 GCLineStyle
| GCCapStyle
| GCJoinStyle
| GCFillStyle
, &val
);
193 /***********************************************************************
196 * Setup dc->u.x.gc for text drawing operations.
197 * Return 0 if the font is null, 1 otherwise.
199 int DC_SetupGCForText( DC
* dc
)
203 if (!dc
->u
.x
.font
.fstruct
)
205 FONT_SelectObject(dc
, STOCK_SYSTEM_FIXED_FONT
, NULL
);
207 val
.function
= DC_XROPfunction
[dc
->w
.ROPmode
-1];
208 val
.foreground
= dc
->w
.textPixel
;
209 val
.background
= dc
->w
.backgroundPixel
;
210 val
.fill_style
= FillSolid
;
211 val
.font
= dc
->u
.x
.font
.fstruct
->fid
;
212 XChangeGC( display
, dc
->u
.x
.gc
,
213 GCFunction
| GCForeground
| GCBackground
| GCFillStyle
|
219 /***********************************************************************
220 * GetDCState (GDI.179)
222 HDC
GetDCState( HDC hdc
)
227 if (!(dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
))) return 0;
228 if (!(handle
= GDI_AllocObject( sizeof(DC
), DC_MAGIC
))) return 0;
229 newdc
= (DC
*) GDI_HEAP_ADDR( handle
);
232 printf( "GetDCState(%d): returning %d\n", hdc
, handle
);
235 memcpy( &newdc
->w
, &dc
->w
, sizeof(dc
->w
) );
236 newdc
->saveLevel
= 0;
237 newdc
->w
.flags
|= DC_SAVED
;
241 newdc
->w
.hClipRgn
= CreateRectRgn( 0, 0, 0, 0 );
242 CombineRgn( newdc
->w
.hClipRgn
, dc
->w
.hClipRgn
, 0, RGN_COPY
);
246 newdc
->w
.hVisRgn
= CreateRectRgn( 0, 0, 0, 0 );
247 CombineRgn( newdc
->w
.hVisRgn
, dc
->w
.hVisRgn
, 0, RGN_COPY
);
249 newdc
->w
.hGCClipRgn
= 0;
250 COLOR_SetMapping( newdc
, dc
->u
.x
.pal
.hMapping
, dc
->u
.x
.pal
.mappingSize
);
255 /***********************************************************************
256 * SetDCState (GDI.180)
258 void SetDCState( HDC hdc
, HDC hdcs
)
262 if (!(dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
))) return;
263 if (!(dcs
= (DC
*) GDI_GetObjPtr( hdcs
, DC_MAGIC
))) return;
264 if (!dcs
->w
.flags
& DC_SAVED
) return;
266 printf( "SetDCState: %d %d\n", hdc
, hdcs
);
268 if (dc
->w
.hClipRgn
) DeleteObject( dc
->w
.hClipRgn
);
269 if (dc
->w
.hVisRgn
) DeleteObject( dc
->w
.hVisRgn
);
270 if (dc
->w
.hGCClipRgn
) DeleteObject( dc
->w
.hGCClipRgn
);
272 memcpy( &dc
->w
, &dcs
->w
, sizeof(dc
->w
) );
273 memcpy( &dc
->u
.x
.pen
, &dcs
->u
.x
.pen
, sizeof(dc
->u
.x
.pen
) );
274 dc
->w
.hClipRgn
= dc
->w
.hVisRgn
= dc
->w
.hGCClipRgn
= 0;
275 dc
->w
.flags
&= ~DC_SAVED
;
277 SelectObject( hdc
, dcs
->w
.hBrush
);
278 SelectObject( hdc
, dcs
->w
.hFont
);
279 COLOR_SetMapping( dc
, dcs
->u
.x
.pal
.hMapping
, dcs
->u
.x
.pal
.mappingSize
);
281 SelectClipRgn( hdc
, dcs
->w
.hClipRgn
);
282 SelectVisRgn( hdc
, dcs
->w
.hVisRgn
);
286 /***********************************************************************
289 int SaveDC( HDC hdc
)
294 if (!(dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
))) return 0;
295 if (!(hdcs
= GetDCState( hdc
))) return 0;
296 dcs
= (DC
*) GDI_HEAP_ADDR( hdcs
);
297 dcs
->header
.hNext
= dc
->header
.hNext
;
298 dc
->header
.hNext
= hdcs
;
300 printf( "SaveDC(%d): returning %d\n", hdc
, dc
->saveLevel
+1 );
302 return ++dc
->saveLevel
;
306 /***********************************************************************
309 BOOL
RestoreDC( HDC hdc
, short level
)
314 printf( "RestoreDC: %d %d\n", hdc
, level
);
316 if (!(dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
))) return FALSE
;
317 if (level
== -1) level
= dc
->saveLevel
;
318 if ((level
< 1) || (level
> (short)dc
->saveLevel
)) return FALSE
;
320 while ((short)dc
->saveLevel
>= level
)
322 HDC hdcs
= dc
->header
.hNext
;
323 if (!(dcs
= (DC
*) GDI_GetObjPtr( hdcs
, DC_MAGIC
))) return FALSE
;
324 dc
->header
.hNext
= dcs
->header
.hNext
;
325 if ((short)--dc
->saveLevel
< level
) SetDCState( hdc
, hdcs
);
332 /***********************************************************************
335 HDC
CreateDC( LPSTR driver
, LPSTR device
, LPSTR output
, LPSTR initData
)
340 handle
= GDI_AllocObject( sizeof(DC
), DC_MAGIC
);
341 if (!handle
) return 0;
342 dc
= (DC
*) GDI_HEAP_ADDR( handle
);
345 printf( "CreateDC(%s %s %s): returning %d\n", driver
, device
, output
, handle
);
350 displayDevCaps
= (DeviceCaps
*) malloc( sizeof(DeviceCaps
) );
351 DC_FillDevCaps( displayDevCaps
);
355 memcpy( &dc
->w
, &DCVAL_defaultValues
, sizeof(DCVAL_defaultValues
) );
356 memset( &dc
->u
.x
, 0, sizeof(dc
->u
.x
) );
358 dc
->u
.x
.drawable
= rootWindow
;
359 dc
->u
.x
.gc
= XCreateGC( display
, dc
->u
.x
.drawable
, 0, NULL
);
361 dc
->w
.devCaps
= displayDevCaps
;
362 dc
->w
.bitsPerPixel
= displayDevCaps
->bitsPixel
;
363 dc
->w
.DCSizeX
= displayDevCaps
->horzRes
;
364 dc
->w
.DCSizeY
= displayDevCaps
->vertRes
;
372 /***********************************************************************
375 HDC
CreateIC( LPSTR driver
, LPSTR device
, LPSTR output
, LPSTR initData
)
377 /* Nothing special yet for ICs */
378 return CreateDC( driver
, device
, output
, initData
);
382 /***********************************************************************
383 * CreateCompatibleDC (GDI.52)
385 HDC
CreateCompatibleDC( HDC hdc
)
390 handle
= GDI_AllocObject( sizeof(DC
), DC_MAGIC
);
391 if (!handle
) return 0;
392 dc
= (DC
*) GDI_HEAP_ADDR( handle
);
395 printf( "CreateCompatibleDC(%d): returning %d\n", hdc
, handle
);
399 memcpy( &dc
->w
, &DCVAL_defaultValues
, sizeof(DCVAL_defaultValues
) );
400 memset( &dc
->u
.x
, 0, sizeof(dc
->u
.x
) );
402 dc
->u
.x
.drawable
= XCreatePixmap( display
, rootWindow
, 1, 1, 1 );
403 dc
->u
.x
.gc
= XCreateGC( display
, dc
->u
.x
.drawable
, 0, NULL
);
404 dc
->w
.flags
= DC_MEMORY
;
405 dc
->w
.bitsPerPixel
= 1;
406 dc
->w
.devCaps
= displayDevCaps
;
410 SelectObject( handle
, BITMAP_hbitmapMemDC
);
417 /***********************************************************************
420 BOOL
DeleteDC( HDC hdc
)
422 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
423 if (!dc
) return FALSE
;
426 printf( "DeleteDC: %d\n", hdc
);
429 while (dc
->saveLevel
)
432 HDC hdcs
= dc
->header
.hNext
;
433 if (!(dcs
= (DC
*) GDI_GetObjPtr( hdcs
, DC_MAGIC
))) break;
434 dc
->header
.hNext
= dcs
->header
.hNext
;
439 if (!(dc
->w
.flags
& DC_SAVED
))
441 SelectObject( hdc
, STOCK_BLACK_PEN
);
442 SelectObject( hdc
, STOCK_WHITE_BRUSH
);
443 SelectObject( hdc
, STOCK_SYSTEM_FONT
);
444 XFreeGC( display
, dc
->u
.x
.gc
);
447 if (dc
->w
.hClipRgn
) DeleteObject( dc
->w
.hClipRgn
);
448 if (dc
->w
.hVisRgn
) DeleteObject( dc
->w
.hVisRgn
);
449 if (dc
->w
.hGCClipRgn
) DeleteObject( dc
->w
.hGCClipRgn
);
451 return GDI_FreeObject( hdc
);
455 /***********************************************************************
456 * GetDeviceCaps (GDI.80)
458 int GetDeviceCaps( HDC hdc
, WORD cap
)
460 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
463 if (cap
> sizeof(DeviceCaps
)-sizeof(WORD
)) return 0;
466 printf( "GetDeviceCaps(%d,%d): returning %d\n",
467 hdc
, cap
, *(WORD
*)(((char *)dc
->w
.devCaps
) + cap
) );
469 return *(WORD
*)(((char *)dc
->w
.devCaps
) + cap
);
473 /***********************************************************************
476 COLORREF
SetBkColor( HDC hdc
, COLORREF color
)
479 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
480 if (!dc
) return 0x80000000;
482 oldColor
= dc
->w
.backgroundColor
;
483 dc
->w
.backgroundColor
= color
;
484 dc
->w
.backgroundPixel
= COLOR_ToPhysical( dc
, color
);
489 /***********************************************************************
490 * SetTextColor (GDI.9)
492 COLORREF
SetTextColor( HDC hdc
, COLORREF color
)
495 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
496 if (!dc
) return 0x80000000;
498 oldColor
= dc
->w
.textColor
;
499 dc
->w
.textColor
= color
;
500 dc
->w
.textPixel
= COLOR_ToPhysical( dc
, color
);
505 /***********************************************************************
508 DWORD
SetDCOrg( HDC hdc
, short x
, short y
)
511 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
513 prevOrg
= dc
->w
.DCOrgX
| (dc
->w
.DCOrgY
<< 16);