Release 970329
[wine/multimedia.git] / windows / graphics.c
blob2de7bd9ae2d92fce7f1ee1aa508a058691b90d83
1 /*
2 * GDI graphics operations
4 * Copyright 1993, 1994 Alexandre Julliard
5 */
7 #include <assert.h>
8 #include <math.h>
9 #include <stdlib.h>
10 #include <X11/Xlib.h>
11 #include <X11/Xutil.h>
12 #include <X11/Intrinsic.h>
13 #ifndef PI
14 #define PI M_PI
15 #endif
16 #include "graphics.h"
17 #include "gdi.h"
18 #include "dc.h"
19 #include "bitmap.h"
20 #include "callback.h"
21 #include "metafile.h"
22 #include "syscolor.h"
23 #include "stddebug.h"
24 #include "palette.h"
25 #include "color.h"
26 #include "region.h"
27 #include "debug.h"
28 #include "xmalloc.h"
30 #define MAX_DRAWLINES 8
32 /***********************************************************************
33 * LineTo16 (GDI.19)
35 BOOL16 LineTo16( HDC16 hdc, INT16 x, INT16 y )
37 return LineTo32( hdc, x, y );
41 /***********************************************************************
42 * LineTo32 (GDI32.249)
44 BOOL32 LineTo32( HDC32 hdc, INT32 x, INT32 y )
46 DC * dc = DC_GetDCPtr( hdc );
48 return dc && dc->funcs->pLineTo &&
49 dc->funcs->pLineTo(dc,x,y);
53 /***********************************************************************
54 * MoveTo (GDI.20)
56 DWORD MoveTo( HDC16 hdc, INT16 x, INT16 y )
58 POINT16 pt;
60 if (!MoveToEx16(hdc,x,y,&pt))
61 return 0;
62 return MAKELONG(pt.x,pt.y);
66 /***********************************************************************
67 * MoveToEx16 (GDI.483)
69 BOOL16 MoveToEx16( HDC16 hdc, INT16 x, INT16 y, LPPOINT16 pt )
71 POINT32 pt32;
73 if (!MoveToEx32( (HDC32)hdc, (INT32)x, (INT32)y, &pt32 )) return FALSE;
74 if (pt) CONV_POINT32TO16( &pt32, pt );
75 return TRUE;
80 /***********************************************************************
81 * MoveToEx32 (GDI32.254)
83 BOOL32 MoveToEx32( HDC32 hdc, INT32 x, INT32 y, LPPOINT32 pt )
85 DC * dc = DC_GetDCPtr( hdc );
87 return dc && dc->funcs->pMoveToEx &&
88 dc->funcs->pMoveToEx(dc,x,y,pt);
92 /***********************************************************************
93 * Arc16 (GDI.23)
95 BOOL16 Arc16( HDC16 hdc, INT16 left, INT16 top, INT16 right, INT16 bottom,
96 INT16 xstart, INT16 ystart, INT16 xend, INT16 yend )
98 return Arc32( (HDC32)hdc, (INT32)left, (INT32)top, (INT32)right,
99 (INT32)bottom, (INT32)xstart, (INT32)ystart, (INT32)xend,
100 (INT32)yend );
104 /***********************************************************************
105 * Arc32 (GDI32.7)
107 BOOL32 Arc32( HDC32 hdc, INT32 left, INT32 top, INT32 right, INT32 bottom,
108 INT32 xstart, INT32 ystart, INT32 xend, INT32 yend )
110 DC * dc = DC_GetDCPtr( hdc );
112 return dc && dc->funcs->pArc &&
113 dc->funcs->pArc(dc,left,top,right,bottom,xstart,ystart,xend,yend);
117 /***********************************************************************
118 * Pie16 (GDI.26)
120 BOOL16 Pie16( HDC16 hdc, INT16 left, INT16 top, INT16 right, INT16 bottom,
121 INT16 xstart, INT16 ystart, INT16 xend, INT16 yend )
123 return Pie32( (HDC32)hdc, (INT32)left, (INT32)top, (INT32)right,
124 (INT32)bottom, (INT32)xstart, (INT32)ystart, (INT32)xend,
125 (INT32)yend );
129 /***********************************************************************
130 * Pie32 (GDI32.262)
132 BOOL32 Pie32( HDC32 hdc, INT32 left, INT32 top, INT32 right, INT32 bottom,
133 INT32 xstart, INT32 ystart, INT32 xend, INT32 yend )
135 DC * dc = DC_GetDCPtr( hdc );
137 return dc && dc->funcs->pPie &&
138 dc->funcs->pPie(dc,left,top,right,bottom,xstart,ystart,xend,yend);
142 /***********************************************************************
143 * Chord16 (GDI.348)
145 BOOL16 Chord16( HDC16 hdc, INT16 left, INT16 top, INT16 right, INT16 bottom,
146 INT16 xstart, INT16 ystart, INT16 xend, INT16 yend )
148 return Chord32( hdc, left, top, right, bottom, xstart, ystart, xend, yend );
152 /***********************************************************************
153 * Chord32 (GDI32.14)
155 BOOL32 Chord32( HDC32 hdc, INT32 left, INT32 top, INT32 right, INT32 bottom,
156 INT32 xstart, INT32 ystart, INT32 xend, INT32 yend )
158 DC * dc = DC_GetDCPtr( hdc );
160 return dc && dc->funcs->pChord &&
161 dc->funcs->pChord(dc,left,top,right,bottom,xstart,ystart,xend,yend);
165 /***********************************************************************
166 * Ellipse16 (GDI.24)
168 BOOL16 Ellipse16( HDC16 hdc, INT16 left, INT16 top, INT16 right, INT16 bottom )
170 return Ellipse32( hdc, left, top, right, bottom );
174 /***********************************************************************
175 * Ellipse32 (GDI32.75)
177 BOOL32 Ellipse32( HDC32 hdc, INT32 left, INT32 top, INT32 right, INT32 bottom )
179 DC * dc = DC_GetDCPtr( hdc );
181 return dc && dc->funcs->pEllipse &&
182 dc->funcs->pEllipse(dc,left,top,right,bottom);
186 /***********************************************************************
187 * Rectangle16 (GDI.27)
189 BOOL16 Rectangle16(HDC16 hdc, INT16 left, INT16 top, INT16 right, INT16 bottom)
191 return Rectangle32( hdc, left, top, right, bottom );
195 /***********************************************************************
196 * Rectangle32 (GDI32.283)
198 BOOL32 Rectangle32(HDC32 hdc, INT32 left, INT32 top, INT32 right, INT32 bottom)
200 DC * dc = DC_GetDCPtr( hdc );
202 return dc && dc->funcs->pRectangle &&
203 dc->funcs->pRectangle(dc,left,top,right,bottom);
207 /***********************************************************************
208 * RoundRect16 (GDI.28)
210 BOOL16 RoundRect16( HDC16 hdc, INT16 left, INT16 top, INT16 right,
211 INT16 bottom, INT16 ell_width, INT16 ell_height )
213 return RoundRect32( hdc, left, top, right, bottom, ell_width, ell_height );
217 /***********************************************************************
218 * RoundRect32 (GDI32.291)
220 BOOL32 RoundRect32( HDC32 hdc, INT32 left, INT32 top, INT32 right,
221 INT32 bottom, INT32 ell_width, INT32 ell_height )
223 DC * dc = DC_GetDCPtr( hdc );
225 return dc && dc->funcs->pRoundRect &&
226 dc->funcs->pRoundRect(dc,left,top,right,bottom,ell_width,ell_height);
230 /***********************************************************************
231 * FillRect16 (USER.81)
233 INT16 FillRect16( HDC16 hdc, const RECT16 *rect, HBRUSH16 hbrush )
235 HBRUSH16 prevBrush;
237 /* coordinates are logical so we cannot fast-check 'rect',
238 * it will be done later in the PatBlt().
241 if (!(prevBrush = SelectObject16( hdc, hbrush ))) return 0;
242 PatBlt32( hdc, rect->left, rect->top,
243 rect->right - rect->left, rect->bottom - rect->top, PATCOPY );
244 SelectObject16( hdc, prevBrush );
245 return 1;
249 /***********************************************************************
250 * FillRect32 (USER32.196)
252 INT32 FillRect32( HDC32 hdc, const RECT32 *rect, HBRUSH32 hbrush )
254 HBRUSH32 prevBrush;
256 if (!(prevBrush = SelectObject32( hdc, hbrush ))) return 0;
257 PatBlt32( hdc, rect->left, rect->top,
258 rect->right - rect->left, rect->bottom - rect->top, PATCOPY );
259 SelectObject32( hdc, prevBrush );
260 return 1;
264 /***********************************************************************
265 * InvertRect16 (USER.82)
267 void InvertRect16( HDC16 hdc, const RECT16 *rect )
269 PatBlt32( hdc, rect->left, rect->top,
270 rect->right - rect->left, rect->bottom - rect->top, DSTINVERT );
274 /***********************************************************************
275 * InvertRect32 (USER32.329)
277 void InvertRect32( HDC32 hdc, const RECT32 *rect )
279 PatBlt32( hdc, rect->left, rect->top,
280 rect->right - rect->left, rect->bottom - rect->top, DSTINVERT );
284 /***********************************************************************
285 * FrameRect16 (USER.83)
287 INT16 FrameRect16( HDC16 hdc, const RECT16 *rect, HBRUSH16 hbrush )
289 HBRUSH16 prevBrush;
290 int left, top, right, bottom;
292 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
293 if (!dc) return FALSE;
295 left = XLPTODP( dc, rect->left );
296 top = YLPTODP( dc, rect->top );
297 right = XLPTODP( dc, rect->right );
298 bottom = YLPTODP( dc, rect->bottom );
300 if ( (right <= left) || (bottom <= top) ) return 0;
301 if (!(prevBrush = SelectObject16( hdc, hbrush ))) return 0;
303 if (DC_SetupGCForBrush( dc ))
305 PatBlt32( hdc, rect->left, rect->top, 1,
306 rect->bottom - rect->top, PATCOPY );
307 PatBlt32( hdc, rect->right - 1, rect->top, 1,
308 rect->bottom - rect->top, PATCOPY );
309 PatBlt32( hdc, rect->left, rect->top,
310 rect->right - rect->left, 1, PATCOPY );
311 PatBlt32( hdc, rect->left, rect->bottom - 1,
312 rect->right - rect->left, 1, PATCOPY );
314 SelectObject16( hdc, prevBrush );
315 return 1;
319 /***********************************************************************
320 * FrameRect32 (USER32.202)
322 INT32 FrameRect32( HDC32 hdc, const RECT32 *rect, HBRUSH32 hbrush )
324 RECT16 rect16;
325 CONV_RECT32TO16( rect, &rect16 );
326 return FrameRect16( (HDC16)hdc, &rect16, (HBRUSH16)hbrush );
330 /***********************************************************************
331 * SetPixel16 (GDI.31)
333 COLORREF SetPixel16( HDC16 hdc, INT16 x, INT16 y, COLORREF color )
335 return SetPixel32( hdc, x, y, color );
339 /***********************************************************************
340 * SetPixel32 (GDI32.327)
342 COLORREF SetPixel32( HDC32 hdc, INT32 x, INT32 y, COLORREF color )
344 DC * dc = DC_GetDCPtr( hdc );
346 if (!dc || !dc->funcs->pSetPixel) return 0;
347 return dc->funcs->pSetPixel(dc,x,y,color);
351 /***********************************************************************
352 * GetPixel16 (GDI.83)
354 COLORREF GetPixel16( HDC16 hdc, INT16 x, INT16 y )
356 return GetPixel32( hdc, x, y );
360 /***********************************************************************
361 * GetPixel32 (GDI32.211)
363 COLORREF GetPixel32( HDC32 hdc, INT32 x, INT32 y )
365 DC * dc = DC_GetDCPtr( hdc );
367 if (!dc) return 0;
368 #ifdef SOLITAIRE_SPEED_HACK
369 return 0;
370 #endif
372 /* FIXME: should this be in the graphics driver? */
373 if (!PtVisible32( hdc, x, y )) return 0;
374 if (!dc || !dc->funcs->pGetPixel) return 0;
375 return dc->funcs->pGetPixel(dc,x,y);
379 /***********************************************************************
380 * PaintRgn16 (GDI.43)
382 BOOL16 PaintRgn16( HDC16 hdc, HRGN16 hrgn )
384 return PaintRgn32( hdc, hrgn );
388 /***********************************************************************
389 * PaintRgn32 (GDI32.259)
391 BOOL32 PaintRgn32( HDC32 hdc, HRGN32 hrgn )
393 DC * dc = DC_GetDCPtr( hdc );
395 return dc && dc->funcs->pPaintRgn &&
396 dc->funcs->pPaintRgn(dc,hrgn);
400 /***********************************************************************
401 * FillRgn16 (GDI.40)
403 BOOL16 FillRgn16( HDC16 hdc, HRGN16 hrgn, HBRUSH16 hbrush )
405 return FillRgn32( hdc, hrgn, hbrush );
409 /***********************************************************************
410 * FillRgn32 (GDI32.101)
412 BOOL32 FillRgn32( HDC32 hdc, HRGN32 hrgn, HBRUSH32 hbrush )
414 BOOL32 retval;
415 HBRUSH32 prevBrush = SelectObject32( hdc, hbrush );
416 if (!prevBrush) return FALSE;
417 retval = PaintRgn32( hdc, hrgn );
418 SelectObject32( hdc, prevBrush );
419 return retval;
423 /***********************************************************************
424 * FrameRgn16 (GDI.41)
426 BOOL16 FrameRgn16( HDC16 hdc, HRGN16 hrgn, HBRUSH16 hbrush,
427 INT16 nWidth, INT16 nHeight )
429 return FrameRgn32( hdc, hrgn, hbrush, nWidth, nHeight );
433 /***********************************************************************
434 * FrameRgn32 (GDI32.105)
436 BOOL32 FrameRgn32( HDC32 hdc, HRGN32 hrgn, HBRUSH32 hbrush,
437 INT32 nWidth, INT32 nHeight )
439 HRGN32 tmp = CreateRectRgn32( 0, 0, 0, 0 );
440 if(!REGION_FrameRgn( tmp, hrgn, nWidth, nHeight )) return FALSE;
441 FillRgn32( hdc, tmp, hbrush );
442 DeleteObject32( tmp );
443 return TRUE;
447 /***********************************************************************
448 * InvertRgn16 (GDI.42)
450 BOOL16 InvertRgn16( HDC16 hdc, HRGN16 hrgn )
452 return InvertRgn32( hdc, hrgn );
456 /***********************************************************************
457 * InvertRgn32 (GDI32.246)
459 BOOL32 InvertRgn32( HDC32 hdc, HRGN32 hrgn )
461 HBRUSH32 prevBrush = SelectObject32( hdc, GetStockObject32(BLACK_BRUSH) );
462 INT32 prevROP = SetROP232( hdc, R2_NOT );
463 BOOL32 retval = PaintRgn32( hdc, hrgn );
464 SelectObject32( hdc, prevBrush );
465 SetROP232( hdc, prevROP );
466 return retval;
470 /***********************************************************************
471 * DrawFocusRect16 (USER.466)
473 void DrawFocusRect16( HDC16 hdc, const RECT16* rc )
475 RECT32 rect32;
476 CONV_RECT16TO32( rc, &rect32 );
477 DrawFocusRect32( hdc, &rect32 );
481 /***********************************************************************
482 * DrawFocusRect32 (USER32.155)
484 * FIXME: should use Rectangle32!
486 void DrawFocusRect32( HDC32 hdc, const RECT32* rc )
488 HPEN32 hOldPen;
489 INT32 oldDrawMode, oldBkMode;
490 INT32 left, top, right, bottom;
492 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
493 if (!dc) return;
495 left = XLPTODP( dc, rc->left );
496 top = YLPTODP( dc, rc->top );
497 right = XLPTODP( dc, rc->right );
498 bottom = YLPTODP( dc, rc->bottom );
500 hOldPen = SelectObject32( hdc, sysColorObjects.hpenWindowText );
501 oldDrawMode = SetROP232(hdc, R2_XORPEN);
502 oldBkMode = SetBkMode32(hdc, TRANSPARENT);
504 /* Hack: make sure the XORPEN operation has an effect */
505 dc->u.x.pen.pixel = (1 << screenDepth) - 1;
507 if (DC_SetupGCForPen( dc ))
508 XDrawRectangle( display, dc->u.x.drawable, dc->u.x.gc,
509 dc->w.DCOrgX + left, dc->w.DCOrgY + top,
510 right-left-1, bottom-top-1 );
512 SetBkMode32(hdc, oldBkMode);
513 SetROP232(hdc, oldDrawMode);
514 SelectObject32(hdc, hOldPen);
518 /**********************************************************************
519 * Polyline16 (GDI.37)
521 BOOL16 Polyline16( HDC16 hdc, LPPOINT16 pt, INT16 count )
523 register int i;
524 LPPOINT32 pt32 = (LPPOINT32)xmalloc(count*sizeof(POINT32));
525 BOOL16 ret;
527 for (i=count;i--;) CONV_POINT16TO32(&(pt[i]),&(pt32[i]));
528 ret = Polyline32(hdc,pt32,count);
529 free(pt32);
530 return ret;
534 /**********************************************************************
535 * Polyline32 (GDI32.276)
537 BOOL32 Polyline32( HDC32 hdc, const LPPOINT32 pt, INT32 count )
539 DC * dc = DC_GetDCPtr( hdc );
541 return dc && dc->funcs->pPolyline &&
542 dc->funcs->pPolyline(dc,pt,count);
546 /**********************************************************************
547 * Polygon16 (GDI.36)
549 BOOL16 Polygon16( HDC16 hdc, LPPOINT16 pt, INT16 count )
551 register int i;
552 LPPOINT32 pt32 = (LPPOINT32)xmalloc(count*sizeof(POINT32));
553 BOOL32 ret;
556 for (i=count;i--;) CONV_POINT16TO32(&(pt[i]),&(pt32[i]));
557 ret = Polygon32(hdc,pt32,count);
558 free(pt32);
559 return ret;
563 /**********************************************************************
564 * Polygon32 (GDI32.275)
566 BOOL32 Polygon32( HDC32 hdc, LPPOINT32 pt, INT32 count )
568 DC * dc = DC_GetDCPtr( hdc );
570 return dc && dc->funcs->pPolygon &&
571 dc->funcs->pPolygon(dc,pt,count);
575 /**********************************************************************
576 * PolyPolygon16 (GDI.450)
578 BOOL16 PolyPolygon16( HDC16 hdc, LPPOINT16 pt, LPINT16 counts, UINT16 polygons)
580 int i,nrpts;
581 LPPOINT32 pt32;
582 LPINT32 counts32;
583 BOOL16 ret;
585 nrpts=0;
586 for (i=polygons;i--;)
587 nrpts+=counts[i];
588 pt32 = (LPPOINT32)xmalloc(sizeof(POINT32)*nrpts);
589 for (i=nrpts;i--;)
590 CONV_POINT16TO32(&(pt[i]),&(pt32[i]));
591 counts32 = (LPINT32)xmalloc(polygons*sizeof(INT32));
592 for (i=polygons;i--;) counts32[i]=counts[i];
594 ret = PolyPolygon32(hdc,pt32,counts32,polygons);
595 free(counts32);
596 free(pt32);
597 return ret;
600 /**********************************************************************
601 * PolyPolygon32 (GDI.450)
603 BOOL32 PolyPolygon32( HDC32 hdc, LPPOINT32 pt, LPINT32 counts, UINT32 polygons)
605 DC * dc = DC_GetDCPtr( hdc );
607 return dc && dc->funcs->pPolyPolygon &&
608 dc->funcs->pPolyPolygon(dc,pt,counts,polygons);
611 /**********************************************************************
612 * ExtFloodFill16 (GDI.372)
614 BOOL16 ExtFloodFill16( HDC16 hdc, INT16 x, INT16 y, COLORREF color,
615 UINT16 fillType )
617 return ExtFloodFill32( hdc, x, y, color, fillType );
621 /**********************************************************************
622 * ExtFloodFill32 (GDI32.96)
624 BOOL32 ExtFloodFill32( HDC32 hdc, INT32 x, INT32 y, COLORREF color,
625 UINT32 fillType )
627 DC *dc = DC_GetDCPtr( hdc );
629 return dc && dc->funcs->pExtFloodFill &&
630 dc->funcs->pExtFloodFill(dc,x,y,color,fillType);
634 /**********************************************************************
635 * FloodFill16 (GDI.25)
637 BOOL16 FloodFill16( HDC16 hdc, INT16 x, INT16 y, COLORREF color )
639 return ExtFloodFill32( hdc, x, y, color, FLOODFILLBORDER );
643 /**********************************************************************
644 * FloodFill32 (GDI32.104)
646 BOOL32 FloodFill32( HDC32 hdc, INT32 x, INT32 y, COLORREF color )
648 return ExtFloodFill32( hdc, x, y, color, FLOODFILLBORDER );
652 /**********************************************************************
653 * DrawEdge16 (USER.659)
655 BOOL16 DrawEdge16( HDC16 hdc, LPRECT16 rc, UINT16 edge, UINT16 flags )
657 RECT32 rect32;
658 BOOL32 ret;
660 CONV_RECT16TO32( rc, &rect32 );
661 ret = DrawEdge32( hdc, &rect32, edge, flags );
662 CONV_RECT32TO16( &rect32, rc );
663 return ret;
667 /**********************************************************************
668 * DrawEdge32 (USER32.154)
670 BOOL32 DrawEdge32( HDC32 hdc, LPRECT32 rc, UINT32 edge, UINT32 flags )
672 HBRUSH32 hbrushOld;
674 if (flags >= BF_DIAGONAL)
675 fprintf( stderr, "DrawEdge: unsupported flags %04x\n", flags );
677 dprintf_graphics( stddeb, "DrawEdge: %04x %d,%d-%d,%d %04x %04x\n",
678 hdc, rc->left, rc->top, rc->right, rc->bottom,
679 edge, flags );
681 /* First do all the raised edges */
683 hbrushOld = SelectObject32( hdc, sysColorObjects.hbrushBtnHighlight );
684 if (edge & BDR_RAISEDOUTER)
686 if (flags & BF_LEFT) PatBlt32( hdc, rc->left, rc->top,
687 1, rc->bottom - rc->top - 1, PATCOPY );
688 if (flags & BF_TOP) PatBlt32( hdc, rc->left, rc->top,
689 rc->right - rc->left - 1, 1, PATCOPY );
691 if (edge & BDR_SUNKENOUTER)
693 if (flags & BF_RIGHT) PatBlt32( hdc, rc->right - 1, rc->top,
694 1, rc->bottom - rc->top, PATCOPY );
695 if (flags & BF_BOTTOM) PatBlt32( hdc, rc->left, rc->bottom - 1,
696 rc->right - rc->left, 1, PATCOPY );
698 if (edge & BDR_RAISEDINNER)
700 if (flags & BF_LEFT) PatBlt32( hdc, rc->left + 1, rc->top + 1,
701 1, rc->bottom - rc->top - 2, PATCOPY );
702 if (flags & BF_TOP) PatBlt32( hdc, rc->left + 1, rc->top + 1,
703 rc->right - rc->left - 2, 1, PATCOPY );
705 if (edge & BDR_SUNKENINNER)
707 if (flags & BF_RIGHT) PatBlt32( hdc, rc->right - 2, rc->top + 1,
708 1, rc->bottom - rc->top - 2, PATCOPY );
709 if (flags & BF_BOTTOM) PatBlt32( hdc, rc->left + 1, rc->bottom - 2,
710 rc->right - rc->left - 2, 1, PATCOPY );
713 /* Then do all the sunken edges */
715 SelectObject32( hdc, sysColorObjects.hbrushBtnShadow );
716 if (edge & BDR_SUNKENOUTER)
718 if (flags & BF_LEFT) PatBlt32( hdc, rc->left, rc->top,
719 1, rc->bottom - rc->top - 1, PATCOPY );
720 if (flags & BF_TOP) PatBlt32( hdc, rc->left, rc->top,
721 rc->right - rc->left - 1, 1, PATCOPY );
723 if (edge & BDR_RAISEDOUTER)
725 if (flags & BF_RIGHT) PatBlt32( hdc, rc->right - 1, rc->top,
726 1, rc->bottom - rc->top, PATCOPY );
727 if (flags & BF_BOTTOM) PatBlt32( hdc, rc->left, rc->bottom - 1,
728 rc->right - rc->left, 1, PATCOPY );
730 if (edge & BDR_SUNKENINNER)
732 if (flags & BF_LEFT) PatBlt32( hdc, rc->left + 1, rc->top + 1,
733 1, rc->bottom - rc->top - 2, PATCOPY );
734 if (flags & BF_TOP) PatBlt32( hdc, rc->left + 1, rc->top + 1,
735 rc->right - rc->left - 2, 1, PATCOPY );
737 if (edge & BDR_RAISEDINNER)
739 if (flags & BF_RIGHT) PatBlt32( hdc, rc->right - 2, rc->top + 1,
740 1, rc->bottom - rc->top - 2, PATCOPY );
741 if (flags & BF_BOTTOM) PatBlt32( hdc, rc->left + 1, rc->bottom - 2,
742 rc->right - rc->left - 2, 1, PATCOPY );
745 SelectObject32( hdc, hbrushOld );
746 return TRUE;
750 /**********************************************************************
751 * DrawFrameControl16 (USER.656)
753 BOOL16 DrawFrameControl16( HDC16 hdc, LPRECT16 rc, UINT16 edge, UINT16 flags )
755 fprintf( stdnimp,"DrawFrameControl16(%x,%p,%d,%x), empty stub!\n",
756 hdc,rc,edge,flags );
757 return TRUE;
761 /**********************************************************************
762 * DrawFrameControl32 (USER32.157)
764 BOOL32 DrawFrameControl32( HDC32 hdc, LPRECT32 rc, UINT32 edge, UINT32 flags )
766 fprintf( stdnimp,"DrawFrameControl32(%x,%p,%d,%x), empty stub!\n",
767 hdc,rc,edge,flags );
768 return TRUE;
771 /******************************* X-specific shortcuts to speed up WM code.
772 * `----------------------------------------
774 * Caveat: no coordinate transformations except origin translation.
777 /**********************************************************************
779 * GRAPH_DrawLines
781 * Draw multiple unconnected lines (limited by MAX_DRAWLINES).
783 BOOL32 GRAPH_DrawLines( HDC32 hdc, LPPOINT32 pXY, INT32 N, HPEN32 hPen )
785 BOOL32 bRet = FALSE;
786 DC* dc;
788 assert( N <= MAX_DRAWLINES );
789 if( (dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC )) )
791 HPEN32 hPrevPen = 0;
793 if( hPen ) hPrevPen = SelectObject32( hdc, hPen );
794 if( DC_SetupGCForPen( dc ) )
796 XSegment l[MAX_DRAWLINES];
797 INT32 i, j;
799 for( i = 0; i < N; i++ )
801 j = 2 * i;
802 l[i].x1 = pXY[j].x + dc->w.DCOrgX;
803 l[i].x2 = pXY[j + 1].x + dc->w.DCOrgX;
804 l[i].y1 = pXY[j].y + dc->w.DCOrgY;
805 l[i].y2 = pXY[j + 1].y + dc->w.DCOrgY;
807 XDrawSegments( display, dc->u.x.drawable, dc->u.x.gc, l, N );
808 bRet = TRUE;
810 if( hPrevPen ) SelectObject32( hdc, hPrevPen );
812 return bRet;
815 /**********************************************************************
817 * GRAPH_DrawBitmap
819 * Short-cut function to blit a bitmap into a device.
820 * Faster than CreateCompatibleDC() + SelectBitmap() + BitBlt() + DeleteDC().
822 BOOL32 GRAPH_DrawBitmap( HDC32 hdc, HBITMAP32 hbitmap,
823 INT32 xdest, INT32 ydest, INT32 xsrc, INT32 ysrc,
824 INT32 width, INT32 height )
826 BITMAPOBJ *bmp;
827 DC *dc;
829 if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return FALSE;
830 if (!(bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC )))
831 return FALSE;
832 XSetFunction( display, dc->u.x.gc, GXcopy );
833 if (bmp->bitmap.bmBitsPixel == 1)
835 XSetForeground( display, dc->u.x.gc, dc->w.backgroundPixel );
836 XSetBackground( display, dc->u.x.gc, dc->w.textPixel );
837 XCopyPlane( display, bmp->pixmap, dc->u.x.drawable, dc->u.x.gc,
838 xsrc, ysrc, width, height,
839 dc->w.DCOrgX + xdest, dc->w.DCOrgY + ydest, 1 );
840 return TRUE;
842 else if (bmp->bitmap.bmBitsPixel == dc->w.bitsPerPixel)
844 XCopyArea( display, bmp->pixmap, dc->u.x.drawable, dc->u.x.gc,
845 xsrc, ysrc, width, height,
846 dc->w.DCOrgX + xdest, dc->w.DCOrgY + ydest );
847 return TRUE;
849 else return FALSE;
853 /**********************************************************************
854 * GRAPH_DrawReliefRect
856 * Used in the standard control code for button edge drawing.
858 void GRAPH_DrawReliefRect( HDC32 hdc, const RECT32 *rect, INT32 highlight_size,
859 INT32 shadow_size, BOOL32 pressed )
861 DC* dc;
862 HBRUSH32 hPrevBrush;
863 INT32 w, h;
864 RECT32 r = *rect;
866 if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return;
868 OffsetRect32( &r, dc->w.DCOrgX, dc->w.DCOrgY);
869 h = rect->bottom - rect->top; w = rect->right - rect->left;
871 hPrevBrush = SelectObject32(hdc, pressed ? sysColorObjects.hbrushBtnShadow :
872 sysColorObjects.hbrushBtnHighlight );
873 if ( DC_SetupGCForBrush( dc ) )
875 INT32 i;
877 XSetFunction( display, dc->u.x.gc, GXcopy );
878 for (i = 0; i < highlight_size; i++)
880 XFillRectangle( display, dc->u.x.drawable, dc->u.x.gc,
881 r.left + i, r.top, 1, h - i );
882 XFillRectangle( display, dc->u.x.drawable, dc->u.x.gc,
883 r.left, r.top + i, w - i, 1 );
887 SelectObject32( hdc, pressed ? sysColorObjects.hbrushBtnHighlight :
888 sysColorObjects.hbrushBtnShadow );
889 if ( DC_SetupGCForBrush( dc ) )
891 INT32 i;
893 XSetFunction( display, dc->u.x.gc, GXcopy );
894 for (i = 0; i < shadow_size; i++)
896 XFillRectangle( display, dc->u.x.drawable, dc->u.x.gc,
897 r.right - i - 1, r.top + i, 1, h - i );
898 XFillRectangle( display, dc->u.x.drawable, dc->u.x.gc,
899 r.left + i, r.bottom - i - 1, w - i, 1 );
903 SelectObject32( hdc, hPrevBrush );
906 /**********************************************************************
907 * GRAPH_DrawRectangle
909 void GRAPH_DrawRectangle( HDC32 hdc, INT32 x, INT32 y,
910 INT32 w, INT32 h, HPEN32 hPen )
912 DC* dc;
914 if( (dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC )) )
916 HPEN32 hPrevPen = 0;
918 if( hPen ) hPrevPen = SelectObject32( hdc, hPen );
919 if( DC_SetupGCForPen( dc ) )
920 XDrawRectangle( display, dc->u.x.drawable, dc->u.x.gc,
921 x + dc->w.DCOrgX, y + dc->w.DCOrgY, w - 1, h - 1);
922 if( hPrevPen ) SelectObject32( hdc, hPrevPen );
926 /**********************************************************************
927 * GRAPH_SelectClipMask
929 BOOL32 GRAPH_SelectClipMask( HDC32 hdc, HBITMAP32 hMonoBitmap, INT32 x, INT32 y)
931 BITMAPOBJ *bmp = NULL;
932 DC *dc;
934 if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return FALSE;
935 if ( hMonoBitmap )
937 if ( !(bmp = (BITMAPOBJ *) GDI_GetObjPtr( hMonoBitmap, BITMAP_MAGIC))
938 || bmp->bitmap.bmBitsPixel != 1 ) return FALSE;
940 XSetClipOrigin( display, dc->u.x.gc, dc->w.DCOrgX + x, dc->w.DCOrgY + y);
943 XSetClipMask( display, dc->u.x.gc, (bmp) ? bmp->pixmap : None );
945 return TRUE;