Copy the first 128 colors from the default colormap to Wine's private
[wine.git] / graphics / x11drv / graphics.c
blobf48a758f3e4d104dd924b5d67cdba8359dd03fb8
1 /*
2 * X11 graphics driver graphics functions
4 * Copyright 1993,1994 Alexandre Julliard
5 */
7 /*
8 * FIXME: only some of these functions obey the GM_ADVANCED
9 * graphics mode
12 #include "config.h"
14 #include <X11/Intrinsic.h>
16 #include "ts_xlib.h"
17 #include "ts_xutil.h"
19 #include <math.h>
20 #ifdef HAVE_FLOAT_H
21 # include <float.h>
22 #endif
23 #include <stdlib.h>
24 #ifndef PI
25 #define PI M_PI
26 #endif
27 #include <string.h>
29 #include "x11drv.h"
30 #include "x11font.h"
31 #include "bitmap.h"
32 #include "gdi.h"
33 #include "metafile.h"
34 #include "palette.h"
35 #include "color.h"
36 #include "region.h"
37 #include "debugtools.h"
39 DEFAULT_DEBUG_CHANNEL(graphics);
41 #define ABS(x) ((x)<0?(-(x)):(x))
43 /* ROP code to GC function conversion */
44 const int X11DRV_XROPfunction[16] =
46 GXclear, /* R2_BLACK */
47 GXnor, /* R2_NOTMERGEPEN */
48 GXandInverted, /* R2_MASKNOTPEN */
49 GXcopyInverted, /* R2_NOTCOPYPEN */
50 GXandReverse, /* R2_MASKPENNOT */
51 GXinvert, /* R2_NOT */
52 GXxor, /* R2_XORPEN */
53 GXnand, /* R2_NOTMASKPEN */
54 GXand, /* R2_MASKPEN */
55 GXequiv, /* R2_NOTXORPEN */
56 GXnoop, /* R2_NOP */
57 GXorInverted, /* R2_MERGENOTPEN */
58 GXcopy, /* R2_COPYPEN */
59 GXorReverse, /* R2_MERGEPENNOT */
60 GXor, /* R2_MERGEPEN */
61 GXset /* R2_WHITE */
65 /***********************************************************************
66 * X11DRV_SetupGCForPatBlt
68 * Setup the GC for a PatBlt operation using current brush.
69 * If fMapColors is TRUE, X pixels are mapped to Windows colors.
70 * Return FALSE if brush is BS_NULL, TRUE otherwise.
72 BOOL X11DRV_SetupGCForPatBlt( DC * dc, GC gc, BOOL fMapColors )
74 XGCValues val;
75 unsigned long mask;
76 Pixmap pixmap = 0;
77 X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
79 if (physDev->brush.style == BS_NULL) return FALSE;
80 if (physDev->brush.pixel == -1)
82 /* Special case used for monochrome pattern brushes.
83 * We need to swap foreground and background because
84 * Windows does it the wrong way...
86 val.foreground = physDev->backgroundPixel;
87 val.background = physDev->textPixel;
89 else
91 val.foreground = physDev->brush.pixel;
92 val.background = physDev->backgroundPixel;
94 if (fMapColors && X11DRV_PALETTE_XPixelToPalette)
96 val.foreground = X11DRV_PALETTE_XPixelToPalette[val.foreground];
97 val.background = X11DRV_PALETTE_XPixelToPalette[val.background];
100 val.function = X11DRV_XROPfunction[dc->ROPmode-1];
102 ** Let's replace GXinvert by GXxor with (black xor white)
103 ** This solves the selection color and leak problems in excel
104 ** FIXME : Let's do that only if we work with X-pixels, not with Win-pixels
106 if (val.function == GXinvert)
108 val.foreground = BlackPixelOfScreen(X11DRV_GetXScreen()) ^ WhitePixelOfScreen(X11DRV_GetXScreen());
109 val.function = GXxor;
111 val.fill_style = physDev->brush.fillStyle;
112 switch(val.fill_style)
114 case FillStippled:
115 case FillOpaqueStippled:
116 if (dc->backgroundMode==OPAQUE) val.fill_style = FillOpaqueStippled;
117 val.stipple = physDev->brush.pixmap;
118 mask = GCStipple;
119 break;
121 case FillTiled:
122 if (fMapColors && X11DRV_PALETTE_XPixelToPalette)
124 register int x, y;
125 XImage *image;
126 wine_tsx11_lock();
127 pixmap = XCreatePixmap( display, X11DRV_GetXRootWindow(),
128 8, 8, X11DRV_GetDepth() );
129 image = XGetImage( display, physDev->brush.pixmap, 0, 0, 8, 8,
130 AllPlanes, ZPixmap );
131 for (y = 0; y < 8; y++)
132 for (x = 0; x < 8; x++)
133 XPutPixel( image, x, y,
134 X11DRV_PALETTE_XPixelToPalette[XGetPixel( image, x, y)] );
135 XPutImage( display, pixmap, gc, image, 0, 0, 0, 0, 8, 8 );
136 XDestroyImage( image );
137 wine_tsx11_unlock();
138 val.tile = pixmap;
140 else val.tile = physDev->brush.pixmap;
141 mask = GCTile;
142 break;
144 default:
145 mask = 0;
146 break;
148 val.ts_x_origin = dc->DCOrgX + dc->brushOrgX;
149 val.ts_y_origin = dc->DCOrgY + dc->brushOrgY;
150 val.fill_rule = (dc->polyFillMode==WINDING) ? WindingRule : EvenOddRule;
151 TSXChangeGC( display, gc,
152 GCFunction | GCForeground | GCBackground | GCFillStyle |
153 GCFillRule | GCTileStipXOrigin | GCTileStipYOrigin | mask,
154 &val );
155 if (pixmap) TSXFreePixmap( display, pixmap );
156 return TRUE;
160 /***********************************************************************
161 * X11DRV_SetupGCForBrush
163 * Setup physDev->gc for drawing operations using current brush.
164 * Return FALSE if brush is BS_NULL, TRUE otherwise.
166 BOOL X11DRV_SetupGCForBrush( DC * dc )
168 X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
169 return X11DRV_SetupGCForPatBlt( dc, physDev->gc, FALSE );
173 /***********************************************************************
174 * X11DRV_SetupGCForPen
176 * Setup physDev->gc for drawing operations using current pen.
177 * Return FALSE if pen is PS_NULL, TRUE otherwise.
179 BOOL X11DRV_SetupGCForPen( DC * dc )
181 XGCValues val;
182 X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
184 if (physDev->pen.style == PS_NULL) return FALSE;
186 switch (dc->ROPmode)
188 case R2_BLACK :
189 val.foreground = BlackPixelOfScreen( X11DRV_GetXScreen() );
190 val.function = GXcopy;
191 break;
192 case R2_WHITE :
193 val.foreground = WhitePixelOfScreen( X11DRV_GetXScreen() );
194 val.function = GXcopy;
195 break;
196 case R2_XORPEN :
197 val.foreground = physDev->pen.pixel;
198 /* It is very unlikely someone wants to XOR with 0 */
199 /* This fixes the rubber-drawings in paintbrush */
200 if (val.foreground == 0)
201 val.foreground = BlackPixelOfScreen( X11DRV_GetXScreen() )
202 ^ WhitePixelOfScreen( X11DRV_GetXScreen() );
203 val.function = GXxor;
204 break;
205 default :
206 val.foreground = physDev->pen.pixel;
207 val.function = X11DRV_XROPfunction[dc->ROPmode-1];
209 val.background = physDev->backgroundPixel;
210 val.fill_style = FillSolid;
211 if ((physDev->pen.width <= 1) &&
212 (physDev->pen.style != PS_SOLID) &&
213 (physDev->pen.style != PS_INSIDEFRAME))
215 TSXSetDashes( display, physDev->gc, 0, physDev->pen.dashes,
216 physDev->pen.dash_len );
217 val.line_style = (dc->backgroundMode == OPAQUE) ?
218 LineDoubleDash : LineOnOffDash;
220 else val.line_style = LineSolid;
221 val.line_width = physDev->pen.width;
222 if (val.line_width <= 1) {
223 val.cap_style = CapNotLast;
224 } else {
225 switch (physDev->pen.endcap)
227 case PS_ENDCAP_SQUARE:
228 val.cap_style = CapProjecting;
229 break;
230 case PS_ENDCAP_FLAT:
231 val.cap_style = CapButt;
232 break;
233 case PS_ENDCAP_ROUND:
234 default:
235 val.cap_style = CapRound;
238 switch (physDev->pen.linejoin)
240 case PS_JOIN_BEVEL:
241 val.join_style = JoinBevel;
242 break;
243 case PS_JOIN_MITER:
244 val.join_style = JoinMiter;
245 break;
246 case PS_JOIN_ROUND:
247 default:
248 val.join_style = JoinRound;
250 TSXChangeGC( display, physDev->gc,
251 GCFunction | GCForeground | GCBackground | GCLineWidth |
252 GCLineStyle | GCCapStyle | GCJoinStyle | GCFillStyle, &val );
253 return TRUE;
257 /***********************************************************************
258 * X11DRV_SetupGCForText
260 * Setup physDev->gc for text drawing operations.
261 * Return FALSE if the font is null, TRUE otherwise.
263 BOOL X11DRV_SetupGCForText( DC * dc )
265 X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
266 XFontStruct* xfs = XFONT_GetFontStruct( physDev->font );
268 if( xfs )
270 XGCValues val;
272 val.function = GXcopy; /* Text is always GXcopy */
273 val.foreground = physDev->textPixel;
274 val.background = physDev->backgroundPixel;
275 val.fill_style = FillSolid;
276 val.font = xfs->fid;
278 TSXChangeGC( display, physDev->gc,
279 GCFunction | GCForeground | GCBackground | GCFillStyle |
280 GCFont, &val );
281 return TRUE;
283 WARN("Physical font failure\n" );
284 return FALSE;
287 /***********************************************************************
288 * X11DRV_LineTo
290 BOOL
291 X11DRV_LineTo( DC *dc, INT x, INT y )
293 X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
294 POINT start;
295 POINT end;
297 if (X11DRV_SetupGCForPen( dc )) {
298 /* Update the pixmap from the DIB section */
299 X11DRV_LockDIBSection(dc, DIB_Status_GdiMod, FALSE);
301 start.x = dc->CursPosX;
302 start.y = dc->CursPosY;
303 end.x = x;
304 end.y = y;
305 INTERNAL_LPTODP(dc,&start);
306 INTERNAL_LPTODP(dc,&end);
308 TSXDrawLine(display, physDev->drawable, physDev->gc,
309 dc->DCOrgX + start.x,
310 dc->DCOrgY + start.y,
311 dc->DCOrgX + end.x,
312 dc->DCOrgY + end.y);
314 /* Update the DIBSection from the pixmap */
315 X11DRV_UnlockDIBSection(dc, TRUE);
317 return TRUE;
322 /***********************************************************************
323 * X11DRV_DrawArc
325 * Helper functions for Arc(), Chord() and Pie().
326 * 'lines' is the number of lines to draw: 0 for Arc, 1 for Chord, 2 for Pie.
329 static BOOL
330 X11DRV_DrawArc( DC *dc, INT left, INT top, INT right,
331 INT bottom, INT xstart, INT ystart,
332 INT xend, INT yend, INT lines )
334 INT xcenter, ycenter, istart_angle, idiff_angle;
335 INT width, oldwidth, oldendcap;
336 double start_angle, end_angle;
337 XPoint points[4];
338 X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
339 BOOL update = FALSE;
341 left = XLPTODP( dc, left );
342 top = YLPTODP( dc, top );
343 right = XLPTODP( dc, right );
344 bottom = YLPTODP( dc, bottom );
345 xstart = XLPTODP( dc, xstart );
346 ystart = YLPTODP( dc, ystart );
347 xend = XLPTODP( dc, xend );
348 yend = YLPTODP( dc, yend );
350 if (right < left) { INT tmp = right; right = left; left = tmp; }
351 if (bottom < top) { INT tmp = bottom; bottom = top; top = tmp; }
352 if ((left == right) || (top == bottom)
353 ||(lines && ((right-left==1)||(bottom-top==1)))) return TRUE;
355 if( dc->ArcDirection == AD_CLOCKWISE )
356 { INT tmp = xstart; xstart = xend; xend = tmp;
357 tmp = ystart; ystart = yend; yend = tmp; }
359 oldwidth = width = physDev->pen.width;
360 oldendcap = physDev->pen.endcap;
361 if (!width) width = 1;
362 if(physDev->pen.style == PS_NULL) width = 0;
364 if ((physDev->pen.style == PS_INSIDEFRAME))
366 if (2*width > (right-left)) width=(right-left + 1)/2;
367 if (2*width > (bottom-top)) width=(bottom-top + 1)/2;
368 left += width / 2;
369 right -= (width - 1) / 2;
370 top += width / 2;
371 bottom -= (width - 1) / 2;
373 if(width == 0) width = 1; /* more accurate */
374 physDev->pen.width = width;
375 physDev->pen.endcap = PS_ENDCAP_SQUARE;
377 xcenter = (right + left) / 2;
378 ycenter = (bottom + top) / 2;
379 start_angle = atan2( (double)(ycenter-ystart)*(right-left),
380 (double)(xstart-xcenter)*(bottom-top) );
381 end_angle = atan2( (double)(ycenter-yend)*(right-left),
382 (double)(xend-xcenter)*(bottom-top) );
383 if ((xstart==xend)&&(ystart==yend))
384 { /* A lazy program delivers xstart=xend=ystart=yend=0) */
385 start_angle = 0;
386 end_angle = 2* PI;
388 else /* notorious cases */
389 if ((start_angle == PI)&&( end_angle <0))
390 start_angle = - PI;
391 else
392 if ((end_angle == PI)&&( start_angle <0))
393 end_angle = - PI;
394 istart_angle = (INT)(start_angle * 180 * 64 / PI + 0.5);
395 idiff_angle = (INT)((end_angle - start_angle) * 180 * 64 / PI + 0.5);
396 if (idiff_angle <= 0) idiff_angle += 360 * 64;
398 /* Update the pixmap from the DIB section */
399 X11DRV_LockDIBSection(dc, DIB_Status_GdiMod, FALSE);
401 /* Fill arc with brush if Chord() or Pie() */
403 if ((lines > 0) && X11DRV_SetupGCForBrush( dc )) {
404 TSXSetArcMode( display, physDev->gc,
405 (lines==1) ? ArcChord : ArcPieSlice);
406 TSXFillArc( display, physDev->drawable, physDev->gc,
407 dc->DCOrgX + left, dc->DCOrgY + top,
408 right-left-1, bottom-top-1, istart_angle, idiff_angle );
409 update = TRUE;
412 /* Draw arc and lines */
414 if (X11DRV_SetupGCForPen( dc )){
415 TSXDrawArc( display, physDev->drawable, physDev->gc,
416 dc->DCOrgX + left, dc->DCOrgY + top,
417 right-left-1, bottom-top-1, istart_angle, idiff_angle );
418 if (lines) {
419 /* use the truncated values */
420 start_angle=(double)istart_angle*PI/64./180.;
421 end_angle=(double)(istart_angle+idiff_angle)*PI/64./180.;
422 /* calculate the endpoints and round correctly */
423 points[0].x = (int) floor(dc->DCOrgX + (right+left)/2.0 +
424 cos(start_angle) * (right-left-width*2+2) / 2. + 0.5);
425 points[0].y = (int) floor(dc->DCOrgY + (top+bottom)/2.0 -
426 sin(start_angle) * (bottom-top-width*2+2) / 2. + 0.5);
427 points[1].x = (int) floor(dc->DCOrgX + (right+left)/2.0 +
428 cos(end_angle) * (right-left-width*2+2) / 2. + 0.5);
429 points[1].y = (int) floor(dc->DCOrgY + (top+bottom)/2.0 -
430 sin(end_angle) * (bottom-top-width*2+2) / 2. + 0.5);
432 /* OK, this stuff is optimized for Xfree86
433 * which is probably the server most used by
434 * wine users. Other X servers will not
435 * display correctly. (eXceed for instance)
436 * so if you feel you must make changes, make sure that
437 * you either use Xfree86 or separate your changes
438 * from these (compile switch or whatever)
440 if (lines == 2) {
441 INT dx1,dy1;
442 points[3] = points[1];
443 points[1].x = dc->DCOrgX + xcenter;
444 points[1].y = dc->DCOrgY + ycenter;
445 points[2] = points[1];
446 dx1=points[1].x-points[0].x;
447 dy1=points[1].y-points[0].y;
448 if(((top-bottom) | -2) == -2)
449 if(dy1>0) points[1].y--;
450 if(dx1<0) {
451 if (((-dx1)*64)<=ABS(dy1)*37) points[0].x--;
452 if(((-dx1*9))<(dy1*16)) points[0].y--;
453 if( dy1<0 && ((dx1*9)) < (dy1*16)) points[0].y--;
454 } else {
455 if(dy1 < 0) points[0].y--;
456 if(((right-left) | -2) == -2) points[1].x--;
458 dx1=points[3].x-points[2].x;
459 dy1=points[3].y-points[2].y;
460 if(((top-bottom) | -2 ) == -2)
461 if(dy1 < 0) points[2].y--;
462 if( dx1<0){
463 if( dy1>0) points[3].y--;
464 if(((right-left) | -2) == -2 ) points[2].x--;
465 }else {
466 points[3].y--;
467 if( dx1 * 64 < dy1 * -37 ) points[3].x--;
469 lines++;
471 TSXDrawLines( display, physDev->drawable, physDev->gc,
472 points, lines+1, CoordModeOrigin );
474 update = TRUE;
477 /* Update the DIBSection of the pixmap */
478 X11DRV_UnlockDIBSection(dc, update);
480 physDev->pen.width = oldwidth;
481 physDev->pen.endcap = oldendcap;
482 return TRUE;
486 /***********************************************************************
487 * X11DRV_Arc
489 BOOL
490 X11DRV_Arc( DC *dc, INT left, INT top, INT right, INT bottom,
491 INT xstart, INT ystart, INT xend, INT yend )
493 return X11DRV_DrawArc( dc, left, top, right, bottom,
494 xstart, ystart, xend, yend, 0 );
498 /***********************************************************************
499 * X11DRV_Pie
501 BOOL
502 X11DRV_Pie( DC *dc, INT left, INT top, INT right, INT bottom,
503 INT xstart, INT ystart, INT xend, INT yend )
505 return X11DRV_DrawArc( dc, left, top, right, bottom,
506 xstart, ystart, xend, yend, 2 );
509 /***********************************************************************
510 * X11DRV_Chord
512 BOOL
513 X11DRV_Chord( DC *dc, INT left, INT top, INT right, INT bottom,
514 INT xstart, INT ystart, INT xend, INT yend )
516 return X11DRV_DrawArc( dc, left, top, right, bottom,
517 xstart, ystart, xend, yend, 1 );
521 /***********************************************************************
522 * X11DRV_Ellipse
524 BOOL
525 X11DRV_Ellipse( DC *dc, INT left, INT top, INT right, INT bottom )
527 INT width, oldwidth;
528 X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
529 BOOL update = FALSE;
531 left = XLPTODP( dc, left );
532 top = YLPTODP( dc, top );
533 right = XLPTODP( dc, right );
534 bottom = YLPTODP( dc, bottom );
535 if ((left == right) || (top == bottom)) return TRUE;
537 if (right < left) { INT tmp = right; right = left; left = tmp; }
538 if (bottom < top) { INT tmp = bottom; bottom = top; top = tmp; }
540 oldwidth = width = physDev->pen.width;
541 if (!width) width = 1;
542 if(physDev->pen.style == PS_NULL) width = 0;
544 if ((physDev->pen.style == PS_INSIDEFRAME))
546 if (2*width > (right-left)) width=(right-left + 1)/2;
547 if (2*width > (bottom-top)) width=(bottom-top + 1)/2;
548 left += width / 2;
549 right -= (width - 1) / 2;
550 top += width / 2;
551 bottom -= (width - 1) / 2;
553 if(width == 0) width = 1; /* more accurate */
554 physDev->pen.width = width;
556 /* Update the pixmap from the DIB section */
557 X11DRV_LockDIBSection(dc, DIB_Status_GdiMod, FALSE);
559 if (X11DRV_SetupGCForBrush( dc ))
561 TSXFillArc( display, physDev->drawable, physDev->gc,
562 dc->DCOrgX + left, dc->DCOrgY + top,
563 right-left-1, bottom-top-1, 0, 360*64 );
564 update = TRUE;
566 if (X11DRV_SetupGCForPen( dc ))
568 TSXDrawArc( display, physDev->drawable, physDev->gc,
569 dc->DCOrgX + left, dc->DCOrgY + top,
570 right-left-1, bottom-top-1, 0, 360*64 );
571 update = TRUE;
574 /* Update the DIBSection from the pixmap */
575 X11DRV_UnlockDIBSection(dc, update);
577 physDev->pen.width = oldwidth;
578 return TRUE;
582 /***********************************************************************
583 * X11DRV_Rectangle
585 BOOL
586 X11DRV_Rectangle(DC *dc, INT left, INT top, INT right, INT bottom)
588 INT width, oldwidth, oldjoinstyle;
589 X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
590 BOOL update = FALSE;
592 TRACE("(%d %d %d %d)\n",
593 left, top, right, bottom);
595 left = INTERNAL_XWPTODP( dc, left, top );
596 top = INTERNAL_YWPTODP( dc, left, top );
597 right = INTERNAL_XWPTODP( dc, right, bottom );
598 bottom = INTERNAL_YWPTODP( dc, right, bottom );
600 if ((left == right) || (top == bottom)) return TRUE;
602 if (right < left) { INT tmp = right; right = left; left = tmp; }
603 if (bottom < top) { INT tmp = bottom; bottom = top; top = tmp; }
605 oldwidth = width = physDev->pen.width;
606 if (!width) width = 1;
607 if(physDev->pen.style == PS_NULL) width = 0;
609 if ((physDev->pen.style == PS_INSIDEFRAME))
611 if (2*width > (right-left)) width=(right-left + 1)/2;
612 if (2*width > (bottom-top)) width=(bottom-top + 1)/2;
613 left += width / 2;
614 right -= (width - 1) / 2;
615 top += width / 2;
616 bottom -= (width - 1) / 2;
618 if(width == 1) width = 0;
619 physDev->pen.width = width;
620 oldjoinstyle = physDev->pen.linejoin;
621 if(physDev->pen.type != PS_GEOMETRIC)
622 physDev->pen.linejoin = PS_JOIN_MITER;
624 /* Update the pixmap from the DIB section */
625 X11DRV_LockDIBSection(dc, DIB_Status_GdiMod, FALSE);
627 if ((right > left + width) && (bottom > top + width))
628 if (X11DRV_SetupGCForBrush( dc ))
630 TSXFillRectangle( display, physDev->drawable, physDev->gc,
631 dc->DCOrgX + left + (width + 1) / 2,
632 dc->DCOrgY + top + (width + 1) / 2,
633 right-left-width-1, bottom-top-width-1);
634 update = TRUE;
636 if (X11DRV_SetupGCForPen( dc ))
638 TSXDrawRectangle( display, physDev->drawable, physDev->gc,
639 dc->DCOrgX + left, dc->DCOrgY + top,
640 right-left-1, bottom-top-1 );
641 update = TRUE;
644 /* Update the DIBSection from the pixmap */
645 X11DRV_UnlockDIBSection(dc, update);
647 physDev->pen.width = oldwidth;
648 physDev->pen.linejoin = oldjoinstyle;
649 return TRUE;
652 /***********************************************************************
653 * X11DRV_RoundRect
655 BOOL
656 X11DRV_RoundRect( DC *dc, INT left, INT top, INT right,
657 INT bottom, INT ell_width, INT ell_height )
659 INT width, oldwidth, oldendcap;
660 X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
661 BOOL update = FALSE;
663 TRACE("(%d %d %d %d %d %d\n",
664 left, top, right, bottom, ell_width, ell_height);
666 left = XLPTODP( dc, left );
667 top = YLPTODP( dc, top );
668 right = XLPTODP( dc, right );
669 bottom = YLPTODP( dc, bottom );
671 if ((left == right) || (top == bottom))
672 return TRUE;
674 /* Make sure ell_width and ell_height are >= 1 otherwise XDrawArc gets
675 called with width/height < 0 */
676 ell_width = max(abs( ell_width * dc->vportExtX / dc->wndExtX ), 1);
677 ell_height = max(abs( ell_height * dc->vportExtY / dc->wndExtY ), 1);
679 /* Fix the coordinates */
681 if (right < left) { INT tmp = right; right = left; left = tmp; }
682 if (bottom < top) { INT tmp = bottom; bottom = top; top = tmp; }
684 oldwidth = width = physDev->pen.width;
685 oldendcap = physDev->pen.endcap;
686 if (!width) width = 1;
687 if(physDev->pen.style == PS_NULL) width = 0;
689 if ((physDev->pen.style == PS_INSIDEFRAME))
691 if (2*width > (right-left)) width=(right-left + 1)/2;
692 if (2*width > (bottom-top)) width=(bottom-top + 1)/2;
693 left += width / 2;
694 right -= (width - 1) / 2;
695 top += width / 2;
696 bottom -= (width - 1) / 2;
698 if(width == 0) width = 1;
699 physDev->pen.width = width;
700 physDev->pen.endcap = PS_ENDCAP_SQUARE;
702 /* Update the pixmap from the DIB section */
703 X11DRV_LockDIBSection(dc, DIB_Status_GdiMod, FALSE);
705 if (X11DRV_SetupGCForBrush( dc ))
707 if (ell_width > (right-left) )
708 if (ell_height > (bottom-top) )
709 TSXFillArc( display, physDev->drawable, physDev->gc,
710 dc->DCOrgX + left, dc->DCOrgY + top,
711 right - left - 1, bottom - top - 1,
712 0, 360 * 64 );
713 else{
714 TSXFillArc( display, physDev->drawable, physDev->gc,
715 dc->DCOrgX + left, dc->DCOrgY + top,
716 right - left - 1, ell_height, 0, 180 * 64 );
717 TSXFillArc( display, physDev->drawable, physDev->gc,
718 dc->DCOrgX + left,
719 dc->DCOrgY + bottom - ell_height - 1,
720 right - left - 1, ell_height, 180 * 64,
721 180 * 64 );
723 else if (ell_height > (bottom-top) ){
724 TSXFillArc( display, physDev->drawable, physDev->gc,
725 dc->DCOrgX + left, dc->DCOrgY + top,
726 ell_width, bottom - top - 1, 90 * 64, 180 * 64 );
727 TSXFillArc( display, physDev->drawable, physDev->gc,
728 dc->DCOrgX + right - ell_width -1, dc->DCOrgY + top,
729 ell_width, bottom - top - 1, 270 * 64, 180 * 64 );
730 }else{
731 TSXFillArc( display, physDev->drawable, physDev->gc,
732 dc->DCOrgX + left, dc->DCOrgY + top,
733 ell_width, ell_height, 90 * 64, 90 * 64 );
734 TSXFillArc( display, physDev->drawable, physDev->gc,
735 dc->DCOrgX + left,
736 dc->DCOrgY + bottom - ell_height - 1,
737 ell_width, ell_height, 180 * 64, 90 * 64 );
738 TSXFillArc( display, physDev->drawable, physDev->gc,
739 dc->DCOrgX + right - ell_width - 1,
740 dc->DCOrgY + bottom - ell_height - 1,
741 ell_width, ell_height, 270 * 64, 90 * 64 );
742 TSXFillArc( display, physDev->drawable, physDev->gc,
743 dc->DCOrgX + right - ell_width - 1,
744 dc->DCOrgY + top,
745 ell_width, ell_height, 0, 90 * 64 );
747 if (ell_width < right - left)
749 TSXFillRectangle( display, physDev->drawable, physDev->gc,
750 dc->DCOrgX + left + (ell_width + 1) / 2,
751 dc->DCOrgY + top + 1,
752 right - left - ell_width - 1,
753 (ell_height + 1) / 2 - 1);
754 TSXFillRectangle( display, physDev->drawable, physDev->gc,
755 dc->DCOrgX + left + (ell_width + 1) / 2,
756 dc->DCOrgY + bottom - (ell_height) / 2 - 1,
757 right - left - ell_width - 1,
758 (ell_height) / 2 );
760 if (ell_height < bottom - top)
762 TSXFillRectangle( display, physDev->drawable, physDev->gc,
763 dc->DCOrgX + left + 1,
764 dc->DCOrgY + top + (ell_height + 1) / 2,
765 right - left - 2,
766 bottom - top - ell_height - 1);
768 update = TRUE;
770 /* FIXME: this could be done with on X call
771 * more efficient and probably more correct
772 * on any X server: XDrawArcs will draw
773 * straight horizontal and vertical lines
774 * if width or height are zero.
776 * BTW this stuff is optimized for an Xfree86 server
777 * read the comments inside the X11DRV_DrawArc function
779 if (X11DRV_SetupGCForPen(dc)) {
780 if (ell_width > (right-left) )
781 if (ell_height > (bottom-top) )
782 TSXDrawArc( display, physDev->drawable, physDev->gc,
783 dc->DCOrgX + left, dc->DCOrgY + top,
784 right - left - 1, bottom -top - 1, 0 , 360 * 64 );
785 else{
786 TSXDrawArc( display, physDev->drawable, physDev->gc,
787 dc->DCOrgX + left, dc->DCOrgY + top,
788 right - left - 1, ell_height - 1, 0 , 180 * 64 );
789 TSXDrawArc( display, physDev->drawable, physDev->gc,
790 dc->DCOrgX + left,
791 dc->DCOrgY + bottom - ell_height,
792 right - left - 1, ell_height - 1, 180 * 64 , 180 * 64 );
794 else if (ell_height > (bottom-top) ){
795 TSXDrawArc( display, physDev->drawable, physDev->gc,
796 dc->DCOrgX + left, dc->DCOrgY + top,
797 ell_width - 1 , bottom - top - 1, 90 * 64 , 180 * 64 );
798 TSXDrawArc( display, physDev->drawable, physDev->gc,
799 dc->DCOrgX + right - ell_width,
800 dc->DCOrgY + top,
801 ell_width - 1 , bottom - top - 1, 270 * 64 , 180 * 64 );
802 }else{
803 TSXDrawArc( display, physDev->drawable, physDev->gc,
804 dc->DCOrgX + left, dc->DCOrgY + top,
805 ell_width - 1, ell_height - 1, 90 * 64, 90 * 64 );
806 TSXDrawArc( display, physDev->drawable, physDev->gc,
807 dc->DCOrgX + left, dc->DCOrgY + bottom - ell_height,
808 ell_width - 1, ell_height - 1, 180 * 64, 90 * 64 );
809 TSXDrawArc( display, physDev->drawable, physDev->gc,
810 dc->DCOrgX + right - ell_width,
811 dc->DCOrgY + bottom - ell_height,
812 ell_width - 1, ell_height - 1, 270 * 64, 90 * 64 );
813 TSXDrawArc( display, physDev->drawable, physDev->gc,
814 dc->DCOrgX + right - ell_width, dc->DCOrgY + top,
815 ell_width - 1, ell_height - 1, 0, 90 * 64 );
817 if (ell_width < right - left)
819 TSXDrawLine( display, physDev->drawable, physDev->gc,
820 dc->DCOrgX + left + ell_width / 2,
821 dc->DCOrgY + top,
822 dc->DCOrgX + right - (ell_width+1) / 2,
823 dc->DCOrgY + top);
824 TSXDrawLine( display, physDev->drawable, physDev->gc,
825 dc->DCOrgX + left + ell_width / 2 ,
826 dc->DCOrgY + bottom - 1,
827 dc->DCOrgX + right - (ell_width+1)/ 2,
828 dc->DCOrgY + bottom - 1);
830 if (ell_height < bottom - top)
832 TSXDrawLine( display, physDev->drawable, physDev->gc,
833 dc->DCOrgX + right - 1,
834 dc->DCOrgY + top + ell_height / 2,
835 dc->DCOrgX + right - 1,
836 dc->DCOrgY + bottom - (ell_height+1) / 2);
837 TSXDrawLine( display, physDev->drawable, physDev->gc,
838 dc->DCOrgX + left,
839 dc->DCOrgY + top + ell_height / 2,
840 dc->DCOrgX + left,
841 dc->DCOrgY + bottom - (ell_height+1) / 2);
843 update = TRUE;
846 /* Update the DIBSection from the pixmap */
847 X11DRV_UnlockDIBSection(dc, update);
849 physDev->pen.width = oldwidth;
850 physDev->pen.endcap = oldendcap;
851 return TRUE;
855 /***********************************************************************
856 * X11DRV_SetPixel
858 COLORREF
859 X11DRV_SetPixel( DC *dc, INT x, INT y, COLORREF color )
861 Pixel pixel;
862 X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
864 x = dc->DCOrgX + INTERNAL_XWPTODP( dc, x, y );
865 y = dc->DCOrgY + INTERNAL_YWPTODP( dc, x, y );
866 pixel = X11DRV_PALETTE_ToPhysical( dc, color );
868 /* Update the pixmap from the DIB section */
869 X11DRV_LockDIBSection(dc, DIB_Status_GdiMod, FALSE);
871 /* inefficient but simple... */
872 TSXSetForeground( display, physDev->gc, pixel );
873 TSXSetFunction( display, physDev->gc, GXcopy );
874 TSXDrawPoint( display, physDev->drawable, physDev->gc, x, y );
876 /* Update the DIBSection from the pixmap */
877 X11DRV_UnlockDIBSection(dc, TRUE);
879 return X11DRV_PALETTE_ToLogical(pixel);
883 /***********************************************************************
884 * X11DRV_GetPixel
886 COLORREF
887 X11DRV_GetPixel( DC *dc, INT x, INT y )
889 static Pixmap pixmap = 0;
890 XImage * image;
891 int pixel;
892 X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
894 /* Update the pixmap from the DIB section */
895 X11DRV_LockDIBSection(dc, DIB_Status_GdiMod, FALSE);
897 x = dc->DCOrgX + INTERNAL_XWPTODP( dc, x, y );
898 y = dc->DCOrgY + INTERNAL_YWPTODP( dc, x, y );
899 wine_tsx11_lock();
900 if (dc->flags & DC_MEMORY)
902 image = XGetImage( display, physDev->drawable, x, y, 1, 1,
903 AllPlanes, ZPixmap );
905 else
907 /* If we are reading from the screen, use a temporary copy */
908 /* to avoid a BadMatch error */
909 if (!pixmap) pixmap = XCreatePixmap( display, X11DRV_GetXRootWindow(),
910 1, 1, dc->bitsPerPixel );
911 XCopyArea( display, physDev->drawable, pixmap, BITMAP_colorGC,
912 x, y, 1, 1, 0, 0 );
913 image = XGetImage( display, pixmap, 0, 0, 1, 1, AllPlanes, ZPixmap );
915 pixel = XGetPixel( image, 0, 0 );
916 XDestroyImage( image );
917 wine_tsx11_unlock();
919 /* Update the DIBSection from the pixmap */
920 X11DRV_UnlockDIBSection(dc, FALSE);
922 return X11DRV_PALETTE_ToLogical(pixel);
926 /***********************************************************************
927 * X11DRV_PaintRgn
929 BOOL
930 X11DRV_PaintRgn( DC *dc, HRGN hrgn )
932 RECT box;
933 HRGN tmpVisRgn, prevVisRgn;
934 HDC hdc = dc->hSelf; /* FIXME: should not mix dc/hdc this way */
935 X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
937 if (!(tmpVisRgn = CreateRectRgn( 0, 0, 0, 0 ))) return FALSE;
939 /* Transform region into device co-ords */
940 if ( !REGION_LPTODP( hdc, tmpVisRgn, hrgn )
941 || OffsetRgn( tmpVisRgn, dc->DCOrgX, dc->DCOrgY ) == ERROR) {
942 DeleteObject( tmpVisRgn );
943 return FALSE;
946 /* Modify visible region */
947 if (!(prevVisRgn = SaveVisRgn16( hdc ))) {
948 DeleteObject( tmpVisRgn );
949 return FALSE;
951 CombineRgn( tmpVisRgn, prevVisRgn, tmpVisRgn, RGN_AND );
952 SelectVisRgn16( hdc, tmpVisRgn );
953 DeleteObject( tmpVisRgn );
955 /* Fill the region */
957 GetRgnBox( dc->hGCClipRgn, &box );
958 if (X11DRV_SetupGCForBrush( dc ))
960 /* Update the pixmap from the DIB section */
961 X11DRV_LockDIBSection(dc, DIB_Status_GdiMod, FALSE);
963 TSXFillRectangle( display, physDev->drawable, physDev->gc,
964 box.left, box.top,
965 box.right-box.left, box.bottom-box.top );
967 /* Update the DIBSection from the pixmap */
968 X11DRV_UnlockDIBSection(dc, TRUE);
971 /* Restore the visible region */
973 RestoreVisRgn16( hdc );
974 return TRUE;
977 /**********************************************************************
978 * X11DRV_Polyline
980 BOOL
981 X11DRV_Polyline( DC *dc, const POINT* pt, INT count )
983 INT oldwidth;
984 register int i;
985 XPoint *points;
986 X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
988 if((oldwidth = physDev->pen.width) == 0) physDev->pen.width = 1;
990 if (!(points = HeapAlloc( GetProcessHeap(), 0, sizeof(XPoint) * count )))
992 WARN("No memory to convert POINTs to XPoints!\n");
993 return FALSE;
995 for (i = 0; i < count; i++)
997 points[i].x = dc->DCOrgX + INTERNAL_XWPTODP( dc, pt[i].x, pt[i].y );
998 points[i].y = dc->DCOrgY + INTERNAL_YWPTODP( dc, pt[i].x, pt[i].y );
1001 if (X11DRV_SetupGCForPen ( dc ))
1003 /* Update the pixmap from the DIB section */
1004 X11DRV_LockDIBSection(dc, DIB_Status_GdiMod, FALSE);
1006 TSXDrawLines( display, physDev->drawable, physDev->gc,
1007 points, count, CoordModeOrigin );
1009 /* Update the DIBSection from the pixmap */
1010 X11DRV_UnlockDIBSection(dc, TRUE);
1013 HeapFree( GetProcessHeap(), 0, points );
1014 physDev->pen.width = oldwidth;
1015 return TRUE;
1019 /**********************************************************************
1020 * X11DRV_Polygon
1022 BOOL
1023 X11DRV_Polygon( DC *dc, const POINT* pt, INT count )
1025 register int i;
1026 XPoint *points;
1027 X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
1028 BOOL update = FALSE;
1030 if (!(points = HeapAlloc( GetProcessHeap(), 0, sizeof(XPoint) * (count+1) )))
1032 WARN("No memory to convert POINTs to XPoints!\n");
1033 return FALSE;
1035 for (i = 0; i < count; i++)
1037 points[i].x = dc->DCOrgX + INTERNAL_XWPTODP( dc, pt[i].x, pt[i].y );
1038 points[i].y = dc->DCOrgY + INTERNAL_YWPTODP( dc, pt[i].x, pt[i].y );
1040 points[count] = points[0];
1042 /* Update the pixmap from the DIB section */
1043 X11DRV_LockDIBSection(dc, DIB_Status_GdiMod, FALSE);
1045 if (X11DRV_SetupGCForBrush( dc ))
1047 TSXFillPolygon( display, physDev->drawable, physDev->gc,
1048 points, count+1, Complex, CoordModeOrigin);
1049 update = TRUE;
1051 if (X11DRV_SetupGCForPen ( dc ))
1053 TSXDrawLines( display, physDev->drawable, physDev->gc,
1054 points, count+1, CoordModeOrigin );
1055 update = TRUE;
1058 /* Update the DIBSection from the pixmap */
1059 X11DRV_UnlockDIBSection(dc, update);
1061 HeapFree( GetProcessHeap(), 0, points );
1062 return TRUE;
1066 /**********************************************************************
1067 * X11DRV_PolyPolygon
1069 BOOL
1070 X11DRV_PolyPolygon( DC *dc, const POINT* pt, const INT* counts, UINT polygons)
1072 HRGN hrgn;
1073 X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
1075 /* FIXME: The points should be converted to device coords before */
1076 /* creating the region. */
1078 hrgn = CreatePolyPolygonRgn( pt, counts, polygons, dc->polyFillMode );
1079 X11DRV_PaintRgn( dc, hrgn );
1080 DeleteObject( hrgn );
1082 /* Draw the outline of the polygons */
1084 if (X11DRV_SetupGCForPen ( dc ))
1086 int i, j, max = 0;
1087 XPoint *points;
1089 /* Update the pixmap from the DIB section */
1090 X11DRV_LockDIBSection(dc, DIB_Status_GdiMod, FALSE);
1092 for (i = 0; i < polygons; i++) if (counts[i] > max) max = counts[i];
1093 if (!(points = HeapAlloc( GetProcessHeap(), 0, sizeof(XPoint) * (max+1) )))
1095 WARN("No memory to convert POINTs to XPoints!\n");
1096 return FALSE;
1098 for (i = 0; i < polygons; i++)
1100 for (j = 0; j < counts[i]; j++)
1102 points[j].x = dc->DCOrgX + INTERNAL_XWPTODP( dc, pt->x, pt->y );
1103 points[j].y = dc->DCOrgY + INTERNAL_YWPTODP( dc, pt->x, pt->y );
1104 pt++;
1106 points[j] = points[0];
1107 TSXDrawLines( display, physDev->drawable, physDev->gc,
1108 points, j + 1, CoordModeOrigin );
1111 /* Update the DIBSection of the dc's bitmap */
1112 X11DRV_UnlockDIBSection(dc, TRUE);
1114 HeapFree( GetProcessHeap(), 0, points );
1116 return TRUE;
1120 /**********************************************************************
1121 * X11DRV_PolyPolyline
1123 BOOL
1124 X11DRV_PolyPolyline( DC *dc, const POINT* pt, const DWORD* counts, DWORD polylines )
1126 X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
1128 if (X11DRV_SetupGCForPen ( dc ))
1130 int i, j, max = 0;
1131 XPoint *points;
1133 /* Update the pixmap from the DIB section */
1134 X11DRV_LockDIBSection(dc, DIB_Status_GdiMod, FALSE);
1136 for (i = 0; i < polylines; i++) if (counts[i] > max) max = counts[i];
1137 if (!(points = HeapAlloc( GetProcessHeap(), 0, sizeof(XPoint) * max )))
1139 WARN("No memory to convert POINTs to XPoints!\n");
1140 return FALSE;
1142 for (i = 0; i < polylines; i++)
1144 for (j = 0; j < counts[i]; j++)
1146 points[j].x = dc->DCOrgX + INTERNAL_XWPTODP( dc, pt->x, pt->y );
1147 points[j].y = dc->DCOrgY + INTERNAL_YWPTODP( dc, pt->x, pt->y );
1148 pt++;
1150 TSXDrawLines( display, physDev->drawable, physDev->gc,
1151 points, j, CoordModeOrigin );
1154 /* Update the DIBSection of the dc's bitmap */
1155 X11DRV_UnlockDIBSection(dc, TRUE);
1157 HeapFree( GetProcessHeap(), 0, points );
1159 return TRUE;
1163 /**********************************************************************
1164 * X11DRV_InternalFloodFill
1166 * Internal helper function for flood fill.
1167 * (xorg,yorg) is the origin of the X image relative to the drawable.
1168 * (x,y) is relative to the origin of the X image.
1170 static void X11DRV_InternalFloodFill(XImage *image, DC *dc,
1171 int x, int y,
1172 int xOrg, int yOrg,
1173 Pixel pixel, WORD fillType )
1175 X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
1176 int left, right;
1178 #define TO_FLOOD(x,y) ((fillType == FLOODFILLBORDER) ? \
1179 (XGetPixel(image,x,y) != pixel) : \
1180 (XGetPixel(image,x,y) == pixel))
1182 if (!TO_FLOOD(x,y)) return;
1184 /* Find left and right boundaries */
1186 left = right = x;
1187 while ((left > 0) && TO_FLOOD( left-1, y )) left--;
1188 while ((right < image->width) && TO_FLOOD( right, y )) right++;
1189 XFillRectangle( display, physDev->drawable, physDev->gc,
1190 xOrg + left, yOrg + y, right-left, 1 );
1192 /* Set the pixels of this line so we don't fill it again */
1194 for (x = left; x < right; x++)
1196 if (fillType == FLOODFILLBORDER) XPutPixel( image, x, y, pixel );
1197 else XPutPixel( image, x, y, ~pixel );
1200 /* Fill the line above */
1202 if (--y >= 0)
1204 x = left;
1205 while (x < right)
1207 while ((x < right) && !TO_FLOOD(x,y)) x++;
1208 if (x >= right) break;
1209 while ((x < right) && TO_FLOOD(x,y)) x++;
1210 X11DRV_InternalFloodFill(image, dc, x-1, y,
1211 xOrg, yOrg, pixel, fillType );
1215 /* Fill the line below */
1217 if ((y += 2) < image->height)
1219 x = left;
1220 while (x < right)
1222 while ((x < right) && !TO_FLOOD(x,y)) x++;
1223 if (x >= right) break;
1224 while ((x < right) && TO_FLOOD(x,y)) x++;
1225 X11DRV_InternalFloodFill(image, dc, x-1, y,
1226 xOrg, yOrg, pixel, fillType );
1229 #undef TO_FLOOD
1233 /**********************************************************************
1234 * X11DRV_ExtFloodFill
1236 BOOL
1237 X11DRV_ExtFloodFill( DC *dc, INT x, INT y, COLORREF color,
1238 UINT fillType )
1240 XImage *image;
1241 RECT rect;
1242 X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
1244 TRACE("X11DRV_ExtFloodFill %d,%d %06lx %d\n", x, y, color, fillType );
1246 if (!PtVisible( dc->hSelf, x, y )) return FALSE;
1247 if (GetRgnBox( dc->hGCClipRgn, &rect ) == ERROR) return FALSE;
1249 if (!(image = TSXGetImage( display, physDev->drawable,
1250 rect.left,
1251 rect.top,
1252 rect.right - rect.left,
1253 rect.bottom - rect.top,
1254 AllPlanes, ZPixmap ))) return FALSE;
1256 wine_tsx11_lock();
1257 if (X11DRV_SetupGCForBrush( dc ))
1259 /* Update the pixmap from the DIB section */
1260 X11DRV_LockDIBSection(dc, DIB_Status_GdiMod, FALSE);
1262 /* ROP mode is always GXcopy for flood-fill */
1263 XSetFunction( display, physDev->gc, GXcopy );
1264 X11DRV_InternalFloodFill(image, dc,
1265 XLPTODP(dc,x) + dc->DCOrgX - rect.left,
1266 YLPTODP(dc,y) + dc->DCOrgY - rect.top,
1267 rect.left, rect.top,
1268 X11DRV_PALETTE_ToPhysical( dc, color ),
1269 fillType );
1270 /* Update the DIBSection of the dc's bitmap */
1271 X11DRV_UnlockDIBSection(dc, TRUE);
1274 XDestroyImage( image );
1275 wine_tsx11_unlock();
1276 return TRUE;
1279 /**********************************************************************
1280 * X11DRV_SetBkColor
1282 COLORREF
1283 X11DRV_SetBkColor( DC *dc, COLORREF color )
1285 X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
1286 COLORREF oldColor;
1288 oldColor = dc->backgroundColor;
1289 dc->backgroundColor = color;
1291 physDev->backgroundPixel = X11DRV_PALETTE_ToPhysical( dc, color );
1293 return oldColor;
1296 /**********************************************************************
1297 * X11DRV_SetTextColor
1299 COLORREF
1300 X11DRV_SetTextColor( DC *dc, COLORREF color )
1302 X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
1303 COLORREF oldColor;
1305 oldColor = dc->textColor;
1306 dc->textColor = color;
1308 physDev->textPixel = X11DRV_PALETTE_ToPhysical( dc, color );
1310 return oldColor;
1313 /***********************************************************************
1314 * X11DRV_GetDCOrgEx
1316 BOOL X11DRV_GetDCOrgEx( DC *dc, LPPOINT lpp )
1318 if (!(dc->flags & DC_MEMORY))
1320 X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *) dc->physDev;
1321 Window root;
1322 int w, h, border, depth;
1324 /* FIXME: this is not correct for managed windows */
1325 TSXGetGeometry( display, physDev->drawable, &root,
1326 (int*)&lpp->x, (int*)&lpp->y, &w, &h, &border, &depth );
1328 else lpp->x = lpp->y = 0;
1329 return TRUE;