⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wingdi.c

📁 开放源码实时操作系统源码.
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * Copyright (c) 1999, 2000, 2001 Greg Haerr <greg@censoft.com>
 *
 * Win32 API upper level graphics drawing routines
 */
#include "windows.h"
#include "wintern.h"
#include "device.h"
#include <stdlib.h>
#include <string.h>

#define MAXSYSCOLORS	29	/* # of COLOR_* system colors*/
#define MAXSTOCKOBJECTS	18	/* # of stock objects*/

#if ERASEMOVE
BOOL mwERASEMOVE = TRUE;	/* default XORMOVE repaint algorithm*/
#else
BOOL mwERASEMOVE = FALSE;	/* default ERASEMOVE repaint algorithm*/
#endif

/* cast a pointer to an integer*/
#if DOS_TURBOC
#define PTRTOINT	unsigned long
#else
#define PTRTOINT	unsigned int
#endif

static HDC	cliphdc;	/* current window cliprects*/

/* default bitmap for new DCs*/
static MWBITMAPOBJ default_bitmap = {
	{OBJ_BITMAP, TRUE}, 1, 1, 1, 1, 1, 1
};

static BOOL MwExtTextOut(HDC hdc, int x, int y, UINT fuOptions,
		CONST RECT *lprc, LPCVOID lpszString, UINT cbCount,
		CONST INT *lpDx, int flags);
static int  MwDrawText(HDC hdc, LPCVOID lpString, int nCount, LPRECT lpRect,
		UINT uFormat, int flags);

HDC WINAPI
GetDCEx(HWND hwnd,HRGN hrgnClip,DWORD flags)
{
	HDC	hdc;

	if(!hwnd)		/* handle NULL hwnd => desktop*/
		hwnd = rootwp;

	/* handle private DC's*/
	if(hwnd->owndc && !(flags & DCX_WINDOW))
		return hwnd->owndc;

	/* add caching?*/
	hdc = GdItemNew(struct hdc);
	if(!hdc)
		return NULL;

	hdc->psd = &scrdev;
	hdc->hwnd = hwnd;
	if(flags & DCX_DEFAULTCLIP) {
		flags &= ~DCX_DEFAULTCLIP;
		if(hwnd->style & WS_CLIPSIBLINGS)
			flags |= DCX_CLIPSIBLINGS;
		if(hwnd->style & WS_CLIPCHILDREN)
			flags |= DCX_CLIPCHILDREN;
	}
	hdc->flags = flags;
	hdc->bkmode = OPAQUE;
	hdc->textalign = TA_LEFT | TA_TOP | TA_NOUPDATECP;
	hdc->bkcolor = RGB(255, 255, 255);	/* WHITE*/
	hdc->textcolor = RGB(0, 0, 0);		/* BLACK*/
	hdc->brush = (MWBRUSHOBJ *)GetStockObject(WHITE_BRUSH);
	hdc->pen = (MWPENOBJ *)GetStockObject(BLACK_PEN);
	hdc->font = (MWFONTOBJ *)GetStockObject(SYSTEM_FONT);
#if UPDATEREGIONS
	if(hrgnClip) {
		/* make a copy of passed region*/
		hdc->region = (MWRGNOBJ *)CreateRectRgn(0, 0, 0, 0);
		CombineRgn((HRGN)hdc->region, hrgnClip, NULL, RGN_COPY);
	}
#endif

	/* make default bitmap compatible with scrdev
	 * otherwise problems occur later because selecting
	 * in the default bitmap overwrite planes and bpp
	 * in a memory dc, and thus it becomes incompatible
	 * with scrdev.
	 */
	default_bitmap.planes = scrdev.planes;
	default_bitmap.bpp = scrdev.bpp;
	hdc->bitmap = &default_bitmap;

	hdc->drawmode = R2_COPYPEN;
	hdc->pt.x = 0;
	hdc->pt.y = 0;

	/* assign private DC if CS_OWNDC and not WindowDC*/
	if((hwnd->pClass->style & CS_OWNDC) && !(flags & DCX_WINDOW)) {
		/* must exclude update region due to BeginPaint GetDCEx call*/
		hdc->flags |= DCX_EXCLUDEUPDATE;
		hwnd->owndc = hdc;
	}

	return hdc;
}

HDC WINAPI
GetDC(HWND hwnd)
{
	/*
	 * Exclude update regions when drawing with GetDC.
	 * This is required because some programs use GetDC
	 * when painting outside of BeginPaint/EndPaint, and
	 * the update region is empty then.
	 */
	return GetDCEx(hwnd, NULL, DCX_DEFAULTCLIP|DCX_EXCLUDEUPDATE);
}

HDC WINAPI
GetWindowDC(HWND hwnd)
{
	/* 
	 * Exclude update region for now, since we
	 * don't keep track of non-client update regions yet
	 */
	return GetDCEx(hwnd, NULL,DCX_WINDOW|DCX_DEFAULTCLIP|DCX_EXCLUDEUPDATE);
}

/* free a DC allocated from GetDC*/
int WINAPI 
ReleaseDC(HWND hwnd, HDC hdc)
{
	/* don't delete a memory dc on release*/
	if(!hdc || (hdc->psd->flags&PSF_MEMORY))
		return 0;

	if(hdc == cliphdc)
		cliphdc = NULL;

	/* handle private DC's*/
	if(hdc->hwnd->owndc && !(hdc->flags & DCX_WINDOW))
		return 1;

	DeleteObject((HBRUSH)hdc->brush);
	DeleteObject((HPEN)hdc->pen);
#if 0 /* don't delete font resources on ReleaseDC... use DeleteObject instead*/
	DeleteObject((HFONT)hdc->font);
#endif
	DeleteObject((HRGN)hdc->region);
	/*
	 * We can only select a bitmap in a memory DC,
	 * so bitmaps aren't released except through DeleteDC.
	 */
	DeleteObject((HBITMAP)hdc->bitmap);
	GdItemFree(hdc);
	return 1;
}

/* free a dc allocated from CreateCompatibleDC*/
BOOL WINAPI
DeleteDC(HDC hdc)
{
	/* don't delete a normal dc, only memory dc's*/
	if(!hdc || !(hdc->psd->flags&PSF_MEMORY))
		return 0;

	/* free allocated memory screen device*/
	hdc->psd->FreeMemGC(hdc->psd);

	/* make it look like a GetDC dc, and free it*/
	hdc->psd = &scrdev;
	return ReleaseDC(NULL, hdc);
}

void
MwPaintNCArea(HWND hwnd)
{
	SendMessage(hwnd, WM_NCPAINT, 0, 0L);

	/* for now, we always paint NC scrollbar areas*/
	MwPaintNCScrollbars(hwnd, NULL);
}

HDC WINAPI 
BeginPaint(HWND hwnd, LPPAINTSTRUCT lpPaint)
{
	HDC	hdc;

	/* first update non-client area*/
	if(mwforceNCpaint || hwnd->paintNC != mwpaintNC) {
		MwPaintNCArea(hwnd);
		hwnd->paintNC = mwpaintNC;
	}

	/* If ERASEMOVE:
	 * Don't allow windows to repaint while user is moving
	 * a window.  Instead, just erase backgrounds
	 * and indicate delayed painting required, which
	 * will occur after user completes window move.
	 */
	if(mwERASEMOVE && dragwp) {
		hdc = NULL;
		lpPaint->fErase = !DefWindowProc(hwnd, WM_ERASEBKGND, 0, 0L);
		hwnd->gotPaintMsg = PAINT_DELAYPAINT;
	} else {
		HideCaret(hwnd);

		/* FIXME: mdemo requires update excluded or draw errors occur*/
		hdc = GetDCEx(hwnd, NULL, DCX_DEFAULTCLIP
				|DCX_EXCLUDEUPDATE);	/* FIXME - bug*/

		/* erase client background*/
		lpPaint->fErase = !SendMessage(hwnd, WM_ERASEBKGND, (WPARAM)hdc,
			0L);
	}
	lpPaint->hdc = hdc;

	GetUpdateRect(hwnd, &lpPaint->rcPaint, FALSE);
	return hdc;
}

BOOL WINAPI 
EndPaint(HWND hwnd, CONST PAINTSTRUCT *lpPaint)
{
	ReleaseDC(hwnd, lpPaint->hdc);
#if UPDATEREGIONS
	/* don't clear update region until done dragging*/
	if(mwERASEMOVE && !dragwp)
		GdSetRectRegion(hwnd->update, 0, 0, 0, 0);
#endif
	ShowCaret(hwnd);
	return TRUE;
}

COLORREF WINAPI
SetTextColor(HDC hdc, COLORREF crColor)
{
	COLORREF	oldtextcolor;

	if (!hdc)
		return CLR_INVALID;
	oldtextcolor = hdc->textcolor;
	hdc->textcolor = (MWCOLORVAL)crColor;
	return oldtextcolor;
}

COLORREF WINAPI
SetBkColor(HDC hdc, COLORREF crColor)
{
	COLORREF	oldbkcolor;

	if (!hdc)
		return CLR_INVALID;
	oldbkcolor = hdc->bkcolor;
	hdc->bkcolor = crColor;
	return oldbkcolor;
}

int WINAPI
SetBkMode(HDC hdc, int iBkMode)
{
	int	oldbkmode;

	if(!hdc)
		return 0;
	oldbkmode = hdc->bkmode;
	hdc->bkmode = iBkMode;
	return oldbkmode;
}

UINT WINAPI
SetTextAlign(HDC hdc, UINT fMode)
{
	UINT	oldfMode;

	if(!hdc)
		return GDI_ERROR;
	oldfMode = hdc->textalign;
	hdc->textalign = fMode;
	return oldfMode;
}

/* FIXME: releasing a DC does NOT change back the drawing mode!*/
int WINAPI
SetROP2(HDC hdc, int fnDrawMode)
{
	int	newmode, oldmode;

	if(!hdc || (fnDrawMode <= 0 || fnDrawMode > R2_LAST))
		return 0;

	oldmode = hdc->drawmode;
	newmode = fnDrawMode - 1;	/* map to MWMODE_xxx*/
	hdc->drawmode = newmode;
	GdSetMode(newmode);
	return oldmode;
}

/* 
 * Setup clip region from device context's associated window or bitmap.
 * Memory DC's are always associated with the desktop window, and are
 * always visible.  Return the DC's hwnd if window is visible.
 */
HWND
MwPrepareDC(HDC hdc)
{
	HWND	hwnd;

	if(!hdc || !hdc->hwnd)
		return NULL;

	hwnd = hdc->hwnd;
	if (hwnd->unmapcount)
		return NULL;

	/*
	 * If the window is not the currently clipped one, then
	 * make it the current one and define its clip rectangles.
	 */
	if(hdc != cliphdc) {
		/* clip memory dc's to the bitmap size*/
		if(hdc->psd->flags&PSF_MEMORY) {
#if DYNAMICREGIONS
			GdSetClipRegion(hdc->psd,
				GdAllocRectRegion(0, 0, hdc->psd->xvirtres,
					hdc->psd->yvirtres));
#else
			static MWCLIPRECT crc = {0, 0, 0, 0};

			crc.width = hdc->psd->xvirtres;
			crc.height = hdc->psd->yvirtres;
			GdSetClipRects(hdc->psd, 1, &crc);
#endif
		} else MwSetClipWindow(hdc);
		cliphdc = hdc;
	}

	return hwnd;
}

/* return RGB value at specified coordinates*/
COLORREF WINAPI
GetPixel(HDC hdc, int x, int y)
{
	HWND		hwnd;
	POINT		pt;
	MWPIXELVAL	pixel;
	MWPALENTRY	rgb;

	hwnd = MwPrepareDC(hdc);
	if(!hwnd)
		return CLR_INVALID;
	pt.x = x;
	pt.y = y;
	if(MwIsClientDC(hdc))
		ClientToScreen(hwnd, &pt);

	/* read pixel value*/
	GdReadArea(hdc->psd, pt.x, pt.y, 1, 1, &pixel);

	switch(hdc->psd->pixtype) {
	case MWPF_TRUECOLOR0888:
	case MWPF_TRUECOLOR888:
		/* create RGB colorval from 8/8/8 pixel*/
		return PIXEL888TOCOLORVAL(pixel);

	case MWPF_TRUECOLOR565:
		/* create RGB colorval from 5/6/5 pixel*/
		return PIXEL565TOCOLORVAL(pixel);

	case MWPF_TRUECOLOR555:
		/* create RGB colorval from 5/5/5 pixel*/
		return PIXEL555TOCOLORVAL(pixel);

	case MWPF_TRUECOLOR332:
		/* create RGB colorval from 3/3/2 pixel*/
		return PIXEL332TOCOLORVAL(pixel);

	case MWPF_TRUECOLOR233:
		/* create RGB colorval from 2/3/3 pixel*/
		return PIXEL233TOCOLORVAL(pixel);

	case MWPF_PALETTE:
		if(GdGetPalette(hdc->psd, pixel, 1, &rgb))
			return RGB(rgb.r, rgb.g, rgb.b);
	}
	return CLR_INVALID;
}

COLORREF WINAPI
SetPixel(HDC hdc, int x, int y, COLORREF crColor)
{
	HWND		hwnd;
	POINT		pt;

	hwnd = MwPrepareDC(hdc);
	if(!hwnd)
		return 0;	/* doesn't return previous color*/
	pt.x = x;
	pt.y = y;
	if(MwIsClientDC(hdc))
		ClientToScreen(hwnd, &pt);

	/* draw point in passed color*/
	GdSetForeground(GdFindColor(crColor));
	GdPoint(hdc->psd, pt.x, pt.y);
	return 0;		/* doesn't return previous color*/
}

BOOL WINAPI 
MoveToEx(HDC hdc, int x, int y, LPPOINT lpPoint)
{
	if(!hdc)
		return FALSE;
	if(lpPoint)
		*lpPoint = hdc->pt;
	hdc->pt.x = x;
	hdc->pt.y = y;
	return TRUE;
}

BOOL WINAPI
LineTo(HDC hdc, int x, int y)
{
	HWND		hwnd;
	POINT		beg, end;

	hwnd = MwPrepareDC(hdc);
	if(!hwnd)
		return FALSE;

	beg.x = hdc->pt.x;
	beg.y = hdc->pt.y;
	end.x = x;
	end.y = y;
	if(MwIsClientDC(hdc)) {
		ClientToScreen(hwnd, &beg);
		ClientToScreen(hwnd, &end);
	}

	/* draw line in current pen color*/
	if(hdc->pen->style != PS_NULL) {
		GdSetForeground(GdFindColor(hdc->pen->color));
		/* don't draw last point*/
		GdLine(hdc->psd, beg.x, beg.y, end.x, end.y, FALSE);
	}
	hdc->pt.x = x;
	hdc->pt.y = y;
	return TRUE;
}

/* draw line segments by connecting passed points*/
BOOL WINAPI
Polyline(HDC hdc, CONST POINT *lppt, int cPoints)
{
	HWND		hwnd;
	POINT		beg, end;

	if(cPoints <= 1)
		return FALSE;

	hwnd = MwPrepareDC(hdc);
	if(!hwnd)
		return FALSE;

	if(hdc->pen->style == PS_NULL)
		return TRUE;

	/* draw line in current pen color*/
	GdSetForeground(GdFindColor(hdc->pen->color));

	beg = *lppt++;
	if(MwIsClientDC(hdc))
		ClientToScreen(hwnd, &beg);
	while(--cPoints > 0) {
		end = *lppt++;
		if(MwIsClientDC(hdc))
			ClientToScreen(hwnd, &end);

		/* don't draw last point*/
		GdLine(hdc->psd, beg.x, beg.y, end.x, end.y, FALSE);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -