| /* |
| * X-specific shortcuts to speed up WM code. |
| * No coordinate transformations except origin translation. |
| * |
| * Copyright 1993, 1994 Alexandre Julliard |
| */ |
| |
| #include <assert.h> |
| #include <stdlib.h> |
| #include <X11/Xlib.h> |
| #include <X11/Xutil.h> |
| #include <X11/Intrinsic.h> |
| #include "graphics.h" |
| #include "bitmap.h" |
| #include "gdi.h" |
| #include "dc.h" |
| #include "syscolor.h" |
| |
| #define MAX_DRAWLINES 8 |
| |
| |
| /********************************************************************** |
| * GRAPH_DrawLines |
| * |
| * Draw multiple unconnected lines (limited by MAX_DRAWLINES). |
| */ |
| BOOL32 GRAPH_DrawLines( HDC32 hdc, LPPOINT32 pXY, INT32 N, HPEN32 hPen ) |
| { |
| BOOL32 bRet = FALSE; |
| DC* dc; |
| |
| assert( N <= MAX_DRAWLINES ); |
| if( (dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC )) ) |
| { |
| HPEN32 hPrevPen = 0; |
| |
| if( hPen ) hPrevPen = SelectObject32( hdc, hPen ); |
| if( DC_SetupGCForPen( dc ) ) |
| { |
| XSegment l[MAX_DRAWLINES]; |
| INT32 i, j; |
| |
| for( i = 0; i < N; i++ ) |
| { |
| j = 2 * i; |
| l[i].x1 = pXY[j].x + dc->w.DCOrgX; |
| l[i].x2 = pXY[j + 1].x + dc->w.DCOrgX; |
| l[i].y1 = pXY[j].y + dc->w.DCOrgY; |
| l[i].y2 = pXY[j + 1].y + dc->w.DCOrgY; |
| } |
| XDrawSegments( display, dc->u.x.drawable, dc->u.x.gc, l, N ); |
| bRet = TRUE; |
| } |
| if( hPrevPen ) SelectObject32( hdc, hPrevPen ); |
| } |
| return bRet; |
| } |
| |
| /********************************************************************** |
| * |
| * GRAPH_DrawBitmap |
| * |
| * Short-cut function to blit a bitmap into a device. |
| * Faster than CreateCompatibleDC() + SelectBitmap() + BitBlt() + DeleteDC(). |
| */ |
| BOOL32 GRAPH_DrawBitmap( HDC32 hdc, HBITMAP32 hbitmap, |
| INT32 xdest, INT32 ydest, INT32 xsrc, INT32 ysrc, |
| INT32 width, INT32 height ) |
| { |
| BITMAPOBJ *bmp; |
| DC *dc; |
| |
| if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return FALSE; |
| if (!(bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ))) |
| return FALSE; |
| XSetFunction( display, dc->u.x.gc, GXcopy ); |
| if (bmp->bitmap.bmBitsPixel == 1) |
| { |
| XSetForeground( display, dc->u.x.gc, dc->w.backgroundPixel ); |
| XSetBackground( display, dc->u.x.gc, dc->w.textPixel ); |
| XCopyPlane( display, bmp->pixmap, dc->u.x.drawable, dc->u.x.gc, |
| xsrc, ysrc, width, height, |
| dc->w.DCOrgX + xdest, dc->w.DCOrgY + ydest, 1 ); |
| return TRUE; |
| } |
| else if (bmp->bitmap.bmBitsPixel == dc->w.bitsPerPixel) |
| { |
| XCopyArea( display, bmp->pixmap, dc->u.x.drawable, dc->u.x.gc, |
| xsrc, ysrc, width, height, |
| dc->w.DCOrgX + xdest, dc->w.DCOrgY + ydest ); |
| return TRUE; |
| } |
| else return FALSE; |
| } |
| |
| |
| /********************************************************************** |
| * GRAPH_DrawReliefRect |
| * |
| * Used in the standard control code for button edge drawing. |
| */ |
| void GRAPH_DrawReliefRect( HDC32 hdc, const RECT32 *rect, INT32 highlight_size, |
| INT32 shadow_size, BOOL32 pressed ) |
| { |
| DC* dc; |
| HBRUSH32 hPrevBrush; |
| INT32 w, h; |
| RECT32 r = *rect; |
| |
| if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return; |
| |
| OffsetRect32( &r, dc->w.DCOrgX, dc->w.DCOrgY); |
| h = rect->bottom - rect->top; w = rect->right - rect->left; |
| |
| hPrevBrush = SelectObject32(hdc, pressed ? sysColorObjects.hbrushBtnShadow : |
| sysColorObjects.hbrushBtnHighlight ); |
| if ( DC_SetupGCForBrush( dc ) ) |
| { |
| INT32 i; |
| |
| XSetFunction( display, dc->u.x.gc, GXcopy ); |
| for (i = 0; i < highlight_size; i++) |
| { |
| XFillRectangle( display, dc->u.x.drawable, dc->u.x.gc, |
| r.left + i, r.top, 1, h - i ); |
| XFillRectangle( display, dc->u.x.drawable, dc->u.x.gc, |
| r.left, r.top + i, w - i, 1 ); |
| } |
| } |
| |
| SelectObject32( hdc, pressed ? sysColorObjects.hbrushBtnHighlight : |
| sysColorObjects.hbrushBtnShadow ); |
| if ( DC_SetupGCForBrush( dc ) ) |
| { |
| INT32 i; |
| |
| XSetFunction( display, dc->u.x.gc, GXcopy ); |
| for (i = 0; i < shadow_size; i++) |
| { |
| XFillRectangle( display, dc->u.x.drawable, dc->u.x.gc, |
| r.right - i - 1, r.top + i, 1, h - i ); |
| XFillRectangle( display, dc->u.x.drawable, dc->u.x.gc, |
| r.left + i, r.bottom - i - 1, w - i, 1 ); |
| } |
| } |
| |
| SelectObject32( hdc, hPrevBrush ); |
| } |
| |
| /********************************************************************** |
| * GRAPH_DrawRectangle |
| */ |
| void GRAPH_DrawRectangle( HDC32 hdc, INT32 x, INT32 y, |
| INT32 w, INT32 h, HPEN32 hPen ) |
| { |
| DC* dc; |
| |
| if( (dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC )) ) |
| { |
| HPEN32 hPrevPen = 0; |
| |
| if( hPen ) hPrevPen = SelectObject32( hdc, hPen ); |
| if( DC_SetupGCForPen( dc ) ) |
| XDrawRectangle( display, dc->u.x.drawable, dc->u.x.gc, |
| x + dc->w.DCOrgX, y + dc->w.DCOrgY, w - 1, h - 1); |
| if( hPrevPen ) SelectObject32( hdc, hPrevPen ); |
| } |
| } |
| |
| /********************************************************************** |
| * GRAPH_SelectClipMask |
| */ |
| BOOL32 GRAPH_SelectClipMask( HDC32 hdc, HBITMAP32 hMonoBitmap, INT32 x, INT32 y) |
| { |
| BITMAPOBJ *bmp = NULL; |
| DC *dc; |
| |
| if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return FALSE; |
| if ( hMonoBitmap ) |
| { |
| if ( !(bmp = (BITMAPOBJ *) GDI_GetObjPtr( hMonoBitmap, BITMAP_MAGIC)) |
| || bmp->bitmap.bmBitsPixel != 1 ) return FALSE; |
| |
| XSetClipOrigin( display, dc->u.x.gc, dc->w.DCOrgX + x, dc->w.DCOrgY + y); |
| } |
| |
| XSetClipMask( display, dc->u.x.gc, (bmp) ? bmp->pixmap : None ); |
| |
| return TRUE; |
| } |
| |