283 lines
7.6 KiB
C
283 lines
7.6 KiB
C
/*
|
|
* 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 "ts_xlib.h"
|
|
#include "ts_xutil.h"
|
|
#include <X11/Intrinsic.h>
|
|
#include "graphics.h"
|
|
#include "color.h"
|
|
#include "bitmap.h"
|
|
#include "gdi.h"
|
|
#include "dc.h"
|
|
#include "x11drv.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;
|
|
X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
|
|
|
|
if( hPen ) hPrevPen = SelectObject32( hdc, hPen );
|
|
if( X11DRV_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;
|
|
}
|
|
TSXDrawSegments( display, physDev->drawable, physDev->gc, l, N );
|
|
bRet = TRUE;
|
|
}
|
|
if( hPrevPen ) SelectObject32( hdc, hPrevPen );
|
|
GDI_HEAP_UNLOCK( hdc );
|
|
}
|
|
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, BOOL32 bMono )
|
|
{
|
|
BITMAPOBJ *bmp;
|
|
DC *dc;
|
|
BOOL32 ret = TRUE;
|
|
X11DRV_PHYSBITMAP *pbitmap;
|
|
X11DRV_PDEVICE *physDev;
|
|
|
|
if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return FALSE;
|
|
if (!(bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC )))
|
|
{
|
|
GDI_HEAP_UNLOCK( hdc );
|
|
return FALSE;
|
|
}
|
|
physDev = (X11DRV_PDEVICE *)dc->physDev;
|
|
|
|
/* HACK for now */
|
|
if(!bmp->DDBitmap)
|
|
X11DRV_CreateBitmap( hbitmap );
|
|
pbitmap = bmp->DDBitmap->physBitmap;
|
|
|
|
xdest += dc->w.DCOrgX; ydest += dc->w.DCOrgY;
|
|
|
|
TSXSetFunction( display, physDev->gc, GXcopy );
|
|
if (bmp->bitmap.bmBitsPixel == 1)
|
|
{
|
|
TSXSetForeground( display, physDev->gc, physDev->backgroundPixel );
|
|
TSXSetBackground( display, physDev->gc, physDev->textPixel );
|
|
TSXCopyPlane( display, pbitmap->pixmap, physDev->drawable, physDev->gc,
|
|
xsrc, ysrc, width, height, xdest, ydest, 1 );
|
|
}
|
|
else if (bmp->bitmap.bmBitsPixel == dc->w.bitsPerPixel)
|
|
{
|
|
if( bMono )
|
|
{
|
|
INT32 plane;
|
|
|
|
if( COLOR_GetMonoPlane(&plane) )
|
|
{
|
|
TSXSetForeground( display, physDev->gc,
|
|
physDev->backgroundPixel );
|
|
TSXSetBackground( display, physDev->gc, physDev->textPixel );
|
|
}
|
|
else
|
|
{
|
|
TSXSetForeground( display, physDev->gc, physDev->textPixel );
|
|
TSXSetBackground( display, physDev->gc,
|
|
physDev->backgroundPixel );
|
|
}
|
|
TSXCopyPlane( display, pbitmap->pixmap, physDev->drawable,
|
|
physDev->gc, xsrc, ysrc, width, height, xdest, ydest,
|
|
plane );
|
|
}
|
|
else
|
|
{
|
|
TSXCopyArea( display, pbitmap->pixmap, physDev->drawable,
|
|
physDev->gc, xsrc, ysrc, width, height, xdest,
|
|
ydest );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ret = FALSE;
|
|
}
|
|
|
|
GDI_HEAP_UNLOCK( hdc );
|
|
GDI_HEAP_UNLOCK( hbitmap );
|
|
return ret;
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
* 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 )
|
|
{
|
|
if(pressed)
|
|
GRAPH_DrawGenericReliefRect(hdc, rect, highlight_size, shadow_size,
|
|
GetSysColorBrush32(COLOR_BTNSHADOW),
|
|
GetSysColorBrush32(COLOR_BTNHIGHLIGHT));
|
|
else
|
|
GRAPH_DrawGenericReliefRect(hdc, rect, highlight_size, shadow_size,
|
|
GetSysColorBrush32(COLOR_BTNHIGHLIGHT),
|
|
GetSysColorBrush32(COLOR_BTNSHADOW));
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
* GRAPH_DrawGenericReliefRect
|
|
*
|
|
* Creates a rectangle with the specified highlight and shadow colors.
|
|
* Adapted from DrawReliefRect (which is somewhat misnamed).
|
|
*/
|
|
void GRAPH_DrawGenericReliefRect(
|
|
HDC32 hdc,
|
|
const RECT32 *rect,
|
|
INT32 highlight_size,
|
|
INT32 shadow_size,
|
|
HBRUSH32 highlight,
|
|
HBRUSH32 shadow )
|
|
{
|
|
DC* dc;
|
|
HBRUSH32 hPrevBrush;
|
|
INT32 w, h;
|
|
RECT32 r = *rect;
|
|
X11DRV_PDEVICE *physDev;
|
|
|
|
if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return;
|
|
physDev = (X11DRV_PDEVICE *)dc->physDev;
|
|
OffsetRect32( &r, dc->w.DCOrgX, dc->w.DCOrgY);
|
|
h = rect->bottom - rect->top; w = rect->right - rect->left;
|
|
|
|
hPrevBrush = SelectObject32(hdc, highlight);
|
|
|
|
if ( X11DRV_SetupGCForBrush( dc ) )
|
|
{
|
|
INT32 i;
|
|
|
|
TSXSetFunction( display, physDev->gc, GXcopy );
|
|
for (i = 0; i < highlight_size; i++)
|
|
{
|
|
TSXFillRectangle( display, physDev->drawable, physDev->gc,
|
|
r.left + i, r.top, 1, h - i );
|
|
TSXFillRectangle( display, physDev->drawable, physDev->gc,
|
|
r.left, r.top + i, w - i, 1 );
|
|
}
|
|
}
|
|
|
|
SelectObject32( hdc, shadow );
|
|
if ( X11DRV_SetupGCForBrush( dc ) )
|
|
{
|
|
INT32 i;
|
|
|
|
TSXSetFunction( display, physDev->gc, GXcopy );
|
|
for (i = 0; i < shadow_size; i++)
|
|
{
|
|
TSXFillRectangle( display, physDev->drawable, physDev->gc,
|
|
r.right - i - 1, r.top + i, 1, h - i );
|
|
TSXFillRectangle( display, physDev->drawable, physDev->gc,
|
|
r.left + i, r.bottom - i - 1, w - i, 1 );
|
|
}
|
|
}
|
|
|
|
SelectObject32( hdc, hPrevBrush );
|
|
GDI_HEAP_UNLOCK( hdc );
|
|
}
|
|
|
|
|
|
|
|
/**********************************************************************
|
|
* 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;
|
|
X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
|
|
|
|
if( hPen ) hPrevPen = SelectObject32( hdc, hPen );
|
|
if( X11DRV_SetupGCForPen( dc ) )
|
|
TSXDrawRectangle( display, physDev->drawable, physDev->gc,
|
|
x + dc->w.DCOrgX, y + dc->w.DCOrgY, w - 1, h - 1);
|
|
if( hPrevPen ) SelectObject32( hdc, hPrevPen );
|
|
GDI_HEAP_UNLOCK( hdc );
|
|
}
|
|
}
|
|
|
|
/**********************************************************************
|
|
* GRAPH_SelectClipMask
|
|
*/
|
|
BOOL32 GRAPH_SelectClipMask( HDC32 hdc, HBITMAP32 hMonoBitmap, INT32 x, INT32 y)
|
|
{
|
|
BITMAPOBJ *bmp = NULL;
|
|
DC *dc;
|
|
X11DRV_PHYSBITMAP *pbitmap = NULL;
|
|
X11DRV_PDEVICE *physDev;
|
|
|
|
if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return FALSE;
|
|
physDev = (X11DRV_PDEVICE *)dc->physDev;
|
|
if ( hMonoBitmap )
|
|
{
|
|
if ( !(bmp = (BITMAPOBJ *) GDI_GetObjPtr( hMonoBitmap, BITMAP_MAGIC))
|
|
|| bmp->bitmap.bmBitsPixel != 1 )
|
|
{
|
|
GDI_HEAP_UNLOCK( hdc );
|
|
return FALSE;
|
|
}
|
|
|
|
/* HACK for now */
|
|
if(!bmp->DDBitmap)
|
|
X11DRV_CreateBitmap( hMonoBitmap );
|
|
pbitmap = bmp->DDBitmap->physBitmap;
|
|
TSXSetClipOrigin( display, physDev->gc, dc->w.DCOrgX + x,
|
|
dc->w.DCOrgY + y );
|
|
}
|
|
|
|
TSXSetClipMask( display, physDev->gc, (bmp) ? pbitmap->pixmap : None );
|
|
|
|
GDI_HEAP_UNLOCK( hdc );
|
|
GDI_HEAP_UNLOCK( hMonoBitmap );
|
|
return TRUE;
|
|
}
|
|
|