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

📄 guicurs.c

📁 MCB2300_ucgui_LCD320240.rar LPC2368的uc/gui的移植
💻 C
字号:
/*
*********************************************************************************************************
*   											 uC/GUI
*   					 Universal graphic software for embedded applications
*
*   					(c) Copyright 2002, Micrium Inc., Weston, FL
*   					(c) Copyright 2002, SEGGER Microcontroller Systeme GmbH
*
*   		   礐/GUI is protected by international copyright laws. Knowledge of the
*   		   source code may not be used to write a similar product. This file may
*   		   only be used in accordance with a license and should not be redistributed
*   		   in any way. We appreciate your understanding and fairness.
*
----------------------------------------------------------------------
File		: GUICurs.C
Purpose 	: Cursor routines of the graphics library
---------------------------END-OF-HEADER------------------------------
*/

#include <stddef.h> 		  /* needed for definition of NULL */
#include "GUI_Private.h"

#if GUI_SUPPORT_CURSOR

/*********************************************************************
*
*   	static data
*
**********************************************************************
*/

static GUI_HMEM 		 _hBuffer;
static GUI_RECT 		 _Rect;
static char 			 _CursorIsVis;  	  /* Currently visible ? */
static char 			 _CursorOn;
static const GUI_CURSOR GUI_UNI_PTR * _pCursor;
static U8   			 _CursorDeActCnt;
static int  			 _AllocSize;
static int  			 _x, _y;			  /* Position of hot spot */
static GUI_RECT 		 _ClipRect;
static LCD_PIXELINDEX    _ColorIndex[4];	  /* Color-Cache */

/*********************************************************************
*
*   	static code, helper functions
*
**********************************************************************
*/
/*********************************************************************
*
*   	_SetPixelIndex
*
* Purpose
*   Sets the pixel index for the Cursor.
*   Note the following:
*   - We do the clipping in this routine
*   - We do NOT call the driver directly, but thru its API table.
*     This allows others (e.g. the VNC server) to be in the loop-
*/
static void _SetPixelIndex(int x, int y, int Index)
{
	if ((y >= _ClipRect.y0) && (y <= _ClipRect.y1))
	{
		if ((x >= _ClipRect.x0) && (x <= _ClipRect.x1))
		{
			LCD_aAPI[0]->pfSetPixelIndex(x, y, Index);
		}
	}
}

/*********************************************************************
*
*   	_GetPixelIndex
*
* Purpose
*   Gets a pixel index for the Cursor.
*/
static int _GetPixelIndex(int x, int y)
{
	if ((y >= _ClipRect.y0) && (y <= _ClipRect.y1))
	{
		if ((x >= _ClipRect.x0) && (x <= _ClipRect.x1))
		{
			return LCD_L0_GetPixelIndex(x, y);
		}
	}
	return 0;
}

/*********************************************************************
*
*   	_Undraw
*
* Purpose
*   Remove the cursors
*/
static void _Undraw(void)
{
	int x, y, xSize, ySize;
	LCD_PIXELINDEX* pData;
	/* Save bitmap data */
	GUI_LOCK();
	if (_hBuffer)
	{
		pData = (LCD_PIXELINDEX *) GUI_ALLOC_h2p(_hBuffer);
		xSize = _Rect.x1 - _Rect.x0 + 1;
		ySize = _Rect.y1 - _Rect.y0 + 1;
		for (y = 0; y < ySize; y++)
		{
			for (x = 0; x < xSize; x++)
			{
				_SetPixelIndex(x + _Rect.x0, y + _Rect.y0, *(pData + x));
			}
			pData += _pCursor->pBitmap->XSize;
		}
	}
	GUI_UNLOCK();
}

/*********************************************************************
*
*   	_Log2Phys
*/
static int _Log2Phys(int Index)
{
	if (Index < 4)
	{
		return _ColorIndex[Index];
	}
	else
	{
		LCD_COLOR Color = *(_pCursor->pBitmap->pPal->pPalEntries + Index);
		return LCD_Color2Index(Color);
	}
}

/*********************************************************************
*
*   	_Draw
*/
static void _Draw(void)
{
	int x, y, xSize, ySize;
	LCD_PIXELINDEX* pData;
	const GUI_BITMAP GUI_UNI_PTR * pBM;
	GUI_LOCK();
	if (_hBuffer)
	{
		/* Save bitmap data */
		pBM = _pCursor->pBitmap;
		pData = (LCD_PIXELINDEX *) GUI_ALLOC_h2p(_hBuffer);
		xSize = _Rect.x1 - _Rect.x0 + 1;
		ySize = _Rect.y1 - _Rect.y0 + 1;
		for (y = 0; y < ySize; y++)
		{
			for (x = 0; x < xSize; x++)
			{
				int BitmapPixel;
				*(pData + x) = _GetPixelIndex(_Rect.x0 + x, _Rect.y0 + y);
				BitmapPixel = GUI_GetBitmapPixelIndex(pBM, x, y);
				if (BitmapPixel)
				{
					_SetPixelIndex(_Rect.x0 + x, _Rect.y0 + y, _Log2Phys(BitmapPixel));
				}
			}
			pData += pBM->XSize;
		}
	}
	GUI_UNLOCK();
}

/*********************************************************************
*
*   	_CalcRect
*/
static void _CalcRect(void)
{
	if (_pCursor)
	{
		_Rect.x0 = _x - _pCursor->xHot;
		_Rect.y0 = _y - _pCursor->yHot;
		_Rect.x1 = _Rect.x0 + _pCursor->pBitmap->XSize - 1;
		_Rect.y1 = _Rect.y0 + _pCursor->pBitmap->YSize - 1;
	}
}

/*********************************************************************
*
*   	_Hide
*/
static void _Hide(void)
{
	if (_CursorIsVis)
	{
		_Undraw();
		_CursorIsVis = 0;
	}
}

/*********************************************************************
*
*   	_Show
*/
static void _Show(void)
{
	if (_CursorOn && (_CursorDeActCnt == 0))
	{
		_CursorIsVis = 1;
		_Draw();
	}
}

/*********************************************************************
*
*   	_TempHide
*
* Purpose:
*   Hide cursor if a part of the given rectangle is located in the
*   rectangle used for the cursor. This routine is called automatically
*   by the window manager. This way the window manager can
*   automatically make sure that the cursor is always displayed
*   correctly.
*
* Params:
*   pRect   Rectangle under consideration
*
* Return value:
*   0:  	No action taken
*   		Cursor was not visible or not affected because rectangles
*   		did not overlap
*   1:  	Cursor hidden -> WM needs to restore cursor after
*   		drawing operation
*/
static char _TempHide(const GUI_RECT *pRect)
{
	if (!_CursorIsVis)
	{
		return 0;   		  /* Cursor not visible -> nothing to do */
	}
	if ((pRect == NULL) || GUI_RectsIntersect(pRect, &_Rect))
	{
		_Hide();			  /* Cursor needs to be hidden */
		return 1;
	}
	return 0;   			/* Cursor not affected -> nothing to do */
}

/*********************************************************************
*
*   	_TempUnhide
*/
static void _TempUnhide(void)
{
	_Show();
}

/*********************************************************************
*
*   	Public code
*
**********************************************************************
*/
/*********************************************************************
*
*   	GUI_CURSOR_Activate
*/
void GUI_CURSOR_Activate(void)
{
	GUI_LOCK();
	if ((--_CursorDeActCnt) == 0)
	{
		_Show();
	}
	GUI_UNLOCK();
}

/*********************************************************************
*
*   	GUI_CURSOR_Deactivate
*/
void GUI_CURSOR_Deactivate(void)
{
	GUI_LOCK();
	if (_CursorDeActCnt++ == 0)
	{
		_Hide();
	}
	GUI_UNLOCK();
}

/*********************************************************************
*
*   	GUI_CURSOR_Select
*/
const GUI_CURSOR GUI_UNI_PTR * GUI_CURSOR_Select(const GUI_CURSOR GUI_UNI_PTR *pCursor)
{
	int AllocSize;
	const GUI_BITMAP GUI_UNI_PTR * pBM;
	const GUI_CURSOR GUI_UNI_PTR * pOldCursor;
	GUI_LOCK();
	pOldCursor = _pCursor;
	if (pCursor != _pCursor)
	{
		int i;
		pBM = pCursor->pBitmap;
		i = pBM->pPal->NumEntries > 4 ? 4 : pBM->pPal->NumEntries;
		while (i--)
		{
			LCD_COLOR Color = *(pBM->pPal->pPalEntries + i);
			_ColorIndex[i] = LCD_Color2Index(Color);
		}
		_Hide();
		AllocSize = pBM->XSize * pBM->YSize * sizeof(LCD_PIXELINDEX);
		if (AllocSize != _AllocSize)
		{
			GUI_ALLOC_Free(_hBuffer);
			_hBuffer = 0;
		}
		_hBuffer = GUI_ALLOC_AllocZero(AllocSize);
		_CursorOn = 1;
		_pCursor = pCursor;
		_CalcRect();
		_Show();
	}
	GUI_UNLOCK();
	return pOldCursor;
}

/*********************************************************************
*
*   	GUI_CURSOR_Hide
*/
void GUI_CURSOR_Hide(void)
{
	GUI_LOCK();
	_Hide();
	_CursorOn = 0;
	/* Set function pointer which window manager can use */
	GUI_CURSOR_pfTempHide = NULL;
	GUI_CURSOR_pfTempUnhide = NULL;
	GUI_UNLOCK();
}

/*********************************************************************
*
*   	GUI_CURSOR_Show
*/
void GUI_CURSOR_Show(void)
{
	GUI_LOCK();
	LCDDEV_L0_GetRect(&_ClipRect);
	_Hide();
	_CursorOn = 1;
	/* Set function pointer which window manager can use */
	GUI_CURSOR_pfTempHide = _TempHide;
	GUI_CURSOR_pfTempUnhide = _TempUnhide;
	if (!_pCursor)
	{
		GUI_CURSOR_Select(GUI_DEFAULT_CURSOR);
	}
	else
	{
		_Show();
	}
	GUI_UNLOCK();
}

/*********************************************************************
*
*   	GUI_CURSOR_SetPosition
*/
void GUI_CURSOR_SetPosition(int xNewPos, int yNewPos)
{
	int x, xStart, xStep, xEnd, xOff, xOverlapMin, xOverlapMax;
	int y, yStart, yStep, yEnd, yOff, yOverlapMin, yOverlapMax;
	int xSize;
	LCD_PIXELINDEX* pData;
	GUI_LOCK();
	if (_hBuffer)
	{
		if ((_x != xNewPos) | (_y != yNewPos))
		{
			if (_CursorOn)
			{
				const GUI_BITMAP GUI_UNI_PTR * pBM = _pCursor->pBitmap;
				/* Save & set clip rect */
				/* Compute helper variables */
				pData = (LCD_PIXELINDEX *) GUI_ALLOC_h2p(_hBuffer);
				xSize = _pCursor->pBitmap->XSize;
				xOff = xNewPos - _x;
				if (xOff > 0)
				{
					xStep = 1;
					xStart = 0;
					xEnd = _pCursor->pBitmap->XSize;
					xOverlapMax = xEnd - 1;
					xOverlapMin = xOff;
				}
				else
				{
					xStep = -1;
					xStart = xSize - 1;
					xEnd = -1;
					xOverlapMin = 0;
					xOverlapMax = xStart + xOff;
				}
				yOff = yNewPos - _y;
				if (yOff > 0)
				{
					yStep = 1;
					yStart = 0;
					yEnd = _pCursor->pBitmap->YSize;
					yOverlapMax = yEnd - 1;
					yOverlapMin = yOff;
				}
				else
				{
					yStep = -1;
					yStart = _pCursor->pBitmap->YSize - 1;
					yEnd = -1;
					yOverlapMin = 0;
					yOverlapMax = yStart + yOff;
				}
				/* Restore & Draw */
				for (y = yStart; y != yEnd; y += yStep)
				{
					char yOverlaps;
					char yNewOverlaps;
					int yNew = y + yOff;
					yOverlaps = (y >= yOverlapMin) && (y <= yOverlapMax);
					yNewOverlaps = (yNew >= yOverlapMin) && (yNew <= yOverlapMax);
					for (x = xStart; x != xEnd; x += xStep)
					{
						char xyOverlaps, xyNewOverlaps;
						int BitmapPixel;
						LCD_PIXELINDEX Pixel;
						LCD_PIXELINDEX* pSave = pData + x + y *xSize;
						int xNew = x + xOff;
						BitmapPixel = GUI_GetBitmapPixelIndex(pBM, x, y);
						xyOverlaps = (x >= xOverlapMin) && (x <= xOverlapMax) && yOverlaps;
						xyNewOverlaps = (xNew >= xOverlapMin) && (xNew <= xOverlapMax) && yNewOverlaps;
						/* Restore old pixel if it was not transparent */
						if (BitmapPixel)
						{
							if (!xyOverlaps || (GUI_GetBitmapPixelIndex(pBM, x - xOff, y - yOff) == 0))
							{
								_SetPixelIndex(x + _Rect.x0, y + _Rect.y0, *(pSave));
							}
						}
						/* Save */
						if (xyNewOverlaps)
						{
							Pixel = *(pData + xNew + yNew * xSize);
						}
						else
						{
							Pixel = _GetPixelIndex(_Rect.x0 + xNew, _Rect.y0 + yNew);
						}
						*pSave = Pixel;
						/* Write new  ... We could write pixel by pixel here */
						if (BitmapPixel)
						{
							LCD_PIXELINDEX NewPixel = _Log2Phys(BitmapPixel);
							_SetPixelIndex(_Rect.x0 + xNew, _Rect.y0 + yNew, NewPixel);
						}
					}
				}
			}
			_x = xNewPos;
			_y = yNewPos;
			_CalcRect();
		}
	}
	GUI_UNLOCK();
}

#else

void GUICurs_C(void);
void GUICurs_C(void)
{
} /* avoid empty object files */

#endif   /* GUI_SUPPORT_CURSOR */

/*************************** End of file ****************************/

⌨️ 快捷键说明

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