2 * X11 graphics driver graphics functions
4 * Copyright 1993,1994 Alexandre Julliard
8 * FIXME: none of these functions obey the GM_ADVANCED
14 #include <X11/Intrinsic.h>
38 #include "debugtools.h"
40 DEFAULT_DEBUG_CHANNEL(graphics
);
42 #define ABS(x) ((x)<0?(-(x)):(x))
44 /* ROP code to GC function conversion */
45 const int X11DRV_XROPfunction
[16] =
47 GXclear
, /* R2_BLACK */
48 GXnor
, /* R2_NOTMERGEPEN */
49 GXandInverted
, /* R2_MASKNOTPEN */
50 GXcopyInverted
, /* R2_NOTCOPYPEN */
51 GXandReverse
, /* R2_MASKPENNOT */
52 GXinvert
, /* R2_NOT */
53 GXxor
, /* R2_XORPEN */
54 GXnand
, /* R2_NOTMASKPEN */
55 GXand
, /* R2_MASKPEN */
56 GXequiv
, /* R2_NOTXORPEN */
58 GXorInverted
, /* R2_MERGENOTPEN */
59 GXcopy
, /* R2_COPYPEN */
60 GXorReverse
, /* R2_MERGEPENNOT */
61 GXor
, /* R2_MERGEPEN */
66 /***********************************************************************
67 * X11DRV_SetupGCForPatBlt
69 * Setup the GC for a PatBlt operation using current brush.
70 * If fMapColors is TRUE, X pixels are mapped to Windows colors.
71 * Return FALSE if brush is BS_NULL, TRUE otherwise.
73 BOOL
X11DRV_SetupGCForPatBlt( DC
* dc
, GC gc
, BOOL fMapColors
)
78 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
80 if (physDev
->brush
.style
== BS_NULL
) return FALSE
;
81 if (physDev
->brush
.pixel
== -1)
83 /* Special case used for monochrome pattern brushes.
84 * We need to swap foreground and background because
85 * Windows does it the wrong way...
87 val
.foreground
= physDev
->backgroundPixel
;
88 val
.background
= physDev
->textPixel
;
92 val
.foreground
= physDev
->brush
.pixel
;
93 val
.background
= physDev
->backgroundPixel
;
95 if (fMapColors
&& X11DRV_PALETTE_XPixelToPalette
)
97 val
.foreground
= X11DRV_PALETTE_XPixelToPalette
[val
.foreground
];
98 val
.background
= X11DRV_PALETTE_XPixelToPalette
[val
.background
];
101 val
.function
= X11DRV_XROPfunction
[dc
->ROPmode
-1];
103 ** Let's replace GXinvert by GXxor with (black xor white)
104 ** This solves the selection color and leak problems in excel
105 ** FIXME : Let's do that only if we work with X-pixels, not with Win-pixels
107 if (val
.function
== GXinvert
)
109 val
.foreground
= BlackPixelOfScreen(X11DRV_GetXScreen()) ^ WhitePixelOfScreen(X11DRV_GetXScreen());
110 val
.function
= GXxor
;
112 val
.fill_style
= physDev
->brush
.fillStyle
;
113 switch(val
.fill_style
)
116 case FillOpaqueStippled
:
117 if (dc
->backgroundMode
==OPAQUE
) val
.fill_style
= FillOpaqueStippled
;
118 val
.stipple
= physDev
->brush
.pixmap
;
123 if (fMapColors
&& X11DRV_PALETTE_XPixelToPalette
)
127 EnterCriticalSection( &X11DRV_CritSection
);
128 pixmap
= XCreatePixmap( display
, X11DRV_GetXRootWindow(),
129 8, 8, X11DRV_GetDepth() );
130 image
= XGetImage( display
, physDev
->brush
.pixmap
, 0, 0, 8, 8,
131 AllPlanes
, ZPixmap
);
132 for (y
= 0; y
< 8; y
++)
133 for (x
= 0; x
< 8; x
++)
134 XPutPixel( image
, x
, y
,
135 X11DRV_PALETTE_XPixelToPalette
[XGetPixel( image
, x
, y
)] );
136 XPutImage( display
, pixmap
, gc
, image
, 0, 0, 0, 0, 8, 8 );
137 XDestroyImage( image
);
138 LeaveCriticalSection( &X11DRV_CritSection
);
141 else val
.tile
= physDev
->brush
.pixmap
;
149 val
.ts_x_origin
= dc
->DCOrgX
+ dc
->brushOrgX
;
150 val
.ts_y_origin
= dc
->DCOrgY
+ dc
->brushOrgY
;
151 val
.fill_rule
= (dc
->polyFillMode
==WINDING
) ? WindingRule
: EvenOddRule
;
152 TSXChangeGC( display
, gc
,
153 GCFunction
| GCForeground
| GCBackground
| GCFillStyle
|
154 GCFillRule
| GCTileStipXOrigin
| GCTileStipYOrigin
| mask
,
156 if (pixmap
) TSXFreePixmap( display
, pixmap
);
161 /***********************************************************************
162 * X11DRV_SetupGCForBrush
164 * Setup physDev->gc for drawing operations using current brush.
165 * Return FALSE if brush is BS_NULL, TRUE otherwise.
167 BOOL
X11DRV_SetupGCForBrush( DC
* dc
)
169 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
170 return X11DRV_SetupGCForPatBlt( dc
, physDev
->gc
, FALSE
);
174 /***********************************************************************
175 * X11DRV_SetupGCForPen
177 * Setup physDev->gc for drawing operations using current pen.
178 * Return FALSE if pen is PS_NULL, TRUE otherwise.
180 BOOL
X11DRV_SetupGCForPen( DC
* dc
)
183 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
185 if (physDev
->pen
.style
== PS_NULL
) return FALSE
;
190 val
.foreground
= BlackPixelOfScreen( X11DRV_GetXScreen() );
191 val
.function
= GXcopy
;
194 val
.foreground
= WhitePixelOfScreen( X11DRV_GetXScreen() );
195 val
.function
= GXcopy
;
198 val
.foreground
= physDev
->pen
.pixel
;
199 /* It is very unlikely someone wants to XOR with 0 */
200 /* This fixes the rubber-drawings in paintbrush */
201 if (val
.foreground
== 0)
202 val
.foreground
= BlackPixelOfScreen( X11DRV_GetXScreen() )
203 ^ WhitePixelOfScreen( X11DRV_GetXScreen() );
204 val
.function
= GXxor
;
207 val
.foreground
= physDev
->pen
.pixel
;
208 val
.function
= X11DRV_XROPfunction
[dc
->ROPmode
-1];
210 val
.background
= physDev
->backgroundPixel
;
211 val
.fill_style
= FillSolid
;
212 if ((physDev
->pen
.width
<= 1) &&
213 (physDev
->pen
.style
!= PS_SOLID
) &&
214 (physDev
->pen
.style
!= PS_INSIDEFRAME
))
216 TSXSetDashes( display
, physDev
->gc
, 0, physDev
->pen
.dashes
,
217 physDev
->pen
.dash_len
);
218 val
.line_style
= (dc
->backgroundMode
== OPAQUE
) ?
219 LineDoubleDash
: LineOnOffDash
;
221 else val
.line_style
= LineSolid
;
222 val
.line_width
= physDev
->pen
.width
;
223 if (val
.line_width
<= 1) {
224 val
.cap_style
= CapNotLast
;
226 switch (physDev
->pen
.endcap
)
228 case PS_ENDCAP_SQUARE
:
229 val
.cap_style
= CapProjecting
;
232 val
.cap_style
= CapButt
;
234 case PS_ENDCAP_ROUND
:
236 val
.cap_style
= CapRound
;
239 switch (physDev
->pen
.linejoin
)
242 val
.join_style
= JoinBevel
;
245 val
.join_style
= JoinMiter
;
249 val
.join_style
= JoinRound
;
251 TSXChangeGC( display
, physDev
->gc
,
252 GCFunction
| GCForeground
| GCBackground
| GCLineWidth
|
253 GCLineStyle
| GCCapStyle
| GCJoinStyle
| GCFillStyle
, &val
);
258 /***********************************************************************
259 * X11DRV_SetupGCForText
261 * Setup physDev->gc for text drawing operations.
262 * Return FALSE if the font is null, TRUE otherwise.
264 BOOL
X11DRV_SetupGCForText( DC
* dc
)
266 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
267 XFontStruct
* xfs
= XFONT_GetFontStruct( physDev
->font
);
273 val
.function
= GXcopy
; /* Text is always GXcopy */
274 val
.foreground
= physDev
->textPixel
;
275 val
.background
= physDev
->backgroundPixel
;
276 val
.fill_style
= FillSolid
;
279 TSXChangeGC( display
, physDev
->gc
,
280 GCFunction
| GCForeground
| GCBackground
| GCFillStyle
|
284 WARN("Physical font failure\n" );
288 /***********************************************************************
292 X11DRV_LineTo( DC
*dc
, INT x
, INT y
)
294 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
296 if (X11DRV_SetupGCForPen( dc
)) {
297 /* Update the pixmap from the DIB section */
298 X11DRV_DIB_UpdateDIBSection(dc
, FALSE
);
299 TSXDrawLine(display
, physDev
->drawable
, physDev
->gc
,
300 dc
->DCOrgX
+ XLPTODP( dc
, dc
->CursPosX
),
301 dc
->DCOrgY
+ YLPTODP( dc
, dc
->CursPosY
),
302 dc
->DCOrgX
+ XLPTODP( dc
, x
),
303 dc
->DCOrgY
+ YLPTODP( dc
, y
) );
304 /* Update the DIBSection from the pixmap */
305 X11DRV_DIB_UpdateDIBSection(dc
, TRUE
);
312 /***********************************************************************
315 * Helper functions for Arc(), Chord() and Pie().
316 * 'lines' is the number of lines to draw: 0 for Arc, 1 for Chord, 2 for Pie.
320 X11DRV_DrawArc( DC
*dc
, INT left
, INT top
, INT right
,
321 INT bottom
, INT xstart
, INT ystart
,
322 INT xend
, INT yend
, INT lines
)
324 INT xcenter
, ycenter
, istart_angle
, idiff_angle
;
325 INT width
, oldwidth
, oldendcap
;
326 double start_angle
, end_angle
;
328 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
331 left
= XLPTODP( dc
, left
);
332 top
= YLPTODP( dc
, top
);
333 right
= XLPTODP( dc
, right
);
334 bottom
= YLPTODP( dc
, bottom
);
335 xstart
= XLPTODP( dc
, xstart
);
336 ystart
= YLPTODP( dc
, ystart
);
337 xend
= XLPTODP( dc
, xend
);
338 yend
= YLPTODP( dc
, yend
);
340 if (right
< left
) { INT tmp
= right
; right
= left
; left
= tmp
; }
341 if (bottom
< top
) { INT tmp
= bottom
; bottom
= top
; top
= tmp
; }
342 if ((left
== right
) || (top
== bottom
)
343 ||(lines
&& ((right
-left
==1)||(bottom
-top
==1)))) return TRUE
;
345 if( dc
->ArcDirection
== AD_CLOCKWISE
)
346 { INT tmp
= xstart
; xstart
= xend
; xend
= tmp
;
347 tmp
= ystart
; ystart
= yend
; yend
= tmp
; }
349 oldwidth
= width
= physDev
->pen
.width
;
350 oldendcap
= physDev
->pen
.endcap
;
351 if (!width
) width
= 1;
352 if(physDev
->pen
.style
== PS_NULL
) width
= 0;
354 if ((physDev
->pen
.style
== PS_INSIDEFRAME
))
356 if (2*width
> (right
-left
)) width
=(right
-left
+ 1)/2;
357 if (2*width
> (bottom
-top
)) width
=(bottom
-top
+ 1)/2;
359 right
-= (width
- 1) / 2;
361 bottom
-= (width
- 1) / 2;
363 if(width
== 0) width
= 1; /* more accurate */
364 physDev
->pen
.width
= width
;
365 physDev
->pen
.endcap
= PS_ENDCAP_SQUARE
;
367 xcenter
= (right
+ left
) / 2;
368 ycenter
= (bottom
+ top
) / 2;
369 start_angle
= atan2( (double)(ycenter
-ystart
)*(right
-left
),
370 (double)(xstart
-xcenter
)*(bottom
-top
) );
371 end_angle
= atan2( (double)(ycenter
-yend
)*(right
-left
),
372 (double)(xend
-xcenter
)*(bottom
-top
) );
373 if ((xstart
==xend
)&&(ystart
==yend
))
374 { /* A lazy program delivers xstart=xend=ystart=yend=0) */
378 else /* notorious cases */
379 if ((start_angle
== PI
)&&( end_angle
<0))
382 if ((end_angle
== PI
)&&( start_angle
<0))
384 istart_angle
= (INT
)(start_angle
* 180 * 64 / PI
+ 0.5);
385 idiff_angle
= (INT
)((end_angle
- start_angle
) * 180 * 64 / PI
+ 0.5);
386 if (idiff_angle
<= 0) idiff_angle
+= 360 * 64;
388 /* Update the pixmap from the DIB section */
389 X11DRV_DIB_UpdateDIBSection(dc
, FALSE
);
391 /* Fill arc with brush if Chord() or Pie() */
393 if ((lines
> 0) && X11DRV_SetupGCForBrush( dc
)) {
394 TSXSetArcMode( display
, physDev
->gc
,
395 (lines
==1) ? ArcChord
: ArcPieSlice
);
396 TSXFillArc( display
, physDev
->drawable
, physDev
->gc
,
397 dc
->DCOrgX
+ left
, dc
->DCOrgY
+ top
,
398 right
-left
-1, bottom
-top
-1, istart_angle
, idiff_angle
);
402 /* Draw arc and lines */
404 if (X11DRV_SetupGCForPen( dc
)){
405 TSXDrawArc( display
, physDev
->drawable
, physDev
->gc
,
406 dc
->DCOrgX
+ left
, dc
->DCOrgY
+ top
,
407 right
-left
-1, bottom
-top
-1, istart_angle
, idiff_angle
);
409 /* use the truncated values */
410 start_angle
=(double)istart_angle
*PI
/64./180.;
411 end_angle
=(double)(istart_angle
+idiff_angle
)*PI
/64./180.;
412 /* calculate the endpoints and round correctly */
413 points
[0].x
= (int) floor(dc
->DCOrgX
+ (right
+left
)/2.0 +
414 cos(start_angle
) * (right
-left
-width
*2+2) / 2. + 0.5);
415 points
[0].y
= (int) floor(dc
->DCOrgY
+ (top
+bottom
)/2.0 -
416 sin(start_angle
) * (bottom
-top
-width
*2+2) / 2. + 0.5);
417 points
[1].x
= (int) floor(dc
->DCOrgX
+ (right
+left
)/2.0 +
418 cos(end_angle
) * (right
-left
-width
*2+2) / 2. + 0.5);
419 points
[1].y
= (int) floor(dc
->DCOrgY
+ (top
+bottom
)/2.0 -
420 sin(end_angle
) * (bottom
-top
-width
*2+2) / 2. + 0.5);
422 /* OK this stuff is optimized for Xfree86
423 * which is probably the most used server by
424 * wine users. Other X servers will not
425 * display correctly. (eXceed for instance)
426 * so if you feel you must change make sure that
427 * you either use Xfree86 or seperate your changes
428 * from these (compile switch or whatever)
432 points
[3] = points
[1];
433 points
[1].x
= dc
->DCOrgX
+ xcenter
;
434 points
[1].y
= dc
->DCOrgY
+ ycenter
;
435 points
[2] = points
[1];
436 dx1
=points
[1].x
-points
[0].x
;
437 dy1
=points
[1].y
-points
[0].y
;
438 if(((top
-bottom
) | -2) == -2)
439 if(dy1
>0) points
[1].y
--;
441 if (((-dx1
)*64)<=ABS(dy1
)*37) points
[0].x
--;
442 if(((-dx1
*9))<(dy1
*16)) points
[0].y
--;
443 if( dy1
<0 && ((dx1
*9)) < (dy1
*16)) points
[0].y
--;
445 if(dy1
< 0) points
[0].y
--;
446 if(((right
-left
) | -2) == -2) points
[1].x
--;
448 dx1
=points
[3].x
-points
[2].x
;
449 dy1
=points
[3].y
-points
[2].y
;
450 if(((top
-bottom
) | -2 ) == -2)
451 if(dy1
< 0) points
[2].y
--;
453 if( dy1
>0) points
[3].y
--;
454 if(((right
-left
) | -2) == -2 ) points
[2].x
--;
457 if( dx1
* 64 < dy1
* -37 ) points
[3].x
--;
461 TSXDrawLines( display
, physDev
->drawable
, physDev
->gc
,
462 points
, lines
+1, CoordModeOrigin
);
467 /* Update the DIBSection of the pixmap */
468 if (update
) X11DRV_DIB_UpdateDIBSection(dc
, TRUE
);
470 physDev
->pen
.width
= oldwidth
;
471 physDev
->pen
.endcap
= oldendcap
;
476 /***********************************************************************
480 X11DRV_Arc( DC
*dc
, INT left
, INT top
, INT right
, INT bottom
,
481 INT xstart
, INT ystart
, INT xend
, INT yend
)
483 return X11DRV_DrawArc( dc
, left
, top
, right
, bottom
,
484 xstart
, ystart
, xend
, yend
, 0 );
488 /***********************************************************************
492 X11DRV_Pie( DC
*dc
, INT left
, INT top
, INT right
, INT bottom
,
493 INT xstart
, INT ystart
, INT xend
, INT yend
)
495 return X11DRV_DrawArc( dc
, left
, top
, right
, bottom
,
496 xstart
, ystart
, xend
, yend
, 2 );
499 /***********************************************************************
503 X11DRV_Chord( DC
*dc
, INT left
, INT top
, INT right
, INT bottom
,
504 INT xstart
, INT ystart
, INT xend
, INT yend
)
506 return X11DRV_DrawArc( dc
, left
, top
, right
, bottom
,
507 xstart
, ystart
, xend
, yend
, 1 );
511 /***********************************************************************
515 X11DRV_Ellipse( DC
*dc
, INT left
, INT top
, INT right
, INT bottom
)
518 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
521 left
= XLPTODP( dc
, left
);
522 top
= YLPTODP( dc
, top
);
523 right
= XLPTODP( dc
, right
);
524 bottom
= YLPTODP( dc
, bottom
);
525 if ((left
== right
) || (top
== bottom
)) return TRUE
;
527 if (right
< left
) { INT tmp
= right
; right
= left
; left
= tmp
; }
528 if (bottom
< top
) { INT tmp
= bottom
; bottom
= top
; top
= tmp
; }
530 oldwidth
= width
= physDev
->pen
.width
;
531 if (!width
) width
= 1;
532 if(physDev
->pen
.style
== PS_NULL
) width
= 0;
534 if ((physDev
->pen
.style
== PS_INSIDEFRAME
))
536 if (2*width
> (right
-left
)) width
=(right
-left
+ 1)/2;
537 if (2*width
> (bottom
-top
)) width
=(bottom
-top
+ 1)/2;
539 right
-= (width
- 1) / 2;
541 bottom
-= (width
- 1) / 2;
543 if(width
== 0) width
= 1; /* more accurate */
544 physDev
->pen
.width
= width
;
546 /* Update the pixmap from the DIB section */
547 X11DRV_DIB_UpdateDIBSection(dc
, FALSE
);
549 if (X11DRV_SetupGCForBrush( dc
))
551 TSXFillArc( display
, physDev
->drawable
, physDev
->gc
,
552 dc
->DCOrgX
+ left
, dc
->DCOrgY
+ top
,
553 right
-left
-1, bottom
-top
-1, 0, 360*64 );
556 if (X11DRV_SetupGCForPen( dc
))
558 TSXDrawArc( display
, physDev
->drawable
, physDev
->gc
,
559 dc
->DCOrgX
+ left
, dc
->DCOrgY
+ top
,
560 right
-left
-1, bottom
-top
-1, 0, 360*64 );
564 /* Update the DIBSection from the pixmap */
565 if (update
) X11DRV_DIB_UpdateDIBSection(dc
, TRUE
);
567 physDev
->pen
.width
= oldwidth
;
572 /***********************************************************************
576 X11DRV_Rectangle(DC
*dc
, INT left
, INT top
, INT right
, INT bottom
)
578 INT width
, oldwidth
, oldjoinstyle
;
579 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
582 TRACE("(%d %d %d %d)\n",
583 left
, top
, right
, bottom
);
585 left
= XLPTODP( dc
, left
);
586 top
= YLPTODP( dc
, top
);
587 right
= XLPTODP( dc
, right
);
588 bottom
= YLPTODP( dc
, bottom
);
590 if ((left
== right
) || (top
== bottom
)) return TRUE
;
592 if (right
< left
) { INT tmp
= right
; right
= left
; left
= tmp
; }
593 if (bottom
< top
) { INT tmp
= bottom
; bottom
= top
; top
= tmp
; }
595 oldwidth
= width
= physDev
->pen
.width
;
596 if (!width
) width
= 1;
597 if(physDev
->pen
.style
== PS_NULL
) width
= 0;
599 if ((physDev
->pen
.style
== PS_INSIDEFRAME
))
601 if (2*width
> (right
-left
)) width
=(right
-left
+ 1)/2;
602 if (2*width
> (bottom
-top
)) width
=(bottom
-top
+ 1)/2;
604 right
-= (width
- 1) / 2;
606 bottom
-= (width
- 1) / 2;
608 if(width
== 1) width
= 0;
609 physDev
->pen
.width
= width
;
610 oldjoinstyle
= physDev
->pen
.linejoin
;
611 if(physDev
->pen
.type
!= PS_GEOMETRIC
)
612 physDev
->pen
.linejoin
= PS_JOIN_MITER
;
614 /* Update the pixmap from the DIB section */
615 X11DRV_DIB_UpdateDIBSection(dc
, FALSE
);
617 if ((right
> left
+ width
) && (bottom
> top
+ width
))
618 if (X11DRV_SetupGCForBrush( dc
))
620 TSXFillRectangle( display
, physDev
->drawable
, physDev
->gc
,
621 dc
->DCOrgX
+ left
+ (width
+ 1) / 2,
622 dc
->DCOrgY
+ top
+ (width
+ 1) / 2,
623 right
-left
-width
-1, bottom
-top
-width
-1);
626 if (X11DRV_SetupGCForPen( dc
))
628 TSXDrawRectangle( display
, physDev
->drawable
, physDev
->gc
,
629 dc
->DCOrgX
+ left
, dc
->DCOrgY
+ top
,
630 right
-left
-1, bottom
-top
-1 );
634 /* Update the DIBSection from the pixmap */
635 if (update
) X11DRV_DIB_UpdateDIBSection(dc
, TRUE
);
637 physDev
->pen
.width
= oldwidth
;
638 physDev
->pen
.linejoin
= oldjoinstyle
;
642 /***********************************************************************
646 X11DRV_RoundRect( DC
*dc
, INT left
, INT top
, INT right
,
647 INT bottom
, INT ell_width
, INT ell_height
)
649 INT width
, oldwidth
, oldendcap
;
650 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
653 TRACE("(%d %d %d %d %d %d\n",
654 left
, top
, right
, bottom
, ell_width
, ell_height
);
656 left
= XLPTODP( dc
, left
);
657 top
= YLPTODP( dc
, top
);
658 right
= XLPTODP( dc
, right
);
659 bottom
= YLPTODP( dc
, bottom
);
661 if ((left
== right
) || (top
== bottom
))
664 /* Make sure ell_width and ell_height are >= 1 otherwise XDrawArc gets
665 called with width/height < 0 */
666 ell_width
= max(abs( ell_width
* dc
->vportExtX
/ dc
->wndExtX
), 1);
667 ell_height
= max(abs( ell_height
* dc
->vportExtY
/ dc
->wndExtY
), 1);
669 /* Fix the coordinates */
671 if (right
< left
) { INT tmp
= right
; right
= left
; left
= tmp
; }
672 if (bottom
< top
) { INT tmp
= bottom
; bottom
= top
; top
= tmp
; }
674 oldwidth
= width
= physDev
->pen
.width
;
675 oldendcap
= physDev
->pen
.endcap
;
676 if (!width
) width
= 1;
677 if(physDev
->pen
.style
== PS_NULL
) width
= 0;
679 if ((physDev
->pen
.style
== PS_INSIDEFRAME
))
681 if (2*width
> (right
-left
)) width
=(right
-left
+ 1)/2;
682 if (2*width
> (bottom
-top
)) width
=(bottom
-top
+ 1)/2;
684 right
-= (width
- 1) / 2;
686 bottom
-= (width
- 1) / 2;
688 if(width
== 0) width
= 1;
689 physDev
->pen
.width
= width
;
690 physDev
->pen
.endcap
= PS_ENDCAP_SQUARE
;
692 /* Update the pixmap from the DIB section */
693 X11DRV_DIB_UpdateDIBSection(dc
, FALSE
);
695 if (X11DRV_SetupGCForBrush( dc
))
697 if (ell_width
> (right
-left
) )
698 if (ell_height
> (bottom
-top
) )
699 TSXFillArc( display
, physDev
->drawable
, physDev
->gc
,
700 dc
->DCOrgX
+ left
, dc
->DCOrgY
+ top
,
701 right
- left
- 1, bottom
- top
- 1,
704 TSXFillArc( display
, physDev
->drawable
, physDev
->gc
,
705 dc
->DCOrgX
+ left
, dc
->DCOrgY
+ top
,
706 right
- left
- 1, ell_height
, 0, 180 * 64 );
707 TSXFillArc( display
, physDev
->drawable
, physDev
->gc
,
709 dc
->DCOrgY
+ bottom
- ell_height
- 1,
710 right
- left
- 1, ell_height
, 180 * 64,
713 else if (ell_height
> (bottom
-top
) ){
714 TSXFillArc( display
, physDev
->drawable
, physDev
->gc
,
715 dc
->DCOrgX
+ left
, dc
->DCOrgY
+ top
,
716 ell_width
, bottom
- top
- 1, 90 * 64, 180 * 64 );
717 TSXFillArc( display
, physDev
->drawable
, physDev
->gc
,
718 dc
->DCOrgX
+ right
- ell_width
-1, dc
->DCOrgY
+ top
,
719 ell_width
, bottom
- top
- 1, 270 * 64, 180 * 64 );
721 TSXFillArc( display
, physDev
->drawable
, physDev
->gc
,
722 dc
->DCOrgX
+ left
, dc
->DCOrgY
+ top
,
723 ell_width
, ell_height
, 90 * 64, 90 * 64 );
724 TSXFillArc( display
, physDev
->drawable
, physDev
->gc
,
726 dc
->DCOrgY
+ bottom
- ell_height
- 1,
727 ell_width
, ell_height
, 180 * 64, 90 * 64 );
728 TSXFillArc( display
, physDev
->drawable
, physDev
->gc
,
729 dc
->DCOrgX
+ right
- ell_width
- 1,
730 dc
->DCOrgY
+ bottom
- ell_height
- 1,
731 ell_width
, ell_height
, 270 * 64, 90 * 64 );
732 TSXFillArc( display
, physDev
->drawable
, physDev
->gc
,
733 dc
->DCOrgX
+ right
- ell_width
- 1,
735 ell_width
, ell_height
, 0, 90 * 64 );
737 if (ell_width
< right
- left
)
739 TSXFillRectangle( display
, physDev
->drawable
, physDev
->gc
,
740 dc
->DCOrgX
+ left
+ (ell_width
+ 1) / 2,
741 dc
->DCOrgY
+ top
+ 1,
742 right
- left
- ell_width
- 1,
743 (ell_height
+ 1) / 2 - 1);
744 TSXFillRectangle( display
, physDev
->drawable
, physDev
->gc
,
745 dc
->DCOrgX
+ left
+ (ell_width
+ 1) / 2,
746 dc
->DCOrgY
+ bottom
- (ell_height
) / 2 - 1,
747 right
- left
- ell_width
- 1,
750 if (ell_height
< bottom
- top
)
752 TSXFillRectangle( display
, physDev
->drawable
, physDev
->gc
,
753 dc
->DCOrgX
+ left
+ 1,
754 dc
->DCOrgY
+ top
+ (ell_height
+ 1) / 2,
756 bottom
- top
- ell_height
- 1);
760 /* FIXME: this could be done with on X call
761 * more efficient and probably more correct
762 * on any X server: XDrawArcs will draw
763 * straight horizontal and vertical lines
764 * if width or height are zero.
766 * BTW this stuff is optimized for an Xfree86 server
767 * read the comments inside the X11DRV_DrawArc function
769 if (X11DRV_SetupGCForPen(dc
)) {
770 if (ell_width
> (right
-left
) )
771 if (ell_height
> (bottom
-top
) )
772 TSXDrawArc( display
, physDev
->drawable
, physDev
->gc
,
773 dc
->DCOrgX
+ left
, dc
->DCOrgY
+ top
,
774 right
- left
- 1, bottom
-top
- 1, 0 , 360 * 64 );
776 TSXDrawArc( display
, physDev
->drawable
, physDev
->gc
,
777 dc
->DCOrgX
+ left
, dc
->DCOrgY
+ top
,
778 right
- left
- 1, ell_height
- 1, 0 , 180 * 64 );
779 TSXDrawArc( display
, physDev
->drawable
, physDev
->gc
,
781 dc
->DCOrgY
+ bottom
- ell_height
,
782 right
- left
- 1, ell_height
- 1, 180 * 64 , 180 * 64 );
784 else if (ell_height
> (bottom
-top
) ){
785 TSXDrawArc( display
, physDev
->drawable
, physDev
->gc
,
786 dc
->DCOrgX
+ left
, dc
->DCOrgY
+ top
,
787 ell_width
- 1 , bottom
- top
- 1, 90 * 64 , 180 * 64 );
788 TSXDrawArc( display
, physDev
->drawable
, physDev
->gc
,
789 dc
->DCOrgX
+ right
- ell_width
,
791 ell_width
- 1 , bottom
- top
- 1, 270 * 64 , 180 * 64 );
793 TSXDrawArc( display
, physDev
->drawable
, physDev
->gc
,
794 dc
->DCOrgX
+ left
, dc
->DCOrgY
+ top
,
795 ell_width
- 1, ell_height
- 1, 90 * 64, 90 * 64 );
796 TSXDrawArc( display
, physDev
->drawable
, physDev
->gc
,
797 dc
->DCOrgX
+ left
, dc
->DCOrgY
+ bottom
- ell_height
,
798 ell_width
- 1, ell_height
- 1, 180 * 64, 90 * 64 );
799 TSXDrawArc( display
, physDev
->drawable
, physDev
->gc
,
800 dc
->DCOrgX
+ right
- ell_width
,
801 dc
->DCOrgY
+ bottom
- ell_height
,
802 ell_width
- 1, ell_height
- 1, 270 * 64, 90 * 64 );
803 TSXDrawArc( display
, physDev
->drawable
, physDev
->gc
,
804 dc
->DCOrgX
+ right
- ell_width
, dc
->DCOrgY
+ top
,
805 ell_width
- 1, ell_height
- 1, 0, 90 * 64 );
807 if (ell_width
< right
- left
)
809 TSXDrawLine( display
, physDev
->drawable
, physDev
->gc
,
810 dc
->DCOrgX
+ left
+ ell_width
/ 2,
812 dc
->DCOrgX
+ right
- (ell_width
+1) / 2,
814 TSXDrawLine( display
, physDev
->drawable
, physDev
->gc
,
815 dc
->DCOrgX
+ left
+ ell_width
/ 2 ,
816 dc
->DCOrgY
+ bottom
- 1,
817 dc
->DCOrgX
+ right
- (ell_width
+1)/ 2,
818 dc
->DCOrgY
+ bottom
- 1);
820 if (ell_height
< bottom
- top
)
822 TSXDrawLine( display
, physDev
->drawable
, physDev
->gc
,
823 dc
->DCOrgX
+ right
- 1,
824 dc
->DCOrgY
+ top
+ ell_height
/ 2,
825 dc
->DCOrgX
+ right
- 1,
826 dc
->DCOrgY
+ bottom
- (ell_height
+1) / 2);
827 TSXDrawLine( display
, physDev
->drawable
, physDev
->gc
,
829 dc
->DCOrgY
+ top
+ ell_height
/ 2,
831 dc
->DCOrgY
+ bottom
- (ell_height
+1) / 2);
836 /* Update the DIBSection from the pixmap */
837 if (update
) X11DRV_DIB_UpdateDIBSection(dc
, TRUE
);
839 physDev
->pen
.width
= oldwidth
;
840 physDev
->pen
.endcap
= oldendcap
;
845 /***********************************************************************
849 X11DRV_SetPixel( DC
*dc
, INT x
, INT y
, COLORREF color
)
852 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
854 x
= dc
->DCOrgX
+ XLPTODP( dc
, x
);
855 y
= dc
->DCOrgY
+ YLPTODP( dc
, y
);
856 pixel
= X11DRV_PALETTE_ToPhysical( dc
, color
);
858 TSXSetForeground( display
, physDev
->gc
, pixel
);
859 TSXSetFunction( display
, physDev
->gc
, GXcopy
);
860 TSXDrawPoint( display
, physDev
->drawable
, physDev
->gc
, x
, y
);
862 /* inefficient but simple... */
864 /* FIXME: the DIBSection pixel should be updated too */
866 return X11DRV_PALETTE_ToLogical(pixel
);
870 /***********************************************************************
874 X11DRV_GetPixel( DC
*dc
, INT x
, INT y
)
876 static Pixmap pixmap
= 0;
879 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
881 x
= dc
->DCOrgX
+ XLPTODP( dc
, x
);
882 y
= dc
->DCOrgY
+ YLPTODP( dc
, y
);
883 EnterCriticalSection( &X11DRV_CritSection
);
884 if (dc
->flags
& DC_MEMORY
)
886 image
= XGetImage( display
, physDev
->drawable
, x
, y
, 1, 1,
887 AllPlanes
, ZPixmap
);
891 /* If we are reading from the screen, use a temporary copy */
892 /* to avoid a BadMatch error */
893 if (!pixmap
) pixmap
= XCreatePixmap( display
, X11DRV_GetXRootWindow(),
894 1, 1, dc
->bitsPerPixel
);
895 XCopyArea( display
, physDev
->drawable
, pixmap
, BITMAP_colorGC
,
897 image
= XGetImage( display
, pixmap
, 0, 0, 1, 1, AllPlanes
, ZPixmap
);
899 pixel
= XGetPixel( image
, 0, 0 );
900 XDestroyImage( image
);
901 LeaveCriticalSection( &X11DRV_CritSection
);
903 return X11DRV_PALETTE_ToLogical(pixel
);
907 /***********************************************************************
911 X11DRV_PaintRgn( DC
*dc
, HRGN hrgn
)
914 HRGN tmpVisRgn
, prevVisRgn
;
915 HDC hdc
= dc
->hSelf
; /* FIXME: should not mix dc/hdc this way */
916 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
918 if (!(tmpVisRgn
= CreateRectRgn( 0, 0, 0, 0 ))) return FALSE
;
920 /* Transform region into device co-ords */
921 if ( !REGION_LPTODP( hdc
, tmpVisRgn
, hrgn
)
922 || OffsetRgn( tmpVisRgn
, dc
->DCOrgX
, dc
->DCOrgY
) == ERROR
) {
923 DeleteObject( tmpVisRgn
);
927 /* Modify visible region */
928 if (!(prevVisRgn
= SaveVisRgn16( hdc
))) {
929 DeleteObject( tmpVisRgn
);
932 CombineRgn( tmpVisRgn
, prevVisRgn
, tmpVisRgn
, RGN_AND
);
933 SelectVisRgn16( hdc
, tmpVisRgn
);
934 DeleteObject( tmpVisRgn
);
936 /* Fill the region */
938 GetRgnBox( dc
->hGCClipRgn
, &box
);
939 if (X11DRV_SetupGCForBrush( dc
))
941 /* Update the pixmap from the DIB section */
942 X11DRV_DIB_UpdateDIBSection(dc
, FALSE
);
944 TSXFillRectangle( display
, physDev
->drawable
, physDev
->gc
,
946 box
.right
-box
.left
, box
.bottom
-box
.top
);
948 /* Update the DIBSection from the pixmap */
949 X11DRV_DIB_UpdateDIBSection(dc
, TRUE
);
952 /* Restore the visible region */
954 RestoreVisRgn16( hdc
);
958 /**********************************************************************
962 X11DRV_Polyline( DC
*dc
, const POINT
* pt
, INT count
)
967 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
969 if((oldwidth
= physDev
->pen
.width
) == 0) physDev
->pen
.width
= 1;
971 if (!(points
= HeapAlloc( GetProcessHeap(), 0, sizeof(XPoint
) * count
)))
973 WARN("No memory to convert POINTs to XPoints!\n");
976 for (i
= 0; i
< count
; i
++)
978 points
[i
].x
= dc
->DCOrgX
+ XLPTODP( dc
, pt
[i
].x
);
979 points
[i
].y
= dc
->DCOrgY
+ YLPTODP( dc
, pt
[i
].y
);
982 if (X11DRV_SetupGCForPen ( dc
))
984 /* Update the pixmap from the DIB section */
985 X11DRV_DIB_UpdateDIBSection(dc
, FALSE
);
987 TSXDrawLines( display
, physDev
->drawable
, physDev
->gc
,
988 points
, count
, CoordModeOrigin
);
990 /* Update the DIBSection from the pixmap */
991 X11DRV_DIB_UpdateDIBSection(dc
, TRUE
);
994 HeapFree( GetProcessHeap(), 0, points
);
995 physDev
->pen
.width
= oldwidth
;
1000 /**********************************************************************
1004 X11DRV_Polygon( DC
*dc
, const POINT
* pt
, INT count
)
1008 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
1009 BOOL update
= FALSE
;
1011 if (!(points
= HeapAlloc( GetProcessHeap(), 0, sizeof(XPoint
) * (count
+1) )))
1013 WARN("No memory to convert POINTs to XPoints!\n");
1016 for (i
= 0; i
< count
; i
++)
1018 points
[i
].x
= dc
->DCOrgX
+ XLPTODP( dc
, pt
[i
].x
);
1019 points
[i
].y
= dc
->DCOrgY
+ YLPTODP( dc
, pt
[i
].y
);
1021 points
[count
] = points
[0];
1023 /* Update the pixmap from the DIB section */
1024 X11DRV_DIB_UpdateDIBSection(dc
, FALSE
);
1026 if (X11DRV_SetupGCForBrush( dc
))
1028 TSXFillPolygon( display
, physDev
->drawable
, physDev
->gc
,
1029 points
, count
+1, Complex
, CoordModeOrigin
);
1032 if (X11DRV_SetupGCForPen ( dc
))
1034 TSXDrawLines( display
, physDev
->drawable
, physDev
->gc
,
1035 points
, count
+1, CoordModeOrigin
);
1039 /* Update the DIBSection from the pixmap */
1040 if (update
) X11DRV_DIB_UpdateDIBSection(dc
, TRUE
);
1042 HeapFree( GetProcessHeap(), 0, points
);
1047 /**********************************************************************
1048 * X11DRV_PolyPolygon
1051 X11DRV_PolyPolygon( DC
*dc
, const POINT
* pt
, const INT
* counts
, UINT polygons
)
1054 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
1056 /* FIXME: The points should be converted to device coords before */
1057 /* creating the region. */
1059 hrgn
= CreatePolyPolygonRgn( pt
, counts
, polygons
, dc
->polyFillMode
);
1060 X11DRV_PaintRgn( dc
, hrgn
);
1061 DeleteObject( hrgn
);
1063 /* Draw the outline of the polygons */
1065 if (X11DRV_SetupGCForPen ( dc
))
1070 /* Update the pixmap from the DIB section */
1071 X11DRV_DIB_UpdateDIBSection(dc
, FALSE
);
1073 for (i
= 0; i
< polygons
; i
++) if (counts
[i
] > max
) max
= counts
[i
];
1074 if (!(points
= HeapAlloc( GetProcessHeap(), 0, sizeof(XPoint
) * (max
+1) )))
1076 WARN("No memory to convert POINTs to XPoints!\n");
1079 for (i
= 0; i
< polygons
; i
++)
1081 for (j
= 0; j
< counts
[i
]; j
++)
1083 points
[j
].x
= dc
->DCOrgX
+ XLPTODP( dc
, pt
->x
);
1084 points
[j
].y
= dc
->DCOrgY
+ YLPTODP( dc
, pt
->y
);
1087 points
[j
] = points
[0];
1088 TSXDrawLines( display
, physDev
->drawable
, physDev
->gc
,
1089 points
, j
+ 1, CoordModeOrigin
);
1092 /* Update the DIBSection of the dc's bitmap */
1093 X11DRV_DIB_UpdateDIBSection(dc
, TRUE
);
1095 HeapFree( GetProcessHeap(), 0, points
);
1101 /**********************************************************************
1102 * X11DRV_PolyPolyline
1105 X11DRV_PolyPolyline( DC
*dc
, const POINT
* pt
, const DWORD
* counts
, DWORD polylines
)
1107 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
1109 if (X11DRV_SetupGCForPen ( dc
))
1114 /* Update the pixmap from the DIB section */
1115 X11DRV_DIB_UpdateDIBSection(dc
, FALSE
);
1117 for (i
= 0; i
< polylines
; i
++) if (counts
[i
] > max
) max
= counts
[i
];
1118 if (!(points
= HeapAlloc( GetProcessHeap(), 0, sizeof(XPoint
) * max
)))
1120 WARN("No memory to convert POINTs to XPoints!\n");
1123 for (i
= 0; i
< polylines
; i
++)
1125 for (j
= 0; j
< counts
[i
]; j
++)
1127 points
[j
].x
= dc
->DCOrgX
+ XLPTODP( dc
, pt
->x
);
1128 points
[j
].y
= dc
->DCOrgY
+ YLPTODP( dc
, pt
->y
);
1131 TSXDrawLines( display
, physDev
->drawable
, physDev
->gc
,
1132 points
, j
, CoordModeOrigin
);
1135 /* Update the DIBSection of the dc's bitmap */
1136 X11DRV_DIB_UpdateDIBSection(dc
, TRUE
);
1138 HeapFree( GetProcessHeap(), 0, points
);
1144 /**********************************************************************
1145 * X11DRV_InternalFloodFill
1147 * Internal helper function for flood fill.
1148 * (xorg,yorg) is the origin of the X image relative to the drawable.
1149 * (x,y) is relative to the origin of the X image.
1151 static void X11DRV_InternalFloodFill(XImage
*image
, DC
*dc
,
1154 Pixel pixel
, WORD fillType
)
1156 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
1159 #define TO_FLOOD(x,y) ((fillType == FLOODFILLBORDER) ? \
1160 (XGetPixel(image,x,y) != pixel) : \
1161 (XGetPixel(image,x,y) == pixel))
1163 if (!TO_FLOOD(x
,y
)) return;
1165 /* Find left and right boundaries */
1168 while ((left
> 0) && TO_FLOOD( left
-1, y
)) left
--;
1169 while ((right
< image
->width
) && TO_FLOOD( right
, y
)) right
++;
1170 XFillRectangle( display
, physDev
->drawable
, physDev
->gc
,
1171 xOrg
+ left
, yOrg
+ y
, right
-left
, 1 );
1173 /* Set the pixels of this line so we don't fill it again */
1175 for (x
= left
; x
< right
; x
++)
1177 if (fillType
== FLOODFILLBORDER
) XPutPixel( image
, x
, y
, pixel
);
1178 else XPutPixel( image
, x
, y
, ~pixel
);
1181 /* Fill the line above */
1188 while ((x
< right
) && !TO_FLOOD(x
,y
)) x
++;
1189 if (x
>= right
) break;
1190 while ((x
< right
) && TO_FLOOD(x
,y
)) x
++;
1191 X11DRV_InternalFloodFill(image
, dc
, x
-1, y
,
1192 xOrg
, yOrg
, pixel
, fillType
);
1196 /* Fill the line below */
1198 if ((y
+= 2) < image
->height
)
1203 while ((x
< right
) && !TO_FLOOD(x
,y
)) x
++;
1204 if (x
>= right
) break;
1205 while ((x
< right
) && TO_FLOOD(x
,y
)) x
++;
1206 X11DRV_InternalFloodFill(image
, dc
, x
-1, y
,
1207 xOrg
, yOrg
, pixel
, fillType
);
1214 /**********************************************************************
1215 * X11DRV_DoFloodFill
1217 * Main flood-fill routine.
1219 * The Xlib critical section must be entered before calling this function.
1222 struct FloodFill_params
1231 static BOOL
X11DRV_DoFloodFill( const struct FloodFill_params
*params
)
1235 DC
*dc
= params
->dc
;
1236 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
1238 if (GetRgnBox( dc
->hGCClipRgn
, &rect
) == ERROR
) return FALSE
;
1240 if (!(image
= XGetImage( display
, physDev
->drawable
,
1243 rect
.right
- rect
.left
,
1244 rect
.bottom
- rect
.top
,
1245 AllPlanes
, ZPixmap
))) return FALSE
;
1247 if (X11DRV_SetupGCForBrush( dc
))
1249 /* Update the pixmap from the DIB section */
1250 X11DRV_DIB_UpdateDIBSection(dc
, FALSE
);
1252 /* ROP mode is always GXcopy for flood-fill */
1253 XSetFunction( display
, physDev
->gc
, GXcopy
);
1254 X11DRV_InternalFloodFill(image
, dc
,
1255 XLPTODP(dc
,params
->x
) + dc
->DCOrgX
- rect
.left
,
1256 YLPTODP(dc
,params
->y
) + dc
->DCOrgY
- rect
.top
,
1259 X11DRV_PALETTE_ToPhysical( dc
, params
->color
),
1262 /* Update the DIBSection of the dc's bitmap */
1263 X11DRV_DIB_UpdateDIBSection(dc
, TRUE
);
1266 XDestroyImage( image
);
1271 /**********************************************************************
1272 * X11DRV_ExtFloodFill
1275 X11DRV_ExtFloodFill( DC
*dc
, INT x
, INT y
, COLORREF color
,
1279 struct FloodFill_params params
;
1281 TRACE("X11DRV_ExtFloodFill %d,%d %06lx %d\n",
1282 x
, y
, color
, fillType
);
1287 params
.color
= color
;
1288 params
.fillType
= fillType
;
1290 if (!PtVisible( dc
->hSelf
, x
, y
)) return FALSE
;
1291 EnterCriticalSection( &X11DRV_CritSection
);
1292 result
= CALL_LARGE_STACK( X11DRV_DoFloodFill
, ¶ms
);
1293 LeaveCriticalSection( &X11DRV_CritSection
);
1297 /**********************************************************************
1301 X11DRV_SetBkColor( DC
*dc
, COLORREF color
)
1303 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
1306 oldColor
= dc
->backgroundColor
;
1307 dc
->backgroundColor
= color
;
1309 physDev
->backgroundPixel
= X11DRV_PALETTE_ToPhysical( dc
, color
);
1314 /**********************************************************************
1315 * X11DRV_SetTextColor
1318 X11DRV_SetTextColor( DC
*dc
, COLORREF color
)
1320 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
1323 oldColor
= dc
->textColor
;
1324 dc
->textColor
= color
;
1326 physDev
->textPixel
= X11DRV_PALETTE_ToPhysical( dc
, color
);
1331 /***********************************************************************
1334 BOOL
X11DRV_GetDCOrgEx( DC
*dc
, LPPOINT lpp
)
1336 if (!(dc
->flags
& DC_MEMORY
))
1338 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*) dc
->physDev
;
1340 int w
, h
, border
, depth
;
1342 /* FIXME: this is not correct for managed windows */
1343 TSXGetGeometry( display
, physDev
->drawable
, &root
,
1344 (int*)&lpp
->x
, (int*)&lpp
->y
, &w
, &h
, &border
, &depth
);
1346 else lpp
->x
= lpp
->y
= 0;