1
0
Fork 0
mirror of synced 2025-03-07 03:53:26 +01:00
wine/windows/graphics.c
Alexandre Julliard 86a8d0f942 Release 0.7
Thu Jan 13 11:45:13 1994  John Richardson <jrichard@cs.uml.edu>

	* [window/win.c]
	Added functions EnableWindow, IsWindowEnabled, and helper 
	WIN_SetSensitive.
	
	* [window/event.c]
	Added checks for WS_DISABLED windows in EVENT_key, EVENT_MotionNotify,
	EVENT_ButtonPress, EVENT_ButtonRelease, EVENT_ConfigureNotify,
	EVENT_FocusIn, EVENT_FocusOut, and EVENT_EnterNotify.  Key and 
	button presses beep for a disabled window.  
	If anyone finds better places for these checks, please tell me.

Jan 17, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte)

	* [misc/message.c]
	Cleanup on buttons answer value returned.

	* [control/combo.c]
	Now use OBM_COMBO bitmap dropdown button.

Mon Jan 17 21:56:45 1994  Erik Bos (erik@trashcan.hacktic.nl)

	* [misc/comm/c]
	A few bugfixes.

Tue Jan 18 06:36:48 1994  julliard@di.epfl.ch (Alexandre Julliard)

	* [loader/cursor.c]
	Added X cursor for IDC_SIZENS and IDC_SIZEWE.

	* [include/options.h] [misc/main.c]  (New files)
	Rewrote main() function to get rid of Xt application context,
	and added command-line option parsing.

	* [objects/color.c]
	Use of a private map now configurable with command-line option.

	* [windows/defwnd.c]
	Added WM_SYSCOMMAND handling, and better WM_SETCURSOR handling.

	* [windows/event.c]
	Removed ConfigureNotify event handler (no longer needed).

	* [windows/message.c]
	Send WM_SETCURSOR message on mouse events.

	* [windows/nonclient.c]
	Use OEM bitmaps for the drawing of the non-client area.
	Added caption bar buttons handling, and moving and resizing of
	the window via the window frame (bypassing the window manager).

	* [windows/painting.c]
	Bug fix in BeginPaint().

	* [windows/win.c]
	Set the override_redirect flag for windows (to bypass window
	manager).

	* [windows/winpos.c]
	Implemented WindowFromPoint(), ChildWindowFromPoint(),
	BringWindowToTop(), Get/SetInternalWindowPos(),
	Get/SetWindowPlacement().

Mon Jan 17 20:48:24 1994  Bob Amstadt  (bob@pooh)

	* [memory/heap.c]
	Added support for multiple local heaps.
1994-01-18 23:04:40 +00:00

515 lines
15 KiB
C

/*
* GDI graphics operations
*
* Copyright 1993 Alexandre Julliard
*/
static char Copyright[] = "Copyright Alexandre Julliard, 1993";
#include <math.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#ifndef PI
#define PI M_PI
#endif
#include "gdi.h"
/***********************************************************************
* LineTo (GDI.19)
*/
BOOL LineTo( HDC hdc, short x, short y )
{
DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
if (!dc) return FALSE;
if (DC_SetupGCForPen( dc ))
XDrawLine(XT_display, dc->u.x.drawable, dc->u.x.gc,
dc->w.DCOrgX + XLPTODP( dc, dc->w.CursPosX ),
dc->w.DCOrgY + YLPTODP( dc, dc->w.CursPosY ),
dc->w.DCOrgX + XLPTODP( dc, x ),
dc->w.DCOrgY + YLPTODP( dc, y ) );
dc->w.CursPosX = x;
dc->w.CursPosY = y;
return TRUE;
}
/***********************************************************************
* MoveTo (GDI.20)
*/
DWORD MoveTo( HDC hdc, short x, short y )
{
POINT pt;
if (MoveToEx( hdc, x, y, &pt )) return pt.x | (pt.y << 16);
else return 0;
}
/***********************************************************************
* MoveToEx (GDI.483)
*/
BOOL MoveToEx( HDC hdc, short x, short y, LPPOINT pt )
{
DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
if (!dc) return FALSE;
if (pt)
{
pt->x = dc->w.CursPosX;
pt->y = dc->w.CursPosY;
}
dc->w.CursPosX = x;
dc->w.CursPosY = y;
return TRUE;
}
/***********************************************************************
* GRAPH_DrawArc
*
* Helper functions for Arc(), Chord() and Pie().
* 'lines' is the number of lines to draw: 0 for Arc, 1 for Chord, 2 for Pie.
*/
BOOL GRAPH_DrawArc( HDC hdc, int left, int top, int right, int bottom,
int xstart, int ystart, int xend, int yend, int lines )
{
int xcenter, ycenter;
double start_angle, end_angle, diff_angle;
XPoint points[3];
DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
if (!dc) return FALSE;
left = XLPTODP( dc, left );
top = YLPTODP( dc, top );
right = XLPTODP( dc, right );
bottom = YLPTODP( dc, bottom );
xstart = XLPTODP( dc, xstart );
ystart = YLPTODP( dc, ystart );
xend = XLPTODP( dc, xend );
yend = YLPTODP( dc, yend );
if ((left == right) || (top == bottom)) return FALSE;
if (!DC_SetupGCForPen( dc )) return TRUE;
xcenter = (right + left) / 2;
ycenter = (bottom + top) / 2;
start_angle = atan2( (double)(ycenter-ystart)*(right-left),
(double)(xstart-xcenter)*(bottom-top) );
end_angle = atan2( (double)(ycenter-yend)*(right-left),
(double)(xend-xcenter)*(bottom-top) );
diff_angle = end_angle - start_angle;
if (diff_angle < 0.0) diff_angle += 2*PI;
XDrawArc( XT_display, dc->u.x.drawable, dc->u.x.gc,
dc->w.DCOrgX + left, dc->w.DCOrgY + top,
right-left-1, bottom-top-1,
(int)(start_angle * 180 * 64 / PI),
(int)(diff_angle * 180 * 64 / PI) );
if (!lines) return TRUE;
points[0].x = dc->w.DCOrgX + xcenter + (int)(cos(start_angle) * (right-left) / 2);
points[0].y = dc->w.DCOrgY + ycenter - (int)(sin(start_angle) * (bottom-top) / 2);
points[1].x = dc->w.DCOrgX + xcenter + (int)(cos(end_angle) * (right-left) / 2);
points[1].y = dc->w.DCOrgY + ycenter - (int)(sin(end_angle) * (bottom-top) / 2);
if (lines == 2)
{
points[2] = points[1];
points[1].x = dc->w.DCOrgX + xcenter;
points[1].y = dc->w.DCOrgY + ycenter;
}
XDrawLines( XT_display, dc->u.x.drawable, dc->u.x.gc,
points, lines+1, CoordModeOrigin );
return TRUE;
}
/***********************************************************************
* Arc (GDI.23)
*/
BOOL Arc( HDC hdc, int left, int top, int right, int bottom,
int xstart, int ystart, int xend, int yend )
{
return GRAPH_DrawArc( hdc, left, top, right, bottom,
xstart, ystart, xend, yend, 0 );
}
/***********************************************************************
* Pie (GDI.26)
*/
BOOL Pie( HDC hdc, int left, int top, int right, int bottom,
int xstart, int ystart, int xend, int yend )
{
return GRAPH_DrawArc( hdc, left, top, right, bottom,
xstart, ystart, xend, yend, 2 );
}
/***********************************************************************
* Chord (GDI.348)
*/
BOOL Chord( HDC hdc, int left, int top, int right, int bottom,
int xstart, int ystart, int xend, int yend )
{
return GRAPH_DrawArc( hdc, left, top, right, bottom,
xstart, ystart, xend, yend, 1 );
}
/***********************************************************************
* Ellipse (GDI.24)
*/
BOOL Ellipse( HDC hdc, int left, int top, int right, int bottom )
{
DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
if (!dc) return FALSE;
left = XLPTODP( dc, left );
top = YLPTODP( dc, top );
right = XLPTODP( dc, right );
bottom = YLPTODP( dc, bottom );
if ((left == right) || (top == bottom)) return FALSE;
if (DC_SetupGCForBrush( dc ))
XFillArc( XT_display, dc->u.x.drawable, dc->u.x.gc,
dc->w.DCOrgX + left, dc->w.DCOrgY + top,
right-left-1, bottom-top-1, 0, 360*64 );
if (DC_SetupGCForPen( dc ))
XDrawArc( XT_display, dc->u.x.drawable, dc->u.x.gc,
dc->w.DCOrgX + left, dc->w.DCOrgY + top,
right-left-1, bottom-top-1, 0, 360*64 );
return TRUE;
}
/***********************************************************************
* Rectangle (GDI.27)
*/
BOOL Rectangle( HDC hdc, int left, int top, int right, int bottom )
{
DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
if (!dc) return FALSE;
left = XLPTODP( dc, left );
top = YLPTODP( dc, top );
right = XLPTODP( dc, right );
bottom = YLPTODP( dc, bottom );
if (DC_SetupGCForBrush( dc ))
XFillRectangle( XT_display, dc->u.x.drawable, dc->u.x.gc,
dc->w.DCOrgX + left, dc->w.DCOrgY + top,
right-left-1, bottom-top-1 );
if (DC_SetupGCForPen( dc ))
XDrawRectangle( XT_display, dc->u.x.drawable, dc->u.x.gc,
dc->w.DCOrgX + left, dc->w.DCOrgY + top,
right-left-1, bottom-top-1 );
return TRUE;
}
/***********************************************************************
* FillRect (USER.81)
*/
int FillRect( HDC hdc, LPRECT rect, HBRUSH hbrush )
{
HBRUSH prevBrush;
if ((rect->right <= rect->left) || (rect->bottom <= rect->top)) return 0;
if (!(prevBrush = SelectObject( hdc, hbrush ))) return 0;
PatBlt( hdc, rect->left, rect->top,
rect->right - rect->left, rect->bottom - rect->top, PATCOPY );
SelectObject( hdc, prevBrush );
return 1;
}
/***********************************************************************
* InvertRect (USER.82)
*/
void InvertRect( HDC hdc, LPRECT rect )
{
if ((rect->right <= rect->left) || (rect->bottom <= rect->top)) return;
PatBlt( hdc, rect->left, rect->top,
rect->right - rect->left, rect->bottom - rect->top, DSTINVERT );
}
/***********************************************************************
* FrameRect (USER.83)
*/
int FrameRect( HDC hdc, LPRECT rect, HBRUSH hbrush )
{
HBRUSH prevBrush;
int left, top, right, bottom;
DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
if (!dc) return FALSE;
if ((rect->right <= rect->left) || (rect->bottom <= rect->top)) return 0;
if (!(prevBrush = SelectObject( hdc, hbrush ))) return 0;
left = XLPTODP( dc, rect->left );
top = YLPTODP( dc, rect->top );
right = XLPTODP( dc, rect->right );
bottom = YLPTODP( dc, rect->bottom );
if (DC_SetupGCForBrush( dc )) {
PatBlt( hdc, rect->left, rect->top, 1,
rect->bottom - rect->top, PATCOPY );
PatBlt( hdc, rect->right - 1, rect->top, 1,
rect->bottom - rect->top, PATCOPY );
PatBlt( hdc, rect->left, rect->top,
rect->right - rect->left, 1, PATCOPY );
PatBlt( hdc, rect->left, rect->bottom - 1,
rect->right - rect->left, 1, PATCOPY );
}
SelectObject( hdc, prevBrush );
return 1;
}
/***********************************************************************
* SetPixel (GDI.31)
*/
COLORREF SetPixel( HDC hdc, short x, short y, COLORREF color )
{
int pixel;
PALETTEENTRY entry;
DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
if (!dc) return 0;
x = dc->w.DCOrgX + XLPTODP( dc, x );
y = dc->w.DCOrgY + YLPTODP( dc, y );
pixel = GetNearestPaletteIndex( dc->w.hPalette, color );
GetPaletteEntries( dc->w.hPalette, pixel, 1, &entry );
XSetForeground( XT_display, dc->u.x.gc, pixel );
XSetFunction( XT_display, dc->u.x.gc, GXcopy );
XDrawPoint( XT_display, dc->u.x.drawable, dc->u.x.gc, x, y );
return RGB( entry.peRed, entry.peGreen, entry.peBlue );
}
/***********************************************************************
* GetPixel (GDI.83)
*/
COLORREF GetPixel( HDC hdc, short x, short y )
{
PALETTEENTRY entry;
XImage * image;
DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
if (!dc) return 0;
x = dc->w.DCOrgX + XLPTODP( dc, x );
y = dc->w.DCOrgY + YLPTODP( dc, y );
if ((x < 0) || (y < 0)) return 0;
if (!(dc->w.flags & DC_MEMORY))
{
XWindowAttributes win_attr;
if (!XGetWindowAttributes( XT_display, dc->u.x.drawable, &win_attr ))
return 0;
if (win_attr.map_state != IsViewable) return 0;
if ((x >= win_attr.width) || (y >= win_attr.height)) return 0;
}
image = XGetImage( XT_display, dc->u.x.drawable, x, y,
1, 1, AllPlanes, ZPixmap );
GetPaletteEntries( dc->w.hPalette, XGetPixel( image, 0, 0 ), 1, &entry );
XDestroyImage( image );
return RGB( entry.peRed, entry.peGreen, entry.peBlue );
}
/***********************************************************************
* PaintRgn (GDI.43)
*/
BOOL PaintRgn( HDC hdc, HRGN hrgn )
{
RECT box;
HRGN tmpVisRgn, prevVisRgn;
DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
if (!dc) return FALSE;
/* Modify visible region */
prevVisRgn = SaveVisRgn( hdc );
if (prevVisRgn)
{
if (!(tmpVisRgn = CreateRectRgn( 0, 0, 0, 0 )))
{
RestoreVisRgn( hdc );
return FALSE;
}
CombineRgn( tmpVisRgn, prevVisRgn, hrgn, RGN_AND );
SelectVisRgn( hdc, tmpVisRgn );
DeleteObject( tmpVisRgn );
}
else SelectVisRgn( hdc, hrgn );
/* Fill the region */
GetClipBox( hdc, &box );
if (DC_SetupGCForBrush( dc ))
XFillRectangle( XT_display, dc->u.x.drawable, dc->u.x.gc,
dc->w.DCOrgX + box.left, dc->w.DCOrgY + box.top,
box.right-box.left, box.bottom-box.top );
/* Restore the visible region */
if (prevVisRgn) RestoreVisRgn( hdc );
else SelectVisRgn( hdc, 0 );
return TRUE;
}
/***********************************************************************
* FillRgn (GDI.40)
*/
BOOL FillRgn( HDC hdc, HRGN hrgn, HBRUSH hbrush )
{
BOOL retval;
HBRUSH prevBrush = SelectObject( hdc, hbrush );
if (!prevBrush) return FALSE;
retval = PaintRgn( hdc, hrgn );
SelectObject( hdc, prevBrush );
return retval;
}
/***********************************************************************
* DrawFocusRect (USER.466)
*/
void DrawFocusRect( HDC hdc, LPRECT rc )
{
HPEN hPen, hOldPen;
int oldDrawMode, oldBkMode;
int left, top, right, bottom;
DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
if (!dc) return;
left = XLPTODP( dc, rc->left );
top = YLPTODP( dc, rc->top );
right = XLPTODP( dc, rc->right );
bottom = YLPTODP( dc, rc->bottom );
hPen = CreatePen(PS_DOT, 1, GetSysColor(COLOR_WINDOWTEXT));
hOldPen = (HPEN)SelectObject(hdc, (HANDLE)hPen);
oldDrawMode = SetROP2(hdc, R2_XORPEN);
oldBkMode = SetBkMode(hdc, TRANSPARENT);
if (DC_SetupGCForPen( dc ))
XDrawRectangle( XT_display, dc->u.x.drawable, dc->u.x.gc,
dc->w.DCOrgX + left, dc->w.DCOrgY + top,
right-left-1, bottom-top-1 );
SetBkMode(hdc, oldBkMode);
SetROP2(hdc, oldDrawMode);
SelectObject(hdc, (HANDLE)hOldPen);
DeleteObject((HANDLE)hPen);
}
/**********************************************************************
* DrawReliefRect (Not a MSWin Call)
*/
void DrawReliefRect( HDC hdc, RECT rect, int thickness, BOOL pressed )
{
HBRUSH hbrushOld, hbrushShadow, hbrushHighlight;
int i;
hbrushShadow = CreateSolidBrush( GetSysColor(COLOR_BTNSHADOW) );
hbrushHighlight = CreateSolidBrush( GetSysColor(COLOR_BTNHIGHLIGHT) );
if (pressed) hbrushOld = SelectObject( hdc, hbrushShadow );
else hbrushOld = SelectObject( hdc, hbrushHighlight );
for (i = 0; i < thickness; i++)
{
PatBlt( hdc, rect.left + i, rect.top,
1, rect.bottom - rect.top - i, PATCOPY );
PatBlt( hdc, rect.left, rect.top + i,
rect.right - rect.left - i, 1, PATCOPY );
}
if (pressed) hbrushOld = SelectObject( hdc, hbrushHighlight );
else hbrushOld = SelectObject( hdc, hbrushShadow );
for (i = 0; i < thickness; i++)
{
PatBlt( hdc, rect.right - i - 1, rect.top + i,
1, rect.bottom - rect.top - i, PATCOPY );
PatBlt( hdc, rect.left + i, rect.bottom - i - 1,
rect.right - rect.left - i, 1, PATCOPY );
}
SelectObject( hdc, hbrushOld );
DeleteObject( hbrushShadow );
DeleteObject( hbrushHighlight );
}
/**********************************************************************
* Polyline (GDI.37)
*/
BOOL Polyline (HDC hdc, LPPOINT pt, int count)
{
register int i;
DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
if (DC_SetupGCForPen( dc ))
{
for (i = 0; i < count-1; i ++)
XDrawLine (XT_display, dc->u.x.drawable, dc->u.x.gc,
dc->w.DCOrgX + XLPTODP(dc, pt [i].x),
dc->w.DCOrgY + YLPTODP(dc, pt [i].y),
dc->w.DCOrgX + XLPTODP(dc, pt [i+1].x),
dc->w.DCOrgY + YLPTODP(dc, pt [i+1].y));
XDrawLine (XT_display, dc->u.x.drawable, dc->u.x.gc,
dc->w.DCOrgX + XLPTODP(dc, pt [count-1].x),
dc->w.DCOrgY + YLPTODP(dc, pt [count-1].y),
dc->w.DCOrgX + XLPTODP(dc, pt [0].x),
dc->w.DCOrgY + YLPTODP(dc, pt [0].y));
}
return (TRUE);
}
/**********************************************************************
* Polygon (GDI.36)
*/
BOOL Polygon (HDC hdc, LPPOINT pt, int count)
{
register int i;
DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
XPoint *points = (XPoint *) malloc (sizeof (XPoint) * count+1);
if (DC_SetupGCForBrush( dc ))
{
for (i = 0; i < count; i++)
{
points [i].x = dc->w.DCOrgX + XLPTODP(dc, pt [i].x);
points [i].y = dc->w.DCOrgY + YLPTODP(dc, pt [i].y);
}
points [count] = points [0];
XFillPolygon( XT_display, dc->u.x.drawable, dc->u.x.gc,
points, count, Complex, CoordModeOrigin);
if (DC_SetupGCForPen ( dc ))
{
XDrawLines( XT_display, dc->u.x.drawable, dc->u.x.gc,
points, count, CoordModeOrigin );
}
}
free ((void *) points);
return (TRUE);
}