2 * GDI graphics operations
4 * Copyright 1993 Alexandre Julliard
7 static char Copyright
[] = "Copyright Alexandre Julliard, 1993";
12 #include <X11/Xutil.h>
19 /***********************************************************************
22 BOOL
LineTo( HDC hdc
, short x
, short y
)
24 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
25 if (!dc
) return FALSE
;
26 if (DC_SetupGCForPen( dc
))
27 XDrawLine(XT_display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
28 dc
->w
.DCOrgX
+ XLPTODP( dc
, dc
->w
.CursPosX
),
29 dc
->w
.DCOrgY
+ YLPTODP( dc
, dc
->w
.CursPosY
),
30 dc
->w
.DCOrgX
+ XLPTODP( dc
, x
),
31 dc
->w
.DCOrgY
+ YLPTODP( dc
, y
) );
38 /***********************************************************************
41 DWORD
MoveTo( HDC hdc
, short x
, short y
)
44 if (MoveToEx( hdc
, x
, y
, &pt
)) return pt
.x
| (pt
.y
<< 16);
49 /***********************************************************************
52 BOOL
MoveToEx( HDC hdc
, short x
, short y
, LPPOINT pt
)
54 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
55 if (!dc
) return FALSE
;
58 pt
->x
= dc
->w
.CursPosX
;
59 pt
->y
= dc
->w
.CursPosY
;
67 /***********************************************************************
70 * Helper functions for Arc(), Chord() and Pie().
71 * 'lines' is the number of lines to draw: 0 for Arc, 1 for Chord, 2 for Pie.
73 BOOL
GRAPH_DrawArc( HDC hdc
, int left
, int top
, int right
, int bottom
,
74 int xstart
, int ystart
, int xend
, int yend
, int lines
)
77 double start_angle
, end_angle
, diff_angle
;
79 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
80 if (!dc
) return FALSE
;
82 left
= XLPTODP( dc
, left
);
83 top
= YLPTODP( dc
, top
);
84 right
= XLPTODP( dc
, right
);
85 bottom
= YLPTODP( dc
, bottom
);
86 xstart
= XLPTODP( dc
, xstart
);
87 ystart
= YLPTODP( dc
, ystart
);
88 xend
= XLPTODP( dc
, xend
);
89 yend
= YLPTODP( dc
, yend
);
90 if ((left
== right
) || (top
== bottom
)) return FALSE
;
92 if (!DC_SetupGCForPen( dc
)) return TRUE
;
94 xcenter
= (right
+ left
) / 2;
95 ycenter
= (bottom
+ top
) / 2;
96 start_angle
= atan2( (double)(ycenter
-ystart
)*(right
-left
),
97 (double)(xstart
-xcenter
)*(bottom
-top
) );
98 end_angle
= atan2( (double)(ycenter
-yend
)*(right
-left
),
99 (double)(xend
-xcenter
)*(bottom
-top
) );
100 diff_angle
= end_angle
- start_angle
;
101 if (diff_angle
< 0.0) diff_angle
+= 2*PI
;
103 XDrawArc( XT_display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
104 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
,
105 right
-left
-1, bottom
-top
-1,
106 (int)(start_angle
* 180 * 64 / PI
),
107 (int)(diff_angle
* 180 * 64 / PI
) );
108 if (!lines
) return TRUE
;
110 points
[0].x
= dc
->w
.DCOrgX
+ xcenter
+ (int)(cos(start_angle
) * (right
-left
) / 2);
111 points
[0].y
= dc
->w
.DCOrgY
+ ycenter
- (int)(sin(start_angle
) * (bottom
-top
) / 2);
112 points
[1].x
= dc
->w
.DCOrgX
+ xcenter
+ (int)(cos(end_angle
) * (right
-left
) / 2);
113 points
[1].y
= dc
->w
.DCOrgY
+ ycenter
- (int)(sin(end_angle
) * (bottom
-top
) / 2);
116 points
[2] = points
[1];
117 points
[1].x
= dc
->w
.DCOrgX
+ xcenter
;
118 points
[1].y
= dc
->w
.DCOrgY
+ ycenter
;
120 XDrawLines( XT_display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
121 points
, lines
+1, CoordModeOrigin
);
126 /***********************************************************************
129 BOOL
Arc( HDC hdc
, int left
, int top
, int right
, int bottom
,
130 int xstart
, int ystart
, int xend
, int yend
)
132 return GRAPH_DrawArc( hdc
, left
, top
, right
, bottom
,
133 xstart
, ystart
, xend
, yend
, 0 );
137 /***********************************************************************
140 BOOL
Pie( HDC hdc
, int left
, int top
, int right
, int bottom
,
141 int xstart
, int ystart
, int xend
, int yend
)
143 return GRAPH_DrawArc( hdc
, left
, top
, right
, bottom
,
144 xstart
, ystart
, xend
, yend
, 2 );
148 /***********************************************************************
151 BOOL
Chord( HDC hdc
, int left
, int top
, int right
, int bottom
,
152 int xstart
, int ystart
, int xend
, int yend
)
154 return GRAPH_DrawArc( hdc
, left
, top
, right
, bottom
,
155 xstart
, ystart
, xend
, yend
, 1 );
159 /***********************************************************************
162 BOOL
Ellipse( HDC hdc
, int left
, int top
, int right
, int bottom
)
164 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
165 if (!dc
) return FALSE
;
167 left
= XLPTODP( dc
, left
);
168 top
= YLPTODP( dc
, top
);
169 right
= XLPTODP( dc
, right
);
170 bottom
= YLPTODP( dc
, bottom
);
171 if ((left
== right
) || (top
== bottom
)) return FALSE
;
173 if (DC_SetupGCForBrush( dc
))
174 XFillArc( XT_display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
175 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
,
176 right
-left
-1, bottom
-top
-1, 0, 360*64 );
177 if (DC_SetupGCForPen( dc
))
178 XDrawArc( XT_display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
179 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
,
180 right
-left
-1, bottom
-top
-1, 0, 360*64 );
185 /***********************************************************************
188 BOOL
Rectangle( HDC hdc
, int left
, int top
, int right
, int bottom
)
190 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
191 if (!dc
) return FALSE
;
193 left
= XLPTODP( dc
, left
);
194 top
= YLPTODP( dc
, top
);
195 right
= XLPTODP( dc
, right
);
196 bottom
= YLPTODP( dc
, bottom
);
198 if (DC_SetupGCForBrush( dc
))
199 XFillRectangle( XT_display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
200 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
,
201 right
-left
-1, bottom
-top
-1 );
202 if (DC_SetupGCForPen( dc
))
203 XDrawRectangle( XT_display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
204 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
,
205 right
-left
-1, bottom
-top
-1 );
210 /***********************************************************************
213 int FillRect( HDC hdc
, LPRECT rect
, HBRUSH hbrush
)
217 if ((rect
->right
<= rect
->left
) || (rect
->bottom
<= rect
->top
)) return 0;
218 if (!(prevBrush
= SelectObject( hdc
, hbrush
))) return 0;
219 PatBlt( hdc
, rect
->left
, rect
->top
,
220 rect
->right
- rect
->left
, rect
->bottom
- rect
->top
, PATCOPY
);
221 SelectObject( hdc
, prevBrush
);
226 /***********************************************************************
227 * InvertRect (USER.82)
229 void InvertRect( HDC hdc
, LPRECT rect
)
231 if ((rect
->right
<= rect
->left
) || (rect
->bottom
<= rect
->top
)) return;
232 PatBlt( hdc
, rect
->left
, rect
->top
,
233 rect
->right
- rect
->left
, rect
->bottom
- rect
->top
, DSTINVERT
);
237 /***********************************************************************
238 * FrameRect (USER.83)
240 int FrameRect( HDC hdc
, LPRECT rect
, HBRUSH hbrush
)
243 int left
, top
, right
, bottom
;
245 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
246 if (!dc
) return FALSE
;
248 if ((rect
->right
<= rect
->left
) || (rect
->bottom
<= rect
->top
)) return 0;
249 if (!(prevBrush
= SelectObject( hdc
, hbrush
))) return 0;
251 left
= XLPTODP( dc
, rect
->left
);
252 top
= YLPTODP( dc
, rect
->top
);
253 right
= XLPTODP( dc
, rect
->right
);
254 bottom
= YLPTODP( dc
, rect
->bottom
);
256 if (DC_SetupGCForBrush( dc
)) {
257 PatBlt( hdc
, rect
->left
, rect
->top
, 1,
258 rect
->bottom
- rect
->top
, PATCOPY
);
259 PatBlt( hdc
, rect
->right
- 1, rect
->top
, 1,
260 rect
->bottom
- rect
->top
, PATCOPY
);
261 PatBlt( hdc
, rect
->left
, rect
->top
,
262 rect
->right
- rect
->left
, 1, PATCOPY
);
263 PatBlt( hdc
, rect
->left
, rect
->bottom
- 1,
264 rect
->right
- rect
->left
, 1, PATCOPY
);
266 SelectObject( hdc
, prevBrush
);
271 /***********************************************************************
274 COLORREF
SetPixel( HDC hdc
, short x
, short y
, COLORREF color
)
279 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
282 x
= dc
->w
.DCOrgX
+ XLPTODP( dc
, x
);
283 y
= dc
->w
.DCOrgY
+ YLPTODP( dc
, y
);
284 pixel
= GetNearestPaletteIndex( dc
->w
.hPalette
, color
);
285 GetPaletteEntries( dc
->w
.hPalette
, pixel
, 1, &entry
);
287 XSetForeground( XT_display
, dc
->u
.x
.gc
, pixel
);
288 XSetFunction( XT_display
, dc
->u
.x
.gc
, GXcopy
);
289 XDrawPoint( XT_display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
, x
, y
);
291 return RGB( entry
.peRed
, entry
.peGreen
, entry
.peBlue
);
295 /***********************************************************************
298 COLORREF
GetPixel( HDC hdc
, short x
, short y
)
303 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
306 x
= dc
->w
.DCOrgX
+ XLPTODP( dc
, x
);
307 y
= dc
->w
.DCOrgY
+ YLPTODP( dc
, y
);
308 if ((x
< 0) || (y
< 0)) return 0;
310 if (!(dc
->w
.flags
& DC_MEMORY
))
312 XWindowAttributes win_attr
;
314 if (!XGetWindowAttributes( XT_display
, dc
->u
.x
.drawable
, &win_attr
))
316 if (win_attr
.map_state
!= IsViewable
) return 0;
317 if ((x
>= win_attr
.width
) || (y
>= win_attr
.height
)) return 0;
320 image
= XGetImage( XT_display
, dc
->u
.x
.drawable
, x
, y
,
321 1, 1, AllPlanes
, ZPixmap
);
322 GetPaletteEntries( dc
->w
.hPalette
, XGetPixel( image
, 0, 0 ), 1, &entry
);
323 XDestroyImage( image
);
324 return RGB( entry
.peRed
, entry
.peGreen
, entry
.peBlue
);
328 /***********************************************************************
331 BOOL
PaintRgn( HDC hdc
, HRGN hrgn
)
334 HRGN tmpVisRgn
, prevVisRgn
;
335 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
336 if (!dc
) return FALSE
;
338 /* Modify visible region */
340 prevVisRgn
= SaveVisRgn( hdc
);
343 if (!(tmpVisRgn
= CreateRectRgn( 0, 0, 0, 0 )))
345 RestoreVisRgn( hdc
);
348 CombineRgn( tmpVisRgn
, prevVisRgn
, hrgn
, RGN_AND
);
349 SelectVisRgn( hdc
, tmpVisRgn
);
350 DeleteObject( tmpVisRgn
);
352 else SelectVisRgn( hdc
, hrgn
);
354 /* Fill the region */
356 GetClipBox( hdc
, &box
);
357 if (DC_SetupGCForBrush( dc
))
358 XFillRectangle( XT_display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
359 dc
->w
.DCOrgX
+ box
.left
, dc
->w
.DCOrgY
+ box
.top
,
360 box
.right
-box
.left
, box
.bottom
-box
.top
);
362 /* Restore the visible region */
364 if (prevVisRgn
) RestoreVisRgn( hdc
);
365 else SelectVisRgn( hdc
, 0 );
370 /***********************************************************************
373 BOOL
FillRgn( HDC hdc
, HRGN hrgn
, HBRUSH hbrush
)
376 HBRUSH prevBrush
= SelectObject( hdc
, hbrush
);
377 if (!prevBrush
) return FALSE
;
378 retval
= PaintRgn( hdc
, hrgn
);
379 SelectObject( hdc
, prevBrush
);
384 /***********************************************************************
385 * DrawFocusRect (USER.466)
387 void DrawFocusRect( HDC hdc
, LPRECT rc
)
390 int oldDrawMode
, oldBkMode
;
391 int left
, top
, right
, bottom
;
392 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
395 left
= XLPTODP( dc
, rc
->left
);
396 top
= YLPTODP( dc
, rc
->top
);
397 right
= XLPTODP( dc
, rc
->right
);
398 bottom
= YLPTODP( dc
, rc
->bottom
);
400 hPen
= CreatePen(PS_DOT
, 1, GetSysColor(COLOR_WINDOWTEXT
));
401 hOldPen
= (HPEN
)SelectObject(hdc
, (HANDLE
)hPen
);
402 oldDrawMode
= SetROP2(hdc
, R2_XORPEN
);
403 oldBkMode
= SetBkMode(hdc
, TRANSPARENT
);
405 if (DC_SetupGCForPen( dc
))
406 XDrawRectangle( XT_display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
407 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
,
408 right
-left
-1, bottom
-top
-1 );
410 SetBkMode(hdc
, oldBkMode
);
411 SetROP2(hdc
, oldDrawMode
);
412 SelectObject(hdc
, (HANDLE
)hOldPen
);
413 DeleteObject((HANDLE
)hPen
);
417 /**********************************************************************
418 * DrawReliefRect (Not a MSWin Call)
420 void DrawReliefRect( HDC hdc
, RECT rect
, int thickness
, BOOL pressed
)
422 HBRUSH hbrushOld
, hbrushShadow
, hbrushHighlight
;
425 hbrushShadow
= CreateSolidBrush( GetSysColor(COLOR_BTNSHADOW
) );
426 hbrushHighlight
= CreateSolidBrush( GetSysColor(COLOR_BTNHIGHLIGHT
) );
428 if (pressed
) hbrushOld
= SelectObject( hdc
, hbrushShadow
);
429 else hbrushOld
= SelectObject( hdc
, hbrushHighlight
);
431 for (i
= 0; i
< thickness
; i
++)
433 PatBlt( hdc
, rect
.left
+ i
, rect
.top
,
434 1, rect
.bottom
- rect
.top
- i
, PATCOPY
);
435 PatBlt( hdc
, rect
.left
, rect
.top
+ i
,
436 rect
.right
- rect
.left
- i
, 1, PATCOPY
);
439 if (pressed
) hbrushOld
= SelectObject( hdc
, hbrushHighlight
);
440 else hbrushOld
= SelectObject( hdc
, hbrushShadow
);
442 for (i
= 0; i
< thickness
; i
++)
444 PatBlt( hdc
, rect
.right
- i
- 1, rect
.top
+ i
,
445 1, rect
.bottom
- rect
.top
- i
, PATCOPY
);
446 PatBlt( hdc
, rect
.left
+ i
, rect
.bottom
- i
- 1,
447 rect
.right
- rect
.left
- i
, 1, PATCOPY
);
450 SelectObject( hdc
, hbrushOld
);
451 DeleteObject( hbrushShadow
);
452 DeleteObject( hbrushHighlight
);
456 /**********************************************************************
459 BOOL
Polyline (HDC hdc
, LPPOINT pt
, int count
)
462 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
464 if (DC_SetupGCForPen( dc
))
466 for (i
= 0; i
< count
-1; i
++)
467 XDrawLine (XT_display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
468 dc
->w
.DCOrgX
+ XLPTODP(dc
, pt
[i
].x
),
469 dc
->w
.DCOrgY
+ YLPTODP(dc
, pt
[i
].y
),
470 dc
->w
.DCOrgX
+ XLPTODP(dc
, pt
[i
+1].x
),
471 dc
->w
.DCOrgY
+ YLPTODP(dc
, pt
[i
+1].y
));
472 XDrawLine (XT_display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
473 dc
->w
.DCOrgX
+ XLPTODP(dc
, pt
[count
-1].x
),
474 dc
->w
.DCOrgY
+ YLPTODP(dc
, pt
[count
-1].y
),
475 dc
->w
.DCOrgX
+ XLPTODP(dc
, pt
[0].x
),
476 dc
->w
.DCOrgY
+ YLPTODP(dc
, pt
[0].y
));
483 /**********************************************************************
486 BOOL
Polygon (HDC hdc
, LPPOINT pt
, int count
)
489 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
490 XPoint
*points
= (XPoint
*) malloc (sizeof (XPoint
) * count
+1);
492 if (DC_SetupGCForBrush( dc
))
495 for (i
= 0; i
< count
; i
++)
497 points
[i
].x
= dc
->w
.DCOrgX
+ XLPTODP(dc
, pt
[i
].x
);
498 points
[i
].y
= dc
->w
.DCOrgY
+ YLPTODP(dc
, pt
[i
].y
);
500 points
[count
] = points
[0];
502 XFillPolygon( XT_display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
503 points
, count
, Complex
, CoordModeOrigin
);
505 if (DC_SetupGCForPen ( dc
))
507 XDrawLines( XT_display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
508 points
, count
, CoordModeOrigin
);
511 free ((void *) points
);