2 * X11 graphics driver graphics functions
4 * Copyright 1993,1994 Alexandre Julliard
8 * FIXME: none of these functions obey the GM_ADVANCED
14 #ifndef X_DISPLAY_MISSING
16 #include <X11/Intrinsic.h>
41 #include "debugtools.h"
43 DEFAULT_DEBUG_CHANNEL(graphics
);
45 #define ABS(x) ((x)<0?(-(x)):(x))
47 /* ROP code to GC function conversion */
48 const int X11DRV_XROPfunction
[16] =
50 GXclear
, /* R2_BLACK */
51 GXnor
, /* R2_NOTMERGEPEN */
52 GXandInverted
, /* R2_MASKNOTPEN */
53 GXcopyInverted
, /* R2_NOTCOPYPEN */
54 GXandReverse
, /* R2_MASKPENNOT */
55 GXinvert
, /* R2_NOT */
56 GXxor
, /* R2_XORPEN */
57 GXnand
, /* R2_NOTMASKPEN */
58 GXand
, /* R2_MASKPEN */
59 GXequiv
, /* R2_NOTXORPEN */
61 GXorInverted
, /* R2_MERGENOTPEN */
62 GXcopy
, /* R2_COPYPEN */
63 GXorReverse
, /* R2_MERGEPENNOT */
64 GXor
, /* R2_MERGEPEN */
69 /***********************************************************************
70 * X11DRV_SetupGCForPatBlt
72 * Setup the GC for a PatBlt operation using current brush.
73 * If fMapColors is TRUE, X pixels are mapped to Windows colors.
74 * Return FALSE if brush is BS_NULL, TRUE otherwise.
76 BOOL
X11DRV_SetupGCForPatBlt( DC
* dc
, GC gc
, BOOL fMapColors
)
81 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
83 if (physDev
->brush
.style
== BS_NULL
) return FALSE
;
84 if (physDev
->brush
.pixel
== -1)
86 /* Special case used for monochrome pattern brushes.
87 * We need to swap foreground and background because
88 * Windows does it the wrong way...
90 val
.foreground
= physDev
->backgroundPixel
;
91 val
.background
= physDev
->textPixel
;
95 val
.foreground
= physDev
->brush
.pixel
;
96 val
.background
= physDev
->backgroundPixel
;
98 if (fMapColors
&& X11DRV_PALETTE_XPixelToPalette
)
100 val
.foreground
= X11DRV_PALETTE_XPixelToPalette
[val
.foreground
];
101 val
.background
= X11DRV_PALETTE_XPixelToPalette
[val
.background
];
104 if (dc
->w
.flags
& DC_DIRTY
) CLIPPING_UpdateGCRegion(dc
);
106 val
.function
= X11DRV_XROPfunction
[dc
->w
.ROPmode
-1];
108 ** Let's replace GXinvert by GXxor with (black xor white)
109 ** This solves the selection color and leak problems in excel
110 ** FIXME : Let's do that only if we work with X-pixels, not with Win-pixels
112 if (val
.function
== GXinvert
)
114 val
.foreground
= BlackPixelOfScreen(X11DRV_GetXScreen()) ^ WhitePixelOfScreen(X11DRV_GetXScreen());
115 val
.function
= GXxor
;
117 val
.fill_style
= physDev
->brush
.fillStyle
;
118 switch(val
.fill_style
)
121 case FillOpaqueStippled
:
122 if (dc
->w
.backgroundMode
==OPAQUE
) val
.fill_style
= FillOpaqueStippled
;
123 val
.stipple
= physDev
->brush
.pixmap
;
128 if (fMapColors
&& X11DRV_PALETTE_XPixelToPalette
)
132 EnterCriticalSection( &X11DRV_CritSection
);
133 pixmap
= XCreatePixmap( display
, X11DRV_GetXRootWindow(),
134 8, 8, X11DRV_GetDepth() );
135 image
= XGetImage( display
, physDev
->brush
.pixmap
, 0, 0, 8, 8,
136 AllPlanes
, ZPixmap
);
137 for (y
= 0; y
< 8; y
++)
138 for (x
= 0; x
< 8; x
++)
139 XPutPixel( image
, x
, y
,
140 X11DRV_PALETTE_XPixelToPalette
[XGetPixel( image
, x
, y
)] );
141 XPutImage( display
, pixmap
, gc
, image
, 0, 0, 0, 0, 8, 8 );
142 XDestroyImage( image
);
143 LeaveCriticalSection( &X11DRV_CritSection
);
146 else val
.tile
= physDev
->brush
.pixmap
;
154 val
.ts_x_origin
= dc
->w
.DCOrgX
+ dc
->w
.brushOrgX
;
155 val
.ts_y_origin
= dc
->w
.DCOrgY
+ dc
->w
.brushOrgY
;
156 val
.fill_rule
= (dc
->w
.polyFillMode
==WINDING
) ? WindingRule
: EvenOddRule
;
157 TSXChangeGC( display
, gc
,
158 GCFunction
| GCForeground
| GCBackground
| GCFillStyle
|
159 GCFillRule
| GCTileStipXOrigin
| GCTileStipYOrigin
| mask
,
161 if (pixmap
) TSXFreePixmap( display
, pixmap
);
166 /***********************************************************************
167 * X11DRV_SetupGCForBrush
169 * Setup physDev->gc for drawing operations using current brush.
170 * Return FALSE if brush is BS_NULL, TRUE otherwise.
172 BOOL
X11DRV_SetupGCForBrush( DC
* dc
)
174 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
175 return X11DRV_SetupGCForPatBlt( dc
, physDev
->gc
, FALSE
);
179 /***********************************************************************
180 * X11DRV_SetupGCForPen
182 * Setup physDev->gc for drawing operations using current pen.
183 * Return FALSE if pen is PS_NULL, TRUE otherwise.
185 BOOL
X11DRV_SetupGCForPen( DC
* dc
)
188 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
190 if (physDev
->pen
.style
== PS_NULL
) return FALSE
;
192 if (dc
->w
.flags
& DC_DIRTY
) CLIPPING_UpdateGCRegion(dc
);
194 switch (dc
->w
.ROPmode
)
197 val
.foreground
= BlackPixelOfScreen( X11DRV_GetXScreen() );
198 val
.function
= GXcopy
;
201 val
.foreground
= WhitePixelOfScreen( X11DRV_GetXScreen() );
202 val
.function
= GXcopy
;
205 val
.foreground
= physDev
->pen
.pixel
;
206 /* It is very unlikely someone wants to XOR with 0 */
207 /* This fixes the rubber-drawings in paintbrush */
208 if (val
.foreground
== 0)
209 val
.foreground
= BlackPixelOfScreen( X11DRV_GetXScreen() )
210 ^ WhitePixelOfScreen( X11DRV_GetXScreen() );
211 val
.function
= GXxor
;
214 val
.foreground
= physDev
->pen
.pixel
;
215 val
.function
= X11DRV_XROPfunction
[dc
->w
.ROPmode
-1];
217 val
.background
= physDev
->backgroundPixel
;
218 val
.fill_style
= FillSolid
;
219 if ((physDev
->pen
.width
<= 1) &&
220 (physDev
->pen
.style
!= PS_SOLID
) &&
221 (physDev
->pen
.style
!= PS_INSIDEFRAME
))
223 TSXSetDashes( display
, physDev
->gc
, 0, physDev
->pen
.dashes
,
224 physDev
->pen
.dash_len
);
225 val
.line_style
= (dc
->w
.backgroundMode
== OPAQUE
) ?
226 LineDoubleDash
: LineOnOffDash
;
228 else val
.line_style
= LineSolid
;
229 val
.line_width
= physDev
->pen
.width
;
230 if (val
.line_width
<= 1) {
231 val
.cap_style
= CapNotLast
;
233 switch (physDev
->pen
.endcap
)
235 case PS_ENDCAP_SQUARE
:
236 val
.cap_style
= CapProjecting
;
239 val
.cap_style
= CapButt
;
241 case PS_ENDCAP_ROUND
:
243 val
.cap_style
= CapRound
;
246 switch (physDev
->pen
.linejoin
)
249 val
.join_style
= JoinBevel
;
252 val
.join_style
= JoinMiter
;
256 val
.join_style
= JoinRound
;
258 TSXChangeGC( display
, physDev
->gc
,
259 GCFunction
| GCForeground
| GCBackground
| GCLineWidth
|
260 GCLineStyle
| GCCapStyle
| GCJoinStyle
| GCFillStyle
, &val
);
265 /***********************************************************************
266 * X11DRV_SetupGCForText
268 * Setup physDev->gc for text drawing operations.
269 * Return FALSE if the font is null, TRUE otherwise.
271 BOOL
X11DRV_SetupGCForText( DC
* dc
)
273 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
274 XFontStruct
* xfs
= XFONT_GetFontStruct( physDev
->font
);
280 if (dc
->w
.flags
& DC_DIRTY
) CLIPPING_UpdateGCRegion(dc
);
282 val
.function
= GXcopy
; /* Text is always GXcopy */
283 val
.foreground
= physDev
->textPixel
;
284 val
.background
= physDev
->backgroundPixel
;
285 val
.fill_style
= FillSolid
;
288 TSXChangeGC( display
, physDev
->gc
,
289 GCFunction
| GCForeground
| GCBackground
| GCFillStyle
|
293 WARN("Physical font failure\n" );
297 /***********************************************************************
301 X11DRV_LineTo( DC
*dc
, INT x
, INT y
)
303 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
305 if (X11DRV_SetupGCForPen( dc
)) {
306 /* Update the pixmap from the DIB section */
307 X11DRV_DIB_UpdateDIBSection(dc
, FALSE
);
308 TSXDrawLine(display
, physDev
->drawable
, physDev
->gc
,
309 dc
->w
.DCOrgX
+ XLPTODP( dc
, dc
->w
.CursPosX
),
310 dc
->w
.DCOrgY
+ YLPTODP( dc
, dc
->w
.CursPosY
),
311 dc
->w
.DCOrgX
+ XLPTODP( dc
, x
),
312 dc
->w
.DCOrgY
+ YLPTODP( dc
, y
) );
313 /* Update the DIBSection from the pixmap */
314 X11DRV_DIB_UpdateDIBSection(dc
, TRUE
);
321 /***********************************************************************
324 * Helper functions for Arc(), Chord() and Pie().
325 * 'lines' is the number of lines to draw: 0 for Arc, 1 for Chord, 2 for Pie.
329 X11DRV_DrawArc( DC
*dc
, INT left
, INT top
, INT right
,
330 INT bottom
, INT xstart
, INT ystart
,
331 INT xend
, INT yend
, INT lines
)
333 INT xcenter
, ycenter
, istart_angle
, idiff_angle
;
334 INT width
, oldwidth
, oldendcap
;
335 double start_angle
, end_angle
;
337 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
340 left
= XLPTODP( dc
, left
);
341 top
= YLPTODP( dc
, top
);
342 right
= XLPTODP( dc
, right
);
343 bottom
= YLPTODP( dc
, bottom
);
344 xstart
= XLPTODP( dc
, xstart
);
345 ystart
= YLPTODP( dc
, ystart
);
346 xend
= XLPTODP( dc
, xend
);
347 yend
= YLPTODP( dc
, yend
);
349 if (right
< left
) { INT tmp
= right
; right
= left
; left
= tmp
; }
350 if (bottom
< top
) { INT tmp
= bottom
; bottom
= top
; top
= tmp
; }
351 if ((left
== right
) || (top
== bottom
)
352 ||(lines
&& ((right
-left
==1)||(bottom
-top
==1)))) return TRUE
;
354 oldwidth
= width
= physDev
->pen
.width
;
355 oldendcap
= physDev
->pen
.endcap
;
356 if (!width
) width
= 1;
357 if(physDev
->pen
.style
== PS_NULL
) width
= 0;
359 if ((physDev
->pen
.style
== PS_INSIDEFRAME
))
361 if (2*width
> (right
-left
)) width
=(right
-left
+ 1)/2;
362 if (2*width
> (bottom
-top
)) width
=(bottom
-top
+ 1)/2;
364 right
-= (width
- 1) / 2;
366 bottom
-= (width
- 1) / 2;
368 if(width
== 0) width
= 1; /* more accurate */
369 physDev
->pen
.width
= width
;
370 physDev
->pen
.endcap
= PS_ENDCAP_SQUARE
;
372 xcenter
= (right
+ left
) / 2;
373 ycenter
= (bottom
+ top
) / 2;
374 start_angle
= atan2( (double)(ycenter
-ystart
)*(right
-left
),
375 (double)(xstart
-xcenter
)*(bottom
-top
) );
376 end_angle
= atan2( (double)(ycenter
-yend
)*(right
-left
),
377 (double)(xend
-xcenter
)*(bottom
-top
) );
378 if ((xstart
==xend
)&&(ystart
==yend
))
379 { /* A lazy program delivers xstart=xend=ystart=yend=0) */
383 else /* notorious cases */
384 if ((start_angle
== PI
)&&( end_angle
<0))
387 if ((end_angle
== PI
)&&( start_angle
<0))
389 istart_angle
= (INT
)(start_angle
* 180 * 64 / PI
+ 0.5);
390 idiff_angle
= (INT
)((end_angle
- start_angle
) * 180 * 64 / PI
+ 0.5);
391 if (idiff_angle
<= 0) idiff_angle
+= 360 * 64;
393 /* Update the pixmap from the DIB section */
394 X11DRV_DIB_UpdateDIBSection(dc
, FALSE
);
396 /* Fill arc with brush if Chord() or Pie() */
398 if ((lines
> 0) && X11DRV_SetupGCForBrush( dc
)) {
399 TSXSetArcMode( display
, physDev
->gc
,
400 (lines
==1) ? ArcChord
: ArcPieSlice
);
401 TSXFillArc( display
, physDev
->drawable
, physDev
->gc
,
402 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
,
403 right
-left
-1, bottom
-top
-1, istart_angle
, idiff_angle
);
407 /* Draw arc and lines */
409 if (X11DRV_SetupGCForPen( dc
)){
410 TSXDrawArc( display
, physDev
->drawable
, physDev
->gc
,
411 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
,
412 right
-left
-1, bottom
-top
-1, istart_angle
, idiff_angle
);
414 /* use the truncated values */
415 start_angle
=(double)istart_angle
*PI
/64./180.;
416 end_angle
=(double)(istart_angle
+idiff_angle
)*PI
/64./180.;
417 /* calculate the endpoints and round correctly */
418 points
[0].x
= (int) floor(dc
->w
.DCOrgX
+ (right
+left
)/2.0 +
419 cos(start_angle
) * (right
-left
-width
*2+2) / 2. + 0.5);
420 points
[0].y
= (int) floor(dc
->w
.DCOrgY
+ (top
+bottom
)/2.0 -
421 sin(start_angle
) * (bottom
-top
-width
*2+2) / 2. + 0.5);
422 points
[1].x
= (int) floor(dc
->w
.DCOrgX
+ (right
+left
)/2.0 +
423 cos(end_angle
) * (right
-left
-width
*2+2) / 2. + 0.5);
424 points
[1].y
= (int) floor(dc
->w
.DCOrgY
+ (top
+bottom
)/2.0 -
425 sin(end_angle
) * (bottom
-top
-width
*2+2) / 2. + 0.5);
427 /* OK this stuff is optimized for Xfree86
428 * which is probably the most used server by
429 * wine users. Other X servers will not
430 * display correctly. (eXceed for instance)
431 * so if you feel you must change make sure that
432 * you either use Xfree86 or seperate your changes
433 * from these (compile switch or whatever)
437 points
[3] = points
[1];
438 points
[1].x
= dc
->w
.DCOrgX
+ xcenter
;
439 points
[1].y
= dc
->w
.DCOrgY
+ ycenter
;
440 points
[2] = points
[1];
441 dx1
=points
[1].x
-points
[0].x
;
442 dy1
=points
[1].y
-points
[0].y
;
443 if(((top
-bottom
) | -2) == -2)
444 if(dy1
>0) points
[1].y
--;
446 if (((-dx1
)*64)<=ABS(dy1
)*37) points
[0].x
--;
447 if(((-dx1
*9))<(dy1
*16)) points
[0].y
--;
448 if( dy1
<0 && ((dx1
*9)) < (dy1
*16)) points
[0].y
--;
450 if(dy1
< 0) points
[0].y
--;
451 if(((right
-left
) | -2) == -2) points
[1].x
--;
453 dx1
=points
[3].x
-points
[2].x
;
454 dy1
=points
[3].y
-points
[2].y
;
455 if(((top
-bottom
) | -2 ) == -2)
456 if(dy1
< 0) points
[2].y
--;
458 if( dy1
>0) points
[3].y
--;
459 if(((right
-left
) | -2) == -2 ) points
[2].x
--;
462 if( dx1
* 64 < dy1
* -37 ) points
[3].x
--;
466 TSXDrawLines( display
, physDev
->drawable
, physDev
->gc
,
467 points
, lines
+1, CoordModeOrigin
);
472 /* Update the DIBSection of the pixmap */
473 if (update
) X11DRV_DIB_UpdateDIBSection(dc
, TRUE
);
475 physDev
->pen
.width
= oldwidth
;
476 physDev
->pen
.endcap
= oldendcap
;
481 /***********************************************************************
485 X11DRV_Arc( DC
*dc
, INT left
, INT top
, INT right
, INT bottom
,
486 INT xstart
, INT ystart
, INT xend
, INT yend
)
488 return X11DRV_DrawArc( dc
, left
, top
, right
, bottom
,
489 xstart
, ystart
, xend
, yend
, 0 );
493 /***********************************************************************
497 X11DRV_Pie( DC
*dc
, INT left
, INT top
, INT right
, INT bottom
,
498 INT xstart
, INT ystart
, INT xend
, INT yend
)
500 return X11DRV_DrawArc( dc
, left
, top
, right
, bottom
,
501 xstart
, ystart
, xend
, yend
, 2 );
504 /***********************************************************************
508 X11DRV_Chord( DC
*dc
, INT left
, INT top
, INT right
, INT bottom
,
509 INT xstart
, INT ystart
, INT xend
, INT yend
)
511 return X11DRV_DrawArc( dc
, left
, top
, right
, bottom
,
512 xstart
, ystart
, xend
, yend
, 1 );
516 /***********************************************************************
520 X11DRV_Ellipse( DC
*dc
, INT left
, INT top
, INT right
, INT bottom
)
523 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
526 left
= XLPTODP( dc
, left
);
527 top
= YLPTODP( dc
, top
);
528 right
= XLPTODP( dc
, right
);
529 bottom
= YLPTODP( dc
, bottom
);
530 if ((left
== right
) || (top
== bottom
)) return TRUE
;
532 if (right
< left
) { INT tmp
= right
; right
= left
; left
= tmp
; }
533 if (bottom
< top
) { INT tmp
= bottom
; bottom
= top
; top
= tmp
; }
535 oldwidth
= width
= physDev
->pen
.width
;
536 if (!width
) width
= 1;
537 if(physDev
->pen
.style
== PS_NULL
) width
= 0;
539 if ((physDev
->pen
.style
== PS_INSIDEFRAME
))
541 if (2*width
> (right
-left
)) width
=(right
-left
+ 1)/2;
542 if (2*width
> (bottom
-top
)) width
=(bottom
-top
+ 1)/2;
544 right
-= (width
- 1) / 2;
546 bottom
-= (width
- 1) / 2;
548 if(width
== 0) width
= 1; /* more accurate */
549 physDev
->pen
.width
= width
;
551 /* Update the pixmap from the DIB section */
552 X11DRV_DIB_UpdateDIBSection(dc
, FALSE
);
554 if (X11DRV_SetupGCForBrush( dc
))
556 TSXFillArc( display
, physDev
->drawable
, physDev
->gc
,
557 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
,
558 right
-left
-1, bottom
-top
-1, 0, 360*64 );
561 if (X11DRV_SetupGCForPen( dc
))
563 TSXDrawArc( display
, physDev
->drawable
, physDev
->gc
,
564 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
,
565 right
-left
-1, bottom
-top
-1, 0, 360*64 );
569 /* Update the DIBSection from the pixmap */
570 if (update
) X11DRV_DIB_UpdateDIBSection(dc
, TRUE
);
572 physDev
->pen
.width
= oldwidth
;
577 /***********************************************************************
581 X11DRV_Rectangle(DC
*dc
, INT left
, INT top
, INT right
, INT bottom
)
583 INT width
, oldwidth
, oldjoinstyle
;
584 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
587 TRACE("(%d %d %d %d)\n",
588 left
, top
, right
, bottom
);
590 left
= XLPTODP( dc
, left
);
591 top
= YLPTODP( dc
, top
);
592 right
= XLPTODP( dc
, right
);
593 bottom
= YLPTODP( dc
, bottom
);
595 if ((left
== right
) || (top
== bottom
)) return TRUE
;
597 if (right
< left
) { INT tmp
= right
; right
= left
; left
= tmp
; }
598 if (bottom
< top
) { INT tmp
= bottom
; bottom
= top
; top
= tmp
; }
600 oldwidth
= width
= physDev
->pen
.width
;
601 if (!width
) width
= 1;
602 if(physDev
->pen
.style
== PS_NULL
) width
= 0;
604 if ((physDev
->pen
.style
== PS_INSIDEFRAME
))
606 if (2*width
> (right
-left
)) width
=(right
-left
+ 1)/2;
607 if (2*width
> (bottom
-top
)) width
=(bottom
-top
+ 1)/2;
609 right
-= (width
- 1) / 2;
611 bottom
-= (width
- 1) / 2;
613 if(width
== 1) width
= 0;
614 physDev
->pen
.width
= width
;
615 oldjoinstyle
= physDev
->pen
.linejoin
;
616 if(physDev
->pen
.type
!= PS_GEOMETRIC
)
617 physDev
->pen
.linejoin
= PS_JOIN_MITER
;
619 /* Update the pixmap from the DIB section */
620 X11DRV_DIB_UpdateDIBSection(dc
, FALSE
);
622 if ((right
> left
+ width
) && (bottom
> top
+ width
))
623 if (X11DRV_SetupGCForBrush( dc
))
625 TSXFillRectangle( display
, physDev
->drawable
, physDev
->gc
,
626 dc
->w
.DCOrgX
+ left
+ (width
+ 1) / 2,
627 dc
->w
.DCOrgY
+ top
+ (width
+ 1) / 2,
628 right
-left
-width
-1, bottom
-top
-width
-1);
631 if (X11DRV_SetupGCForPen( dc
))
633 TSXDrawRectangle( display
, physDev
->drawable
, physDev
->gc
,
634 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
,
635 right
-left
-1, bottom
-top
-1 );
639 /* Update the DIBSection from the pixmap */
640 if (update
) X11DRV_DIB_UpdateDIBSection(dc
, TRUE
);
642 physDev
->pen
.width
= oldwidth
;
643 physDev
->pen
.linejoin
= oldjoinstyle
;
647 /***********************************************************************
651 X11DRV_RoundRect( DC
*dc
, INT left
, INT top
, INT right
,
652 INT bottom
, INT ell_width
, INT ell_height
)
654 INT width
, oldwidth
, oldendcap
;
655 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
658 TRACE("(%d %d %d %d %d %d\n",
659 left
, top
, right
, bottom
, ell_width
, ell_height
);
661 left
= XLPTODP( dc
, left
);
662 top
= YLPTODP( dc
, top
);
663 right
= XLPTODP( dc
, right
);
664 bottom
= YLPTODP( dc
, bottom
);
666 if ((left
== right
) || (top
== bottom
))
669 /* Make sure ell_width and ell_height are >= 1 otherwise XDrawArc gets
670 called with width/height < 0 */
671 ell_width
= MAX(abs( ell_width
* dc
->vportExtX
/ dc
->wndExtX
), 1);
672 ell_height
= MAX(abs( ell_height
* dc
->vportExtY
/ dc
->wndExtY
), 1);
674 /* Fix the coordinates */
676 if (right
< left
) { INT tmp
= right
; right
= left
; left
= tmp
; }
677 if (bottom
< top
) { INT tmp
= bottom
; bottom
= top
; top
= tmp
; }
679 oldwidth
= width
= physDev
->pen
.width
;
680 oldendcap
= physDev
->pen
.endcap
;
681 if (!width
) width
= 1;
682 if(physDev
->pen
.style
== PS_NULL
) width
= 0;
684 if ((physDev
->pen
.style
== PS_INSIDEFRAME
))
686 if (2*width
> (right
-left
)) width
=(right
-left
+ 1)/2;
687 if (2*width
> (bottom
-top
)) width
=(bottom
-top
+ 1)/2;
689 right
-= (width
- 1) / 2;
691 bottom
-= (width
- 1) / 2;
693 if(width
== 0) width
= 1;
694 physDev
->pen
.width
= width
;
695 physDev
->pen
.endcap
= PS_ENDCAP_SQUARE
;
697 /* Update the pixmap from the DIB section */
698 X11DRV_DIB_UpdateDIBSection(dc
, FALSE
);
700 if (X11DRV_SetupGCForBrush( dc
))
702 if (ell_width
> (right
-left
) )
703 if (ell_height
> (bottom
-top
) )
704 TSXFillArc( display
, physDev
->drawable
, physDev
->gc
,
705 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
,
706 right
- left
- 1, bottom
- top
- 1,
709 TSXFillArc( display
, physDev
->drawable
, physDev
->gc
,
710 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
,
711 right
- left
- 1, ell_height
, 0, 180 * 64 );
712 TSXFillArc( display
, physDev
->drawable
, physDev
->gc
,
714 dc
->w
.DCOrgY
+ bottom
- ell_height
- 1,
715 right
- left
- 1, ell_height
, 180 * 64,
718 else if (ell_height
> (bottom
-top
) ){
719 TSXFillArc( display
, physDev
->drawable
, physDev
->gc
,
720 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
,
721 ell_width
, bottom
- top
- 1, 90 * 64, 180 * 64 );
722 TSXFillArc( display
, physDev
->drawable
, physDev
->gc
,
723 dc
->w
.DCOrgX
+ right
- ell_width
-1, dc
->w
.DCOrgY
+ top
,
724 ell_width
, bottom
- top
- 1, 270 * 64, 180 * 64 );
726 TSXFillArc( display
, physDev
->drawable
, physDev
->gc
,
727 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
,
728 ell_width
, ell_height
, 90 * 64, 90 * 64 );
729 TSXFillArc( display
, physDev
->drawable
, physDev
->gc
,
731 dc
->w
.DCOrgY
+ bottom
- ell_height
- 1,
732 ell_width
, ell_height
, 180 * 64, 90 * 64 );
733 TSXFillArc( display
, physDev
->drawable
, physDev
->gc
,
734 dc
->w
.DCOrgX
+ right
- ell_width
- 1,
735 dc
->w
.DCOrgY
+ bottom
- ell_height
- 1,
736 ell_width
, ell_height
, 270 * 64, 90 * 64 );
737 TSXFillArc( display
, physDev
->drawable
, physDev
->gc
,
738 dc
->w
.DCOrgX
+ right
- ell_width
- 1,
740 ell_width
, ell_height
, 0, 90 * 64 );
742 if (ell_width
< right
- left
)
744 TSXFillRectangle( display
, physDev
->drawable
, physDev
->gc
,
745 dc
->w
.DCOrgX
+ left
+ (ell_width
+ 1) / 2,
746 dc
->w
.DCOrgY
+ top
+ 1,
747 right
- left
- ell_width
- 1,
748 (ell_height
+ 1) / 2 - 1);
749 TSXFillRectangle( display
, physDev
->drawable
, physDev
->gc
,
750 dc
->w
.DCOrgX
+ left
+ (ell_width
+ 1) / 2,
751 dc
->w
.DCOrgY
+ bottom
- (ell_height
) / 2 - 1,
752 right
- left
- ell_width
- 1,
755 if (ell_height
< bottom
- top
)
757 TSXFillRectangle( display
, physDev
->drawable
, physDev
->gc
,
758 dc
->w
.DCOrgX
+ left
+ 1,
759 dc
->w
.DCOrgY
+ top
+ (ell_height
+ 1) / 2,
761 bottom
- top
- ell_height
- 1);
765 /* FIXME: this could be done with on X call
766 * more efficient and probably more correct
767 * on any X server: XDrawArcs will draw
768 * straight horizontal and vertical lines
769 * if width or height are zero.
771 * BTW this stuff is optimized for an Xfree86 server
772 * read the comments inside the X11DRV_DrawArc function
774 if (X11DRV_SetupGCForPen(dc
)) {
775 if (ell_width
> (right
-left
) )
776 if (ell_height
> (bottom
-top
) )
777 TSXDrawArc( display
, physDev
->drawable
, physDev
->gc
,
778 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
,
779 right
- left
- 1, bottom
-top
- 1, 0 , 360 * 64 );
781 TSXDrawArc( display
, physDev
->drawable
, physDev
->gc
,
782 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
,
783 right
- left
- 1, ell_height
- 1, 0 , 180 * 64 );
784 TSXDrawArc( display
, physDev
->drawable
, physDev
->gc
,
786 dc
->w
.DCOrgY
+ bottom
- ell_height
,
787 right
- left
- 1, ell_height
- 1, 180 * 64 , 180 * 64 );
789 else if (ell_height
> (bottom
-top
) ){
790 TSXDrawArc( display
, physDev
->drawable
, physDev
->gc
,
791 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
,
792 ell_width
- 1 , bottom
- top
- 1, 90 * 64 , 180 * 64 );
793 TSXDrawArc( display
, physDev
->drawable
, physDev
->gc
,
794 dc
->w
.DCOrgX
+ right
- ell_width
,
796 ell_width
- 1 , bottom
- top
- 1, 270 * 64 , 180 * 64 );
798 TSXDrawArc( display
, physDev
->drawable
, physDev
->gc
,
799 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
,
800 ell_width
- 1, ell_height
- 1, 90 * 64, 90 * 64 );
801 TSXDrawArc( display
, physDev
->drawable
, physDev
->gc
,
802 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ bottom
- ell_height
,
803 ell_width
- 1, ell_height
- 1, 180 * 64, 90 * 64 );
804 TSXDrawArc( display
, physDev
->drawable
, physDev
->gc
,
805 dc
->w
.DCOrgX
+ right
- ell_width
,
806 dc
->w
.DCOrgY
+ bottom
- ell_height
,
807 ell_width
- 1, ell_height
- 1, 270 * 64, 90 * 64 );
808 TSXDrawArc( display
, physDev
->drawable
, physDev
->gc
,
809 dc
->w
.DCOrgX
+ right
- ell_width
, dc
->w
.DCOrgY
+ top
,
810 ell_width
- 1, ell_height
- 1, 0, 90 * 64 );
812 if (ell_width
< right
- left
)
814 TSXDrawLine( display
, physDev
->drawable
, physDev
->gc
,
815 dc
->w
.DCOrgX
+ left
+ ell_width
/ 2,
817 dc
->w
.DCOrgX
+ right
- (ell_width
+1) / 2,
819 TSXDrawLine( display
, physDev
->drawable
, physDev
->gc
,
820 dc
->w
.DCOrgX
+ left
+ ell_width
/ 2 ,
821 dc
->w
.DCOrgY
+ bottom
- 1,
822 dc
->w
.DCOrgX
+ right
- (ell_width
+1)/ 2,
823 dc
->w
.DCOrgY
+ bottom
- 1);
825 if (ell_height
< bottom
- top
)
827 TSXDrawLine( display
, physDev
->drawable
, physDev
->gc
,
828 dc
->w
.DCOrgX
+ right
- 1,
829 dc
->w
.DCOrgY
+ top
+ ell_height
/ 2,
830 dc
->w
.DCOrgX
+ right
- 1,
831 dc
->w
.DCOrgY
+ bottom
- (ell_height
+1) / 2);
832 TSXDrawLine( display
, physDev
->drawable
, physDev
->gc
,
834 dc
->w
.DCOrgY
+ top
+ ell_height
/ 2,
836 dc
->w
.DCOrgY
+ bottom
- (ell_height
+1) / 2);
841 /* Update the DIBSection from the pixmap */
842 if (update
) X11DRV_DIB_UpdateDIBSection(dc
, TRUE
);
844 physDev
->pen
.width
= oldwidth
;
845 physDev
->pen
.endcap
= oldendcap
;
850 /***********************************************************************
854 X11DRV_SetPixel( DC
*dc
, INT x
, INT y
, COLORREF color
)
857 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
859 x
= dc
->w
.DCOrgX
+ XLPTODP( dc
, x
);
860 y
= dc
->w
.DCOrgY
+ YLPTODP( dc
, y
);
861 pixel
= X11DRV_PALETTE_ToPhysical( dc
, color
);
863 TSXSetForeground( display
, physDev
->gc
, pixel
);
864 TSXSetFunction( display
, physDev
->gc
, GXcopy
);
865 TSXDrawPoint( display
, physDev
->drawable
, physDev
->gc
, x
, y
);
867 /* inefficient but simple... */
869 /* FIXME: the DIBSection pixel should be updated too */
871 return X11DRV_PALETTE_ToLogical(pixel
);
875 /***********************************************************************
879 X11DRV_GetPixel( DC
*dc
, INT x
, INT y
)
881 static Pixmap pixmap
= 0;
884 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
886 x
= dc
->w
.DCOrgX
+ XLPTODP( dc
, x
);
887 y
= dc
->w
.DCOrgY
+ YLPTODP( dc
, y
);
888 EnterCriticalSection( &X11DRV_CritSection
);
889 if (dc
->w
.flags
& DC_MEMORY
)
891 image
= XGetImage( display
, physDev
->drawable
, x
, y
, 1, 1,
892 AllPlanes
, ZPixmap
);
896 /* If we are reading from the screen, use a temporary copy */
897 /* to avoid a BadMatch error */
898 if (!pixmap
) pixmap
= XCreatePixmap( display
, X11DRV_GetXRootWindow(),
899 1, 1, dc
->w
.bitsPerPixel
);
900 XCopyArea( display
, physDev
->drawable
, pixmap
, BITMAP_colorGC
,
902 image
= XGetImage( display
, pixmap
, 0, 0, 1, 1, AllPlanes
, ZPixmap
);
904 pixel
= XGetPixel( image
, 0, 0 );
905 XDestroyImage( image
);
906 LeaveCriticalSection( &X11DRV_CritSection
);
908 return X11DRV_PALETTE_ToLogical(pixel
);
912 /***********************************************************************
916 X11DRV_PaintRgn( DC
*dc
, HRGN hrgn
)
919 HRGN tmpVisRgn
, prevVisRgn
;
920 HDC hdc
= dc
->hSelf
; /* FIXME: should not mix dc/hdc this way */
921 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
923 if (!(tmpVisRgn
= CreateRectRgn( 0, 0, 0, 0 ))) return FALSE
;
925 /* Transform region into device co-ords */
926 if ( !REGION_LPTODP( hdc
, tmpVisRgn
, hrgn
)
927 || OffsetRgn( tmpVisRgn
, dc
->w
.DCOrgX
, dc
->w
.DCOrgY
) == ERROR
) {
928 DeleteObject( tmpVisRgn
);
932 /* Modify visible region */
933 if (!(prevVisRgn
= SaveVisRgn16( hdc
))) {
934 DeleteObject( tmpVisRgn
);
937 CombineRgn( tmpVisRgn
, prevVisRgn
, tmpVisRgn
, RGN_AND
);
938 SelectVisRgn16( hdc
, tmpVisRgn
);
939 DeleteObject( tmpVisRgn
);
941 /* Fill the region */
943 GetRgnBox( dc
->w
.hGCClipRgn
, &box
);
944 if (X11DRV_SetupGCForBrush( dc
))
946 /* Update the pixmap from the DIB section */
947 X11DRV_DIB_UpdateDIBSection(dc
, FALSE
);
949 TSXFillRectangle( display
, physDev
->drawable
, physDev
->gc
,
951 box
.right
-box
.left
, box
.bottom
-box
.top
);
953 /* Update the DIBSection from the pixmap */
954 X11DRV_DIB_UpdateDIBSection(dc
, TRUE
);
957 /* Restore the visible region */
959 RestoreVisRgn16( hdc
);
963 /**********************************************************************
967 X11DRV_Polyline( DC
*dc
, const POINT
* pt
, INT count
)
972 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
974 if((oldwidth
= physDev
->pen
.width
) == 0) physDev
->pen
.width
= 1;
976 if (!(points
= HeapAlloc( GetProcessHeap(), 0, sizeof(XPoint
) * count
)))
978 WARN("No memory to convert POINTs to XPoints!\n");
981 for (i
= 0; i
< count
; i
++)
983 points
[i
].x
= dc
->w
.DCOrgX
+ XLPTODP( dc
, pt
[i
].x
);
984 points
[i
].y
= dc
->w
.DCOrgY
+ YLPTODP( dc
, pt
[i
].y
);
987 if (X11DRV_SetupGCForPen ( dc
))
989 /* Update the pixmap from the DIB section */
990 X11DRV_DIB_UpdateDIBSection(dc
, FALSE
);
992 TSXDrawLines( display
, physDev
->drawable
, physDev
->gc
,
993 points
, count
, CoordModeOrigin
);
995 /* Update the DIBSection from the pixmap */
996 X11DRV_DIB_UpdateDIBSection(dc
, TRUE
);
999 HeapFree( GetProcessHeap(), 0, points
);
1000 physDev
->pen
.width
= oldwidth
;
1005 /**********************************************************************
1009 X11DRV_Polygon( DC
*dc
, const POINT
* pt
, INT count
)
1013 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
1014 BOOL update
= FALSE
;
1016 if (!(points
= HeapAlloc( GetProcessHeap(), 0, sizeof(XPoint
) * (count
+1) )))
1018 WARN("No memory to convert POINTs to XPoints!\n");
1021 for (i
= 0; i
< count
; i
++)
1023 points
[i
].x
= dc
->w
.DCOrgX
+ XLPTODP( dc
, pt
[i
].x
);
1024 points
[i
].y
= dc
->w
.DCOrgY
+ YLPTODP( dc
, pt
[i
].y
);
1026 points
[count
] = points
[0];
1028 /* Update the pixmap from the DIB section */
1029 X11DRV_DIB_UpdateDIBSection(dc
, FALSE
);
1031 if (X11DRV_SetupGCForBrush( dc
))
1033 TSXFillPolygon( display
, physDev
->drawable
, physDev
->gc
,
1034 points
, count
+1, Complex
, CoordModeOrigin
);
1037 if (X11DRV_SetupGCForPen ( dc
))
1039 TSXDrawLines( display
, physDev
->drawable
, physDev
->gc
,
1040 points
, count
+1, CoordModeOrigin
);
1044 /* Update the DIBSection from the pixmap */
1045 if (update
) X11DRV_DIB_UpdateDIBSection(dc
, TRUE
);
1047 HeapFree( GetProcessHeap(), 0, points
);
1052 /**********************************************************************
1053 * X11DRV_PolyPolygon
1056 X11DRV_PolyPolygon( DC
*dc
, const POINT
* pt
, const INT
* counts
, UINT polygons
)
1059 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
1061 /* FIXME: The points should be converted to device coords before */
1062 /* creating the region. */
1064 hrgn
= CreatePolyPolygonRgn( pt
, counts
, polygons
, dc
->w
.polyFillMode
);
1065 X11DRV_PaintRgn( dc
, hrgn
);
1066 DeleteObject( hrgn
);
1068 /* Draw the outline of the polygons */
1070 if (X11DRV_SetupGCForPen ( dc
))
1075 /* Update the pixmap from the DIB section */
1076 X11DRV_DIB_UpdateDIBSection(dc
, FALSE
);
1078 for (i
= 0; i
< polygons
; i
++) if (counts
[i
] > max
) max
= counts
[i
];
1079 if (!(points
= HeapAlloc( GetProcessHeap(), 0, sizeof(XPoint
) * (max
+1) )))
1081 WARN("No memory to convert POINTs to XPoints!\n");
1084 for (i
= 0; i
< polygons
; i
++)
1086 for (j
= 0; j
< counts
[i
]; j
++)
1088 points
[j
].x
= dc
->w
.DCOrgX
+ XLPTODP( dc
, pt
->x
);
1089 points
[j
].y
= dc
->w
.DCOrgY
+ YLPTODP( dc
, pt
->y
);
1092 points
[j
] = points
[0];
1093 TSXDrawLines( display
, physDev
->drawable
, physDev
->gc
,
1094 points
, j
+ 1, CoordModeOrigin
);
1097 /* Update the DIBSection of the dc's bitmap */
1098 X11DRV_DIB_UpdateDIBSection(dc
, TRUE
);
1100 HeapFree( GetProcessHeap(), 0, points
);
1106 /**********************************************************************
1107 * X11DRV_PolyPolyline
1110 X11DRV_PolyPolyline( DC
*dc
, const POINT
* pt
, const DWORD
* counts
, DWORD polylines
)
1112 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
1114 if (X11DRV_SetupGCForPen ( dc
))
1119 /* Update the pixmap from the DIB section */
1120 X11DRV_DIB_UpdateDIBSection(dc
, FALSE
);
1122 for (i
= 0; i
< polylines
; i
++) if (counts
[i
] > max
) max
= counts
[i
];
1123 if (!(points
= HeapAlloc( GetProcessHeap(), 0, sizeof(XPoint
) * (max
+1) )))
1125 WARN("No memory to convert POINTs to XPoints!\n");
1128 for (i
= 0; i
< polylines
; i
++)
1130 for (j
= 0; j
< counts
[i
]; j
++)
1132 points
[j
].x
= dc
->w
.DCOrgX
+ XLPTODP( dc
, pt
->x
);
1133 points
[j
].y
= dc
->w
.DCOrgY
+ YLPTODP( dc
, pt
->y
);
1136 points
[j
] = points
[0];
1137 TSXDrawLines( display
, physDev
->drawable
, physDev
->gc
,
1138 points
, j
+ 1, CoordModeOrigin
);
1141 /* Update the DIBSection of the dc's bitmap */
1142 X11DRV_DIB_UpdateDIBSection(dc
, TRUE
);
1144 HeapFree( GetProcessHeap(), 0, points
);
1150 /**********************************************************************
1151 * X11DRV_InternalFloodFill
1153 * Internal helper function for flood fill.
1154 * (xorg,yorg) is the origin of the X image relative to the drawable.
1155 * (x,y) is relative to the origin of the X image.
1157 static void X11DRV_InternalFloodFill(XImage
*image
, DC
*dc
,
1160 Pixel pixel
, WORD fillType
)
1162 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
1165 #define TO_FLOOD(x,y) ((fillType == FLOODFILLBORDER) ? \
1166 (XGetPixel(image,x,y) != pixel) : \
1167 (XGetPixel(image,x,y) == pixel))
1169 if (!TO_FLOOD(x
,y
)) return;
1171 /* Find left and right boundaries */
1174 while ((left
> 0) && TO_FLOOD( left
-1, y
)) left
--;
1175 while ((right
< image
->width
) && TO_FLOOD( right
, y
)) right
++;
1176 XFillRectangle( display
, physDev
->drawable
, physDev
->gc
,
1177 xOrg
+ left
, yOrg
+ y
, right
-left
, 1 );
1179 /* Set the pixels of this line so we don't fill it again */
1181 for (x
= left
; x
< right
; x
++)
1183 if (fillType
== FLOODFILLBORDER
) XPutPixel( image
, x
, y
, pixel
);
1184 else XPutPixel( image
, x
, y
, ~pixel
);
1187 /* Fill the line above */
1194 while ((x
< right
) && !TO_FLOOD(x
,y
)) x
++;
1195 if (x
>= right
) break;
1196 while ((x
< right
) && TO_FLOOD(x
,y
)) x
++;
1197 X11DRV_InternalFloodFill(image
, dc
, x
-1, y
,
1198 xOrg
, yOrg
, pixel
, fillType
);
1202 /* Fill the line below */
1204 if ((y
+= 2) < image
->height
)
1209 while ((x
< right
) && !TO_FLOOD(x
,y
)) x
++;
1210 if (x
>= right
) break;
1211 while ((x
< right
) && TO_FLOOD(x
,y
)) x
++;
1212 X11DRV_InternalFloodFill(image
, dc
, x
-1, y
,
1213 xOrg
, yOrg
, pixel
, fillType
);
1220 /**********************************************************************
1221 * X11DRV_DoFloodFill
1223 * Main flood-fill routine.
1225 * The Xlib critical section must be entered before calling this function.
1228 struct FloodFill_params
1237 static BOOL
X11DRV_DoFloodFill( const struct FloodFill_params
*params
)
1241 DC
*dc
= params
->dc
;
1242 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
1244 if (GetRgnBox( dc
->w
.hGCClipRgn
, &rect
) == ERROR
) return FALSE
;
1246 if (!(image
= XGetImage( display
, physDev
->drawable
,
1249 rect
.right
- rect
.left
,
1250 rect
.bottom
- rect
.top
,
1251 AllPlanes
, ZPixmap
))) return FALSE
;
1253 if (X11DRV_SetupGCForBrush( dc
))
1255 /* Update the pixmap from the DIB section */
1256 X11DRV_DIB_UpdateDIBSection(dc
, FALSE
);
1258 /* ROP mode is always GXcopy for flood-fill */
1259 XSetFunction( display
, physDev
->gc
, GXcopy
);
1260 X11DRV_InternalFloodFill(image
, dc
,
1261 XLPTODP(dc
,params
->x
) + dc
->w
.DCOrgX
- rect
.left
,
1262 YLPTODP(dc
,params
->y
) + dc
->w
.DCOrgY
- rect
.top
,
1265 X11DRV_PALETTE_ToPhysical( dc
, params
->color
),
1268 /* Update the DIBSection of the dc's bitmap */
1269 X11DRV_DIB_UpdateDIBSection(dc
, TRUE
);
1272 XDestroyImage( image
);
1277 /**********************************************************************
1278 * X11DRV_ExtFloodFill
1281 X11DRV_ExtFloodFill( DC
*dc
, INT x
, INT y
, COLORREF color
,
1285 struct FloodFill_params params
;
1287 TRACE("X11DRV_ExtFloodFill %d,%d %06lx %d\n",
1288 x
, y
, color
, fillType
);
1293 params
.color
= color
;
1294 params
.fillType
= fillType
;
1296 if (!PtVisible( dc
->hSelf
, x
, y
)) return FALSE
;
1297 EnterCriticalSection( &X11DRV_CritSection
);
1298 result
= CALL_LARGE_STACK( X11DRV_DoFloodFill
, ¶ms
);
1299 LeaveCriticalSection( &X11DRV_CritSection
);
1303 /**********************************************************************
1307 X11DRV_SetBkColor( DC
*dc
, COLORREF color
)
1309 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
1312 oldColor
= dc
->w
.backgroundColor
;
1313 dc
->w
.backgroundColor
= color
;
1315 physDev
->backgroundPixel
= X11DRV_PALETTE_ToPhysical( dc
, color
);
1320 /**********************************************************************
1321 * X11DRV_SetTextColor
1324 X11DRV_SetTextColor( DC
*dc
, COLORREF color
)
1326 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
1329 oldColor
= dc
->w
.textColor
;
1330 dc
->w
.textColor
= color
;
1332 physDev
->textPixel
= X11DRV_PALETTE_ToPhysical( dc
, color
);
1337 /***********************************************************************
1340 BOOL
X11DRV_GetDCOrgEx( DC
*dc
, LPPOINT lpp
)
1342 if (!(dc
->w
.flags
& DC_MEMORY
))
1344 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*) dc
->physDev
;
1346 int w
, h
, border
, depth
;
1348 /* FIXME: this is not correct for managed windows */
1349 TSXGetGeometry( display
, physDev
->drawable
, &root
,
1350 (int*)&lpp
->x
, (int*)&lpp
->y
, &w
, &h
, &border
, &depth
);
1352 else lpp
->x
= lpp
->y
= 0;
1356 #endif /* !defined(X_DISPLAY_MISSING) */