2 * X11 graphics driver graphics functions
4 * Copyright 1993,1994 Alexandre Julliard
14 #include <X11/Intrinsic.h>
36 /**********************************************************************
40 X11DRV_MoveToEx(DC
*dc
,INT32 x
,INT32 y
,LPPOINT32 pt
) {
43 pt
->x
= dc
->w
.CursPosX
;
44 pt
->y
= dc
->w
.CursPosY
;
51 /***********************************************************************
55 X11DRV_LineTo( DC
*dc
, INT32 x
, INT32 y
)
57 if (DC_SetupGCForPen( dc
))
58 TSXDrawLine(display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
59 dc
->w
.DCOrgX
+ XLPTODP( dc
, dc
->w
.CursPosX
),
60 dc
->w
.DCOrgY
+ YLPTODP( dc
, dc
->w
.CursPosY
),
61 dc
->w
.DCOrgX
+ XLPTODP( dc
, x
),
62 dc
->w
.DCOrgY
+ YLPTODP( dc
, y
) );
70 /***********************************************************************
73 * Helper functions for Arc(), Chord() and Pie().
74 * 'lines' is the number of lines to draw: 0 for Arc, 1 for Chord, 2 for Pie.
77 X11DRV_DrawArc( DC
*dc
, INT32 left
, INT32 top
, INT32 right
,
78 INT32 bottom
, INT32 xstart
, INT32 ystart
,
79 INT32 xend
, INT32 yend
, INT32 lines
)
81 INT32 xcenter
, ycenter
, istart_angle
, idiff_angle
, tmp
;
82 double start_angle
, end_angle
;
85 left
= XLPTODP( dc
, left
);
86 top
= YLPTODP( dc
, top
);
87 right
= XLPTODP( dc
, right
);
88 bottom
= YLPTODP( dc
, bottom
);
89 xstart
= XLPTODP( dc
, xstart
);
90 ystart
= YLPTODP( dc
, ystart
);
91 xend
= XLPTODP( dc
, xend
);
92 yend
= YLPTODP( dc
, yend
);
93 if ((left
== right
) || (top
== bottom
)) return FALSE
;
95 xcenter
= (right
+ left
) / 2;
96 ycenter
= (bottom
+ top
) / 2;
97 start_angle
= atan2( (double)(ycenter
-ystart
)*(right
-left
),
98 (double)(xstart
-xcenter
)*(bottom
-top
) );
99 end_angle
= atan2( (double)(ycenter
-yend
)*(right
-left
),
100 (double)(xend
-xcenter
)*(bottom
-top
) );
101 istart_angle
= (INT32
)(start_angle
* 180 * 64 / PI
);
102 idiff_angle
= (INT32
)((end_angle
- start_angle
) * 180 * 64 / PI
);
103 if (idiff_angle
<= 0) idiff_angle
+= 360 * 64;
104 if (left
> right
) { tmp
=left
; left
=right
; right
=tmp
; }
105 if (top
> bottom
) { tmp
=top
; top
=bottom
; bottom
=tmp
; }
107 /* Fill arc with brush if Chord() or Pie() */
109 if ((lines
> 0) && DC_SetupGCForBrush( dc
))
111 TSXSetArcMode( display
, dc
->u
.x
.gc
, (lines
==1) ? ArcChord
: ArcPieSlice
);
112 TSXFillArc( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
113 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
,
114 right
-left
-1, bottom
-top
-1, istart_angle
, idiff_angle
);
117 /* Draw arc and lines */
119 if (!DC_SetupGCForPen( dc
)) return TRUE
;
120 TSXDrawArc( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
121 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
,
122 right
-left
-1, bottom
-top
-1, istart_angle
, idiff_angle
);
123 if (!lines
) return TRUE
;
125 points
[0].x
= dc
->w
.DCOrgX
+ xcenter
+ (int)(cos(start_angle
) * (right
-left
) / 2);
126 points
[0].y
= dc
->w
.DCOrgY
+ ycenter
- (int)(sin(start_angle
) * (bottom
-top
) / 2);
127 points
[1].x
= dc
->w
.DCOrgX
+ xcenter
+ (int)(cos(end_angle
) * (right
-left
) / 2);
128 points
[1].y
= dc
->w
.DCOrgY
+ ycenter
- (int)(sin(end_angle
) * (bottom
-top
) / 2);
131 points
[2] = points
[1];
132 points
[1].x
= dc
->w
.DCOrgX
+ xcenter
;
133 points
[1].y
= dc
->w
.DCOrgY
+ ycenter
;
135 TSXDrawLines( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
136 points
, lines
+1, CoordModeOrigin
);
141 /***********************************************************************
145 X11DRV_Arc( DC
*dc
, INT32 left
, INT32 top
, INT32 right
, INT32 bottom
,
146 INT32 xstart
, INT32 ystart
, INT32 xend
, INT32 yend
)
148 return X11DRV_DrawArc( dc
, left
, top
, right
, bottom
,
149 xstart
, ystart
, xend
, yend
, 0 );
153 /***********************************************************************
157 X11DRV_Pie( DC
*dc
, INT32 left
, INT32 top
, INT32 right
, INT32 bottom
,
158 INT32 xstart
, INT32 ystart
, INT32 xend
, INT32 yend
)
160 return X11DRV_DrawArc( dc
, left
, top
, right
, bottom
,
161 xstart
, ystart
, xend
, yend
, 2 );
164 /***********************************************************************
168 X11DRV_Chord( DC
*dc
, INT32 left
, INT32 top
, INT32 right
, INT32 bottom
,
169 INT32 xstart
, INT32 ystart
, INT32 xend
, INT32 yend
)
171 return X11DRV_DrawArc( dc
, left
, top
, right
, bottom
,
172 xstart
, ystart
, xend
, yend
, 1 );
176 /***********************************************************************
180 X11DRV_Ellipse( DC
*dc
, INT32 left
, INT32 top
, INT32 right
, INT32 bottom
)
182 left
= XLPTODP( dc
, left
);
183 top
= YLPTODP( dc
, top
);
184 right
= XLPTODP( dc
, right
);
185 bottom
= YLPTODP( dc
, bottom
);
186 if ((left
== right
) || (top
== bottom
)) return FALSE
;
188 if (right
< left
) { INT32 tmp
= right
; right
= left
; left
= tmp
; }
189 if (bottom
< top
) { INT32 tmp
= bottom
; bottom
= top
; top
= tmp
; }
191 if ((dc
->u
.x
.pen
.style
== PS_INSIDEFRAME
) &&
192 (dc
->u
.x
.pen
.width
< right
-left
-1) &&
193 (dc
->u
.x
.pen
.width
< bottom
-top
-1))
195 left
+= dc
->u
.x
.pen
.width
/ 2;
196 right
-= (dc
->u
.x
.pen
.width
+ 1) / 2;
197 top
+= dc
->u
.x
.pen
.width
/ 2;
198 bottom
-= (dc
->u
.x
.pen
.width
+ 1) / 2;
201 if (DC_SetupGCForBrush( dc
))
202 TSXFillArc( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
203 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
,
204 right
-left
-1, bottom
-top
-1, 0, 360*64 );
205 if (DC_SetupGCForPen( dc
))
206 TSXDrawArc( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
207 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
,
208 right
-left
-1, bottom
-top
-1, 0, 360*64 );
213 /***********************************************************************
217 X11DRV_Rectangle(DC
*dc
, INT32 left
, INT32 top
, INT32 right
, INT32 bottom
)
220 left
= XLPTODP( dc
, left
);
221 top
= YLPTODP( dc
, top
);
222 right
= XLPTODP( dc
, right
);
223 bottom
= YLPTODP( dc
, bottom
);
225 if (right
< left
) { INT32 tmp
= right
; right
= left
; left
= tmp
; }
226 if (bottom
< top
) { INT32 tmp
= bottom
; bottom
= top
; top
= tmp
; }
228 if ((left
== right
) || (top
== bottom
))
230 if (DC_SetupGCForPen( dc
))
231 TSXDrawLine(display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
234 dc
->w
.DCOrgX
+ right
,
235 dc
->w
.DCOrgY
+ bottom
);
238 width
= dc
->u
.x
.pen
.width
;
239 if (!width
) width
= 1;
240 if(dc
->u
.x
.pen
.style
== PS_NULL
) width
= 0;
242 if ((dc
->u
.x
.pen
.style
== PS_INSIDEFRAME
) &&
243 (width
< right
-left
) && (width
< bottom
-top
))
246 right
-= (width
+ 1) / 2;
248 bottom
-= (width
+ 1) / 2;
251 if ((right
> left
+ width
) && (bottom
> top
+ width
))
253 if (DC_SetupGCForBrush( dc
))
254 TSXFillRectangle( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
255 dc
->w
.DCOrgX
+ left
+ (width
+ 1) / 2,
256 dc
->w
.DCOrgY
+ top
+ (width
+ 1) / 2,
257 right
-left
-width
-1, bottom
-top
-width
-1);
259 if (DC_SetupGCForPen( dc
))
260 TSXDrawRectangle( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
261 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
,
262 right
-left
-1, bottom
-top
-1 );
266 /***********************************************************************
270 X11DRV_RoundRect( DC
*dc
, INT32 left
, INT32 top
, INT32 right
,
271 INT32 bottom
, INT32 ell_width
, INT32 ell_height
)
273 dprintf_info(graphics
, "X11DRV_RoundRect(%d %d %d %d %d %d\n",
274 left
, top
, right
, bottom
, ell_width
, ell_height
);
276 left
= XLPTODP( dc
, left
);
277 top
= YLPTODP( dc
, top
);
278 right
= XLPTODP( dc
, right
);
279 bottom
= YLPTODP( dc
, bottom
);
280 ell_width
= abs( ell_width
* dc
->vportExtX
/ dc
->wndExtX
);
281 ell_height
= abs( ell_height
* dc
->vportExtY
/ dc
->wndExtY
);
283 /* Fix the coordinates */
285 if (right
< left
) { INT32 tmp
= right
; right
= left
; left
= tmp
; }
286 if (bottom
< top
) { INT32 tmp
= bottom
; bottom
= top
; top
= tmp
; }
287 if (ell_width
> right
- left
) ell_width
= right
- left
;
288 if (ell_height
> bottom
- top
) ell_height
= bottom
- top
;
290 if (DC_SetupGCForBrush( dc
))
292 if (ell_width
&& ell_height
)
294 TSXFillArc( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
295 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
,
296 ell_width
, ell_height
, 90 * 64, 90 * 64 );
297 TSXFillArc( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
298 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ bottom
- ell_height
,
299 ell_width
, ell_height
, 180 * 64, 90 * 64 );
300 TSXFillArc( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
301 dc
->w
.DCOrgX
+ right
- ell_width
,
302 dc
->w
.DCOrgY
+ bottom
- ell_height
,
303 ell_width
, ell_height
, 270 * 64, 90 * 64 );
304 TSXFillArc( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
305 dc
->w
.DCOrgX
+ right
- ell_width
, dc
->w
.DCOrgY
+ top
,
306 ell_width
, ell_height
, 0, 90 * 64 );
308 if (ell_width
< right
- left
)
310 TSXFillRectangle( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
311 dc
->w
.DCOrgX
+ left
+ ell_width
/ 2,
313 right
- left
- ell_width
, ell_height
/ 2 );
314 TSXFillRectangle( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
315 dc
->w
.DCOrgX
+ left
+ ell_width
/ 2,
316 dc
->w
.DCOrgY
+ bottom
- (ell_height
+1) / 2,
317 right
- left
- ell_width
, (ell_height
+1) / 2 );
319 if (ell_height
< bottom
- top
)
321 TSXFillRectangle( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
323 dc
->w
.DCOrgY
+ top
+ ell_height
/ 2,
324 right
- left
, bottom
- top
- ell_height
);
327 if (DC_SetupGCForPen(dc
))
329 if (ell_width
&& ell_height
)
331 TSXDrawArc( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
332 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
,
333 ell_width
, ell_height
, 90 * 64, 90 * 64 );
334 TSXDrawArc( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
335 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ bottom
- ell_height
,
336 ell_width
, ell_height
, 180 * 64, 90 * 64 );
337 TSXDrawArc( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
338 dc
->w
.DCOrgX
+ right
- ell_width
,
339 dc
->w
.DCOrgY
+ bottom
- ell_height
,
340 ell_width
, ell_height
, 270 * 64, 90 * 64 );
341 TSXDrawArc( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
342 dc
->w
.DCOrgX
+ right
- ell_width
, dc
->w
.DCOrgY
+ top
,
343 ell_width
, ell_height
, 0, 90 * 64 );
345 if (ell_width
< right
- left
)
347 TSXDrawLine( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
348 dc
->w
.DCOrgX
+ left
+ ell_width
/ 2,
350 dc
->w
.DCOrgX
+ right
- ell_width
/ 2,
351 dc
->w
.DCOrgY
+ top
);
352 TSXDrawLine( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
353 dc
->w
.DCOrgX
+ left
+ ell_width
/ 2,
354 dc
->w
.DCOrgY
+ bottom
,
355 dc
->w
.DCOrgX
+ right
- ell_width
/ 2,
356 dc
->w
.DCOrgY
+ bottom
);
358 if (ell_height
< bottom
- top
)
360 TSXDrawLine( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
361 dc
->w
.DCOrgX
+ right
,
362 dc
->w
.DCOrgY
+ top
+ ell_height
/ 2,
363 dc
->w
.DCOrgX
+ right
,
364 dc
->w
.DCOrgY
+ bottom
- ell_height
/ 2 );
365 TSXDrawLine( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
367 dc
->w
.DCOrgY
+ top
+ ell_height
/ 2,
369 dc
->w
.DCOrgY
+ bottom
- ell_height
/ 2 );
376 /***********************************************************************
380 X11DRV_SetPixel( DC
*dc
, INT32 x
, INT32 y
, COLORREF color
)
384 x
= dc
->w
.DCOrgX
+ XLPTODP( dc
, x
);
385 y
= dc
->w
.DCOrgY
+ YLPTODP( dc
, y
);
386 pixel
= COLOR_ToPhysical( dc
, color
);
388 TSXSetForeground( display
, dc
->u
.x
.gc
, pixel
);
389 TSXSetFunction( display
, dc
->u
.x
.gc
, GXcopy
);
390 TSXDrawPoint( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
, x
, y
);
392 /* inefficient but simple... */
394 return COLOR_ToLogical(pixel
);
398 /***********************************************************************
402 X11DRV_GetPixel( DC
*dc
, INT32 x
, INT32 y
)
404 static Pixmap pixmap
= 0;
408 x
= dc
->w
.DCOrgX
+ XLPTODP( dc
, x
);
409 y
= dc
->w
.DCOrgY
+ YLPTODP( dc
, y
);
410 EnterCriticalSection( &X11DRV_CritSection
);
411 if (dc
->w
.flags
& DC_MEMORY
)
413 image
= XGetImage( display
, dc
->u
.x
.drawable
, x
, y
, 1, 1,
414 AllPlanes
, ZPixmap
);
418 /* If we are reading from the screen, use a temporary copy */
419 /* to avoid a BadMatch error */
420 if (!pixmap
) pixmap
= XCreatePixmap( display
, rootWindow
,
421 1, 1, dc
->w
.bitsPerPixel
);
422 XCopyArea( display
, dc
->u
.x
.drawable
, pixmap
, BITMAP_colorGC
,
424 image
= XGetImage( display
, pixmap
, 0, 0, 1, 1, AllPlanes
, ZPixmap
);
426 pixel
= XGetPixel( image
, 0, 0 );
427 XDestroyImage( image
);
428 LeaveCriticalSection( &X11DRV_CritSection
);
430 return COLOR_ToLogical(pixel
);
434 /***********************************************************************
438 X11DRV_PaintRgn( DC
*dc
, HRGN32 hrgn
)
441 HRGN32 tmpVisRgn
, prevVisRgn
;
442 HDC32 hdc
= dc
->hSelf
; /* FIXME: should not mix dc/hdc this way */
444 if (!(tmpVisRgn
= CreateRectRgn32( 0, 0, 0, 0 ))) return FALSE
;
446 /* Transform region into device co-ords */
447 if (!REGION_LPTODP( hdc
, tmpVisRgn
, hrgn
)) {
448 DeleteObject32( tmpVisRgn
);
452 /* Modify visible region */
453 if (!(prevVisRgn
= SaveVisRgn( hdc
))) {
454 DeleteObject32( tmpVisRgn
);
457 CombineRgn32( tmpVisRgn
, prevVisRgn
, tmpVisRgn
, RGN_AND
);
458 SelectVisRgn( hdc
, tmpVisRgn
);
459 DeleteObject32( tmpVisRgn
);
461 /* Fill the region */
463 GetRgnBox32( dc
->w
.hGCClipRgn
, &box
);
464 if (DC_SetupGCForBrush( dc
))
465 TSXFillRectangle( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
466 dc
->w
.DCOrgX
+ box
.left
, dc
->w
.DCOrgY
+ box
.top
,
467 box
.right
-box
.left
, box
.bottom
-box
.top
);
469 /* Restore the visible region */
471 RestoreVisRgn( hdc
);
475 /**********************************************************************
479 X11DRV_Polyline( DC
*dc
, const LPPOINT32 pt
, INT32 count
)
483 if (DC_SetupGCForPen( dc
))
484 for (i
= 0; i
< count
-1; i
++)
485 TSXDrawLine (display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
486 dc
->w
.DCOrgX
+ XLPTODP(dc
, pt
[i
].x
),
487 dc
->w
.DCOrgY
+ YLPTODP(dc
, pt
[i
].y
),
488 dc
->w
.DCOrgX
+ XLPTODP(dc
, pt
[i
+1].x
),
489 dc
->w
.DCOrgY
+ YLPTODP(dc
, pt
[i
+1].y
));
494 /**********************************************************************
498 X11DRV_Polygon( DC
*dc
, LPPOINT32 pt
, INT32 count
)
503 points
= (XPoint
*) xmalloc (sizeof (XPoint
) * (count
+1));
504 for (i
= 0; i
< count
; i
++)
506 points
[i
].x
= dc
->w
.DCOrgX
+ XLPTODP( dc
, pt
[i
].x
);
507 points
[i
].y
= dc
->w
.DCOrgY
+ YLPTODP( dc
, pt
[i
].y
);
509 points
[count
] = points
[0];
511 if (DC_SetupGCForBrush( dc
))
512 TSXFillPolygon( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
513 points
, count
+1, Complex
, CoordModeOrigin
);
515 if (DC_SetupGCForPen ( dc
))
516 TSXDrawLines( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
517 points
, count
+1, CoordModeOrigin
);
524 /**********************************************************************
528 X11DRV_PolyPolygon( DC
*dc
, LPPOINT32 pt
, LPINT32 counts
, UINT32 polygons
)
532 /* FIXME: The points should be converted to device coords before */
533 /* creating the region. But as CreatePolyPolygonRgn is not */
534 /* really correct either, it doesn't matter much... */
535 /* At least the outline will be correct :-) */
536 hrgn
= CreatePolyPolygonRgn32( pt
, counts
, polygons
, dc
->w
.polyFillMode
);
537 X11DRV_PaintRgn( dc
, hrgn
);
538 DeleteObject32( hrgn
);
540 /* Draw the outline of the polygons */
542 if (DC_SetupGCForPen ( dc
))
547 for (i
= 0; i
< polygons
; i
++) if (counts
[i
] > max
) max
= counts
[i
];
548 points
= (XPoint
*) xmalloc( sizeof(XPoint
) * (max
+1) );
550 for (i
= 0; i
< polygons
; i
++)
552 for (j
= 0; j
< counts
[i
]; j
++)
554 points
[j
].x
= dc
->w
.DCOrgX
+ XLPTODP( dc
, pt
->x
);
555 points
[j
].y
= dc
->w
.DCOrgY
+ YLPTODP( dc
, pt
->y
);
558 points
[j
] = points
[0];
559 TSXDrawLines( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
560 points
, j
+ 1, CoordModeOrigin
);
568 /**********************************************************************
569 * X11DRV_InternalFloodFill
571 * Internal helper function for flood fill.
572 * (xorg,yorg) is the origin of the X image relative to the drawable.
573 * (x,y) is relative to the origin of the X image.
575 static void X11DRV_InternalFloodFill(XImage
*image
, DC
*dc
,
578 Pixel pixel
, WORD fillType
)
582 #define TO_FLOOD(x,y) ((fillType == FLOODFILLBORDER) ? \
583 (XGetPixel(image,x,y) != pixel) : \
584 (XGetPixel(image,x,y) == pixel))
586 if (!TO_FLOOD(x
,y
)) return;
588 /* Find left and right boundaries */
591 while ((left
> 0) && TO_FLOOD( left
-1, y
)) left
--;
592 while ((right
< image
->width
) && TO_FLOOD( right
, y
)) right
++;
593 XFillRectangle( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
594 xOrg
+ left
, yOrg
+ y
, right
-left
, 1 );
596 /* Set the pixels of this line so we don't fill it again */
598 for (x
= left
; x
< right
; x
++)
600 if (fillType
== FLOODFILLBORDER
) XPutPixel( image
, x
, y
, pixel
);
601 else XPutPixel( image
, x
, y
, ~pixel
);
604 /* Fill the line above */
611 while ((x
< right
) && !TO_FLOOD(x
,y
)) x
++;
612 if (x
>= right
) break;
613 while ((x
< right
) && TO_FLOOD(x
,y
)) x
++;
614 X11DRV_InternalFloodFill(image
, dc
, x
-1, y
,
615 xOrg
, yOrg
, pixel
, fillType
);
619 /* Fill the line below */
621 if ((y
+= 2) < image
->height
)
626 while ((x
< right
) && !TO_FLOOD(x
,y
)) x
++;
627 if (x
>= right
) break;
628 while ((x
< right
) && TO_FLOOD(x
,y
)) x
++;
629 X11DRV_InternalFloodFill(image
, dc
, x
-1, y
,
630 xOrg
, yOrg
, pixel
, fillType
);
637 /**********************************************************************
640 * Main flood-fill routine.
642 * The Xlib critical section must be entered before calling this function.
645 struct FloodFill_params
654 static BOOL32
X11DRV_DoFloodFill( const struct FloodFill_params
*params
)
660 if (GetRgnBox32( dc
->w
.hGCClipRgn
, &rect
) == ERROR
) return FALSE
;
662 if (!(image
= XGetImage( display
, dc
->u
.x
.drawable
,
663 dc
->w
.DCOrgX
+ rect
.left
,
664 dc
->w
.DCOrgY
+ rect
.top
,
665 rect
.right
- rect
.left
,
666 rect
.bottom
- rect
.top
,
667 AllPlanes
, ZPixmap
))) return FALSE
;
669 if (DC_SetupGCForBrush( dc
))
671 /* ROP mode is always GXcopy for flood-fill */
672 XSetFunction( display
, dc
->u
.x
.gc
, GXcopy
);
673 X11DRV_InternalFloodFill(image
, dc
,
674 XLPTODP(dc
,params
->x
) - rect
.left
,
675 YLPTODP(dc
,params
->y
) - rect
.top
,
676 dc
->w
.DCOrgX
+ rect
.left
,
677 dc
->w
.DCOrgY
+ rect
.top
,
678 COLOR_ToPhysical( dc
, params
->color
),
682 XDestroyImage( image
);
687 /**********************************************************************
688 * X11DRV_ExtFloodFill
691 X11DRV_ExtFloodFill( DC
*dc
, INT32 x
, INT32 y
, COLORREF color
,
695 struct FloodFill_params params
= { dc
, x
, y
, color
, fillType
};
697 dprintf_info(graphics
, "X11DRV_ExtFloodFill %d,%d %06lx %d\n",
698 x
, y
, color
, fillType
);
700 if (!PtVisible32( dc
->hSelf
, x
, y
)) return FALSE
;
701 EnterCriticalSection( &X11DRV_CritSection
);
702 result
= CALL_LARGE_STACK( X11DRV_DoFloodFill
, ¶ms
);
703 LeaveCriticalSection( &X11DRV_CritSection
);